class_docstr: A class that orchestrates the execution of the execution of a batch of explanations in parallel.
class_docstr_tok: ["A","class","that","orchestrates","the","execution","of","the","execution","of","a","batch","of","explanations","in","parallel","."]
docstr: Creates a pool of actors (i.e., replicas of an instantiated `explainer_type` in a separate process) which can 
  explain batches of instances in parallel via calls to `get_explanation`. 
  
  
  Parameters
  ----------
  distributed_opts
      A dictionary with the following type (minimal signature)::
  
          class DistributedOpts(TypedDict):
              n_cpus: Optional[int]
              batch_size: Optional[int]
              
      The dictionary may contain two additional keys:
          
          - ``'actor_cpu_frac'`` : ``(float, <= 1.0, >0.0)`` - This is used to create more than one process                 on one CPU/GPU. This may not speed up CPU intensive tasks but it is worth experimenting with when                 few physical cores are available. In particular, this is highly useful when the user wants to share                 a GPU for multiple tasks, with the caviat that the machine learning framework itself needs to                 support running multiple replicas on the same GPU. See the `ray` documentation `here`_ for details.
          
          .. _here:
             https://docs.ray.io/en/latest/ray-core/scheduling/resources.html#fractional-resource-requirements
          
          - ``'algorithm'`` : ``str`` - this is specified internally by the caller. It is used in order to                 register target function callbacks for the parallel pool These should be implemented in the global                 scope. If not specified, its value will be ``'default'``, which will select a default target function                 which expects the actor has a `get_explanation` method. 
  
  explainer_type
      Explainer class.
  explainer_init_args
      Positional arguments to explainer constructor.
  explainer_init_kwargs
      Keyword arguments to explainer constructor.
  concatenate_results
      If ``True`` concatenates the results. See :py:func:`alibi.utils.distributed.concatenate_minibatches` for
      more details.
  return_generator
      If ``True`` a generator that returns the results in the order the computation finishes is returned when
      `get_explanation` is called. Otherwise, the order of the results is the same as the order of the 
      minibatches.
      
  Notes
  -----
  When ``return_generator=True``, the caller has to take elements from the generator (e.g., by calling `next`) in 
  order to start computing the results (because the `ray` pool is implemented as a generator).
code: def __init__(
      self,
      distributed_opts: Dict[str, Any],
      explainer_type: Any,
      explainer_init_args: Tuple,
      explainer_init_kwargs: dict,
      concatenate_results: bool = True,
      return_generator: bool = False,
  ):
      """
          Creates a pool of actors (i.e., replicas of an instantiated `explainer_type` in a separate process) which can 
          explain batches of instances in parallel via calls to `get_explanation`. 
          
          
          Parameters
          ----------
          distributed_opts
              A dictionary with the following type (minimal signature)::
  
                  class DistributedOpts(TypedDict):
                      n_cpus: Optional[int]
                      batch_size: Optional[int]
                      
              The dictionary may contain two additional keys:
                  
                  - ``'actor_cpu_frac'`` : ``(float, <= 1.0, >0.0)`` - This is used to create more than one process \
                  on one CPU/GPU. This may not speed up CPU intensive tasks but it is worth experimenting with when \
                  few physical cores are available. In particular, this is highly useful when the user wants to share \
                  a GPU for multiple tasks, with the caviat that the machine learning framework itself needs to \
                  support running multiple replicas on the same GPU. See the `ray` documentation `here`_ for details.
                  
                  .. _here:
                     https://docs.ray.io/en/latest/ray-core/scheduling/resources.html#fractional-resource-requirements
                  
                  - ``'algorithm'`` : ``str`` - this is specified internally by the caller. It is used in order to \
                  register target function callbacks for the parallel pool These should be implemented in the global \
                  scope. If not specified, its value will be ``'default'``, which will select a default target function \
                  which expects the actor has a `get_explanation` method. 
  
          explainer_type
              Explainer class.
          explainer_init_args
              Positional arguments to explainer constructor.
          explainer_init_kwargs
              Keyword arguments to explainer constructor.
          concatenate_results
              If ``True`` concatenates the results. See :py:func:`alibi.utils.distributed.concatenate_minibatches` for
              more details.
          return_generator
              If ``True`` a generator that returns the results in the order the computation finishes is returned when
              `get_explanation` is called. Otherwise, the order of the results is the same as the order of the 
              minibatches.
              
          Notes
          -----
          When ``return_generator=True``, the caller has to take elements from the generator (e.g., by calling `next`) in 
          order to start computing the results (because the `ray` pool is implemented as a generator).
          """  # noqa W605
  
      self.n_processes = distributed_opts["n_cpus"]
      self.batch_size = distributed_opts["batch_size"]
      self.return_generator = return_generator
      self.concatenate_results = concatenate_results
      algorithm = distributed_opts.get("algorithm", "default")
      if algorithm == "default":
          logger.warning(
              "No algorithm specified in distributed option, default target function will be selected."
          )
      self.target_fcn = default_target_fcn
      # check global scope for any specific target function
      if concatenate_results:
          self.concatenate = concatenate_minibatches
      if f"{algorithm}_target_fcn" in globals():
          self.target_fcn = globals()[f"{algorithm}_target_fcn"]
  
      if not ray.is_initialized():
          logger.info(
              f"Initialising ray on {self.n_processes} processes!"
          )
          ray.init(num_cpus=self.n_processes)
  
      # a pool is a collection of handles to different processes that can process data points in parallel
      self.pool = self.create_parallel_pool(
          explainer_type, explainer_init_args, explainer_init_kwargs
      )
      # use to retrieve state from different actors
      self._actor_index = 0
  
imports: import copy
  import logging
  from functools import partial
  from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Union
  import numpy
  from scipy import sparse
  import ray
label_desc: Use image node_id 1 to create a new DistributedExplainer object  with example: obj = DistributedExplainer(distributed_opts, explainer_type, explainer_init_args, explainer_init_kwargs, concatenate_results, return_generator)