I am trying to nest multiprocessing pool within another multiprocessing pool. Both levels need to be process pools, thread pools are not required for my purposes.
However all 5 of my attempts using multiprocssing
or pathos
have failed
Attempt #1:
from multiprocessing import Pool
def foo(a, b):
return Pool(3).map(bar, range(a+b))
def bar(x):
return Pool(3).map(baz, range(x*2))
def baz(z):
return z**2
if __name__ == '__main__':
results = Pool(3).starmap(foo, list(zip(range(0,10,2), range(1,10,2))))
print(results)
gave the error
AssertionError: daemonic processes are not allowed to have children
Attempt #2:
from pathos.multiprocessing import ProcessPool
def foo(a, b):
return ProcessPool(3).map(bar, range(a+b))
def bar(x):
return ProcessPool(3).map(baz, range(x*2))
def baz(z):
return z**2
if __name__ == '__main__':
results = ProcessPool(3).map(foo, range(0,10,2), range(1,10,2))
print(results)
gave the error
AssertionError: daemonic processes are not allowed to have children
Attempt #3:
from pathos.parallel import ParallelPool
def foo(a, b):
return ParallelPool(nodes=3).map(bar, range(a+b))
def bar(x):
return ParallelPool(nodes=3).map(baz, range(x*2))
def baz(z):
return z**2
if __name__ == '__main__':
results = ParallelPool(nodes=3).map(foo, range(0,10,2), range(1,10,2))
print(results)
gave the error
NameError: name 'AbstractWorkerPool' is not defined
Attempt #4:
Based on Python Process Pool non-daemonic?
import multiprocessing
class NonDaemonPool(multiprocessing.Pool):
def Process(self, *args, **kwds):
proc = super(NonDaemonPool, self).Process(*args, **kwds)
class NonDaemonProcess(proc.__class__):
"""Monkey-patch process to ensure it is never daemonized"""
@property
def daemon(self):
return False
@daemon.setter
def daemon(self, val):
pass
proc.__class__ = NonDaemonProcess
return proc
def foo(a, b):
return NoDaemonPool(3).map(bar, range(a+b))
def bar(x):
return NoDaemonPool(3).map(baz, range(x*2))
def baz(z):
return z**2
if __name__ == '__main__':
results = NoDaemonPool(3).starmap(foo, list(zip(range(0,10,2), range(1,10,2))))
print(results)
gave the error
class NonDaemonPool(multiprocessing.Pool):
TypeError: method expected 2 arguments, got 3
Attempt #5:
Based on Python Process Pool non-daemonic?
import multiprocessing
class NoDaemonProcess(multiprocessing.Process):
@property
def daemon(self):
return False
@daemon.setter
def daemon(self, value):
pass
class NoDaemonContext(type(multiprocessing.get_context())):
Process = NoDaemonProcess
class NonDaemonPool(multiprocessing.Pool):
def __init__(self, *args, **kwargs):
kwargs['context'] = NoDaemonContext()
super(NonDaemonPool, self).__init__(*args, **kwargs)
def foo(a, b):
return NoDaemonPool(3).map(bar, range(a+b))
def bar(x):
return NoDaemonPool(3).map(baz, range(x*2))
def baz(z):
return z**2
if __name__ == '__main__':
results = NoDaemonPool(3).starmap(foo, list(zip(range(0,10,2), range(1,10,2))))
print(results)
gave the error
class NonDaemonPool(multiprocessing.Pool):
TypeError: method expected 2 arguments, got 3
Any advice to achieve multiprocessing pool nested within multiprocessing pool is greatly appreciated! Usage of pathos
is not required, although pathos
appears to already support nested/hierarchical multiprocessing maps so I believe it is the easier solution than Python 3's built-in multiprocessing
module.
Using Python 3.8.0 and pathos 0.2.5 on Mac OS X Catalina 10.15.2