Skip to content
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

placed context stack inside thread-local data space #1555

Merged
merged 3 commits into from Nov 30, 2016

Conversation

burnpanck
Copy link
Contributor

@burnpanck burnpanck commented Nov 26, 2016

Currently, PyMC3's model-context suggests that the effect is scoped to the body of the context manager. However, this is not the case: Since it changes global state (the class attribute contexts is shared globally within the interpreter), it affects any other PyMC3 code that could be running in a different thread. By making the context stack thread-local, the effect of the changes are properly confined to the code inside the context manager.

Fixes #1552

@twiecki
Copy link
Member

twiecki commented Nov 26, 2016

Traceback (most recent call last):
  File "/home/travis/minconda3/envs/testenv/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/home/travis/minconda3/envs/testenv/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/home/travis/minconda3/envs/testenv/lib/python3.5/multiprocessing/pool.py", line 429, in _handle_results
    task = get()
  File "/home/travis/minconda3/envs/testenv/lib/python3.5/multiprocessing/connection.py", line 251, in recv
    return ForkingPickler.loads(buf.getbuffer())
  File "/home/travis/build/pymc-devs/pymc3/pymc3/distributions/distribution.py", line 18, in __new__
    model = Model.get_context()
  File "/home/travis/build/pymc-devs/pymc3/pymc3/model.py", line 120, in get_context
    return cls.get_contexts()[-1]
  File "/home/travis/build/pymc-devs/pymc3/pymc3/model.py", line 114, in get_contexts
    return cls.contexts.stack
AttributeError: '_thread._local' object has no attribute 'stack'

@burnpanck
Copy link
Contributor Author

Oh. I'll look into it.

@burnpanck
Copy link
Contributor Author

Indeed, there was a stupid mistake in my implementation, and I should have tested it before uploading. Now I added a regression test and it does work. However, on my local machine, test_diagnostics (and some other tests?) still fails. Running under py.test (what do you use on travis?), exceptions in threads other than the main thread seem to block indefinitely, which makes it hard to see what's going on. From what I could gather so far, it looks like that test fails somewhere in a multi-processing sampling function. Apparently, some data is serialised via pickle to communicate across threads/processes, which eventually seems to fail possibly due to #895 (by indident, my report there before had nothing to do with this): With this fix here, the receiver doesn't own a model-context any more.

@ColCarroll
Copy link
Member

Can't help much in the next few days, but tests are run using nose on travis -- you can launch them by hand with something like

THEANO_FLAGS='gcc.cxxflags="-march=core2"' nosetests -vv tests/this_is_optional.py

This is equivalent to

./scripts/test.sh -vv tests/this_is_optional.py

If you have Docker running on your machine, you could also ./scripts/start_container.sh to start a pymc3 container, then run the tests inside there (more details are in the CONTRIBUTING.md).

I'm not sure why, but most scientific python projects use nose instead of pytest.

@springcoil
Copy link
Contributor

springcoil commented Nov 28, 2016 via email

@burnpanck
Copy link
Contributor Author

I merged my PR #1560 into this. According to Travis, solving the pickle problem indeed fixes this PR here too.

@@ -10,10 +10,14 @@
__all__ = ['DensityDist', 'Distribution', 'Continuous',
'Discrete', 'NoDistribution', 'TensorType', 'draw_values']

class _Unpickling(object):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably want to rebase.

@twiecki
Copy link
Member

twiecki commented Nov 29, 2016

LGTM. @ColCarroll think we should merge this into master or 3.1?

@burnpanck burnpanck force-pushed the fix-context-manager-thread-safety branch from 17683f2 to 9d5b1a1 Compare November 29, 2016 09:17
@ColCarroll
Copy link
Member

Seems like a bugfix, not a feature, so I'd go with master.

@twiecki twiecki merged commit 68e53eb into pymc-devs:master Nov 30, 2016
@twiecki
Copy link
Member

twiecki commented Nov 30, 2016

Thanks @burnpanck!

ColCarroll pushed a commit to ColCarroll/pymc3 that referenced this pull request Dec 2, 2016
* placed context stack inside thread-local data space

* fixed thread-local context manager, and added a regression test

* fixed docstring of pymc-devs#1552 regression test
@twiecki twiecki mentioned this pull request Dec 2, 2016
ColCarroll pushed a commit to ColCarroll/pymc3 that referenced this pull request Dec 3, 2016
* placed context stack inside thread-local data space

* fixed thread-local context manager, and added a regression test

* fixed docstring of pymc-devs#1552 regression test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants