code: def resolve_linear_schedule(cfg, param_schedulers):
      """
      For the given composite schedulers, for each linear schedule,
      if the training is 1 node only, the https://arxiv.org/abs/1706.02677 linear
      warmup rule has to be checked if the rule is applicable and necessary.
  
      We set the end_value = scaled_lr (assuming it's a linear warmup).
      In case only 1 machine is used in training, the start_lr = scaled_lr and then
      the linear warmup is not needed.
      """
      # compute what should be the linear warmup start LR value.
      # this depends on batchsize per node.
      # TODO - why does it not depend on the global batch size?
      num_nodes = cfg.DISTRIBUTED.NUM_NODES
      num_gpus_per_node = cfg.DISTRIBUTED.NUM_PROC_PER_NODE
      bs_per_gpu = cfg.DATA.TRAIN.BATCHSIZE_PER_REPLICA
      batch_size_per_node = bs_per_gpu * num_gpus_per_node
      base_lr = param_schedulers.auto_lr_scaling.base_value
      base_lr_batch_size = (
          param_schedulers.auto_lr_scaling.base_lr_batch_size
      )
      scale_factor = float(batch_size_per_node) / base_lr_batch_size
      start_value = base_lr * scale_factor
  
      remove_linear_idx = -1
      for idx in range(len(param_schedulers["schedulers"])):
          if param_schedulers["schedulers"][idx]["name"] == "linear":
              param_schedulers["schedulers"][idx][
                  "start_value"
              ] = start_value
              if num_nodes == 1:
                  end_value = param_schedulers["schedulers"][idx][
                      "end_value"
                  ]
                  if start_value <= end_value:
                      # linear schedule is not meaningful as linear warmup is not needed.
                      remove_linear_idx = idx
  
      # check if linear warmup should be removed as its not meaningul
      if remove_linear_idx >= 0:
          del param_schedulers["schedulers"][remove_linear_idx]
      # if after removing linear warmup, there's only one scheduler, then a composite
      # schedule is no longer needed. The remaining scheduler becomes the primary
      # scheduler
      if len(param_schedulers["schedulers"]) == 1:
          for key, value in param_schedulers["schedulers"][0].items():
              param_schedulers[key] = value
      return param_schedulers
  
imports: import contextlib
  import copy
  import logging
  import math
  import os
  import pprint
  import re
  import sys
  from typing import Any, List, NamedTuple, Tuple
  import torch
  from hydra.core.override_parser.overrides_parser import OverridesParser
  from omegaconf import DictConfig, OmegaConf, open_dict
  from vissl.config import AttrDict, check_cfg_version
  from vissl.utils.io import save_file
  from vissl.utils.misc import is_augly_available
label_desc: Use image node_id 11 for calling a global function with example usage: resolve_linear_schedule(cfg, param_schedulers) and returns: param_schedulers