code: def _batch_attribution(
      attr_method,
      num_examples,
      internal_batch_size,
      n_steps,
      include_endpoint=False,
      **kwargs,
  ):
      """
      This method applies internal batching to given attribution method, dividing
      the total steps into batches and running each independently and sequentially,
      adding each result to compute the total attribution.
  
      Step sizes and alphas are spliced for each batch and passed explicitly for each
      call to _attribute.
  
      kwargs include all argument necessary to pass to each attribute call, except
      for n_steps, which is computed based on the number of steps for the batch.
  
      include_endpoint ensures that one step overlaps between each batch, which
      is necessary for some methods, particularly LayerConductance.
      """
      if internal_batch_size < num_examples:
          warnings.warn(
              "Internal batch size cannot be less than the number of input examples. "
              "Defaulting to internal batch size of %d equal to the number of examples."
              % num_examples
          )
      # Number of steps for each batch
      step_count = max(1, internal_batch_size // num_examples)
      if include_endpoint:
          if step_count < 2:
              step_count = 2
              warnings.warn(
                  "This method computes finite differences between evaluations at "
                  "consecutive steps, so internal batch size must be at least twice "
                  "the number of examples. Defaulting to internal batch size of %d"
                  " equal to twice the number of examples."
                  % (2 * num_examples)
              )
  
      total_attr = None
      cumulative_steps = 0
      step_sizes_func, alphas_func = approximation_parameters(
          kwargs["method"]
      )
      full_step_sizes = step_sizes_func(n_steps)
      full_alphas = alphas_func(n_steps)
  
      while cumulative_steps < n_steps:
          start_step = cumulative_steps
          end_step = min(start_step + step_count, n_steps)
          batch_steps = end_step - start_step
  
          if include_endpoint:
              batch_steps -= 1
  
          step_sizes = full_step_sizes[start_step:end_step]
          alphas = full_alphas[start_step:end_step]
          current_attr = attr_method._attribute(
              **kwargs,
              n_steps=batch_steps,
              step_sizes_and_alphas=(step_sizes, alphas),
          )
  
          if total_attr is None:
              total_attr = current_attr
          else:
              if isinstance(total_attr, Tensor):
                  total_attr = total_attr + current_attr.detach()
              else:
                  total_attr = tuple(
                      current.detach() + prev_total
                      for current, prev_total in zip(
                          current_attr, total_attr
                      )
                  )
          if include_endpoint and end_step < n_steps:
              cumulative_steps = end_step - 1
          else:
              cumulative_steps = end_step
      return total_attr
  
file_path: captum/captum/attr/_utils/batching.py
imports: import typing
  import warnings
  from typing import Any, Callable, Iterator, Tuple, Union
  import torch
  from captum._utils.common import _format_additional_forward_args, _format_output, _format_tensor_into_tuples, _reduce_list
  from captum._utils.typing import TargetType, TensorOrTupleOfTensorsGeneric, TupleOrTensorOrBoolGeneric
  from captum.attr._utils.approximation_methods import approximation_parameters
  from torch import Tensor
label_desc: Use image node_id 1 for calling a global function with example usage: _batch_attribution(attr_method, num_examples, internal_batch_size, n_steps, include_endpoint) and returns: total_attr