code: def perform_test(test_loader, model, test_meter, cfg, writer=None):
      """
      For classification:
      Perform mutli-view testing that uniformly samples N clips from a video along
      its temporal axis. For each clip, it takes 3 crops to cover the spatial
      dimension, followed by averaging the softmax scores across all Nx3 views to
      form a video-level prediction. All video predictions are compared to
      ground-truth labels and the final testing performance is logged.
      For detection:
      Perform fully-convolutional testing on the full frames without crop.
      Args:
          test_loader (loader): video testing loader.
          model (model): the pretrained video model to test.
          test_meter (TestMeter): testing meters to log and ensemble the testing
              results.
          cfg (CfgNode): configs. Details can be found in
              slowfast/config/defaults.py
          writer (TensorboardWriter object, optional): TensorboardWriter object
              to writer Tensorboard log.
      """
      # Enable eval mode.
      model.eval()
      test_meter.iter_tic()
  
      for cur_iter, (
          inputs,
          labels,
          video_idx,
          time,
          meta,
      ) in enumerate(test_loader):
          if cfg.NUM_GPUS:
              # Transfer the data to the current GPU device.
              if isinstance(inputs, (list,)):
                  for i in range(len(inputs)):
                      inputs[i] = inputs[i].cuda(non_blocking=True)
              else:
                  inputs = inputs.cuda(non_blocking=True)
              # Transfer the data to the current GPU device.
              labels = labels.cuda()
              video_idx = video_idx.cuda()
              for key, val in meta.items():
                  if isinstance(val, (list,)):
                      for i in range(len(val)):
                          val[i] = val[i].cuda(non_blocking=True)
                  else:
                      meta[key] = val.cuda(non_blocking=True)
          test_meter.data_toc()
  
          if cfg.DETECTION.ENABLE:
              # Compute the predictions.
              preds = model(inputs, meta["boxes"])
              ori_boxes = meta["ori_boxes"]
              metadata = meta["metadata"]
  
              preds = (
                  preds.detach().cpu()
                  if cfg.NUM_GPUS
                  else preds.detach()
              )
              ori_boxes = (
                  ori_boxes.detach().cpu()
                  if cfg.NUM_GPUS
                  else ori_boxes.detach()
              )
              metadata = (
                  metadata.detach().cpu()
                  if cfg.NUM_GPUS
                  else metadata.detach()
              )
  
              if cfg.NUM_GPUS > 1:
                  preds = torch.cat(
                      du.all_gather_unaligned(preds), dim=0
                  )
                  ori_boxes = torch.cat(
                      du.all_gather_unaligned(ori_boxes), dim=0
                  )
                  metadata = torch.cat(
                      du.all_gather_unaligned(metadata), dim=0
                  )
  
              test_meter.iter_toc()
              # Update and log stats.
              test_meter.update_stats(preds, ori_boxes, metadata)
              test_meter.log_iter_stats(None, cur_iter)
          elif (
              cfg.TASK == "ssl"
              and cfg.MODEL.MODEL_NAME == "ContrastiveModel"
          ):
              if not cfg.CONTRASTIVE.KNN_ON:
                  test_meter.finalize_metrics()
                  return test_meter
              # preds = model(inputs, video_idx, time)
              train_labels = (
                  model.module.train_labels
                  if hasattr(model, "module")
                  else model.train_labels
              )
              yd, yi = model(inputs, video_idx, time)
              batchSize = yi.shape[0]
              K = yi.shape[1]
              C = (
                  cfg.CONTRASTIVE.NUM_CLASSES_DOWNSTREAM
              )  # eg 400 for Kinetics400
              candidates = train_labels.view(1, -1).expand(
                  batchSize, -1
              )
              retrieval = torch.gather(candidates, 1, yi)
              retrieval_one_hot = torch.zeros((batchSize * K, C)).cuda()
              retrieval_one_hot.scatter_(1, retrieval.view(-1, 1), 1)
              yd_transform = yd.clone().div_(cfg.CONTRASTIVE.T).exp_()
              probs = torch.mul(
                  retrieval_one_hot.view(batchSize, -1, C),
                  yd_transform.view(batchSize, -1, 1),
              )
              preds = torch.sum(probs, 1)
          else:
              # Perform the forward pass.
              preds = model(inputs)
          # Gather all the predictions across all the devices to perform ensemble.
          if cfg.NUM_GPUS > 1:
              preds, labels, video_idx = du.all_gather(
                  [preds, labels, video_idx]
              )
          if cfg.NUM_GPUS:
              preds = preds.cpu()
              labels = labels.cpu()
              video_idx = video_idx.cpu()
  
          test_meter.iter_toc()
  
          if not cfg.VIS_MASK.ENABLE:
              # Update and log stats.
              test_meter.update_stats(
                  preds.detach(), labels.detach(), video_idx.detach()
              )
          test_meter.log_iter_stats(cur_iter)
  
          test_meter.iter_tic()
  
      # Log epoch stats and print the final testing results.
      if not cfg.DETECTION.ENABLE:
          all_preds = test_meter.video_preds.clone().detach()
          all_labels = test_meter.video_labels
          if cfg.NUM_GPUS:
              all_preds = all_preds.cpu()
              all_labels = all_labels.cpu()
          if writer is not None:
              writer.plot_eval(preds=all_preds, labels=all_labels)
  
          if cfg.TEST.SAVE_RESULTS_PATH != "":
              save_path = os.path.join(
                  cfg.OUTPUT_DIR, cfg.TEST.SAVE_RESULTS_PATH
              )
  
              if du.is_root_proc():
                  with pathmgr.open(save_path, "wb") as f:
                      pickle.dump([all_preds, all_labels], f)
  
              logger.info(
                  "Successfully saved prediction results to {}".format(
                      save_path
                  )
              )
  
      test_meter.finalize_metrics()
      return test_meter
  
file_path: SlowFast/tools/test_net.py
imports: import numpy
  import os
  import pickle
  import torch
  import slowfast.utils.checkpoint
  import slowfast.utils.distributed
  import slowfast.utils.logging
  import slowfast.utils.misc
  import slowfast.visualization.tensorboard_vis
  from slowfast.datasets import loader
  from slowfast.models import build_model
  from slowfast.utils.env import pathmgr
  from slowfast.utils.meters import AVAMeter, TestMeter
label_desc: Use image node_id 1 for calling a global function with example usage: perform_test(test_loader, model, test_meter, cfg, writer) and returns: test_meter, test_meter