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: The method is started on a separate process to perform stepping of a chain.
  
  Parameters
  ----------
  c : int
      number of this chain
  stepper : BlockedStep
      a step method such as CompoundStep
  secondary_end : multiprocessing.connection.PipeConnection
      This is our connection to the main process
docstr_tok: ["The","method","is","started","on","a","separate","process","to","perform","stepping","of","a","chain",".","Parameters","--","--","--","--","--","c",":","int","number","of","this","chain","stepper",":","BlockedStep","a","step","method","such","as","CompoundStep","secondary_end",":","multiprocessing.connection.PipeConnection","This","is","our","connection","to","the","main","process"]
code: def _run_secondary(c, stepper_dumps, secondary_end):
      """The method is started on a separate process to perform stepping of a chain.
  
      Parameters
      ----------
      c : int
          number of this chain
      stepper : BlockedStep
          a step method such as CompoundStep
      secondary_end : multiprocessing.connection.PipeConnection
          This is our connection to the main process
      """
      # re-seed each child process to make them unique
      np.random.seed(None)
      try:
          stepper = cloudpickle.loads(stepper_dumps)
          # the stepper is not necessarily a PopulationArraySharedStep itself,
          # but rather a CompoundStep. PopulationArrayStepShared.population
          # has to be updated, therefore we identify the substeppers first.
          population_steppers = []
          for sm in (
              stepper.methods
              if isinstance(stepper, CompoundStep)
              else [stepper]
          ):
              if isinstance(sm, PopulationArrayStepShared):
                  population_steppers.append(sm)
          while True:
              incoming = secondary_end.recv()
              # receiving a None is the signal to exit
              if incoming is None:
                  break
              tune_stop, population = incoming
              if tune_stop:
                  stepper.stop_tuning()
              # forward the population to the PopulationArrayStepShared objects
              # This is necessary because due to the process fork, the population
              # object is no longer shared between the steppers.
              for popstep in population_steppers:
                  popstep.population = population
              update = stepper.step(population[c])
              secondary_end.send(update)
      except Exception:
          _log.exception(f"ChainWalker{c}")
      return
  
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 4 for calling the PopulationStepper obj's underlying member method code with example usage: obj._run_secondary(c, stepper_dumps, secondary_end) without return types