-
Notifications
You must be signed in to change notification settings - Fork 5
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
feat!: Use a common struct for both QPU and QVM execution results #223
Conversation
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.
Really good work here!
I nitpicked a handful of things for you to address at your leisure.
The main non-nit I found is that it looks like your bounds checks suffer from an off-by-one error. Where possible, bounds-checked direct indexing should be replaced with a method that returns an Option
instead.
Overall, really good stuff, and I think it'll streamline how people interact with returned data.
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.
- One style suggestion
- One note about why
ndarray
doesn't haveget_row(index) -> Option
, etc. methods - One response to the question of using
usize
vsu64
forMemoryReference::index
inquil-rs
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.
Looking good. Need to spend some more time with it, when I'm not tired :)
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, just some pyi
questions
Co-authored-by: jselig-rigetti <[email protected]>
Co-authored-by: jselig-rigetti <[email protected]>
Co-authored-by: jselig-rigetti <[email protected]>
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.
It's almost there! This is excellent work.
Some small typos and a note re: visibility; otherwise, this is ready to go.
Co-authored-by: Kalan <[email protected]>
Co-authored-by: Kalan <[email protected]>
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.
Left a handful of stylistic comments and a question or two.
Main reason for requesting changes is that I ran cargo check --all-targets --all-features
locally and it surfaced some errors inside of tests. It may also be worth running cargo clippy
with the same flags, just to be safe.
Co-authored-by: Michael Bryant <[email protected]>
Those checks fail for the same reasons on |
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.
Three things:
- Enum variants got turned into tuples in a
pyi
file cargo deny check
fails, in part due to the addition ofnumpy
cargo doc
andcargo deadlinks --check-intra-doc-links
show warnings. Not sure how many were there previously, but worth at least looking at.
I added the numpy license to |
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
The original version of this PR attempted to abstract away the differences between QVM memory and QPU readout data by fitting them both into a common representation, where each register name mapped to a corresponding rectangular 2d-matrix where-in each row corresponded to the final state of that register after that shot.
It turns out QPU readout data is more complicated in that it treats each memory reference as a stream. These streams aren't delimited per-shot, so if the program isn't always performing exactly one readout to each memory reference per shot, it isn't clear from the readout data alone what the last value in each shot is. This is often the case for programs using features like mid-circuit measurement and dynamic control flow where a measure to a memory reference could occur more than once, or be skipped conditionally.
After some discussion internally, it became clear that the rectangular matrix this PR was originally attempting to build was indeed the preferred form, as it fits the type of math that is generally done on it. However, we can't escape from the realities of dealing with QPU readout data. In light of this, we've chosen to keep the abstraction, but only allow it if we can build it using the underlying readout data without making potentially erroneous assumptions. This gives users what they want in many cases, but forces them to build exactly what they need if their program calls for it.
This PR now stores the original data returned from either the QPU or QVM in a
ResultData
enum. Users can choose to turn this into aRegisterMap
, which will build the "ideal" mapping of register names to rectangular matrices. If the underlying QPU data would be jagged, an error is returned, signaling to the user that they should build their own based on the program that was run.The matrices themselves are built on the
ndarray
crate. This is not only convenient for working with the data in Rust, but it can also be passed to and from Python as anumpy
ndarray
using thenumpy
crate.Closes #215