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

Add RemoveIdentityEquivalent transpiler pass #12384

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

kevinsung
Copy link
Contributor

@kevinsung kevinsung commented May 9, 2024

Summary

This adds a new transpiler pass RemoveIdentityEquivalent, which is used to remove any Gate in a circuit that is
equivalent to identity and doesn't have an impact on the circuit. This pass works for any gate that defines a matrix and only those that have numeric parameters (a symbolic parameter precludes having a matrix). It computes the average gate fidelity of the the operation for an identity target and if it's below the the specified tolerance the gate will be removed.

Details and comments

Fixes #8654

Co-authored-by: Matthew Treinish mtreinish@kortar.org
TODO:

  • Expand test coverage

@coveralls
Copy link

coveralls commented May 9, 2024

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.

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%
Totals Coverage Status
Change from base Build 9032084393: 0.02%
Covered Lines: 62240
Relevant Lines: 69426

💛 - 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.

I think having a pass like this in the library makes a lot of sense. We don't want to run it by default, but if you know it makes sense in your use case then having this available is useful. We could even look at adding it to the end of the init stage in the preset pass managers and tying the atol value to the approximation_degree value somehow.

qiskit/transpiler/passes/optimization/drop_negligible.py Outdated Show resolved Hide resolved
qiskit/transpiler/passes/optimization/drop_negligible.py Outdated Show resolved Hide resolved
test/python/transpiler/test_drop_negligible.py Outdated Show resolved Hide resolved
@levbishop
Copy link
Member

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.

@mtreinish
Copy link
Member

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.

@kevinsung
Copy link
Contributor Author

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.

@levbishop
Copy link
Member

try:
    decomp = TwoQubitWeylDecomposition(node.op, fidelity=fid,  _specialization=_specializations.IdEquiv)
except QiskitError:
    pass
else:
    <replace dag node with 1q gates from decomp>

@kevinsung
Copy link
Contributor Author

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.

This pivots the pass to work for all gates by checking all the
parameters in the standard gate library are within the specified
tolerance, and the matrix is equivalent to an identity for any other
gate defined in Python (with a matrix defined). To improve the
performance of the pass it is written in rust now. Additionally the
class is named to RemoveIdentityEquivalent to make the purpose of the
pass slightly more clear.
@mtreinish mtreinish added Changelog: New Feature Include in the "Added" section of the changelog Rust This PR or issue is related to Rust code in the repository mod: transpiler Issues and PRs related to Transpiler labels Oct 22, 2024
@mtreinish mtreinish added this to the 1.3.0 milestone Oct 22, 2024
@mtreinish mtreinish marked this pull request as ready for review October 22, 2024 22:46
@mtreinish mtreinish requested a review from a team as a code owner October 22, 2024 22:46
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core

@mtreinish mtreinish changed the title add DropNegligible transpiler pass Add RemoveIdentityEquivalent transpiler pass Oct 22, 2024
@mtreinish
Copy link
Member

I've reworked this PR to compute the identity equivalence numerically for all gates with a matrix defined and to operate purely in Rust for performance. While these gates would be likely caught in later stages between the synthesis peephole optimization and/or Split2QUnitaries this should be a lot faster to compute and will speed up those later stages which are doing more investigation. I think we'll want to add this pass to the init stage and the optimization stage (inside the loop) for levels 2 and 3 in a follow up PR. This should give us pretty good coverage for removing gates that don't have a measurable impact on the circuit.

The only todo here is to expand the test coverage which I need to expand to cover all the combinations of inputs in the pass now.

@coveralls
Copy link

coveralls commented Oct 22, 2024

Pull Request Test Coverage Report for Build 11485027480

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.

Details

  • 58 of 97 (59.79%) changed or added relevant lines in 6 files are covered.
  • 997 unchanged lines in 46 files lost coverage.
  • Overall coverage decreased (-0.01%) to 88.64%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/accelerate/src/remove_identity_equiv.rs 41 80 51.25%
Files with Coverage Reduction New Missed Lines %
qiskit/pulse/instructions/directives.py 1 97.14%
crates/accelerate/src/unitary_synthesis.rs 1 92.24%
qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py 1 96.3%
qiskit/pulse/instructions/play.py 1 97.5%
crates/qasm2/src/expr.rs 1 94.02%
qiskit/transpiler/passes/calibration/pulse_gate.py 1 95.45%
qiskit/pulse/instructions/reference.py 1 93.55%
crates/accelerate/src/two_qubit_decompose.rs 1 92.09%
qiskit/providers/fake_provider/fake_pulse_backend.py 1 95.45%
qiskit/qpy/binary_io/circuits.py 1 91.74%
Totals Coverage Status
Change from base Build 11461474832: -0.01%
Covered Lines: 74957
Relevant Lines: 84563

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: New Feature Include in the "Added" section of the changelog mod: transpiler Issues and PRs related to Transpiler Rust This PR or issue is related to Rust code in the repository
Projects
None yet
5 participants