class_docstr: Wraps population of step methods to step them in parallel with single or multiprocessing.
class_docstr_tok: ["Wraps","population","of","step","methods","to","step","them","in","parallel","with","single","or","multiprocessing","."]
docstr: Use multiprocessing to parallelize chains.
  
  Falls back to sequential evaluation if multiprocessing fails.
  
  In the multiprocessing mode of operation, a new process is started for each
  chain/stepper and Pipes are used to communicate with the main process.
  
  Parameters
  ----------
  steppers : list
      A collection of independent step methods, one for each chain.
  parallelize : bool
      Indicates if parallelization via multiprocessing is desired.
  progressbar : bool
      Should we display a progress bar showing relative progress?
docstr_tok: ["Use","multiprocessing","to","parallelize","chains",".","Falls","back","to","sequential","evaluation","if","multiprocessing","fails",".","In","the","multiprocessing","mode","of","operation",",","a","new","process","is","started","for","each","chain\/stepper","and","Pipes","are","used","to","communicate","with","the","main","process",".","Parameters","--","--","--","--","--","steppers",":","list","A","collection","of","independent","step","methods",",","one","for","each","chain",".","parallelize",":","bool","Indicates","if","parallelization","via","multiprocessing","is","desired",".","progressbar",":","bool","Should","we","display","a","progress","bar","showing","relative","progress","?"]
code: def __init__(
      self, steppers, parallelize: bool, progressbar: bool = True
  ):
      """Use multiprocessing to parallelize chains.
  
      Falls back to sequential evaluation if multiprocessing fails.
  
      In the multiprocessing mode of operation, a new process is started for each
      chain/stepper and Pipes are used to communicate with the main process.
  
      Parameters
      ----------
      steppers : list
          A collection of independent step methods, one for each chain.
      parallelize : bool
          Indicates if parallelization via multiprocessing is desired.
      progressbar : bool
          Should we display a progress bar showing relative progress?
      """
      self.nchains = len(steppers)
      self.is_parallelized = False
      self._primary_ends = []
      self._processes = []
      self._steppers = steppers
      if parallelize:
          try:
              # configure a child process for each stepper
              _log.info(
                  "Attempting to parallelize chains to all cores. You can turn this off with `pm.sample(cores=1)`."
              )
              import multiprocessing
  
              for c, stepper in (
                  enumerate(progress_bar(steppers))
                  if progressbar
                  else enumerate(steppers)
              ):
                  secondary_end, primary_end = multiprocessing.Pipe()
                  stepper_dumps = cloudpickle.dumps(stepper, protocol=4)
                  process = multiprocessing.Process(
                      target=self.__class__._run_secondary,
                      args=(c, stepper_dumps, secondary_end),
                      name=f"ChainWalker{c}",
                  )
                  # we want the child process to exit if the parent is terminated
                  process.daemon = True
                  # Starting the process might fail and takes time.
                  # By doing it in the constructor, the sampling progress bar
                  # will not be confused by the process start.
                  process.start()
                  self._primary_ends.append(primary_end)
                  self._processes.append(process)
              self.is_parallelized = True
          except Exception:
              _log.info(
                  "Population parallelization failed. "
                  "Falling back to sequential stepping of chains."
              )
              _log.debug("Error was: ", exc_info=True)
      else:
          _log.info(
              "Chains are not parallelized. You can enable this by passing "
              "`pm.sample(cores=n)`, where n > 1."
          )
      return super().__init__()
  
imports: import logging
  import warnings
  from copy import copy
  from typing import Iterator, List, Sequence, Tuple, Union
  import cloudpickle
  import numpy
  from fastprogress.fastprogress import progress_bar
  from typing_extensions import TypeAlias
  from pymc.backends.base import BaseTrace
  from pymc.initial_point import PointType
  from pymc.model import Model, modelcontext
  from pymc.stats.convergence import log_warning_stats
  from pymc.step_methods import CompoundStep
  from pymc.step_methods.arraystep import BlockedStep, PopulationArrayStepShared, StatsType
  from pymc.step_methods.metropolis import DEMetropolis
  from pymc.util import RandomSeed
label_desc: Use image node_id 1 to create a new PopulationStepper object  with example: obj = PopulationStepper(steppers, parallelize, progressbar)