class_docstr: A simple trainer for the most common type of task:
  single-cost single-optimizer single-data-source iterative optimization,
  optionally using data-parallelism.
  It assumes that every step, you:
  
  1. Compute the loss with a data from the data_loader.
  2. Compute the gradients with the above loss.
  3. Update the model with the optimizer.
  
  All other tasks during training (checkpointing, logging, evaluation, LR schedule)
  are maintained by hooks, which can be registered by :meth:`TrainerBase.register_hooks`.
  
  If you want to do anything fancier than this,
  either subclass TrainerBase and implement your own `run_step`,
  or write your own training loop.
class_docstr_tok: ["A","simple","trainer","for","the","most","common","type","of","task",":","single-cost","single-optimizer","single-data-source","iterative","optimization",",","optionally","using","data-parallelism",".","It","assumes","that","every","step",",","you",":","1",".","Compute","the","loss","with","a","data","from","the","data_loader",".","2",".","Compute","the","gradients","with","the","above","loss",".","3",".","Update","the","model","with","the","optimizer",".","All","other","tasks","during","training","(","checkpointing",",","logging",",","evaluation",",","LR","schedule",")","are","maintained","by","hooks",",","which","can","be","registered","by",":","meth",":","`","TrainerBase.register_hooks","`",".","If","you","want","to","do","anything","fancier","than","this",",","either","subclass","TrainerBase","and","implement","your","own","`","run_step","`",",","or","write","your","own","training","loop","."]
docstr: Args:
      loss_dict (dict): dict of scalar losses
      data_time (float): time taken by the dataloader iteration
      prefix (str): prefix for logging keys
docstr_tok: ["Args",":","loss_dict","(","dict",")",":","dict","of","scalar","losses","data_time","(","float",")",":","time","taken","by","the","dataloader","iteration","prefix","(","str",")",":","prefix","for","logging","keys"]
code: def write_metrics(
      loss_dict: Mapping[str, torch.Tensor],
      data_time: float,
      cur_iter: int,
      prefix: str = "",
  ) -> None:
      """
      Args:
          loss_dict (dict): dict of scalar losses
          data_time (float): time taken by the dataloader iteration
          prefix (str): prefix for logging keys
      """
      metrics_dict = {
          k: v.detach().cpu().item() for k, v in loss_dict.items()
      }
      metrics_dict["data_time"] = data_time
  
      storage = get_event_storage()
      # Keep track of data time per rank
      storage.put_scalar("rank_data_time", data_time, cur_iter=cur_iter)
  
      # Gather metrics among all workers for logging
      # This assumes we do DDP-style training, which is currently the only
      # supported method in detectron2.
      all_metrics_dict = comm.gather(metrics_dict)
  
      if comm.is_main_process():
          # data_time among workers can have high variance. The actual latency
          # caused by data_time is the maximum among workers.
          data_time = np.max(
              [x.pop("data_time") for x in all_metrics_dict]
          )
          storage.put_scalar("data_time", data_time, cur_iter=cur_iter)
  
          # average the rest metrics
          metrics_dict = {
              k: np.mean([x[k] for x in all_metrics_dict])
              for k in all_metrics_dict[0].keys()
          }
          total_losses_reduced = sum(metrics_dict.values())
          if not np.isfinite(total_losses_reduced):
              raise FloatingPointError(
                  f"Loss became infinite or NaN at iteration={cur_iter}!\n"
                  f"loss_dict = {metrics_dict}"
              )
  
          storage.put_scalar(
              "{}total_loss".format(prefix),
              total_losses_reduced,
              cur_iter=cur_iter,
          )
          if len(metrics_dict) > 1:
              storage.put_scalars(cur_iter=cur_iter, **metrics_dict)
  
imports: import concurrent.futures
  import logging
  import numpy
  import time
  import weakref
  from typing import List, Mapping, Optional
  import torch
  from torch.nn.parallel import DataParallel, DistributedDataParallel
  import detectron2.utils.comm
  from detectron2.utils.events import EventStorage, get_event_storage
  from detectron2.utils.logger import _log_api_usage
label_desc: Use image node_id 6 for calling the SimpleTrainer obj's underlying member method code with example usage: obj.write_metrics(loss_dict, data_time, cur_iter, prefix) without return types