code: def training(local_rank, config, logger, with_clearml):
      rank = idist.get_rank()
      manual_seed(config.seed + local_rank)
  
      train_loader = config.train_loader
      val_loader = config.val_loader
      train_eval_loader = config.train_eval_loader
  
      model, optimizer, criterion = utils.initialize(config)
  
      # Setup trainer for this specific task
      trainer = create_trainer(
          model,
          optimizer,
          criterion,
          train_loader.sampler,
          config,
          logger,
          with_clearml,
      )
  
      # Setup evaluators
      num_classes = config.num_classes
      cm_metric = ConfusionMatrix(num_classes=num_classes)
  
      val_metrics = {
          "IoU": IoU(cm_metric),
          "mIoU_bg": mIoU(cm_metric),
      }
  
      if ("val_metrics" in config) and isinstance(
          config.val_metrics, dict
      ):
          val_metrics.update(config.val_metrics)
  
      evaluator = create_evaluator(
          model, val_metrics, config, with_clearml, tag="val"
      )
      train_evaluator = create_evaluator(
          model, val_metrics, config, with_clearml, tag="train"
      )
  
      val_interval = config.get("val_interval", 1)
  
      # Run validation on every val_interval epoch, in the end of the training
      # and in the begining if config.start_by_validation is True
      event = Events.EPOCH_COMPLETED(every=val_interval)
      if config.num_epochs % val_interval != 0:
          event |= Events.COMPLETED
      if config.get("start_by_validation", False):
          event |= Events.STARTED
  
      @trainer.on(event)
      def run_validation():
          epoch = trainer.state.epoch
          state = train_evaluator.run(train_eval_loader)
          utils.log_metrics(
              logger,
              epoch,
              state.times["COMPLETED"],
              "Train",
              state.metrics,
          )
          state = evaluator.run(val_loader)
          utils.log_metrics(
              logger,
              epoch,
              state.times["COMPLETED"],
              "Test",
              state.metrics,
          )
  
      score_metric_name = "mIoU_bg"
      if "es_patience" in config:
          common.add_early_stopping_by_val_score(
              config.es_patience,
              evaluator,
              trainer,
              metric_name=score_metric_name,
          )
  
      # Store 2 best models by validation accuracy:
      common.gen_save_best_models_by_val_score(
          save_handler=utils.get_save_handler(
              config.output_path.as_posix(), with_clearml
          ),
          evaluator=evaluator,
          models=model,
          metric_name=score_metric_name,
          n_saved=2,
          trainer=trainer,
          tag="val",
      )
  
      # Setup Tensorboard logger
      if rank == 0:
          tb_logger = common.setup_tb_logging(
              config.output_path.as_posix(),
              trainer,
              optimizer,
              evaluators={
                  "training": train_evaluator,
                  "validation": evaluator,
              },
          )
  
          # Log validation predictions as images
          # We define a custom event filter to log less frequently the images (to reduce storage size)
          # - we plot images with masks of the middle validation batch
          # - once every 3 validations and
          # - at the end of the training
          def custom_event_filter(_, val_iteration):
              c1 = val_iteration == len(val_loader) // 2
              c2 = (
                  trainer.state.epoch
                  % (config.get("val_interval", 1) * 3)
                  == 0
              )
              c2 |= trainer.state.epoch == config.num_epochs
              return c1 and c2
  
          # Image denormalization function to plot predictions with images
          mean = config.get("mean", (0.485, 0.456, 0.406))
          std = config.get("std", (0.229, 0.224, 0.225))
          img_denormalize = partial(
              data.denormalize, mean=mean, std=std
          )
  
          tb_logger.attach(
              evaluator,
              log_handler=vis.predictions_gt_images_handler(
                  img_denormalize_fn=img_denormalize,
                  n_images=8,
                  another_engine=trainer,
                  prefix_tag="validation",
              ),
              event_name=Events.ITERATION_COMPLETED(
                  event_filter=custom_event_filter
              ),
          )
  
      # Log confusion matrix to ClearML:
      if with_clearml:
          trainer.add_event_handler(
              Events.COMPLETED,
              compute_and_log_cm,
              cm_metric,
              trainer.state.iteration,
          )
  
      trainer.run(train_loader, max_epochs=config.num_epochs)
  
      if idist.get_rank() == 0:
          tb_logger.close()
  
imports: import os
  from functools import partial
  from pathlib import Path
  import fire
  import torch
  import dataflow
  import utils
  import vis
  from py_config_runner import ConfigObject, get_params, InferenceConfigSchema, TrainvalConfigSchema
  import ignite.distributed
  from ignite.contrib.engines import common
  from ignite.engine import Engine, Events
  from ignite.handlers import Checkpoint
  from ignite.metrics import ConfusionMatrix, IoU, mIoU
  from ignite.utils import manual_seed, setup_logger
label_desc: Use image node_id 2 for calling a global function with example usage: training(local_rank, config, logger, with_clearml) and returns: unknown