class_docstr: ``torch.optim.Optimizer`` wrapper that adds additional functionality to clip per
  sample gradients and add Gaussian noise.
  
  Can be used with any ``torch.optim.Optimizer`` subclass as an underlying optimizer.
  ``DPOptimzer`` assumes that parameters over which it performs optimization belong
  to GradSampleModule and therefore have the ``grad_sample`` attribute.
  
  On a high level ``DPOptimizer``'s step looks like this:
  1) Aggregate ``p.grad_sample`` over all parameters to calculate per sample norms
  2) Clip ``p.grad_sample`` so that per sample norm is not above threshold
  3) Aggregate clipped per sample gradients into ``p.grad``
  4) Add Gaussian noise to ``p.grad`` calibrated to a given noise multiplier and
  max grad norm limit (``std = noise_multiplier * max_grad_norm``).
  5) Call underlying optimizer to perform optimization step
  
  Examples:
      >>> module = MyCustomModel()
      >>> optimizer = torch.optim.SGD(module.parameters(), lr=0.1)
      >>> dp_optimizer = DPOptimizer(
      ...     optimizer=optimizer,
      ...     noise_multiplier=1.0,
      ...     max_grad_norm=1.0,
      ...     expected_batch_size=4,
      ... )
docstr: Signals the optimizer to skip an optimization step and only perform clipping and
  per sample gradient accumulation.
  
  On every call of ``.step()`` optimizer will check the queue of skipped step
  signals. If non-empty and the latest flag is ``True``, optimizer will call
  ``self.clip_and_accumulate``, but won't proceed to adding noise and performing
  the actual optimization step.
  It also affects the behaviour of ``zero_grad()``. If the last step was skipped,
  optimizer will clear per sample gradients accumulated by
  ``self.clip_and_accumulate`` (``p.grad_sample``), but won't touch aggregated
  clipped gradients (``p.summed_grad``)
  
  Used by :class:`~opacus.utils.batch_memory_manager.BatchMemoryManager` to
  simulate large virtual batches with limited memory footprint.
  
  Args:
      do_skip: flag if next step should be skipped
docstr_tok: ["Signals","the","optimizer","to","skip","an","optimization","step","and","only","perform","clipping","and","per","sample","gradient","accumulation",".","On","every","call","of","``",".step","(",")","``","optimizer","will","check","the","queue","of","skipped","step","signals",".","If","non-empty","and","the","latest","flag","is","``","True","``",",","optimizer","will","call","``","self.clip_and_accumulate","``",",","but","wo","n't","proceed","to","adding","noise","and","performing","the","actual","optimization","step",".","It","also","affects","the","behaviour","of","``","zero_grad","(",")","``",".","If","the","last","step","was","skipped",",","optimizer","will","clear","per","sample","gradients","accumulated","by","``","self.clip_and_accumulate","``","(","``","p.grad_sample","``",")",",","but","wo","n't","touch","aggregated","clipped","gradients","(","``","p.summed_grad","``",")","Used","by",":","class",":","`","~opacus.utils.batch_memory_manager.BatchMemoryManager","`","to","simulate","large","virtual","batches","with","limited","memory","footprint",".","Args",":","do_skip",":","flag","if","next","step","should","be","skipped"]
code: def signal_skip_step(self, do_skip=True):
      """
      Signals the optimizer to skip an optimization step and only perform clipping and
      per sample gradient accumulation.
  
      On every call of ``.step()`` optimizer will check the queue of skipped step
      signals. If non-empty and the latest flag is ``True``, optimizer will call
      ``self.clip_and_accumulate``, but won't proceed to adding noise and performing
      the actual optimization step.
      It also affects the behaviour of ``zero_grad()``. If the last step was skipped,
      optimizer will clear per sample gradients accumulated by
      ``self.clip_and_accumulate`` (``p.grad_sample``), but won't touch aggregated
      clipped gradients (``p.summed_grad``)
  
      Used by :class:`~opacus.utils.batch_memory_manager.BatchMemoryManager` to
      simulate large virtual batches with limited memory footprint.
  
      Args:
          do_skip: flag if next step should be skipped
      """
      self._step_skip_queue.append(do_skip)
  
imports: from __future__ import annotations
  import logging
  from typing import Callable, List, Optional, Union
  import torch
  from opacus.optimizers.utils import params
  from opt_einsum.contract import contract
  from torch import nn
  from torch.optim import Optimizer
label_desc: Use image node_id 3 for calling the DPOptimizer obj's underlying member method code with example usage: obj.signal_skip_step(do_skip) without return types