-
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
Refactor OpenQASM 2 exporter #9953
Conversation
This rewrites the handling of instructions in the OpenQASM 2 exporter in several places. First, the definition and the call site are handled at the same time. Previously, these were handled at separate points and required two name munging steps, which mostly just needed to hope that they both converged on the same name. Instead, one singular point handles both, so there are no issues with name mismatches. In a similar vein, this now ensures that the two places will not disagree about when a definition has already been seen before; previously, duplicate definitions could be "used" but not defined. Second, the gate-definition pass is now made properly recursive, so the exact same code is responsible for defining gates that appear in the body of the main circuit, and of custom definitions, including sharing the duplication detection. Previously, two custom definitions that both used the same gate could cause duplicate definitions to appear with incorrect names. Unifying this handling also has the natural consequence of correctly ordering _all_ gate definitions, whereas before some inner gates could be defined after their first use. Inside the call-site/definition-site handling, this refactor separates those into two separate objects. This massively simplified: - handling known-good Qiskit standard gates to have special-cased support for always exporting properly parametrised definitions; - handling `UnitaryGate` and `Permutation` specially, so they no longer need to output special OQ2 strings, but can just define a custom object to use as the source for both call-site and definition site; - handling gates with no definitions as `opaque`.
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the the following people are requested to review this: |
Pull Request Test Coverage Report for Build 4721104772
💛 - Coveralls |
operation.qasm(), | ||
",".join([bit_labels[j] for j in instruction.qubits + instruction.clbits]), | ||
bits_qasm = ",".join( | ||
bit_labels[j] for j in itertools.chain(instruction.qubits, instruction.clbits) |
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.
why not instruction.qubits + instruction.clbits
as before?
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.
Oh, no particular reason - I probably just didn't notice I'd done it during the rewrite. itertools.chain
is the normal idiom I personally use, so I just wouldn't have thought about it.
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.
Impressive work! Thanks for it!
none of my comments are blocking. LGTM!
Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
* Refactor OpenQASM 2 exporter This rewrites the handling of instructions in the OpenQASM 2 exporter in several places. First, the definition and the call site are handled at the same time. Previously, these were handled at separate points and required two name munging steps, which mostly just needed to hope that they both converged on the same name. Instead, one singular point handles both, so there are no issues with name mismatches. In a similar vein, this now ensures that the two places will not disagree about when a definition has already been seen before; previously, duplicate definitions could be "used" but not defined. Second, the gate-definition pass is now made properly recursive, so the exact same code is responsible for defining gates that appear in the body of the main circuit, and of custom definitions, including sharing the duplication detection. Previously, two custom definitions that both used the same gate could cause duplicate definitions to appear with incorrect names. Unifying this handling also has the natural consequence of correctly ordering _all_ gate definitions, whereas before some inner gates could be defined after their first use. Inside the call-site/definition-site handling, this refactor separates those into two separate objects. This massively simplified: - handling known-good Qiskit standard gates to have special-cased support for always exporting properly parametrised definitions; - handling `UnitaryGate` and `Permutation` specially, so they no longer need to output special OQ2 strings, but can just define a custom object to use as the source for both call-site and definition site; - handling gates with no definitions as `opaque`. * Style tweak Co-authored-by: Luciano Bello <bel@zurich.ibm.com> --------- Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
This rewrites the handling of instructions in the OpenQASM 2 exporter in several places.
First, the definition and the call site are handled at the same time. Previously, these were handled at separate points and required two name munging steps, which mostly just needed to hope that they both converged on the same name. Instead, one singular point handles both, so there are no issues with name mismatches. In a similar vein, this now ensures that the two places will not disagree about when a definition has already been seen before; previously, duplicate definitions could be "used" but not defined.
Second, the gate-definition pass is now made properly recursive, so the exact same code is responsible for defining gates that appear in the body of the main circuit, and of custom definitions, including sharing the duplication detection. Previously, two custom definitions that both used the same gate could cause duplicate definitions to appear with incorrect names. Unifying this handling also has the natural consequence of correctly ordering all gate definitions, whereas before some inner gates could be defined after their first use.
Inside the call-site/definition-site handling, this refactor separates those into two separate objects. This massively simplified:
UnitaryGate
andPermutation
specially, so they no longer need to output special OQ2 strings, but can just define a custom object to use as the source for both call-site and definition site;opaque
.Details and comments
This fixes a whole slew of long-standing bugs, albeit not perfectly. The general case of user-defined parametrised gates are still not handled well, but Qiskit's standard gates now generally are. Even in the worst cases, the export should now be much safer and produce rather less invalid OQ2 code than it did before.
To do with duplicate definitions:
RYYGate
in subcircuit (with inverse)QasmError: "Duplicate declaration for gate 'ryy'
#7771QuantumCircuit.qasm
cannot handle nested gates with different parameters #9805To do with the old
UnitaryGate.qasm
:CSwapGate
andDCXGate
:Cannot find gate definition for 'unitary...'
#7772CSwapGate
andCCXGate
:Cannot find gate definition for 'unitary...'
#8222To do with bad orderings of definitions:
Cannot find gate definition for 'rcccx'
#7773A bit more of a mix:
opaque
#5036