LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Classes | Functions | Variables
lsst.ctrl.pool.pool Namespace Reference

Classes

class  PickleHolder
 
class  Comm
 
class  NoOp
 
class  Tags
 
class  Cache
 
class  SingletonMeta
 Metaclass to produce a singleton. More...
 
class  Debugger
 
class  ReductionThread
 
class  PoolNode
 
class  PoolMaster
 
class  PoolSlave
 
class  PoolWrapperMeta
 
class  PoolWrapper
 
class  Pool
 

Functions

def unpickleInstanceMethod (obj, name)
 
def pickleInstanceMethod (method)
 
def unpickleFunction (moduleName, funcName)
 
def pickleFunction (function)
 
def getBatchType ()
 
def setBatchType (batchType)
 
def abortOnError (func)
 
def guessPickleObj ()
 
def pickleSniffer (abort=False)
 
def catchPicklingError (func)
 
def startPool (comm=None, root=0, killSlaves=True)
 Start a process pool. More...
 

Variables

string NODE = "%s:%d" % (os.uname()[1], os.getpid())
 

Function Documentation

◆ abortOnError()

def lsst.ctrl.pool.pool.abortOnError (   func)
Function decorator to throw an MPI abort on an unhandled exception

Definition at line 107 of file pool.py.

107 def abortOnError(func):
108  """Function decorator to throw an MPI abort on an unhandled exception"""
109  @wraps(func)
110  def wrapper(*args, **kwargs):
111  try:
112  return func(*args, **kwargs)
113  except Exception as e:
114  sys.stderr.write("%s on %s in %s: %s\n" % (type(e).__name__, NODE, func.__name__, e))
115  import traceback
116  traceback.print_exc(file=sys.stderr)
117  sys.stdout.flush()
118  sys.stderr.flush()
119  if getBatchType() is not None:
120  mpi.COMM_WORLD.Abort(1)
121  else:
122  raise
123  return wrapper
124 
125 
table::Key< int > type
Definition: Detector.cc:163
def abortOnError(func)
Definition: pool.py:107
def getBatchType()
Definition: pool.py:96

◆ catchPicklingError()

def lsst.ctrl.pool.pool.catchPicklingError (   func)
Function decorator to catch errors in pickling and print something useful

Definition at line 234 of file pool.py.

234 def catchPicklingError(func):
235  """Function decorator to catch errors in pickling and print something useful"""
236  @wraps(func)
237  def wrapper(*args, **kwargs):
238  with pickleSniffer(True):
239  return func(*args, **kwargs)
240  return wrapper
241 
242 
def catchPicklingError(func)
Definition: pool.py:234
def pickleSniffer(abort=False)
Definition: pool.py:187

◆ getBatchType()

def lsst.ctrl.pool.pool.getBatchType ( )
Return a string giving the type of batch system in use

Definition at line 96 of file pool.py.

96 def getBatchType():
97  """Return a string giving the type of batch system in use"""
98  return _batchType
99 
100 

◆ guessPickleObj()

def lsst.ctrl.pool.pool.guessPickleObj ( )
Try to guess what's not pickling after an exception

This tends to work if the problem is coming from the
regular pickle module.  If it's coming from the bowels
of mpi4py, there's not much that can be done.

Definition at line 162 of file pool.py.

162 def guessPickleObj():
163  """Try to guess what's not pickling after an exception
164 
165  This tends to work if the problem is coming from the
166  regular pickle module. If it's coming from the bowels
167  of mpi4py, there's not much that can be done.
168  """
169  import sys
170  excType, excValue, tb = sys.exc_info()
171  # Build a stack of traceback elements
172  stack = []
173  while tb:
174  stack.append(tb)
175  tb = tb.tb_next
176 
177  try:
178  # This is the code version of a my way to find what's not pickling in pdb.
179  # This should work if it's coming from the regular pickle module, and they
180  # haven't changed the variable names since python 2.7.3.
181  return stack[-2].tb_frame.f_locals["obj"]
182  except Exception:
183  return None
184 
185 
186 @contextmanager
def guessPickleObj()
Definition: pool.py:162

◆ pickleFunction()

def lsst.ctrl.pool.pool.pickleFunction (   function)
Pickle a function

This assumes that we can recreate the function object by grabbing
it from the proper module.  This may be violated if the function
is a lambda or in __main__.  In that case, I recommend recasting
the function as an object with a __call__ method.

Another problematic case may be a wrapped (e.g., decorated) method
in a class: the 'method' is then a function, and recreating it is
not as easy as we assume here.

Definition at line 71 of file pool.py.

71 def pickleFunction(function):
72  """Pickle a function
73 
74  This assumes that we can recreate the function object by grabbing
75  it from the proper module. This may be violated if the function
76  is a lambda or in __main__. In that case, I recommend recasting
77  the function as an object with a __call__ method.
78 
79  Another problematic case may be a wrapped (e.g., decorated) method
80  in a class: the 'method' is then a function, and recreating it is
81  not as easy as we assume here.
82  """
83  moduleName = function.__module__
84  funcName = function.__name__
85  return unpickleFunction, (moduleName, funcName)
86 
87 
88 copyreg.pickle(types.FunctionType, pickleFunction)
89 
90 try:
91  _batchType
def pickleFunction(function)
Definition: pool.py:71

◆ pickleInstanceMethod()

def lsst.ctrl.pool.pool.pickleInstanceMethod (   method)
Pickle an instance method

The instance method is divided into the object and the
method name.

Definition at line 46 of file pool.py.

46 def pickleInstanceMethod(method):
47  """Pickle an instance method
48 
49  The instance method is divided into the object and the
50  method name.
51  """
52  obj = method.__self__
53  name = method.__name__
54  return unpickleInstanceMethod, (obj, name)
55 
56 
57 copyreg.pickle(types.MethodType, pickleInstanceMethod)
58 
59 
def pickleInstanceMethod(method)
Definition: pool.py:46

◆ pickleSniffer()

def lsst.ctrl.pool.pool.pickleSniffer (   abort = False)
Context manager to sniff out pickle problems

If there's a pickle error, you're normally told what the problem
class is.  However, all SWIG objects are reported as "SwigPyObject".
In order to figure out which actual SWIG-ed class is causing
problems, we need to go digging.

Use like this:

    with pickleSniffer():
        someOperationInvolvingPickle()

If 'abort' is True, will call MPI abort in the event of problems.

Definition at line 187 of file pool.py.

187 def pickleSniffer(abort=False):
188  """Context manager to sniff out pickle problems
189 
190  If there's a pickle error, you're normally told what the problem
191  class is. However, all SWIG objects are reported as "SwigPyObject".
192  In order to figure out which actual SWIG-ed class is causing
193  problems, we need to go digging.
194 
195  Use like this:
196 
197  with pickleSniffer():
198  someOperationInvolvingPickle()
199 
200  If 'abort' is True, will call MPI abort in the event of problems.
201  """
202  try:
203  yield
204  except Exception as e:
205  if "SwigPyObject" not in str(e) or "pickle" not in str(e):
206  raise
207  import sys
208  import traceback
209 
210  sys.stderr.write("Pickling error detected: %s\n" % e)
211  traceback.print_exc(file=sys.stderr)
212  obj = guessPickleObj()
213  heldObj = PickleHolder().obj
214  if obj is None and heldObj is not None:
215  # Try to reproduce using what was being pickled using the regular pickle module,
216  # so we've got a chance of figuring out what the problem is.
217  import pickle
218  try:
219  pickle.dumps(heldObj)
220  sys.stderr.write("Hmmm, that's strange: no problem with pickling held object?!?!\n")
221  except Exception:
222  obj = guessPickleObj()
223  if obj is None:
224  sys.stderr.write("Unable to determine class causing pickle problems.\n")
225  else:
226  sys.stderr.write("Object that could not be pickled: %s\n" % obj)
227  if abort:
228  if getBatchType() is not None:
229  mpi.COMM_WORLD.Abort(1)
230  else:
231  sys.exit(1)
232 
233 

