class_docstr: A trainer with default training logic. It does the following:
  
  1. Create a :class:`SimpleTrainer` using model, optimizer, dataloader
     defined by the given config. Create a LR scheduler defined by the config.
  2. Load the last checkpoint or `cfg.MODEL.WEIGHTS`, if exists, when
     `resume_or_load` is called.
  3. Register a few common hooks defined by the config.
  
  It is created to simplify the **standard model training workflow** and reduce code boilerplate
  for users who only need the standard training workflow, with standard features.
  It means this class makes *many assumptions* about your training logic that
  may easily become invalid in a new research. In fact, any assumptions beyond those made in the
  :class:`SimpleTrainer` are too much for research.
  
  The code of this class has been annotated about restrictive assumptions it makes.
  When they do not work for you, you're encouraged to:
  
  1. Overwrite methods of this class, OR:
  2. Use :class:`SimpleTrainer`, which only does minimal SGD training and
     nothing else. You can then add your own hooks if needed. OR:
  3. Write your own training loop similar to `tools/plain_train_net.py`.
  
  See the :doc:`/tutorials/training` tutorials for more details.
  
  Note that the behavior of this class, like other functions/classes in
  this file, is not stable, since it is meant to represent the "common default behavior".
  It is only guaranteed to work well with the standard models and training workflow in detectron2.
  To obtain more stable behavior, write your own training logic with other public APIs.
  
  Examples:
  ::
      trainer = DefaultTrainer(cfg)
      trainer.resume_or_load()  # load last checkpoint or MODEL.WEIGHTS
      trainer.train()
  
  Attributes:
      scheduler:
      checkpointer (DetectionCheckpointer):
      cfg (CfgNode):
docstr: When the config is defined for certain number of workers (according to
  ``cfg.SOLVER.REFERENCE_WORLD_SIZE``) that's different from the number of
  workers currently in use, returns a new cfg where the total batch size
  is scaled so that the per-GPU batch size stays the same as the
  original ``IMS_PER_BATCH // REFERENCE_WORLD_SIZE``.
  
  Other config options are also scaled accordingly:
  * training steps and warmup steps are scaled inverse proportionally.
  * learning rate are scaled proportionally, following :paper:`ImageNet in 1h`.
  
  For example, with the original config like the following:
  
  .. code-block:: yaml
  
      IMS_PER_BATCH: 16
      BASE_LR: 0.1
      REFERENCE_WORLD_SIZE: 8
      MAX_ITER: 5000
      STEPS: (4000,)
      CHECKPOINT_PERIOD: 1000
  
  When this config is used on 16 GPUs instead of the reference number 8,
  calling this method will return a new config with:
  
  .. code-block:: yaml
  
      IMS_PER_BATCH: 32
      BASE_LR: 0.2
      REFERENCE_WORLD_SIZE: 16
      MAX_ITER: 2500
      STEPS: (2000,)
      CHECKPOINT_PERIOD: 500
  
  Note that both the original config and this new config can be trained on 16 GPUs.
  It's up to user whether to enable this feature (by setting ``REFERENCE_WORLD_SIZE``).
  
  Returns:
      CfgNode: a new config. Same as original if ``cfg.SOLVER.REFERENCE_WORLD_SIZE==0``.
