-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Enable PyO3 in cargo unit tests. #13169
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
Conversation
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 12795511628Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
If you enable the |
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.
Overall this looks great to me, I really am looking forward to having an established pattern for doing more involved rust testing. Especially as we're moving more into rust. I left a few inline comments, mostly nits in the docs and a question in the tests. The only concern I have right now is that we're defaulting to building the python extension in release mode for rust testing and I feel like we should be defaulting to debug mode for the extension when in a rust testing context. Not because I think we need the debug symbols or optimizations disabled, but just to reduce the compile time since the extension is only there to make python work and we shouldn't really be concerned with the runtime performance of it in a rust testing context.
```bash | ||
tox -erust | ||
``` |
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.
My only concern here is that this results in building Qiskit from source twice on every execution. I'm not sure there is a way around this since we need the python extension built to be able to call it via python in the rust tests it just is pretty slow. We should probably build in debug mode by default in tox and for rust testing by default.
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.
I've enabled debug mode by default for the rust
env's package environment in 6856adb.
I also documented --skip-pkg-install
as an option for running without rebuilding Qiskit when invoking tox -erust
, and I've explained there that this is only an option if you've already built the current working tree: 4813a7c
CONTRIBUTING.md
Outdated
You can also execute them directly in your own virtual environment with these | ||
commands (which is what the ``tox`` env is doing under the hood): |
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.
There is a path to running without a virtual environment, but that's probably not good to encourage because it means people will be installing a dev version of qiskit in their system site packages. It might be good to add a sentence here explaining you should make a venv for testing in this case.
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.
Good point. I've reworded this section to guide users to first create and activate a virtual environment if they're running without tox.
CONTRIBUTING.md
Outdated
|
||
```bash | ||
cargo test --no-default-features | ||
python setup.py build_rust --release --inplace |
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.
I'd actually change this to not include --release
by default. That just increases the build time and we shouldn't be bottlenecked on the python extension's execution time in rust tests.
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.
Should be done in 234b6a5 as well.
[testenv:rust] | ||
basepython = python3 | ||
setenv = | ||
PYTHONUSERBASE={envdir} |
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.
The default tox configuration will build in release mode, I think for rust testing we should use debug mode by default.
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.
Done in 6856adb.
This should be ready to go, @mtreinish. The Rust tests for |
|
||
```bash | ||
cargo test --no-default-features | ||
python setup.py build_rust --inplace | ||
PYTHONUSERBASE="$VIRTUAL_ENV" cargo test --no-default-features |
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.
Overall this PR is great, long needed for running Rust tests easily with PyO3 in Qiskit!
My only comment is about virtual environments other than venv
. For Conda I had to set LD_LIBRARY_PATH
to point to the lib
directory under the env dir so the embedded interpreter could find the required shared libraries. I don't think we should provide examples for other custom virtual envs, but rather just put a [!note] comment that for other virtual envs a different setup might be required (and maybe mention LD_LIBRARY_PATH
for Conda since it's common).
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.
Thanks for trying this on Conda. Any chance you could try the following instead of LD_LIBRARY_PATH
?
PYTHONUSERBASE="$CONDA_PREFIX" cargo test --no-default-features
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.
This was actually my first attempt to make it work in Conda, following the nice documentation you put together. But it doesn't help. I didn't dig into the actual root cause but it surely something about the embedded interpreter not being aware to the virtual environment if it's Conda. I wouldn't put time solving this but rather just include a warning in this section for users to note.
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.
I'd forgotten that on Linux, the rpath of the test executable doesn't include the Python library. To work around this, the rust
tox env now exports LD_LIBRARY_PATH
to include the path to the current Python environment's shared Python lib before running cargo test
. This is similar to what we do in CI.
Can you try running tox -erust
on Linux again with these changes? I've also updated the docs for manual invocations without tox.
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.
I can confirm it's working now. Thanks @kevinhartman!
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, thanks for doing this
* POC for using PyO3 in cargo unit tests. * Reorder jobs in test-linux.yml. * Actually use the venv... * Disable Miri for PyO3-based cargo tests. * Fix disable for module-level. * Improve comment in Rust test runner CI job. * Use pyo3/auto-initialize feature in test. * Update contibuting guide. * Testing for push_back and push_front. * Add tox rust env for Cargo tests. * Set Python user base in CI. * Clean up. * Address review comments. * Set RUST_DEBUG in pkg env for Tox rust env. * Explain --skip-pkg-install option for faster run. * Fix typo. * Update TOC. * Add Python lib to LD_LIBRARY_PATH in tox.
Summary
At present, most of our core data structures like
DAGCircuit
internally rely on the Python interpreter in some way, which has so far prevented us from writing Rust-based unit tests. Up to this point, we've gotten away with depending on our Python-based test coverage to exercise Rust code internally, but this is quickly becoming insufficient as we add more Rust-only API surface.This PR does a few things to enable the use of the Python interpreter and load Qiskit's Python code into it:
auto-initialize
, which initializes the free-threaded Python interpreter. This enables the use ofPython::with_gil
and thus access to aPython
token from within tests.miri
for such tests, since it is not compatible (e.g.#[cfg(not(miri))]
).PYTHONUSERBASE
environment variable to the activevenv
's directory. This allows the Python interpreter baked into the test executable to locate the Pythonqiskit
module.tox
env has been added to orchestrate this. To run Rust tests, simply invoketox -erust
.Details and comments
As an example, this PR adds unit tests for
DAGCircuit::push_back
andDAGCircuit::push_front
. We really ought to add more testing for the other new Rust-facing methods (e.g.DAGCircuit::extend
via additional PRs).As more of Qiskit's core is ported to Rust, our reliance on the Python interpreter from Rust code should eventually be overcome, and at that point we shouldn't need these changes anymore.