class_docstr: Strategy for multi-process single-device training on one or multiple nodes.
class_docstr_tok: ["Strategy","for","multi-process","single-device","training","on","one","or","multiple","nodes","."]
docstr: Performs the actual optimizer step.
  
  Args:
      optimizer: the optimizer performing the step
      closure: closure calculating the loss value
      model: reference to the model, optionally defining optimizer step related hooks
      **kwargs: Any extra arguments to ``optimizer.step``
docstr_tok: ["Performs","the","actual","optimizer","step",".","Args",":","optimizer",":","the","optimizer","performing","the","step","closure",":","closure","calculating","the","loss","value","model",":","reference","to","the","model",",","optionally","defining","optimizer","step","related","hooks","*","*","kwargs",":","Any","extra","arguments","to","``","optimizer.step","``"]
code: def optimizer_step(
      self,
      optimizer: Optimizer,
      closure: Callable[[], Any],
      model: Optional[Union["pl.LightningModule", Module]] = None,
      **kwargs: Any,
  ) -> Any:
      """Performs the actual optimizer step.
  
      Args:
          optimizer: the optimizer performing the step
          closure: closure calculating the loss value
          model: reference to the model, optionally defining optimizer step related hooks
          **kwargs: Any extra arguments to ``optimizer.step``
  
      """
      optimizer_output = super().optimizer_step(
          optimizer, closure, model, **kwargs
      )
  
      if self._model_averager is None:
          return optimizer_output
  
      params = [
          param
          for group in optimizer.param_groups
          for param in group["params"]
          if param.grad is not None
      ]
      self._model_averager.average_parameters(iter(params))
  
      return optimizer_output
  
imports: import logging
  from contextlib import nullcontext
  from datetime import timedelta
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, Literal, Optional, Union
  import torch
  import torch.distributed
  from lightning_utilities.core.rank_zero import rank_zero_only
  from torch import Tensor
  from torch.nn import Module
  from torch.nn.parallel.distributed import DistributedDataParallel
  from torch.optim.optimizer import Optimizer
  from typing_extensions import override
  import lightning.pytorch
  from lightning.fabric.plugins import CheckpointIO, ClusterEnvironment
  from lightning.fabric.plugins.collectives.torch_collective import default_pg_timeout
  from lightning.fabric.strategies import _StrategyRegistry
  from lightning.fabric.utilities.distributed import _distributed_is_initialized, _get_default_process_group_backend_for_device, _init_dist_connection, _sync_ddp_if_available
  from lightning.fabric.utilities.distributed import group
  from lightning.fabric.utilities.imports import _IS_WINDOWS
  from lightning.fabric.utilities.optimizer import _optimizers_to_device
  from lightning.fabric.utilities.seed import reset_seed
  from lightning.fabric.utilities.types import ReduceOp
  from lightning.pytorch.core.optimizer import LightningOptimizer
  from lightning.pytorch.overrides.distributed import _register_ddp_comm_hook, _sync_module_states, prepare_for_backward
  from lightning.pytorch.plugins.precision import Precision
  from lightning.pytorch.strategies.launchers import _MultiProcessingLauncher, _SubprocessScriptLauncher
  from lightning.pytorch.strategies.parallel import ParallelStrategy
  from lightning.pytorch.strategies.strategy import TBroadcast, _ForwardRedirection
  from lightning.pytorch.trainer.states import TrainerFn
  from lightning.pytorch.utilities.exceptions import _augment_message
  from lightning.pytorch.utilities.rank_zero import rank_zero_deprecation, rank_zero_info, rank_zero_only
label_desc: Use image node_id 18 for calling the DDPStrategy obj's underlying member method code with example usage: obj.optimizer_step(optimizer, closure, model) and returns: optimizer_output, optimizer_output