class_docstr: ## Base class for *Adam* and extensions
docstr: ### Optimizer step
  
  We have created a template method that does the common stuff every *Adam* based optimizer needs.
docstr_tok: ["#","#","#","Optimizer","step","We","have","created","a","template","method","that","does","the","common","stuff","every","*","Adam","*","based","optimizer","needs","."]
code: def step(self, closure=None):
      """
      ### Optimizer step
  
      We have created a template method that does the common stuff every *Adam* based optimizer needs.
      """
      # Calculate loss.
      #
      # 🤔 I'm not sure when you need this. I guess it's if you define a function that
      # calculates the loss, does `loss.backward` and return the loss, instead of calling
      # it on your own you could pass it to `optimizer.step`. 🤷‍♂️
      loss = None
      if closure is not None:
          with torch.enable_grad():
              loss = closure()
  
      # Iterate through the parameter groups
      for group in self.param_groups:
          # Iterate through the parameters in the parameter group
          for param in group["params"]:
              # Skip if the parameter has no gradient
              if param.grad is None:
                  continue
              # Get the gradient tensor
              grad = param.grad.data
              # We don't handle sparse gradients
              if grad.is_sparse:
                  raise RuntimeError(
                      "GenericAdaptiveOptimizer does not support sparse gradients,"
                      " please consider SparseAdam instead"
                  )
  
              # Get the state for the parameter
              state = self.state[param]
  
              # Initialize the state if state is uninitialized
              if len(state) == 0:
                  self.init_state(state, group, param)
  
              # Take the optimization step on the parameter
              self.step_param(state, group, grad, param)
  
      # Return the loss, calculated from closure
      return loss
  
file_path: annotated_deep_learning_paper_implementations/labml_nn/optimizers/__init__.py
imports: from typing import Dict, Tuple, Any
  import torch
  from torch import nn
  from torch.optim.optimizer import Optimizer
label_desc: Use image node_id 4 for calling the GenericAdaptiveOptimizer obj's underlying member method code with example usage: obj.step(closure) and returns: loss