Skip to content
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

Adapt crates/qasm3 to work with recent versions of openqasm3_parser #12087

Merged
merged 8 commits into from
May 3, 2024

Conversation

jlapeyre
Copy link
Contributor

This commit adds no new features or capabilities to the importer. But it brings the importer up to date with the latest version of openqasm3_parser as a preliminary step in improving the importer.

The biggest change in openqasm3_parser is in handling stdgates.inc. Upon encountering include "stdgates.inc" openqasm3_parser reads no file, but rather adds symbols to the symbol table for gates in the standard library.

The function convert_asg in the importer calls oq3_semantics::symbols::SymbolTable.gates which returns a Vec of information about each "declared" gate. The information is the gate's name and signature and SymbolID, which is sufficient to do everything the importer could do before this commit.

Encountering Stmt::GateDefinition now is a no-op rather than an error. (This was previously called Stmt::GateDeclaration, but importantly it is really a definition.)

How the standard library, and gates in general, are handled will continue to evolve.

A behavioral difference between this commit and its parent: Before if the importer encountered a gate call before the corresponding definition an error would be raised. With the current commit, the importer behaves as if all gate definitions were moved to the top of the OQ3 program. However, the error will still be found by the parser so that the importer never will begin processing statements.

The importer depends on a particular branch of a copy of openqasm3_parser. When the commit is ready to merge, we will release a version of openqasm3_parser and depend instead on that release.

See openqasm/openqasm#517

@jlapeyre jlapeyre requested a review from a team as a code owner March 26, 2024 22:12
@qiskit-bot
Copy link
Collaborator

One or more of the the following people are requested to review this:

This commit adds no new features or capabilities to the importer. But it brings
the importer up to date with the latest version of openqasm3_parser as a preliminary
step in improving the importer.

