qiskit
qiskit copied to clipboard
add DropNegligible transpiler pass
Summary
Fixes #8654.
Draft PR because I would like feedback before adding more code.
Details and comments
The pass removes a gate if:
- The gate type is explicitly listed in
DROP_NEGLIGIBLE_GATE_CLASSES
. - All of the gate parameters are close to zero up to the specified absolute tolerance (default
1e-8
).
DROP_NEGLIGIBLE_GATE_CLASSES
should list gates with the property that if all of their parameters are close to zero, then the gate's effect is small. It does not guarantee any error bounds based on the tolerance, so in principle this pass can drop gates whose effect is not actually negligible. In practice, I don't expect it to be an issue.
So far, I've only added a few gates to DROP_NEGLIGIBLE_GATE_CLASSES
. If people agree with this approach, I'll go through the rest of the gate library and add the appropriate ones.
@mtreinish @ajavadia thoughts?
Pull Request Test Coverage Report for Build 9038654167
Warning: This coverage report may be inaccurate.
This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
- For more information on this, see Tracking coverage changes with pull request builds.
- To avoid this issue with future PRs, see these Recommended CI Configurations.
- For a quick fix, rebase this PR at GitHub. Your next report should be accurate.
Details
- 27 of 27 (100.0%) changed or added relevant lines in 3 files are covered.
- 8 unchanged lines in 2 files lost coverage.
- Overall coverage increased (+0.02%) to 89.649%
Files with Coverage Reduction | New Missed Lines | % |
---|---|---|
crates/qasm2/src/lex.rs | 2 | 92.88% |
crates/qasm2/src/parse.rs | 6 | 97.61% |
<!-- | Total: | 8 |
Totals | |
---|---|
Change from base Build 9032084393: | 0.02% |
Covered Lines: | 62240 |
Relevant Lines: | 69426 |
💛 - Coveralls
I like the general idea to drop negligible gates but think this implementation is not optimal. TwoQubitBasisDecomposer
will already drop all negligible 2q gates, not just the ones in a hardcoded list; will do it with a controlled approximation (the average-gate-fidelity of the approximation, rather than just a parameter value); and will optimize away 2q gates while keeping an optimal 1q approximation. Because of how the default passmanagers work, this TwoQubitBasisDecomposer
only runs after routing, losing most of the benefit of dropping negligible 2q gates: I've been meaning for a while to write up some notes on a better default passmanager flow - I'll see if I can get something down for discussion over the weekend.
The concern I have with just relying on the TwoQubitBasisDecomposer
for this is the same issue we had with trying to do something similar with the 1q case in #11354 . As soon as we added Optimize1qGatesDecomposition
to the init stage there users testing against main (mainly qiskit-experiments) reported issues that we were breaking transpilation for targets with a discrete basis. So we very quickly reverted this in #11360. In general I really like the idea of doing the peephole optimization early in the pipeline but we just have to be careful around how we do it. Regardless I look forward to seeing your proposal on an improved pipeline.
TwoQubitBasisDecomposer
is not appropriate for some of the uses cases I have in mind. As an example, ffsim defines a high-level gate DiagonalCoulombJW. This gate is defined by a matrix, and it has a gate decomposition into CPhaseGates based on that matrix. Sometimes you know that some entries are close to zero, so you just want to get rid of them. Or, you might want to get rid of some gates based on a threshold just to make it easier to map to hardware. This workflow would not use TwoQubitBasisDecomposer
and you might want to do this independently from the standard "preset staged pass manager" transpilation workflow.
try:
decomp = TwoQubitWeylDecomposition(node.op, fidelity=fid, _specialization=_specializations.IdEquiv)
except QiskitError:
pass
else:
<replace dag node with 1q gates from decomp>
try: decomp = TwoQubitWeylDecomposition(node.op, fidelity=fid, _specialization=_specializations.IdEquiv) except QiskitError: pass else: <replace dag node with 1q gates from decomp>
Doing linear algebra is too expensive when the aim is just to drop gates with small angles.