docstr_tok: ["When","the","config","is","defined","for","certain","number","of","workers","(","according","to","``","cfg.SOLVER.REFERENCE_WORLD_SIZE","``",")","that","'s","different","from","the","number","of","workers","currently","in","use",",","returns","a","new","cfg","where","the","total","batch","size","is","scaled","so","that","the","per-GPU","batch","size","stays","the","same","as","the","original","``","IMS_PER_BATCH","\/\/","REFERENCE_WORLD_SIZE","``",".","Other","config","options","are","also","scaled","accordingly",":","*","training","steps","and","warmup","steps","are","scaled","inverse","proportionally",".","*","learning","rate","are","scaled","proportionally",",","following",":","paper",":","`","ImageNet","in","1h","`",".","For","example",",","with","the","original","config","like","the","following",":","..","code-block",":",":","yaml","IMS_PER_BATCH",":","16","BASE_LR",":","0.1","REFERENCE_WORLD_SIZE",":","8","MAX_ITER",":","5000","STEPS",":","(","4000",",",")","CHECKPOINT_PERIOD",":","1000","When","this","config","is","used","on","16","GPUs","instead","of","the","reference","number","8",",","calling","this","method","will","return","a","new","config","with",":","..","code-block",":",":","yaml","IMS_PER_BATCH",":","32","BASE_LR",":","0.2","REFERENCE_WORLD_SIZE",":","16","MAX_ITER",":","2500","STEPS",":","(","2000",",",")","CHECKPOINT_PERIOD",":","500","Note","that","both","the","original","config","and","this","new","config","can","be","trained","on","16","GPUs",".","It","'s","up","to","user","whether","to","enable","this","feature","(","by","setting","``","REFERENCE_WORLD_SIZE","``",")",".","Returns",":","CfgNode",":","a","new","config",".","Same","as","original","if","``","cfg.SOLVER.REFERENCE_WORLD_SIZE==0","``","."]
code: def auto_scale_workers(cfg, num_workers: int):
      """
      When the config is defined for certain number of workers (according to
      ``cfg.SOLVER.REFERENCE_WORLD_SIZE``) that's different from the number of
      workers currently in use, returns a new cfg where the total batch size
      is scaled so that the per-GPU batch size stays the same as the
      original ``IMS_PER_BATCH // REFERENCE_WORLD_SIZE``.
  
      Other config options are also scaled accordingly:
      * training steps and warmup steps are scaled inverse proportionally.
      * learning rate are scaled proportionally, following :paper:`ImageNet in 1h`.
  
      For example, with the original config like the following:
  
      .. code-block:: yaml
  
          IMS_PER_BATCH: 16
          BASE_LR: 0.1
          REFERENCE_WORLD_SIZE: 8
          MAX_ITER: 5000
          STEPS: (4000,)
          CHECKPOINT_PERIOD: 1000
  
      When this config is used on 16 GPUs instead of the reference number 8,
      calling this method will return a new config with:
  
      .. code-block:: yaml
  
          IMS_PER_BATCH: 32
          BASE_LR: 0.2
          REFERENCE_WORLD_SIZE: 16
          MAX_ITER: 2500
          STEPS: (2000,)
          CHECKPOINT_PERIOD: 500
  
      Note that both the original config and this new config can be trained on 16 GPUs.
      It's up to user whether to enable this feature (by setting ``REFERENCE_WORLD_SIZE``).
  
      Returns:
          CfgNode: a new config. Same as original if ``cfg.SOLVER.REFERENCE_WORLD_SIZE==0``.
      """
      old_world_size = cfg.SOLVER.REFERENCE_WORLD_SIZE
      if old_world_size == 0 or old_world_size == num_workers:
          return cfg
      cfg = cfg.clone()
      frozen = cfg.is_frozen()
      cfg.defrost()
  
      assert (
          cfg.SOLVER.IMS_PER_BATCH % old_world_size == 0
      ), "Invalid REFERENCE_WORLD_SIZE in config!"
      scale = num_workers / old_world_size
      bs = cfg.SOLVER.IMS_PER_BATCH = int(
          round(cfg.SOLVER.IMS_PER_BATCH * scale)
      )
      lr = cfg.SOLVER.BASE_LR = cfg.SOLVER.BASE_LR * scale
      max_iter = cfg.SOLVER.MAX_ITER = int(
          round(cfg.SOLVER.MAX_ITER / scale)
      )
      warmup_iter = cfg.SOLVER.WARMUP_ITERS = int(
          round(cfg.SOLVER.WARMUP_ITERS / scale)
      )
      cfg.SOLVER.STEPS = tuple(
          int(round(s / scale)) for s in cfg.SOLVER.STEPS
      )
      cfg.TEST.EVAL_PERIOD = int(round(cfg.TEST.EVAL_PERIOD / scale))
      cfg.SOLVER.CHECKPOINT_PERIOD = int(
          round(cfg.SOLVER.CHECKPOINT_PERIOD / scale)
      )
      cfg.SOLVER.REFERENCE_WORLD_SIZE = (
          num_workers  # maintain invariant
      )
      logger = logging.getLogger(__name__)
      logger.info(
          f"Auto-scaling the config to batch_size={bs}, learning_rate={lr}, "
          f"max_iter={max_iter}, warmup={warmup_iter}."
      )
  
      if frozen:
          cfg.freeze()
      return cfg
  
imports: import argparse
  import logging
  import os
  import sys
  import weakref
  from collections import OrderedDict
  from typing import Optional
  import torch
  from fvcore.nn.precise_bn import get_bn_modules
  from omegaconf import OmegaConf
  from torch.nn.parallel import DistributedDataParallel
  import detectron2.data.transforms
  from detectron2.checkpoint import DetectionCheckpointer
  from detectron2.config import CfgNode, LazyConfig
  from detectron2.data import MetadataCatalog, build_detection_test_loader, build_detection_train_loader
  from detectron2.evaluation import DatasetEvaluator, inference_on_dataset, print_csv_format, verify_results
  from detectron2.modeling import build_model
  from detectron2.solver import build_lr_scheduler, build_optimizer
  from detectron2.utils import comm
  from detectron2.utils.collect_env import collect_env_info
  from detectron2.utils.env import seed_all_rng
  from detectron2.utils.events import CommonMetricPrinter, JSONWriter, TensorboardXWriter
  from detectron2.utils.file_io import PathManager
  from detectron2.utils.logger import setup_logger
  from .None import hooks
  from .train_loop import AMPTrainer, SimpleTrainer, TrainerBase
label_desc: Use image node_id 16 for calling the DefaultTrainer obj's underlying member method code with example usage: obj.auto_scale_workers(cfg, num_workers) and returns: cfg, cfg