code: def _compare_sample_grads_per_sample(
      self,
      model: Module,
      inputs: Tuple[Tensor, ...],
      loss_fn: Callable,
      loss_type: str = "mean",
  ):
      wrapper = SampleGradientWrapper(model)
      wrapper.add_hooks()
      apply_gradient_requirements(inputs)
      out = model(*inputs)
      wrapper.compute_param_sample_gradients(loss_fn(out), loss_type)
  
      batch_size = inputs[0].shape[0]
      for i in range(batch_size):
          model.zero_grad()
          single_inp = tuple(inp[i : i + 1] for inp in inputs)
          out = model(*single_inp)
          loss_fn(out).backward()
          for layer in model.modules():
              if isinstance(layer, tuple(SUPPORTED_MODULES.keys())):
                  assertTensorAlmostEqual(
                      self,
                      layer.weight.grad,
                      layer.weight.sample_grad[i],  # type: ignore
                      mode="max",
                  )
                  assertTensorAlmostEqual(
                      self,
                      layer.bias.grad,
                      layer.bias.sample_grad[i],  # type: ignore
                      mode="max",
                  )
  
file_path: captum/tests/utils/test_sample_gradient.py
imports: import unittest
  from typing import Callable, Tuple
  import torch
  from captum._utils.gradient import apply_gradient_requirements
  from captum._utils.sample_gradient import _reset_sample_grads, SampleGradientWrapper, SUPPORTED_MODULES
  from packaging import version
  from tests.helpers.basic import assertTensorAlmostEqual, BaseTest
  from tests.helpers.basic_models import BasicModel_ConvNet_One_Conv, BasicModel_ConvNetWithPaddingDilation, BasicModel_MultiLayer
  from torch import Tensor
  from torch.nn import Module
label_desc: Use image node_id 7 for calling the Test obj's underlying member method code with example usage: obj._compare_sample_grads_per_sample(model, inputs, loss_fn, loss_type) without return types