class_docstr: Wrapper which allows computing sample-wise gradients in a single backward pass.
  
  This is accomplished by adding hooks to capture activations and output
  gradients for supported modules, and using these activations and gradients
  to compute the parameter gradients per-sample.
  
  Currently, only nn.Linear and nn.Conv2d modules are supported.
  
  Similar reference implementations of sample-based gradients include:
  - https://github.com/cybertronai/autograd-hacks
  - https://github.com/pytorch/opacus/tree/main/opacus/grad_sample
class_docstr_tok: ["Wrapper","which","allows","computing","sample-wise","gradients","in","a","single","backward","pass",".","This","is","accomplished","by","adding","hooks","to","capture","activations","and","output","gradients","for","supported","modules",",","and","using","these","activations","and","gradients","to","compute","the","parameter","gradients","per-sample",".","Currently",",","only","nn.Linear","and","nn.Conv2d","modules","are","supported",".","Similar","reference","implementations","of","sample-based","gradients","include",":","-","https",":","\/\/github.com\/cybertronai\/autograd-hacks","-","https",":","\/\/github.com\/pytorch\/opacus\/tree\/main\/opacus\/grad_sample"]
code: def compute_param_sample_gradients(
      self, loss_blob, loss_mode="mean"
  ) -> None:
      assert (
          loss_mode.upper() in LossMode.__members__
      ), f"Provided loss mode {loss_mode} is not valid"
      mode = LossMode[loss_mode.upper()]
  
      self.model.zero_grad()
      loss_blob.backward(gradient=torch.ones_like(loss_blob))
  
      for module in self.gradient_dict:
          sample_grad_fn = SUPPORTED_MODULES[type(module)]
          activations = self.activation_dict[module]
          gradients = self.gradient_dict[module]
          assert len(activations) == len(gradients), (
              "Number of saved activations do not match number of saved gradients."
              " This may occur if multiple forward passes are run without calling"
              " reset or computing param gradients."
          )
          # Reversing grads since when a module is used multiple times,
          # the activations will be aligned with the reverse order of the gradients,
          # since the order is reversed in backprop.
          for i, (act, grad) in enumerate(
              zip(activations, list(reversed(gradients)))
          ):
              mult = 1 if mode is LossMode.SUM else act.shape[0]
              sample_grad_fn(module, act, grad * mult, reset=(i == 0))
      self._reset()
  
imports: from collections import defaultdict
  from enum import Enum
  from typing import cast, DefaultDict, Iterable, List, Optional, Tuple, Union
  import torch
  from captum._utils.common import _format_tensor_into_tuples, _register_backward_hook
  from torch import Tensor
  from torch.nn import Module
label_desc: Use image node_id 8 for calling the SampleGradientWrapper obj's underlying member method code with example usage: obj.compute_param_sample_gradients(loss_blob, loss_mode) without return types