◆ setBatchType()

def lsst.ctrl.pool.pool.setBatchType (   batchType)
Return a string giving the type of batch system in use

Definition at line 101 of file pool.py.

101 def setBatchType(batchType):
102  """Return a string giving the type of batch system in use"""
103  global _batchType
104  _batchType = batchType
105 
106 
def setBatchType(batchType)
Definition: pool.py:101

◆ startPool()

def lsst.ctrl.pool.pool.startPool (   comm = None,
  root = 0,
  killSlaves = True 
)

Start a process pool.

Returns a PoolMaster object for the master node.
Slave nodes are run and then optionally killed.

If you elect not to kill the slaves, note that they
will emerge at the point this function was called,
which is likely very different from the point the
master is at, so it will likely be necessary to put
in some rank dependent code (e.g., look at the 'rank'
attribute of the returned pools).

Note that the pool objects should be deleted (either
by going out of scope or explicit 'del') before program
termination to avoid a segmentation fault.

@param comm: MPI communicator
@param root: Rank of root/master node
@param killSlaves: Kill slaves on completion?

Definition at line 1216 of file pool.py.

1216 def startPool(comm=None, root=0, killSlaves=True):
1217  """!Start a process pool.
1218 
1219  Returns a PoolMaster object for the master node.
1220  Slave nodes are run and then optionally killed.
1221 
1222  If you elect not to kill the slaves, note that they
1223  will emerge at the point this function was called,
1224  which is likely very different from the point the
1225  master is at, so it will likely be necessary to put
1226  in some rank dependent code (e.g., look at the 'rank'
1227  attribute of the returned pools).
1228 
1229  Note that the pool objects should be deleted (either
1230  by going out of scope or explicit 'del') before program
1231  termination to avoid a segmentation fault.
1232 
1233  @param comm: MPI communicator
1234  @param root: Rank of root/master node
1235  @param killSlaves: Kill slaves on completion?
1236  """
1237  if comm is None:
1238  comm = Comm()
1239  if comm.rank == root:
1240  return PoolMaster(comm, root=root)
1241  slave = PoolSlave(comm, root=root)
1242  slave.run()
1243  if killSlaves:
1244  del slave # Required to prevent segmentation fault on exit
1245  sys.exit()
1246  return slave
def startPool(comm=None, root=0, killSlaves=True)
Start a process pool.
Definition: pool.py:1216

◆ unpickleFunction()

def lsst.ctrl.pool.pool.unpickleFunction (   moduleName,
  funcName 
)
Unpickle a function

This has to be a named function rather than a lambda because
pickle needs to find it.

Definition at line 60 of file pool.py.

60 def unpickleFunction(moduleName, funcName):
61  """Unpickle a function
62 
63  This has to be a named function rather than a lambda because
64  pickle needs to find it.
65  """
66  import importlib
67  module = importlib.import_module(moduleName)
68  return getattr(module, funcName)
69 
70 
def unpickleFunction(moduleName, funcName)
Definition: pool.py:60

◆ unpickleInstanceMethod()

def lsst.ctrl.pool.pool.unpickleInstanceMethod (   obj,
  name 
)
Unpickle an instance method

This has to be a named function rather than a lambda because
pickle needs to find it.

Definition at line 37 of file pool.py.

37 def unpickleInstanceMethod(obj, name):
38  """Unpickle an instance method
39 
40  This has to be a named function rather than a lambda because
41  pickle needs to find it.
42  """
43  return getattr(obj, name)
44 
45 
def unpickleInstanceMethod(obj, name)
Definition: pool.py:37

Variable Documentation

◆ NODE

string lsst.ctrl.pool.pool.NODE = "%s:%d" % (os.uname()[1], os.getpid())

Definition at line 34 of file pool.py.