-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Fix parallel dispatch with target argument in transpile() #8952
Fix parallel dispatch with target argument in transpile() #8952
Conversation
If a custom target was specified when calling the transpile() function with more than one circuit the parallel dispatch of the shared custom target would fail because the basis_gates created from the target was a dict keys type. Pickle is unable to serialize a dict keys object apparently and this would cause an exception to be raised. This commit fixes this by casting the basis_gates from the target as a list so that it can be serialized.
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the the following people are requested to review this:
|
Pull Request Test Coverage Report for Build 3289841070
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me - it's good to get all these parallel issues squashed.
I'm thinking now that we have a pattern for running things in parallel in the unit tests that we can drop the standalone script we run after the unittests and integrate that into the test suite. I'll do that in a follow up PR |
319d31e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Playing with the tests more locally I don't think the mock is working as expected. I'm not able to trigger the bug with the tests without the code change applied and adding a print in |
In the previous patches we were attempting to use unittest.mock.patch.dict to override the env variable used to control parallel execution in qiskit. However, the issue with doing this is that the env variable is read at import time and stored in a global variable as we don't expect the env variable to change dynamically during the execution of a script. To workaround this the mocks are removed and instead a setUp() method is added to the test class to override the whatever the environment default is and instead hardcode parallel_map to run in parallel for the test and then switch it back to the earlier value after the test finishes. This lets us dynamically adjust the default behavior for parallel execution for this test class.
ok 9d2cfd2 should fix it, it turns out the env variable approach would never have worked because it's only checked once on import. |
In Qiskit#7658 we disabled multiprocessing as part of unittest runs in CI because the multiple layers of parallelism (subprocess from stestr, multiprocessing from qiskit, and multithreading from rust in qiskit) were triggering a latent bug in python's multiprocessing implementation that was blocking CI. To counter the lost coverage from disabling multiprocessing in that PR we added a script verify_parallel_map which force enabled multiprocessing and validated transpile() run in parallel executed correctly. However, in Qiskit#8952 we introduced a model for selectively enabling multiprocessing just for a single test method. This should allow us to avoid the stochastic failure triggering the deadlock in python's multiprocessing by overloading parallelism but still test in isolation that parallel_map() works. This commit builds on the test class introduced in Qiskit#8952 and adds identical test cases to what was previously in verify_parallel_map.py to move that coverage into the unit test suite. Then the verify_parallel_map script is removed and all callers are updated to just run unit tests instead of also executing that script.
In Qiskit#7658 we disabled multiprocessing as part of unittest runs in CI because the multiple layers of parallelism (subprocess from stestr, multiprocessing from qiskit, and multithreading from rust in qiskit) were triggering a latent bug in python's multiprocessing implementation that was blocking CI. To counter the lost coverage from disabling multiprocessing in that PR we added a script verify_parallel_map which force enabled multiprocessing and validated transpile() run in parallel executed correctly. However, in Qiskit#8952 we introduced a model for selectively enabling multiprocessing just for a single test method. This should allow us to avoid the stochastic failure triggering the deadlock in python's multiprocessing by overloading parallelism but still test in isolation that parallel_map() works. This commit builds on the test class introduced in Qiskit#8952 and adds identical test cases to what was previously in verify_parallel_map.py to move that coverage into the unit test suite. Then the verify_parallel_map script is removed and all callers are updated to just run unit tests instead of also executing that script.
# Force parallel execution to True to test multiprocessing for this class | ||
original_val = parallel.PARALLEL_DEFAULT | ||
|
||
def restore_default(): | ||
parallel.PARALLEL_DEFAULT = original_val | ||
|
||
self.addCleanup(restore_default) | ||
parallel.PARALLEL_DEFAULT = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want, you can also do this with unittest.mock.patch.object
in the same way you used patch.dict
before, but it doesn't matter.
* Fix parallel dispatch with target argument in transpile() If a custom target was specified when calling the transpile() function with more than one circuit the parallel dispatch of the shared custom target would fail because the basis_gates created from the target was a dict keys type. Pickle is unable to serialize a dict keys object apparently and this would cause an exception to be raised. This commit fixes this by casting the basis_gates from the target as a list so that it can be serialized. * Use unittest.mock.patch.dict to set parallel execution in tests * Fix parallel flag for test * Fix parallel test setup In the previous patches we were attempting to use unittest.mock.patch.dict to override the env variable used to control parallel execution in qiskit. However, the issue with doing this is that the env variable is read at import time and stored in a global variable as we don't expect the env variable to change dynamically during the execution of a script. To workaround this the mocks are removed and instead a setUp() method is added to the test class to override the whatever the environment default is and instead hardcode parallel_map to run in parallel for the test and then switch it back to the earlier value after the test finishes. This lets us dynamically adjust the default behavior for parallel execution for this test class. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit ef9259d)
In Qiskit#7658 we disabled multiprocessing as part of unittest runs in CI because the multiple layers of parallelism (subprocess from stestr, multiprocessing from qiskit, and multithreading from rust in qiskit) were triggering a latent bug in python's multiprocessing implementation that was blocking CI. To counter the lost coverage from disabling multiprocessing in that PR we added a script verify_parallel_map which force enabled multiprocessing and validated transpile() run in parallel executed correctly. However, in Qiskit#8952 we introduced a model for selectively enabling multiprocessing just for a single test method. This should allow us to avoid the stochastic failure triggering the deadlock in python's multiprocessing by overloading parallelism but still test in isolation that parallel_map() works. This commit builds on the test class introduced in Qiskit#8952 and adds identical test cases to what was previously in verify_parallel_map.py to move that coverage into the unit test suite. Then the verify_parallel_map script is removed and all callers are updated to just run unit tests instead of also executing that script.
) * Fix parallel dispatch with target argument in transpile() If a custom target was specified when calling the transpile() function with more than one circuit the parallel dispatch of the shared custom target would fail because the basis_gates created from the target was a dict keys type. Pickle is unable to serialize a dict keys object apparently and this would cause an exception to be raised. This commit fixes this by casting the basis_gates from the target as a list so that it can be serialized. * Use unittest.mock.patch.dict to set parallel execution in tests * Fix parallel flag for test * Fix parallel test setup In the previous patches we were attempting to use unittest.mock.patch.dict to override the env variable used to control parallel execution in qiskit. However, the issue with doing this is that the env variable is read at import time and stored in a global variable as we don't expect the env variable to change dynamically during the execution of a script. To workaround this the mocks are removed and instead a setUp() method is added to the test class to override the whatever the environment default is and instead hardcode parallel_map to run in parallel for the test and then switch it back to the earlier value after the test finishes. This lets us dynamically adjust the default behavior for parallel execution for this test class. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit ef9259d) Co-authored-by: Matthew Treinish <[email protected]>
In #7658 we disabled multiprocessing as part of unittest runs in CI because the multiple layers of parallelism (subprocess from stestr, multiprocessing from qiskit, and multithreading from rust in qiskit) were triggering a latent bug in python's multiprocessing implementation that was blocking CI. To counter the lost coverage from disabling multiprocessing in that PR we added a script verify_parallel_map which force enabled multiprocessing and validated transpile() run in parallel executed correctly. However, in #8952 we introduced a model for selectively enabling multiprocessing just for a single test method. This should allow us to avoid the stochastic failure triggering the deadlock in python's multiprocessing by overloading parallelism but still test in isolation that parallel_map() works. This commit builds on the test class introduced in #8952 and adds identical test cases to what was previously in verify_parallel_map.py to move that coverage into the unit test suite. Then the verify_parallel_map script is removed and all callers are updated to just run unit tests instead of also executing that script. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Summary
If a custom target was specified when calling the transpile() function with more than one circuit the parallel dispatch of the shared custom target would fail because the basis_gates created from the target was a dict keys type. Pickle is unable to serialize a dict keys object apparently and this would cause an exception to be raised. This commit fixes this by casting the basis_gates from the target as a list so that it can be serialized.
Details and comments