code: def run(model: BaseModel, dataset: BaseDataset, device, cfg):
      reg_thresh = cfg.data.registration_recall_thresh
      if reg_thresh is None:
          reg_thresh = 0.2
      print(time.strftime("%Y%m%d-%H%M%S"))
      dataset.create_dataloaders(
          model,
          1,
          False,
          cfg.training.num_workers,
          False,
      )
      loader = dataset.test_dataloaders[0]
      list_res = []
      with Ctq(loader) as tq_test_loader:
          for i, data in enumerate(tq_test_loader):
              with torch.no_grad():
                  t0 = time.time()
                  model.set_input(data, device)
                  model.forward()
                  t1 = time.time()
                  (
                      name_scene,
                      name_pair_source,
                      name_pair_target,
                  ) = dataset.test_dataset[0].get_name(i)
                  input, input_target = model.get_input()
                  xyz, xyz_target = input.pos, input_target.pos
                  ind, ind_target = input.ind, input_target.ind
                  matches_gt = torch.stack([ind, ind_target]).transpose(
                      0, 1
                  )
                  feat, feat_target = model.get_output()
                  # rand = voxel_selection(xyz, grid_size=0.06, min_points=cfg.data.min_points)
                  # rand_target = voxel_selection(xyz_target, grid_size=0.06, min_points=cfg.data.min_points)
  
                  rand = torch.randperm(len(feat))[
                      : cfg.data.num_points
                  ]
                  rand_target = torch.randperm(len(feat_target))[
                      : cfg.data.num_points
                  ]
                  res = dict(
                      name_scene=name_scene,
                      name_pair_source=name_pair_source,
                      name_pair_target=name_pair_target,
                  )
                  T_gt = estimate_transfo(
                      xyz[matches_gt[:, 0]],
                      xyz_target[matches_gt[:, 1]],
                  )
                  t2 = time.time()
                  metric = compute_metrics(
                      xyz[rand],
                      xyz_target[rand_target],
                      feat[rand],
                      feat_target[rand_target],
                      T_gt,
                      sym=cfg.data.sym,
                      tau_1=cfg.data.tau_1,
                      tau_2=cfg.data.tau_2,
                      rot_thresh=cfg.data.rot_thresh,
                      trans_thresh=cfg.data.trans_thresh,
                      use_ransac=cfg.data.use_ransac,
                      ransac_thresh=cfg.data.first_subsampling,
                      use_teaser=cfg.data.use_teaser,
                      noise_bound_teaser=cfg.data.noise_bound_teaser,
                      xyz_gt=xyz[matches_gt[:, 0]],
                      xyz_target_gt=xyz_target[matches_gt[:, 1]],
                      registration_recall_thresh=reg_thresh,
                  )
                  res = dict(**res, **metric)
                  res["time_feature"] = t1 - t0
                  res["time_feature_per_point"] = (t1 - t0) / (
                      len(input.pos) + len(input_target.pos)
                  )
                  res["time_prep"] = t2 - t1
  
                  list_res.append(res)
  
      df = pd.DataFrame(list_res)
      output_path = os.path.join(
          cfg.training.checkpoint_dir, cfg.data.name, "matches"
      )
      if not os.path.exists(output_path):
          os.makedirs(output_path, exist_ok=True)
      df.to_csv(
          osp.join(
              output_path,
              "final_res_{}.csv".format(time.strftime("%Y%m%d-%H%M%S")),
          )
      )
      print(df.groupby("name_scene").mean())
  
imports: import copy
  import open3d
  import torch
  import hydra
  import logging
  from omegaconf import OmegaConf
  import os
  import os.path
  import sys
  import pandas
  import time
  from torch_points3d.models.model_factory import instantiate_model
  from torch_points3d.datasets.dataset_factory import instantiate_dataset, get_dataset_class
  from torch_points3d.models.base_model import BaseModel
  from torch_points3d.datasets.base_dataset import BaseDataset
  from torch_points3d.utils.registration import estimate_transfo, teaser_pp_registration, fast_global_registration, get_matches
  from torch_points3d.metrics.registration_metrics import compute_hit_ratio, compute_transfo_error, compute_scaled_registration_error, compute_registration_recall
  from torch_points3d.metrics.colored_tqdm import Coloredtqdm
  from torch_points3d.metrics.model_checkpoint import ModelCheckpoint
label_desc: Use image node_id 2 for calling a global function with example usage: run(model, dataset, device, cfg) without return types