class_docstr: The main entry point for any training or feature extraction workflows in VISSL.
  
  The trainer constructs a train_task which prepares all the components of the
  training (optimizer, loss, meters, model etc) using the settings specified by user
  in the yaml config file. See the vissl/trainer/train_task.py for more details.
  
  Args:
      cfg (AttrDict): user specified input config that has optimizer, loss, meters etc
                      settings relevant to the training
      dist_run_id (str): For multi-gpu training with PyTorch, we have to specify
                         how the gpus are going to rendezvous. This requires specifying
                         the communication method: file, tcp and the unique rendezvous
                         run_id that is specific to 1 run.
                         We recommend:
                              1) for 1node: use init_method=tcp and run_id=auto
                              2) for multi-node, use init_method=tcp and specify
                              run_id={master_node}:{port}
      checkpoint_path (str): if the training is being resumed from a checkpoint, path to
                        the checkpoint. The tools/run_distributed_engines.py automatically
                        looks for the checkpoint in the checkpoint directory.
      checkpoint_folder (str): what directory to use for checkpointing. The
                        tools/run_distributed_engines.py creates the directory based on user
                        input in the yaml config file.
      hooks (List[ClassyHooks]): the list of hooks to use during the training. The hooks
                        vissl/engines/{train, extract_features}.py determine the hooks.
docstr: The train workflow. We get the training loop to use (vissl default is
  standard_train_step) but the user can create their own training loop
  and specify the name TRAINER.TRAIN_STEP_NAME
  
  The training happens:
  1. Execute any hooks at the start of training (mostly resets the variable like
     iteration num phase_num etc)
  2. For each epoch (train or test), run the hooks at the start of an epoch. Mostly
     involves setting things like timer, setting dataloader epoch etc
  3. Execute the training loop (1 training iteration) involving forward, loss, backward,
     optimizer update, metrics collection etc.
  4. At the end of epoch, sync meters and execute hooks at the end of phase. Involves
     things like checkpointing model, logging timers, logging to tensorboard etc
docstr_tok: ["The","train","workflow",".","We","get","the","training","loop","to","use","(","vissl","default","is","standard_train_step",")","but","the","user","can","create","their","own","training","loop","and","specify","the","name","TRAINER.TRAIN_STEP_NAME","The","training","happens",":","1",".","Execute","any","hooks","at","the","start","of","training","(","mostly","resets","the","variable","like","iteration","num","phase_num","etc",")","2",".","For","each","epoch","(","train","or","test",")",",","run","the","hooks","at","the","start","of","an","epoch",".","Mostly","involves","setting","things","like","timer",",","setting","dataloader","epoch","etc","3",".","Execute","the","training","loop","(","1","training","iteration",")","involving","forward",",","loss",",","backward",",","optimizer","update",",","metrics","collection","etc",".","4",".","At","the","end","of","epoch",",","sync","meters","and","execute","hooks","at","the","end","of","phase",".","Involves","things","like","checkpointing","model",",","logging","timers",",","logging","to","tensorboard","etc"]
code: def train(self):
      """
      The train workflow. We get the training loop to use (vissl default is
      standard_train_step) but the user can create their own training loop
      and specify the name TRAINER.TRAIN_STEP_NAME
  
      The training happens:
      1. Execute any hooks at the start of training (mostly resets the variable like
         iteration num phase_num etc)
      2. For each epoch (train or test), run the hooks at the start of an epoch. Mostly
         involves setting things like timer, setting dataloader epoch etc
      3. Execute the training loop (1 training iteration) involving forward, loss, backward,
         optimizer update, metrics collection etc.
      4. At the end of epoch, sync meters and execute hooks at the end of phase. Involves
         things like checkpointing model, logging timers, logging to tensorboard etc
      """
      train_step_fn = get_train_step(
          self.cfg["TRAINER"]["TRAIN_STEP_NAME"]
      )
      self.task.prepare(pin_memory=self.cfg.DATA.PIN_MEMORY)
      self.task.init_distributed_data_parallel_model()
  
      # Find what phase, train_phase_idx, local_iteration_num we are starting from.
      # Recover it from the checkpoint (if available)
      task, phase_idx, iteration_num = self._init_training_state(
          self.cfg, self.task
      )
  
      # Good to go, (re) start training
      task.run_hooks(SSLClassyHookFunctions.on_start.name)
  
      if is_primary():
          logging.info("Model is:\n {}".format(task.model))
          logging.info("Loss is: {}".format(task.loss))
      logging.info("Starting training....")
  
      while phase_idx + 1 < len(task.phases):
          self._advance_phase(task)  # advances task.phase_idx
          phase_idx += 1
          iteration_num += 1
          task.local_iteration_num = (
              iteration_num  # iteration_num=0 at this step
          )
          task.run_hooks(SSLClassyHookFunctions.on_phase_start.name)
          while True:
              try:
                  if self.cfg.MODEL.CUDA_CACHE.CLEAR_CUDA_CACHE and (
                      iteration_num
                      % self.cfg.MODEL.CUDA_CACHE.CLEAR_FREQ
                      == 0
                  ):
                      logging.info(
                          f"Emptying CUDA cache at step count: {iteration_num}"
                      )
                      torch.cuda.empty_cache()
                      logging.info("CUDA cache cleared")
                  task = train_step_fn(task)
                  iteration_num += 1
                  task.local_iteration_num = iteration_num
                  # Book-keeping: update the training iteration number (only updated
                  # if it's a training phase).
                  task.iteration += 1 if task.train else 0
                  # Book-keeping. Track how many forward passes have been done.
                  # aka how many batches have been seen by the trainer irrespective of
                  # the train or test phase.
                  task.batches += 1
                  # update the batch time aka the training time for the current iteration.
                  task.batch_time.append(time.time() - task.start_time)
                  task.start_time = time.time()
                  task.run_hooks(SSLClassyHookFunctions.on_step.name)
              except StopIteration:
                  break
              except Exception as e:
                  task.run_hooks(
                      SSLClassyHookFunctions.on_exception.name
                  )
                  raise e
          for meter in task.meters:
              meter.sync_state()
          logging.info("Meters synced")
          barrier()
          task.run_hooks(SSLClassyHookFunctions.on_phase_end.name)
  
      task.run_hooks(SSLClassyHookFunctions.on_end.name)
      if hasattr(task, "data_iterator"):
          del task.data_iterator
          gc.collect()
      if hasattr(task, "dataloaders"):
          del task.dataloaders
          gc.collect()
  
imports: import gc
  import itertools
  import logging
  import os
  import socket
  import time
  from types import SimpleNamespace
  from typing import Any, Dict, List, Tuple
  import numpy
  import torch
  import torch.distributed
  from classy_vision.generic.distributed_util import barrier, is_primary, set_cpu_device, set_cuda_device_index
  from classy_vision.hooks.classy_hook import ClassyHook
  from classy_vision.tasks import ClassyTask, TASK_REGISTRY
  from vissl.config import AttrDict
  from vissl.hooks import SSLClassyHookFunctions
  from vissl.models.model_helpers import get_trunk_output_feature_names
  from vissl.trainer.train_steps import get_train_step
  from vissl.utils.distributed_utils import all_gather_heterogeneous, all_gather_sizes
  from vissl.utils.env import get_machine_local_and_dist_rank
  from vissl.utils.io import save_file
label_desc: Use image node_id 3 for calling the SelfSupervisionTrainer obj's underlying member method code with example usage: obj.train() without return types