code: def perform_clustering(
      embs_and_timestamps,
      AUDIO_RTTM_MAP,
      out_rttm_dir,
      clustering_params,
      device,
      verbose: bool = True,
  ):
      """
      Performs spectral clustering on embeddings with time stamps generated from VAD output
  
      Args:
          embs_and_timestamps (dict): This dictionary contains the following items indexed by unique IDs.
              'embeddings' : Tensor containing embeddings. Dimensions:(# of embs) x (emb. dimension)
              'timestamps' : Tensor containing ime stamps list for each audio recording
              'multiscale_segment_counts' : Tensor containing the number of segments for each scale
          AUDIO_RTTM_MAP (dict): AUDIO_RTTM_MAP for mapping unique id with audio file path and rttm path
          out_rttm_dir (str): Path to write predicted rttms
          clustering_params (dict): clustering parameters provided through config that contains max_num_speakers (int),
          oracle_num_speakers (bool), max_rp_threshold(float), sparse_search_volume(int) and enhance_count_threshold (int)
          use_torch_script (bool): Boolean that determines whether to use torch.jit.script for speaker clustering
          device (torch.device): Device we are running on ('cpu', 'cuda').
          verbose (bool): Enable TQDM progress bar.
  
      Returns:
          all_reference (list[uniq_name,Annotation]): reference annotations for score calculation
          all_hypothesis (list[uniq_name,Annotation]): hypothesis annotations for score calculation
  
      """
      all_hypothesis = []
      all_reference = []
      no_references = False
      lines_cluster_labels = []
  
      cuda = True
      if device.type != "cuda":
          logging.warning(
              "cuda=False, using CPU for eigen decomposition. This might slow down the clustering process."
          )
          cuda = False
  
      speaker_clustering = LongFormSpeakerClustering(cuda=cuda)
  
      if clustering_params.get("export_script_module", False):
          speaker_clustering = torch.jit.script(speaker_clustering)
          torch.jit.save(
              speaker_clustering, "speaker_clustering_script.pt"
          )
  
      for uniq_id, audio_rttm_values in tqdm(
          AUDIO_RTTM_MAP.items(),
          desc="clustering",
          leave=True,
          disable=not verbose,
      ):
          uniq_embs_and_timestamps = embs_and_timestamps[uniq_id]
  
          if clustering_params.oracle_num_speakers:
              num_speakers = audio_rttm_values.get("num_speakers", None)
              if num_speakers is None:
                  raise ValueError(
                      "Provided option as oracle num of speakers but num_speakers in manifest is null"
                  )
          else:
              num_speakers = -1
  
          base_scale_idx = (
              uniq_embs_and_timestamps[
                  "multiscale_segment_counts"
              ].shape[0]
              - 1
          )
  
          cluster_labels = speaker_clustering.forward_infer(
              embeddings_in_scales=uniq_embs_and_timestamps[
                  "embeddings"
              ],
              timestamps_in_scales=uniq_embs_and_timestamps[
                  "timestamps"
              ],
              multiscale_segment_counts=uniq_embs_and_timestamps[
                  "multiscale_segment_counts"
              ],
              multiscale_weights=uniq_embs_and_timestamps[
                  "multiscale_weights"
              ],
              oracle_num_speakers=int(num_speakers),
              max_num_speakers=int(clustering_params.max_num_speakers),
              max_rp_threshold=float(
                  clustering_params.max_rp_threshold
              ),
              sparse_search_volume=int(
                  clustering_params.sparse_search_volume
              ),
              chunk_cluster_count=clustering_params.get(
                  "chunk_cluster_count", None
              ),
              embeddings_per_chunk=clustering_params.get(
                  "embeddings_per_chunk", None
              ),
          )
  
          del uniq_embs_and_timestamps
          if cuda:
              torch.cuda.empty_cache()
          else:
              gc.collect()
          timestamps = speaker_clustering.timestamps_in_scales[
              base_scale_idx
          ]
  
          cluster_labels = cluster_labels.cpu().numpy()
          if len(cluster_labels) != timestamps.shape[0]:
              raise ValueError(
                  "Mismatch of length between cluster_labels and timestamps."
              )
  
          labels, lines = generate_cluster_labels(
              timestamps, cluster_labels
          )
  
          if out_rttm_dir:
              labels_to_rttmfile(labels, uniq_id, out_rttm_dir)
              lines_cluster_labels.extend(
                  [f"{uniq_id} {seg_line}\n" for seg_line in lines]
              )
          hypothesis = labels_to_pyannote_object(
              labels, uniq_name=uniq_id
          )
          all_hypothesis.append([uniq_id, hypothesis])
  
          rttm_file = audio_rttm_values.get("rttm_filepath", None)
          if (
              rttm_file is not None
              and os.path.exists(rttm_file)
              and not no_references
          ):
              ref_labels = rttm_to_labels(rttm_file)
              reference = labels_to_pyannote_object(
                  ref_labels, uniq_name=uniq_id
              )
              all_reference.append([uniq_id, reference])
          else:
              no_references = True
              all_reference = []
  
      if out_rttm_dir:
          write_cluster_labels(
              base_scale_idx, lines_cluster_labels, out_rttm_dir
          )
  
      return all_reference, all_hypothesis
  
imports: import gc
  import json
  import math
  import os
  import shutil
  from copy import deepcopy
  from typing import Dict, List, Tuple, Union
  import numpy
  import omegaconf
  import soundfile
  import torch
  from pyannote.core import Annotation, Segment
  from tqdm import tqdm
  from nemo.collections.asr.data.audio_to_label import repeat_signal
  from nemo.collections.asr.parts.utils.longform_clustering import LongFormSpeakerClustering
  from nemo.collections.asr.parts.utils.offline_clustering import SpeakerClustering, get_argmin_mat, split_input_data
  from nemo.utils import logging
label_desc: Use image node_id 17 for calling a global function with example usage: perform_clustering(embs_and_timestamps, AUDIO_RTTM_MAP, out_rttm_dir, clustering_params, device, verbose) and returns: all_reference,  all_hypothesis