-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parallel sampling hangs on macOS with Python 3.8 with pickling error #3844
Comments
Wow -- haven't played around with this yet, but maybe we add |
And thus Mac now enters the glorious realm of broken pipes, which was exclusive to windows before py38! |
Unfortunately I can't seem to re-open the issue, but I can confirm that #3919 does not fix this issue: https://gist.github.com/dfm/413938425166b0f30fba47a5d7639da7 I can confirm that |
Note that the changes in #3919 have been superseded by a recent PR by @aseyboldt. Does this seem to solve the issue you're having? Also, which version of PyMC3 are you running? |
Sorry - no I'm running the master branch and the changes made in that PR don't help - the problem is |
I don't really understand enough of the underlying issues to see the relevant differences. Perhaps this doesn't matter if people don't regularly use |
Yeah this issue is definitely weird. From my experience, sometimes it works with Does the new kwarg in sample help you with that (you can specify the method you want instead of sticking to the default)? I'm also curious about what @aseyboldt and @lucianopaz think before reopening. |
I think for the most part this issue is just inherent weirdness of multiprocessing/pickle. If the logp func can't be pickled, and the multiprocessing context is one of @dfm For your example I get this: import pymc3 as pm
with pm.Model() as model:
def val(x):
return -0.5 * pm.math.sum(x ** 2)
x = pm.Normal("x")
pm.DensityDist("obs", val)
pm.sample(chains=2, cores=2, mp_ctx="forkserver")
If you specify the multiprocessing context (please use We can avoid this problem at least in this case by using dill instead of pickle (assuming it is installed): import pymc3 as pm
with pm.Model() as model:
def val(x):
return -0.5 * pm.math.sum(x ** 2)
x = pm.Normal("x")
pm.DensityDist("obs", val)
pm.sample(chains=2, cores=2, mp_ctx="forkserver", pickle_backend='dill') Just to show that this isn't specific to pymc3 in any way: In the notebook this doesn't work either. import multiprocessing
ctx = multiprocessing.get_context("forkserver")
def foo(x):
print(2 * x)
proc = ctx.Process(target=foo, args=(2.,))
proc.start() The child process dies and prints the unpickling error to the terminal where the notebook was started. |
I guess we could actually work around this by depending on dill, and overwrite Somthing like this: class DensityDist(Distribution):
...
def __getstate__(self):
logp = dill.dumps(self.logp)
vals = self.__dict__.copy()
vals['logp'] = logp
return vals
def __setstate__(self, vals):
vals['logp'] = dill.loads(vals['logp'])
self.__dict__ = vals' |
@aseyboldt: I think that the suggestion to use dill for DensityDist is a great idea!
I haven't used dill much, are there cases where it can't pickle things that @AlexAndorra: thanks for the response! I was suggesting that it be reopened because the bug still exists even if it's not PyMC3 specific. If it's not re-opened there should probably at least be a |
I haven't used it much either, and I really do not know. That is why I'm a bit worried. I'll also reopen the issue. |
Description of your problem
Starting with Python 3.8 the default start method for multiprocessing on macOS is
spawn
instead offork
- more info here and here. This means that some features that used to work will not continue to work on macOS. I specifically ran into this when using aDensityDist
where the function was defined in place as follows because the function is not picklable:This fails with the following error that does not actually get caught. I was running in a Jupyter notebook and the notebook just hangs and this gets written to the command line:
A temporary workaround that I found was to execute
before importing PyMC3, but my understanding is that this won't be a long term solution. It doesn't seem like there's anything obvious to do about this, but I wanted to bring it up here in case folks had clever ideas!
Versions and main components
The text was updated successfully, but these errors were encountered: