-
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
Split PySparseObservable
off SparseObservable
#13595
Conversation
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 12992269684Details
💛 - 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.
Thanks for doing this.
This is just a quick high-level overview - I'll look more in detail in the new year, especially since I'll have to use a lot more local tools to do a good comparison - with the file move and changes to the code, it's hard to see what's gone on here.
Top level questions:
-
Why split
py_sparse_observable
into a separate flat file? I'd have expected any of:- keep both in the same file
- make a
sparse_observable
module to put them in - make a separate crate that contains only the C component
with a rough preference to just keeping everything in the same file for now. This form to me has meant that a lot of logically private functions have had to become
pub(crate)
, and now there's more places to look to understand the code. -
For everything that's become
pub(crate)
: in some cases, I thinkpub(crate)
just indicates that a function is defined in the wrong file. In many others, since this PR is looking to a future whenSparseObservable
is consumable by non-Qiskit crates directly from Rust, I suspect that anything that becamepub(crate)
should be either private or fullypub
. If it's useful for the Python wrapper, feels highly likely it ought to be a proper public interface.
releasenotes/notes/update-sparse-observable-error-2bb4b9e678675eee.yaml
Outdated
Show resolved
Hide resolved
Thanks for the comments! I think they all make sense but I'll read them more carefully next year as well 🙂 Regarding
To me, having a separate crate (I assume into |
btw should Max be a co-author, or is this all you so far? |
- avoid using &Vec - add unsafe to mutable indices/boundaries - rm upgrade reno
With 3a4b5f0, all code is in a single file for now, but it should be easy to separate if we want to later on (basically the lower half is the Python wrapper)
This was my bit so far, since I was reviewing 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.
This looks like a really nice, clean split, thank you!
I pushed up one minor stylistic commit (just moving trait impls closer to the relevant structs, except when doing so would move "Python" code into "Rust" code), and I sorted out the merge conflict by upgrading the PySparseObservable
conversions into the new PyO3 form. Feel free to mess with those two commits if I've done something against what you wanted.
I had one non-actionable comment and one pretty minor nitpick, but other than that I'm very happy with this and ready to merge!
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 all the work on this!
crates/pyext/src/lib.rs
Outdated
add_submodule(m, ::qiskit_accelerate::sparse_observable::py_sparse_observable, "py_sparse_observable")?; | ||
add_submodule(m, ::qiskit_accelerate::sparse_observable::sparse_observable, "sparse_observable")?; |
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.
Technically this was the only line that actually needed to chance to implement my query (and then, just the string name), but giving them the same name is better anyway.
At some point in the near-ish future when I've lost my rage at my initial failed attempt, I'll post a PR that turns the submodule-construction logic back into more native PyO3 tooling, since PyO3 0.23 gave us the APIs we need, and abi3audit
removed the failure we were getting from it anyway (for reasons I don't 100% agree with).
Wait, no - one second, I think your last merge undid a bunch of stuff. |
- use Arc<> instead of Py<> in ArrayView - py_sparse.. -> sparse_
284c223
to
0741264
Compare
I straightened out the history to remove the second merge, but actually I think I was mistaken anyway - I think I just confused myself because the merge commit you pushed up had the same diff as the one I'd made (since those were the changes you were merging). |
Thanks to you for the help! I'm very happy to see this merged and move forward with the C API bit 😁 |
* Split ``PySparseObservable`` or ``SparseObservable`` * reno and docs * rm Arc<RwLock> for SparseTerm * add Into(Py) for SparseObservable * rm Rust-side PySparseObservable.clone * smaller fixes - avoid using &Vec - add unsafe to mutable indices/boundaries - rm upgrade reno * move back into 1 file * Bring trait impls closer to structs * review comments - use Arc<> instead of Py<> in ArrayView - py_sparse.. -> sparse_ * Tidy up whitespace --------- Co-authored-by: Jake Lishman <[email protected]>
Summary
Closes #13594 to prepare for
SparseObservable
's C API. This change has been tested with our basic C API forSparseObservable
, which will come in a separate PR to keep the review load in balance 🙂Details and comments
This PR splits the sparse observable class into a Rust-only
SparseObservable
struct and aPySparseObservable
, which serves as Python interface. As suggested in #13391, the Python interface keeps anArc
to a read-write-lockedSparseObservable
. TheAPI Change
label is only due to some minuscule change in an error message, the Python interface remains unchanged.The implementation is based on
and methods on
PySparseObservable
first acquire the read- or write-lock to perform actions on theinner
data. For example, implementingtranspose
becomesSome notes/questions:
SparseTerm
we analogously split offPySparseTerm
, since it can be returned to Python. The view/mutable view versions are not returned to Python and don't need a specific interface.IntoPy
toPoisonError
(coming from RwLock::read/write), so as solution we introduced customInnerReadError
s andInnerWriteError
s.pymethods
into the core Rust object and restricted direct access to the inner data, in favor of using public getters/methods.SparseObservable
docstring is moved to the Python interface for now, though we might want to add a bit more Rust-specific info.