class_docstr: SlidingWindowInfererAdapt extends SlidingWindowInferer to automatically switch to buffered and then to CPU stitching,
  when OOM on GPU. It also records a size of such large images to automatically
  try CPU stitching for the next large image of a similar size.  If the stitching 'device' input parameter is provided,
  automatic adaptation won't be attempted, please keep the default option device = None for adaptive behavior.
  Note: the output might be on CPU (even if the input was on GPU), if the GPU memory was not sufficient.
class_docstr_tok: ["SlidingWindowInfererAdapt","extends","SlidingWindowInferer","to","automatically","switch","to","buffered","and","then","to","CPU","stitching",",","when","OOM","on","GPU",".","It","also","records","a","size","of","such","large","images","to","automatically","try","CPU","stitching","for","the","next","large","image","of","a","similar","size",".","If","the","stitching","'device","'","input","parameter","is","provided",",","automatic","adaptation","wo","n't","be","attempted",",","please","keep","the","default","option","device","=","None","for","adaptive","behavior",".","Note",":","the","output","might","be","on","CPU","(","even","if","the","input","was","on","GPU",")",",","if","the","GPU","memory","was","not","sufficient","."]
docstr: Args:
      inputs: model input data for inference.
      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",":","model","input","data","for","inference",".","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,
  ) -> (
      torch.Tensor | tuple[torch.Tensor, ...] | dict[Any, torch.Tensor]
  ):
      """
  
      Args:
          inputs: model input data for inference.
          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``.
  
      """
  
      # if device is provided, use without any adaptations
      if self.device is not None:
          return super().__call__(inputs, network, *args, **kwargs)
  
      skip_buffer = (
          self.buffer_steps is not None and self.buffer_steps <= 0
      )
      cpu_cond = (
          self.cpu_thresh is not None
          and inputs.shape[2:].numel() > self.cpu_thresh
      )
      gpu_stitching = inputs.is_cuda and not cpu_cond
      buffered_stitching = (
          inputs.is_cuda and cpu_cond and not skip_buffer
      )
      buffer_steps = (
          max(1, self.buffer_steps)
          if self.buffer_steps is not None
          else 1
      )
      buffer_dim = -1
  
      sh = list(inputs.shape[2:])
      max_dim = sh.index(max(sh))
      if inputs.shape[max_dim + 2] / inputs.shape[-1] >= 2:
          buffer_dim = max_dim
  
      for _ in range(10):  # at most 10 trials
          try:
              return super().__call__(
                  inputs,
                  network,
                  *args,
                  device=inputs.device
                  if gpu_stitching
                  else torch.device("cpu"),
                  buffer_steps=buffer_steps
                  if buffered_stitching
                  else None,
                  buffer_dim=buffer_dim,
                  **kwargs,
              )
          except RuntimeError as e:
              if (
                  not gpu_stitching
                  and not buffered_stitching
                  or "OutOfMemoryError" not in str(type(e).__name__)
              ):
                  raise e
  
              logger.info(e)
  
              if gpu_stitching:  # if failed on gpu
                  gpu_stitching = False
                  self.cpu_thresh = (
                      inputs.shape[2:].numel() - 1
                  )  # update thresh
  
                  if skip_buffer:
                      buffered_stitching = False
                      logger.warning(
                          f"GPU stitching failed, attempting on CPU, image dim {inputs.shape}."
                      )
  
                  else:
                      buffered_stitching = True
                      self.buffer_steps = buffer_steps
                      logger.warning(
                          f"GPU stitching failed, buffer {buffer_steps} dim {buffer_dim}, image dim {inputs.shape}."
                      )
              elif buffer_steps > 1:
                  buffer_steps = max(1, buffer_steps // 2)
                  self.buffer_steps = buffer_steps
                  logger.warning(
                      f"GPU buffered stitching failed, image dim {inputs.shape} reducing buffer to {buffer_steps}."
                  )
              else:
                  buffered_stitching = False
                  logger.warning(
                      f"GPU buffered stitching failed, attempting on CPU, image dim {inputs.shape}."
                  )
      raise RuntimeError(  # not possible to finish after the trials
          f"SlidingWindowInfererAdapt {skip_buffer} {cpu_cond} {gpu_stitching} {buffered_stitching} {buffer_steps}"
      )
  
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 1 for calling the SlidingWindowInfererAdapt obj's underlying member method code with example usage: obj.__call__(inputs, network) and returns: super, super