code: def step(self, closure=None):
      loss = None
      if closure is not None:
          with torch.enable_grad():
              loss = closure()
  
      for group in self.param_groups:
          for p in group["params"]:
              if p.grad is None:
                  continue
  
              grad = p.grad
              beta1, beta2 = group["betas"]
              nesterov = group["nesterov"]
  
              state = self.state[p]
  
              # State initialization
              if len(state) == 0:
                  state["step"] = 0
                  state["exp_avg"] = torch.zeros_like(p)
                  state["exp_avg_sq"] = torch.zeros_like(p)
  
              # Adam
              exp_avg, exp_avg_sq = (
                  state["exp_avg"],
                  state["exp_avg_sq"],
              )
  
              state["step"] += 1
              bias_correction1 = 1 - beta1 ** state["step"]
              bias_correction2 = 1 - beta2 ** state["step"]
  
              exp_avg.mul_(beta1).add_(grad, alpha=1 - beta1)
              exp_avg_sq.mul_(beta2).addcmul_(
                  grad, grad, value=1 - beta2
              )
  
              denom = (
                  exp_avg_sq.sqrt() / math.sqrt(bias_correction2)
              ).add_(group["eps"])
              step_size = group["lr"] / bias_correction1
  
              if nesterov:
                  perturb = (
                      beta1 * exp_avg + (1 - beta1) * grad
                  ) / denom
              else:
                  perturb = exp_avg / denom
  
              # Projection
              wd_ratio = 1.0
              if len(p.shape) > 1:
                  perturb, wd_ratio = projection(
                      p,
                      grad,
                      perturb,
                      group["delta"],
                      group["wd_ratio"],
                      group["eps"],
                  )
  
              # Weight decay
              if group["weight_decay"] > 0:
                  p.mul_(
                      1.0
                      - group["lr"] * group["weight_decay"] * wd_ratio
                  )
  
              # Step
              p.add_(perturb, alpha=-step_size)
  
      return loss
  
file_path: pywick/pywick/optimizers/adamp.py
imports: import torch
  import torch.nn.functional
  from torch.optim.optimizer import Optimizer
  import math
label_desc: Use image node_id 2 for calling the AdamP obj's underlying member method code with example usage: obj.step(closure) and returns: loss