class_docstr: Inference on patches instead of the whole image based on Splitter and Merger.
  This splits the input image into patches and then merge the resulted patches.
  
  Args:
      splitter: a `Splitter` object that split the inputs into patches. Defaults to None.
          If not provided or None, the inputs are considered to be already split into patches.
          In this case, the output `merged_shape` and the optional `cropped_shape` cannot be inferred
          and should be explicitly provided.
      merger_cls: a `Merger` subclass that can be instantiated to merges patch outputs.
          It can also be a string that matches the name of a class inherited from `Merger` class.
          Defaults to `AvgMerger`.
      batch_size: batch size for patches. If the input tensor is already batched [BxCxWxH],
          this adds additional batching [(Bp*B)xCxWpxHp] for inference on patches.
          Defaults to 1.
      preprocessing: a callable that process patches before the being fed to the network.
          Defaults to None.
      postprocessing: a callable that process the output of the network.
          Defaults to None.
      output_keys: if the network output is a dictionary, this defines the keys of
          the output dictionary to be used for merging.
          Defaults to None, where all the keys are used.
      match_spatial_shape: whether to crop the output to match the input shape. Defaults to True.
      buffer_size: number of patches to be held in the buffer with a separate thread for batch sampling. Defaults to 0.
      merger_kwargs: arguments to be passed to `merger_cls` for instantiation.
          `merged_shape` is calculated automatically based on the input shape and
          the output patch shape unless it is passed here.
class_docstr_tok: ["Inference","on","patches","instead","of","the","whole","image","based","on","Splitter","and","Merger",".","This","splits","the","input","image","into","patches","and","then","merge","the","resulted","patches",".","Args",":","splitter",":","a","`","Splitter","`","object","that","split","the","inputs","into","patches",".","Defaults","to","None",".","If","not","provided","or","None",",","the","inputs","are","considered","to","be","already","split","into","patches",".","In","this","case",",","the","output","`","merged_shape","`","and","the","optional","`","cropped_shape","`","can","not","be","inferred","and","should","be","explicitly","provided",".","merger_cls",":","a","`","Merger","`","subclass","that","can","be","instantiated","to","merges","patch","outputs",".","It","can","also","be","a","string","that","matches","the","name","of","a","class","inherited","from","`","Merger","`","class",".","Defaults","to","`","AvgMerger","`",".","batch_size",":","batch","size","for","patches",".","If","the","input","tensor","is","already","batched","[","BxCxWxH","]",",","this","adds","additional","batching","[","(","Bp","*","B",")","xCxWpxHp","]","for","inference","on","patches",".","Defaults","to","1.","preprocessing",":","a","callable","that","process","patches","before","the","being","fed","to","the","network",".","Defaults","to","None",".","postprocessing",":","a","callable","that","process","the","output","of","the","network",".","Defaults","to","None",".","output_keys",":","if","the","network","output","is","a","dictionary",",","this","defines","the","keys","of","the","output","dictionary","to","be","used","for","merging",".","Defaults","to","None",",","where","all","the","keys","are","used",".","match_spatial_shape",":","whether","to","crop","the","output","to","match","the","input","shape",".","Defaults","to","True",".","buffer_size",":","number","of","patches","to","be","held","in","the","buffer","with","a","separate","thread","for","batch","sampling",".","Defaults","to","0.","merger_kwargs",":","arguments","to","be","passed","to","`","merger_cls","`","for","instantiation",".","`","merged_shape","`","is","calculated","automatically","based","on","the","input","shape","and","the","output","patch","shape","unless","it","is","passed","here","."]
docstr: Args:
      inputs: input data for inference, a torch.Tensor, representing an image or batch of images.
          However if the data is already split, it can be fed by providing a list of tuple (patch, location),
          or a MetaTensor that has metadata for `PatchKeys.LOCATION`. In both cases no splitter should be provided.
      network: target model to execute inference.
          supports callables such as ``lambda x: my_torch_model(x, additional_config)``
      args: optional args to be passed to ``network``.
      kwargs: optional keyword args to be passed to ``network``.
docstr_tok: ["Args",":","inputs",":","input","data","for","inference",",","a","torch.Tensor",",","representing","an","image","or","batch","of","images",".","However","if","the","data","is","already","split",",","it","can","be","fed","by","providing","a","list","of","tuple","(","patch",",","location",")",",","or","a","MetaTensor","that","has","metadata","for","`","PatchKeys.LOCATION","`",".","In","both","cases","no","splitter","should","be","provided",".","network",":","target","model","to","execute","inference",".","supports","callables","such","as","``","lambda","x",":","my_torch_model","(","x",",","additional_config",")","``","args",":","optional","args","to","be","passed","to","``","network","``",".","kwargs",":","optional","keyword","args","to","be","passed","to","``","network","``","."]
code: def __call__(
      self,
      inputs: torch.Tensor,
      network: Callable[
          ...,
          torch.Tensor
          | Sequence[torch.Tensor]
          | dict[Any, torch.Tensor],
      ],
      *args: Any,
      **kwargs: Any,
  ) -> Any:
      """
      Args:
          inputs: input data for inference, a torch.Tensor, representing an image or batch of images.
              However if the data is already split, it can be fed by providing a list of tuple (patch, location),
              or a MetaTensor that has metadata for `PatchKeys.LOCATION`. In both cases no splitter should be provided.
          network: target model to execute inference.
              supports callables such as ``lambda x: my_torch_model(x, additional_config)``
          args: optional args to be passed to ``network``.
          kwargs: optional keyword args to be passed to ``network``.
  
      """
      patches_locations: Iterable[
          tuple[torch.Tensor, Sequence[int]]
      ] | MetaTensor
      if self.splitter is None:
          # handle situations where the splitter is not provided
          if isinstance(inputs, torch.Tensor):
              if isinstance(inputs, MetaTensor):
                  if PatchKeys.LOCATION not in inputs.meta:
                      raise ValueError(
                          "`PatchKey.LOCATION` does not exists in `inputs.meta`. "
                          "If the inputs are already split into patches, the location of patches needs to be "
                          "provided as `PatchKey.LOCATION` metadata in a MetaTensor. "
                          "If the input is not already split, please provide `splitter`."
                      )
              else:
                  raise ValueError(
                      "`splitter` should be set if the input is not already split into patches. "
                      "For inputs that are split, the location of patches needs to be provided as "
                      "(image, location) pairs, or as `PatchKey.LOCATION` metadata in a MetaTensor. "
                      f"The provided inputs type is {type(inputs)}."
                  )
          patches_locations = inputs
      else:
          # apply splitter
          patches_locations = self.splitter(inputs)
  
      ratios: list[float] = []
      mergers: list[Merger] = []
      for patches, locations, batch_size in self._batch_sampler(
          patches_locations
      ):
          # run inference
          outputs = self._run_inference(
              network, patches, *args, **kwargs
          )
          # initialize the mergers
          if not mergers:
              mergers, ratios = self._initialize_mergers(
                  inputs, outputs, patches, batch_size
              )
          # aggregate outputs
          self._aggregate(
              outputs, locations, batch_size, mergers, ratios
          )
  
      # finalize the mergers and get the results
      merged_outputs = [merger.finalize() for merger in mergers]
  
      # return according to the model output
      if self.output_keys:
          return dict(zip(self.output_keys, merged_outputs))
      if len(merged_outputs) == 1:
          return merged_outputs[0]
      return merged_outputs
  
imports: from __future__ import annotations
  import warnings
  from abc import ABC, abstractmethod
  from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
  from pydoc import locate
  from typing import Any
  import torch
  import torch.nn
  from monai.apps.utils import get_logger
  from monai.data.meta_tensor import MetaTensor
  from monai.data.thread_buffer import ThreadBuffer
  from monai.inferers.merger import AvgMerger, Merger
  from monai.inferers.splitter import Splitter
  from monai.inferers.utils import compute_importance_map, sliding_window_inference
  from monai.utils import BlendMode, PatchKeys, PytorchPadMode, ensure_tuple, optional_import
  from monai.visualize import CAM, GradCAM, GradCAMpp
label_desc: Use image node_id 8 for calling the PatchInferer obj's underlying member method code with example usage: obj.__call__(inputs, network) and returns: merged_outputs, dict, merged_outputs