The biggest change in openqasm3_parser is in handling stdgates.inc.  Upon encountering
`include "stdgates.inc" openqasm3_parser reads no file, but rather adds symbols to the
symbol table for gates in the standard library.

The function `convert_asg` in the importer calls oq3_semantics::symbols::SymbolTable.gates
which returns a `Vec` of information about each "declared" gate. The information is the
gate's name and signature and SymbolID, which is sufficient to do everything the importer
could do before this commit.

Encountering `Stmt::GateDefinition` now is a no-op rather than an error.  (This was
previously called `Stmt::GateDeclaration`, but importantly it is really a definition.)

How the standard library, and gates in general, are handled will continue to evolve.

A behavioral difference between this commit and its parent: Before if the importer
encountered a gate call before the corresponding definition an error would be raised. With
the current commit, the importer behaves as if all gate definitions were moved to the top
of the OQ3 program. However, the error will still be found by the parser so that the
importer never will begin processing statements.

The importer depends on a particular branch of a copy of openqasm3_parser. When
the commit is ready to merge, we will release a version of openqasm3_parser and
depend instead on that release.

See openqasm/openqasm#517
@jlapeyre jlapeyre force-pushed the update-for-openqasm3_parser-changes branch from 623f59c to fbca320 Compare March 26, 2024 22:13
@mtreinish mtreinish added the mod: qasm3 Related to OpenQASM 3 import or export label Apr 2, 2024
@mtreinish mtreinish added this to the 1.1.0 milestone Apr 2, 2024
@1ucian0 1ucian0 self-assigned this Apr 2, 2024
@jakelishman jakelishman assigned jakelishman and unassigned 1ucian0 Apr 2, 2024
crates/qasm3/Cargo.toml Outdated Show resolved Hide resolved
Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor code comments and my agreement with Matt's comment aside, this looks good to me.

crates/qasm3/src/build.rs Outdated Show resolved Hide resolved
Comment on lines 235 to 238
if name == "U" {
// The sole built in gate. `gphase` is treated specially.
continue;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we arrange the symbol table to make this check unnecessary? I'd expect all the built-in symbols to have been populated into the symbol table, so there's no special-case behaviour needed to handle them for a consumer; we could just fetch the symbol and get a gate.

Copy link
Contributor Author

@jlapeyre jlapeyre May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you thinking for example that SymbolTable::gates does not return "U" in its list and this check is omitted?
In the parser, it's convenient to make U a symbol of type Gate. For example, we don't need to handle checking number and type of args specially when it's called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed (made the change in my previous comment) in b22b7d7

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I misunderstood why this check was here - I'm expecting U to be both in SymbolTable::gates and to be handled in the same way as other gates in this function.

Comment on lines 375 to 377

let _ = state.map_gate_ids(py, ast_symbols);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is explicitly ignoring a Result, with the one bit of syntax that gets around the clippy lint for not "using" a Result return value. I think what's intended is state.map_gate_ids(py, ast_symbols)?; with no let. It'd be good to add a test that the exceptions are raised in Python space - we didn't do it at the initial merge because of a rush to land the PR, but we ought to back fill.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought clippy complains about throwing away any return value. I agree that state.map_gate_ids(py, ast_symbols)? is much better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partly fixed in 258499c
But I did not yet write a new test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Result as a type is marked #[must_use], so any expression that evaluates to a Result needs to be "used" in some form. Most types don't have that annotation, though some functions returning normally safe types might have it, so you may have seen it there.

Comment on lines +383 to +385
// We ignore gate definitions because the only information we can currently use
// from them is extracted with `SymbolTable::gates` via `map_gate_ids`.
asg::Stmt::GateDefinition(_) => (),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this is fine, but leads me to check: does the backing parser correctly handle the order of definitions? For example, will it correctly reject the program

qubit q;
my_gate q;
gate my_gate q {}

because my_gate isn't defined at the point of use?

I'm guessing so - I'm just checking because this swap from a single-pass iteration in the Qiskit side to relying on the AST means that the responsibility for handling it moves away from us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is rejected:

Error: UndefGateError
   ╭─[/path/to/examples/qasm/ex1.qasm:2:1]
 2 │my_gate q;
   │   ╰──── Near this point

There were some other doubts I had, a bit vague, about this approach. I don't recall what they are. But if they are warranted, it should become clear later.

crates/qasm3/src/build.rs Outdated Show resolved Hide resolved
jlapeyre added a commit to jlapeyre/openqasm3_parser that referenced this pull request May 2, 2024
The Qiskit importer otherwise needs to filter this gate out.
Other consumers probably would do so as well. If it is useful in
antother context, we can add an option to include the U gate

Review comment: Qiskit/qiskit#12087 (comment)
* This requires modifying the external parser crate.
* Depend temporarily on the branch of the parser with this modification.
* Make another change required by other upstream improvments.
* Cargo config files are changed because of above changes.
Previously this error was ignored. This would almost certainly cause
an error later. But better to do it at the correct place.
@jlapeyre
Copy link
Contributor Author

jlapeyre commented May 2, 2024

I think all the changes requested have been made. Except one:

No tests yet added. See #12087 (comment)

I think that issues in this comment #12087 (comment) have been resolved.

This is done: However, I could make SymbolTable::gates return an iterator, and consume it here. On the other hand, there is no additional copy or allocation done here.

jlapeyre added a commit to Qiskit/openqasm3_parser that referenced this pull request May 2, 2024
* Filter U gate from output of SymbolTable::gates

The Qiskit importer otherwise needs to filter this gate out.
Other consumers probably would do so as well. If it is useful in
antother context, we can add an option to include the U gate

Review comment: Qiskit/qiskit#12087 (comment)

* Use impl trait for SymbolTable::gate return type
So we return an iterator, not a `Vec`.
@mtreinish mtreinish added the Changelog: None Do not include in changelog label May 3, 2024
@coveralls
Copy link

Pull Request Test Coverage Report for Build 8937145960

Details

  • 14 of 27 (51.85%) changed or added relevant lines in 2 files are covered.
  • 10 unchanged lines in 3 files lost coverage.
  • Overall coverage increased (+0.01%) to 89.634%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/qasm3/src/build.rs 12 25 48.0%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/expr.rs 1 94.03%
crates/qasm2/src/lex.rs 3 92.62%
crates/qasm2/src/parse.rs 6 97.15%
Totals Coverage Status
Change from base Build 8930297650: 0.01%
Covered Lines: 62250
Relevant Lines: 69449

💛 - Coveralls

Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, I'm not as familiar with the oq3 parser code but nothing looks clearly wrong and this is passing all the tests we have and is using the latest release of oq3_semantics which is the goal of the PR. We can continue to iterate on this if any issues are raised during the rc period.

@mtreinish mtreinish added this pull request to the merge queue May 3, 2024
Merged via the queue into Qiskit:main with commit 68f4b52 May 3, 2024
15 checks passed
ElePT pushed a commit to ElePT/qiskit that referenced this pull request May 31, 2024
…iskit#12087)

* Adapt crates/qasm3 to work with recent versions of openqasm3_parser

This commit adds no new features or capabilities to the importer. But it brings
the importer up to date with the latest version of openqasm3_parser as a preliminary
step in improving the importer.

The biggest change in openqasm3_parser is in handling stdgates.inc.  Upon encountering
`include "stdgates.inc" openqasm3_parser reads no file, but rather adds symbols to the
symbol table for gates in the standard library.

The function `convert_asg` in the importer calls oq3_semantics::symbols::SymbolTable.gates
which returns a `Vec` of information about each "declared" gate. The information is the
gate's name and signature and SymbolID, which is sufficient to do everything the importer
could do before this commit.

Encountering `Stmt::GateDefinition` now is a no-op rather than an error.  (This was
previously called `Stmt::GateDeclaration`, but importantly it is really a definition.)

How the standard library, and gates in general, are handled will continue to evolve.

A behavioral difference between this commit and its parent: Before if the importer
encountered a gate call before the corresponding definition an error would be raised. With
the current commit, the importer behaves as if all gate definitions were moved to the top
of the OQ3 program. However, the error will still be found by the parser so that the
importer never will begin processing statements.

The importer depends on a particular branch of a copy of openqasm3_parser. When
the commit is ready to merge, we will release a version of openqasm3_parser and
depend instead on that release.

See openqasm/openqasm#517

* Remove unnecessary conversion `name.to_string()`

Response to reviewer comment https://github.com/Qiskit/qiskit/pull/12087/files#r1586949717

* Remove check for U gate in map_gate_ids

* This requires modifying the external parser crate.
* Depend temporarily on the branch of the parser with this modification.
* Make another change required by other upstream improvments.
* Cargo config files are changed because of above changes.

* Return error returned by map_gate_ids in convert_asg

Previously this error was ignored. This would almost certainly cause
an error later. But better to do it at the correct place.

* Remove superfluous call to `iter()`

* Depend on published oq3_semantics 0.6.0

* Fix cargo lock file

---------

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: None Do not include in changelog mod: qasm3 Related to OpenQASM 3 import or export
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants