docstr: Run the optimizer defined in evaluators, when manual optimization is turned on.
  
  Call this method when the model should be optimized.
  To keep it as neat as possible, we only implement the basic ``zero_grad``, ``backward``, ``grad_clip``, and ``step`` here.
  Many hooks and pre/post-processing are omitted.
  Inherit this method if you need more advanced behavior.
  
  The full optimizer step could be found
  `here <https://github.com/Lightning-AI/lightning/blob/0e531283/src/pytorch_lightning/loops/optimization/optimizer_loop.py>`__.
  We only implement part of the optimizer loop here.
  
  Parameters
  ----------
  batch_idx: int
      The current batch index.
code: def advance_optimization(
      self,
      loss: Any,
      batch_idx: int,
      gradient_clip_val: int | float | None = None,
      gradient_clip_algorithm: str | None = None,
  ):
      """
      Run the optimizer defined in evaluators, when manual optimization is turned on.
  
      Call this method when the model should be optimized.
      To keep it as neat as possible, we only implement the basic ``zero_grad``, ``backward``, ``grad_clip``, and ``step`` here.
      Many hooks and pre/post-processing are omitted.
      Inherit this method if you need more advanced behavior.
  
      The full optimizer step could be found
      `here <https://github.com/Lightning-AI/lightning/blob/0e531283/src/pytorch_lightning/loops/optimization/optimizer_loop.py>`__.
      We only implement part of the optimizer loop here.
  
      Parameters
      ----------
      batch_idx: int
          The current batch index.
      """
      if self.automatic_optimization:
          raise ValueError(
              "This method should not be used when automatic optimization is turned on."
          )
  
      # Has to be optimizers() here (to get LightningOptimizer)
      # instead of trainer.optimizers (raw optimizers),
      # because otherwise optim_progress is incorrect.
      optimizers = self.optimizers()
      if not isinstance(optimizers, list):
          optimizers = [optimizers]
      # Filter out optimizers for architecture parameters.
      optimizers = cast(
          List[Optimizer],
          [
              opt
              for opt in optimizers
              if not getattr(opt, "is_arch_optimizer", False)
          ],
      )
  
      if hasattr(
          self.trainer, "optimizer_frequencies"
      ):  # lightning < 2
          self._legacy_advance_optimization(
              loss,
              batch_idx,
              optimizers,
              gradient_clip_val,
              gradient_clip_algorithm,
          )
      else:
          if not self.training_module.automatic_optimization:
              raise ValueError(
                  "Evaluator module with manual optimization is not compatible with one-shot algorithms."
              )
          if len(optimizers) != 1:
              raise ValueError(
                  "More than one optimizer returned by evaluator. This is not supported in NAS."
              )
          optimizer = optimizers[0]
  
          # There should be many before/after hooks called here, but they are omitted in this implementation.
          # 1. zero gradient
          self.training_module.optimizer_zero_grad(
              self.trainer.current_epoch, batch_idx, optimizer
          )
          # 2. backward
          self.manual_backward(loss)
          # 3. grad clip
          self.training_module.configure_gradient_clipping(
              optimizer, gradient_clip_val, gradient_clip_algorithm
          )
          # 4. optimizer step
          self.training_module.optimizer_step(
              self.trainer.current_epoch, batch_idx, optimizer
          )
  
      self._optimizer_progress += 1
  
imports: from __future__ import annotations
  import warnings
  from typing import Any, Iterable, List, cast, TYPE_CHECKING
  import torch.optim
  import torch.nn
  from torch.optim import Optimizer
  import nni.nas.nn.pytorch
  from nni.nas.evaluator.pytorch import LightningModule, Trainer
  from nni.mutable import Sample
  from .supermodule.base import BaseSuperNetModule
label_desc: Use image node_id 16 for calling the BaseOneShotLightningModule obj's underlying member method code with example usage: obj.advance_optimization(loss, batch_idx, gradient_clip_val, gradient_clip_algorithm) without return types