-
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
Native OpenQASM 3 importer #11584
Native OpenQASM 3 importer #11584
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.
Apologies - the Rust code isn't super well commented or structured at the moment. I will add more of that in due course. At the moment, in principle, everything happens in Rust, calling out to Python through PyO3 (so I didn’t need to bother defining a transport format) to construct a QuantumCircuit
. The library files are:
lib
defines the Python entry points (loads
)error
at the moment just imports a Python-space exceptioncircuit
defines a few thin Rust-space wrappers around Python objects to inject a little bit more type safety into what I was doingexpr
is the constant-folder / expression evaluator (which doesn’t do much constant folding, but it does evaluate a few expressions)build
is where the loop through the ASG happens, and that manages the construction of theQuantumCircuit
qiskit/qasm/libs/dummy/stdgates.inc
Outdated
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 dummy version of the standard include is because the base parser can't handle the fancy gate-annotations (gate cx a, b { ctrl @ x a, b; }
and the like) that the canonical version of the file uses, so this is the same file with all the definitions stubbed out, just for import-parsing purposes.
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.
gate cx a, b { ctrl @ x a, b; }
is now parsed correctly by version 0.0.7 of the base parser. (also in 0.0.6, but into a different structure.)
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.
Ok cool thanks, I'll remove the dummy library if the regular stdgates.inc
parses.
While I've been the author of the Qiskit side of this, John wrote the separate Rust crates that this depends on, so in principle this contribution to Qiskit is from both of us. Co-authored-by: John Lapeyre <[email protected]>
54f5032
to
f84e86a
Compare
Pull Request Test Coverage Report for Build 7734314938Warning: This coverage report may be inaccurate.We've detected an issue with your CI configuration that might affect the accuracy of this pull request's coverage report.
💛 - Coveralls |
The qasm3 crate fails to build on Windows. This commit should fix this.
Measures, including broadcasted measures, are now supported following increased support on the parser side. The updated version also includes changes to a few APIs, and the include-path settings are now configurable at the entry point, so we switch to those.
Whoopsie, that last commit uses a Rust 1.75 feature: return-position |
Change crates/qasm3/Cargo.toml to depend on a released version of the parser. that is the crate oq3_semantics, rather than a commit of the github repo. All of the commits added since the commit previously specified in the dependency are either updating the README or tweaking the github actions.
NOTE: The following PR has been closed, not merged. |
One or more of the the following people are requested to review this:
|
Long overdue removing from draft, sorry about that. |
I've pushed up the formatting fix (I really ought to sort out my editor - I'm so used to having autoformat setup for Python that I always forget I don't have Rust set to format on write), but I've not reverted 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 ready to go to me. @mtreinish ?
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 the quick update. One thing I missed in my earlier review is that for an experimental api the requirements are it's clearly documented and it raises a warning on use. I just noticed the documentation side of this is missing in the function docstrings. The other missing thing is the release note, I think even as an experimental feature this definitely warrants a feature note. Once those are fixed I think this is good to go.
pyo3.workspace = true | ||
indexmap.workspace = true | ||
hashbrown.workspace = true | ||
oq3_semantics = "0.0.7" |
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.
Does this pin the version at 0.0.7
? In principle we could make backward compatible bug fixes in 0.0.8. There are certainly some bugs that would affect this importer.
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 looks like we might want to release 0.1.0
of the parser in order to allow fixes:
https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-cratesio
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.
Then oq3_semantics = "0.1.0"
would be compatible with 0.1.1
, etc.
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.
Yes, this dependency is equivalent to >=0.0.7,<0.0.8
. Cargo treats leading zeros specially - it basically treats the leftmost non-zero as the semantic-version "major". For how we're updating the base library at the moment, I think that's actually fairly accurate (and not a problem on either side).
That said, this doesn't really affect anything, because we build our Rust crates into cdylib Python extensions that we treat give-or-take like fixed binary objects - one of those ways is that we pin our dependencies with the lockfile, so only precise lockfile updates affect the build environment, and (for the most part) are made separately to Rust code changes. In this case, large tracts of the lockfile are updated because there's so many new dependencies getting pulled in.
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.
In any case, I just released openqasm3_parser 0.1.0 ., This is the same as 0.0.7. Just changed the version (and reduced the sleep between publishing crates to 60 s) : https://crates.io/crates/oq3_semantics
I'm not sure I follow everything you said about versions. But if I understand correctly, a particular version of Qiskit includes a fixed version of every file, including the Cargo.lock
files. And these
fix precise versions of Rust dependencies of Qiksit.
Just thinking: perhaps the largest thing that makes me nervous about this is the problems around negative float literals. If we're able to quickly teach the backend lexer to lex float (and int) literals as |
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 now thanks for the update. Just one quick inline comment on some of the new docs.
I think it's fine to do this between rc1 and the final release. This api endpoint is explicitly experimental and actively warns as such, so changes in behavior seem fair game at any point. But also since it wouldn't be changing any public interface I'd view this as more of a bugfix than anything else. |
Yeah, that sounds reasonable to me. |
I spent a lot of time on the weekend and today on gate modifiers, which turns out not to be important for the release! ... Maybe we can call this the fog of major version release. Anyway, I might be able to fix unary minus pretty quickly. |
John: sorry about that. My aim (certainly in the later half) was less to support modifiers end-to-end, but more to allow us to drop the dummy include file for
edit: That above paragraph makes no sense and hallucinates lexer theory, and I think I'm losing my mind. |
Yes I agree that seems like the easiest way to handle floats. |
I notice FWIW that the reference lexer for OQ3 does not lex the minus sign as part of the float. There must be some reason people sometimes prefer to lex |
Thanks very much for that! I'm really sorry - you pointing out we don't do it in the OQ3 ANTLR lexer made me realise why we don't actually lex like that - it'll produce false parse failures for I don't even know where I got the idea that that was common to do lexer side, I'm sorry. Do you think it's best to stick with this for one release, or switch it back? |
Not a problem. This took only a few minutes. And it's useful to understand the issue. Qiskit/openqasm3_parser#90 fails to parse
If you mean Qiskit/openqasm3_parser#90, we have to revert. Before this commit, I think correcting this between the lexer and the ASG will not be difficult. |
Summary
This is a Qiskit-native version of an OpenQASM 3 parser and converter to
QuantumCircuit
, with the vast majority written in Rust.At the moment, it exposes two entry points on
qiskit.qasm3
:loads_experimental
andload_experimental
, with their API documented.Details and comments
This is hugely experimental right now, and this PR is currently missing a few critical features, some because of lack of support in the Rust code here, some because of lack of support on the parser side at https://github.com/Qiskit/openqasm3_parser.
I don't want to understate that above point: at the moment,Measure and barrier are now both supported, but (for example)measure
isn't supported (but see Qiskit/openqasm3_parser#42 - it's being parsed, just there's a bug in passing it through to the semantic AST).if
statements aren't.I'm opening this PR in draft now to make it public, but there may be significant changes to the Rust internals, and obviously it will expand with new features from both sides. This PR currently includes a re-implementation of #11326 (
ExperimentalWarning
- since it was convenient to get it sorted immediately),and modifiesnow rebased overqiskit.qasm3.dumps
to use anOPENQASM 3.0;
header (like #11418, except without the test modifications) because the parser at the moment doesn't likeOPENQASM 3;
(and we should be more accurate anyway).main
.I haven't written the test suite yet.
As a brief example (and tbh, this shows much of the end-to-end supported feature set - it's not huge yet):