class_docstr: Extending DDPSpawnStrategy to support launch subprocesses with optimized env variables.
docstr: Setup warmup lr_schedulers after resetting the train dataloaders.
code: def on_train_start(self):
      """Setup warmup lr_schedulers after resetting the train dataloaders."""
      # LightnigModule.train_dataloader() generate the training dataloaders after setup,
      # so attach the warmup lr_schedulers in on_train_start hook to infer warmup_steps.
      if not self.auto_lr:
          return
      if self.lr_scheduler_configs:
          warnings.warn(
              f"Nano warmup currently only support no scheduler, "
              f"but got {len(self.lr_scheduler_configs)}. Skip warmup"
          )
      else:
          trainer = self.lightning_module.trainer
          lr_schedulers = []
          warmup_params = {
              "start_factor": 1.0 / self.world_size,
              "end_factor": 1.0,
              "warmup_epochs": trainer.max_epochs // 10,
              "interval": "epoch",
          }
          supported_keys = {"warmup_epochs"}
          if isinstance(self.auto_lr, dict):
              extra_keys = self.auto_lr.keys() - supported_keys
              if extra_keys:
                  warnings.warn(
                      f"Found unsupported keys in the auto_lr dict: {extra_keys}"
                  )
              if "warmup_epochs" not in self.auto_lr:
                  self.auto_lr = True
                  warnings.warn(
                      'Not found "warmup_epochs" in the auto_lr dict'
                      " warmup_epochs is set by default"
                  )
              else:
                  invalidInputError(
                      type(self.auto_lr["warmup_epochs"]) is int,
                      f"\"warmup_epochs\" is {type(self.auto_lr['warmup_epochs'])}",
                      'expect "warmup_epochs" is a integer',
                  )
                  warmup_params["warmup_epochs"] = self.auto_lr[
                      "warmup_epochs"
                  ]
          if type(self.auto_lr) is bool:
              # Call scheduler.step() after each minibatch rather than epoch if max_epochs < 10
              if warmup_params["warmup_epochs"] == 0:
                  train_loader = trainer.train_dataloader
                  max_steps = len(train_loader) * trainer.max_epochs
                  warmup_params["warmup_epochs"] = max_steps // 10
                  warmup_params["interval"] = "step"
          for opt_idx, opt in enumerate(self.optimizers):
              from torch.optim.lr_scheduler import LambdaLR
  
              def lr_func(epoch):
                  current_epoch = trainer.current_epoch
                  start_factor = warmup_params["start_factor"]
                  end_factor = warmup_params["end_factor"]
                  total_iters = warmup_params["warmup_epochs"]
                  if (
                      current_epoch > 0
                      and warmup_params["interval"] == "step"
                      or epoch > total_iters
                  ):
                      return 1.0
                  if epoch == 0:
                      return start_factor
                  return (
                      end_factor - start_factor
                  ) * epoch / total_iters + start_factor
  
              scheduler = LambdaLR(
                  optimizer=opt,
                  lr_lambda=[lr_func] * len(opt.param_groups),
              )
              lr_scheduler = {
                  "scheduler": scheduler,
                  "opt_idx": opt_idx,
                  "interval": warmup_params["interval"],
              }
              lr_schedulers.append(lr_scheduler)
  
          # validates the lr_scheduler_configs, adapted from lightning
          # https://github.com/Lightning-AI/lightning/blob/1.6.4/pytorch_lightning/core/optimizer.py#L175
          lr_scheduler_configs = (
              _configure_schedulers_automatic_opt(lr_schedulers, None)
              if self.lightning_module.automatic_optimization
              else _configure_schedulers_manual_opt(lr_schedulers)
          )
          _set_scheduler_opt_idx(self.optimizers, lr_scheduler_configs)
          _validate_scheduler_api(
              lr_scheduler_configs, self.lightning_module
          )
          self.lr_scheduler_configs = lr_scheduler_configs
  
imports: import os
  import copy
  import multiprocessing
  from typing import Any, List, Optional, Callable
  import torch
  from torch import nn
  from torch.multiprocessing.spawn import ProcessContext
  from torch.nn.parallel.distributed import DistributedDataParallel
  from torch.optim.lr_scheduler import _LRScheduler
  import pytorch_lightning
  from pytorch_lightning.trainer.states import TrainerFn
  from pytorch_lightning.core.optimizer import LightningOptimizer
  from pytorch_lightning.core.optimizer import _configure_schedulers_automatic_opt
  from pytorch_lightning.core.optimizer import _configure_schedulers_manual_opt
  from pytorch_lightning.core.optimizer import _set_scheduler_opt_idx, _validate_scheduler_api
  from pytorch_lightning.strategies.launchers import _SpawnLauncher
  from pytorch_lightning.strategies import DDPSpawnStrategy
  from pytorch_lightning.plugins.environments import LightningEnvironment
  from bigdl.nano.utils.common import schedule_processors
  from bigdl.nano.pytorch.dispatcher import _get_patch_status
  from bigdl.nano.deps.ipex.ipex_api import ipex_optimize
  from bigdl.nano.utils.common import invalidInputError
  from bigdl.nano.utils.common import EnvContext
  from bigdl.nano.utils.pytorch import TORCH_VERSION_LESS_1_12
  import logging
  import warnings
label_desc: Use image node_id 4 for calling the DDPSpawnStrategy obj's underlying member method code with example usage: obj.on_train_start() and returns: unknown, int, start_factor