class_docstr: First version of Epistemic computation used as active learning strategy
class_docstr_tok: ["First","version","of","Epistemic","computation","used","as","active","learning","strategy"]
code: def __call__(self, request, datastore: Datastore):
      logger.info("Starting Epistemic Uncertainty scoring")
  
      model_file = self.infer_task.get_path()
      model_ts = (
          int(os.stat(model_file).st_mtime)
          if model_file and os.path.exists(model_file)
          else 1
      )
      self.infer_task.clear_cache()
  
      # Performing Epistemic for all unlabeled images
      skipped = 0
      unlabeled_images = datastore.get_unlabeled_images()
      max_samples = request.get("max_samples", self.max_samples)
      simulation_size = request.get(
          "simulation_size", self.simulation_size
      )
      if simulation_size < 2:
          simulation_size = 2
          logger.warning(
              "EPISTEMIC:: Fixing 'simulation_size=2' as min 2 simulations are needed to compute entropy"
          )
  
      logger.info(
          f"EPISTEMIC:: Total unlabeled images: {len(unlabeled_images)}; max_samples: {max_samples}"
      )
      t_start = time.time()
  
      image_ids = []
      for image_id in unlabeled_images:
          image_info = datastore.get_image_info(image_id)
          prev_ts = image_info.get("epistemic_ts", 0)
          if prev_ts == model_ts:
              skipped += 1
              continue
          image_ids.append(image_id)
      image_ids = image_ids[:max_samples] if max_samples else image_ids
  
      max_workers = request.get("max_workers", 2)
      multi_gpu = request.get("multi_gpu", False)
      multi_gpus = request.get("gpus", "all")
      gpus = (
          list(range(torch.cuda.device_count()))
          if not multi_gpus or multi_gpus == "all"
          else multi_gpus.split(",")
      )
      device = name_to_device(request.get("device", "cuda"))
      device_ids = (
          [f"cuda:{id}" for id in gpus] if multi_gpu else [device]
      )
  
      max_workers = (
          max_workers
          if max_workers
          else max(1, multiprocessing.cpu_count() // 2)
      )
      max_workers = min(max_workers, multiprocessing.cpu_count())
  
      if len(image_ids) > 1 and (max_workers == 0 or max_workers > 1):
          logger.info(
              f"MultiGpu: {multi_gpu}; Using Device(s): {device_ids}; Max Workers: {max_workers}"
          )
          futures = []
          with ThreadPoolExecutor(
              max_workers if max_workers else None, "ScoreInfer"
          ) as e:
              for image_id in image_ids:
                  futures.append(
                      e.submit(
                          self.run_scoring,
                          image_id,
                          simulation_size,
                          model_ts,
                          datastore,
                      )
                  )
              for future in futures:
                  future.result()
      else:
          for image_id in image_ids:
              self.run_scoring(
                  image_id, simulation_size, model_ts, datastore
              )
  
      summary = {
          "total": len(unlabeled_images),
          "skipped": skipped,
          "executed": len(image_ids),
          "latency": round(time.time() - t_start, 3),
      }
  
      logger.info(f"EPISTEMIC:: {summary}")
      self.infer_task.clear_cache()
      return summary
  
file_path: MONAILabel/monailabel/tasks/scoring/epistemic_v2.py
imports: import logging
  import multiprocessing
  import os
  import time
  from concurrent.futures import ThreadPoolExecutor
  import numpy
  import torch
  from monai.metrics.active_learning_metrics import VarianceMetric
  from monailabel.interfaces.datastore import Datastore
  from monailabel.interfaces.tasks.scoring import ScoringMethod
  from monailabel.tasks.infer.basic_infer import BasicInferTask
  from monailabel.utils.others.generic import name_to_device
label_desc: Use image node_id 4 for calling the EpistemicScoring obj's underlying member method code with example usage: obj.__call__(request, datastore) and returns: summary