class_docstr: Distributed Searchlight
  
  Run a user-defined function over each voxel in a multi-subject
  dataset.
  
  Optionally, users can define a block function which runs over
  larger portions of the volume called blocks.
  
  Parameters
  ----------
  
  sl_rad: radius, in voxels, of the sphere inscribed in the
             searchlight cube, not counting the center voxel
  
  max_blk_edge: max edge length, in voxels, of the 3D block
  
  shape: brainiak.searchlight.searchlight.Shape indicating the
  shape in voxels of the searchlight region
  
  min_active_voxels_proportion: float
      If a searchlight region does not have more than this minimum
      proportion of active voxels in the mask, it is not processed by the
      searchlight function. The mask used for the test is the
      intersection of the global (brain) mask and the `Shape` mask. The
      seed (central) voxel of the searchlight region is taken into
      consideration.
class_docstr_tok: ["Distributed","Searchlight","Run","a","user-defined","function","over","each","voxel","in","a","multi-subject","dataset",".","Optionally",",","users","can","define","a","block","function","which","runs","over","larger","portions","of","the","volume","called","blocks",".","Parameters","--","--","--","--","--","sl_rad",":","radius",",","in","voxels",",","of","the","sphere","inscribed","in","the","searchlight","cube",",","not","counting","the","center","voxel","max_blk_edge",":","max","edge","length",",","in","voxels",",","of","the","3D","block","shape",":","brainiak.searchlight.searchlight.Shape","indicating","the","shape","in","voxels","of","the","searchlight","region","min_active_voxels_proportion",":","float","If","a","searchlight","region","does","not","have","more","than","this","minimum","proportion","of","active","voxels","in","the","mask",",","it","is","not","processed","by","the","searchlight","function",".","The","mask","used","for","the","test","is","the","intersection","of","the","global","(","brain",")","mask","and","the","`","Shape","`","mask",".","The","seed","(","central",")","voxel","of","the","searchlight","region","is","taken","into","consideration","."]
docstr: Perform a function for each block in a volume.
  
  Parameters
  ----------
  
  block_fn: function to apply to each block:
  
          Parameters
  
          data: list of 4D arrays containing subset of subject data,
                which is padded with sl_rad voxels.
  
          mask: 3D array containing subset of mask data
  
          sl_rad: radius, in voxels, of the sphere inscribed in the
          cube
  
          bcast_var: shared data which is broadcast to all processes
  
          extra_params: extra parameters
  
  
          Returns
  
          3D array which is the same size as the mask
          input with padding removed
  
  extra_block_fn_params: tuple
      Extra parameters to pass to the block function
  
  pool_size: int
      Maximum number of processes running the block function in parallel.
      If None, number of available hardware threads, considering cpusets
      restrictions.
docstr_tok: ["Perform","a","function","for","each","block","in","a","volume",".","Parameters","--","--","--","--","--","block_fn",":","function","to","apply","to","each","block",":","Parameters","data",":","list","of","4D","arrays","containing","subset","of","subject","data",",","which","is","padded","with","sl_rad","voxels",".","mask",":","3D","array","containing","subset","of","mask","data","sl_rad",":","radius",",","in","voxels",",","of","the","sphere","inscribed","in","the","cube","bcast_var",":","shared","data","which","is","broadcast","to","all","processes","extra_params",":","extra","parameters","Returns","3D","array","which","is","the","same","size","as","the","mask","input","with","padding","removed","extra_block_fn_params",":","tuple","Extra","parameters","to","pass","to","the","block","function","pool_size",":","int","Maximum","number","of","processes","running","the","block","function","in","parallel",".","If","None",",","number","of","available","hardware","threads",",","considering","cpusets","restrictions","."]
code: def run_block_function(
      self, block_fn, extra_block_fn_params=None, pool_size=None
  ):
      """Perform a function for each block in a volume.
  
      Parameters
      ----------
  
      block_fn: function to apply to each block:
  
              Parameters
  
              data: list of 4D arrays containing subset of subject data,
                    which is padded with sl_rad voxels.
  
              mask: 3D array containing subset of mask data
  
              sl_rad: radius, in voxels, of the sphere inscribed in the
              cube
  
              bcast_var: shared data which is broadcast to all processes
  
              extra_params: extra parameters
  
  
              Returns
  
              3D array which is the same size as the mask
              input with padding removed
  
      extra_block_fn_params: tuple
          Extra parameters to pass to the block function
  
      pool_size: int
          Maximum number of processes running the block function in parallel.
          If None, number of available hardware threads, considering cpusets
          restrictions.
      """
      rank = self.comm.rank
  
      results = []
      usable_cpus = usable_cpu_count()
      if pool_size is None:
          processes = usable_cpus
      else:
          processes = min(pool_size, usable_cpus)
  
      if processes > 1:
          with Pool(processes) as pool:
              for idx, block in enumerate(self.blocks):
                  result = pool.apply_async(
                      block_fn,
                      (
                          [
                              subproblem[idx]
                              for subproblem in self.subproblems
                          ],
                          self.submasks[idx],
                          self.sl_rad,
                          self.bcast_var,
                          extra_block_fn_params,
                      ),
                  )
                  results.append((block[0], result))
              local_outputs = [
                  (result[0], result[1].get()) for result in results
              ]
      else:
          # If we only are using one CPU core, no need to create a Pool,
          # cause an underlying fork(), and send the data to that process.
          # Just do it here in serial. This  will save copying the memory
          # and will stop a fork() which can cause problems in some MPI
          # implementations.
          for idx, block in enumerate(self.blocks):
              subprob_list = [
                  subproblem[idx] for subproblem in self.subproblems
              ]
              result = block_fn(
                  subprob_list,
                  self.submasks[idx],
                  self.sl_rad,
                  self.bcast_var,
                  extra_block_fn_params,
              )
              results.append((block[0], result))
          local_outputs = [(result[0], result[1]) for result in results]
  
      # Collect results
      global_outputs = self.comm.gather(local_outputs)
  
      # Coalesce results
      outmat = np.empty(self.mask.shape, dtype=object)
      if rank == 0:
          for go_rank in global_outputs:
              for pt, mat in go_rank:
                  coords = np.s_[
                      pt[0]
                      + self.sl_rad : pt[0]
                      + self.sl_rad
                      + mat.shape[0],
                      pt[1]
                      + self.sl_rad : pt[1]
                      + self.sl_rad
                      + mat.shape[1],
                      pt[2]
                      + self.sl_rad : pt[2]
                      + self.sl_rad
                      + mat.shape[2],
                  ]
                  outmat[coords] = mat
      return outmat
  
imports: from multiprocessing import Pool
  import numpy
  from mpi4py import MPI
  from scipy.spatial.distance import cityblock, euclidean
  from ..utils.utils import usable_cpu_count
label_desc: Use image node_id 9 for calling the Searchlight obj's underlying member method code with example usage: obj.run_block_function(block_fn, extra_block_fn_params, pool_size) and returns: outmat