Skip to content

Simpler definitions for standard gates #14180

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

Merged
merged 28 commits into from
May 28, 2025

Conversation

alexanderivrii
Copy link
Member

@alexanderivrii alexanderivrii commented Apr 6, 2025

Summary

This PR slightly modernizes the definitions for standard gates:

  • By using discrete gates instead of parametric gates whenever possible. For example, instances of U1(-pi/4) have been replaced by Tdg(), instances of RZ(pi/2) have been replaced by S() with an update to the global phase, and so on.
  • The only definition that changed substantially is the one for ECRGate, following Jake's basis-constructor. In particular, ECR is now defined using 1 rather than 4 CX-gates.
  • U1 gates are replaced by Phase gates, U2 and U3 gates are replaced by U gates, CU1 gates.

This is in the spirit of Jake's "complexity" classes for standard gates (Paulis < 1q Cliffords < 1q Cliffords + T/Tdg < parametric 1q gates). In particular, the definitions for Clifford standard gates are now in terms of simpler Clifford gates (e.g. for RC3X).

Update 1: Apparently we have CI tests that Rust-side definitions are essentially the same as Python-side definitions, so I have also changed the Python-side definitions.

Update 2: Apparently we have CI tests that Python-side definitions are included into the equivalence library, so some of the equivalences in the equivalence library are now updated (and in some cases a new equivalence is added).

Details and comments

Question: can we eventually change the Python-side definitions to just return Rust-based definitions?

Question: are there potential problems with backward compatibility? Personally I think that we should be free to change definitions / synthesis methods and always aim to provide the best decompositions available, however what if there are users that expect that a definition for the ECRGate will contain a pair of RZX gates?

@alexanderivrii alexanderivrii requested a review from a team as a code owner April 6, 2025 04:21
@qiskit-bot
Copy link
Collaborator

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

  • @Qiskit/terra-core

@alexanderivrii alexanderivrii added this to the 2.1.0 milestone Apr 6, 2025
@ShellyGarion
Copy link
Member

ShellyGarion commented Apr 6, 2025

Since U1Gate is going to be deprecated sometime, it's better to use PhaseGate instead of U1Gate and CPhaseGate instead of CU1Gate (these gates have exactly the same definition), see e.g.#12977.

@coveralls
Copy link

coveralls commented Apr 7, 2025

Pull Request Test Coverage Report for Build 15296780896

Details

  • 182 of 182 (100.0%) changed or added relevant lines in 29 files are covered.
  • 15 unchanged lines in 5 files lost coverage.
  • Overall coverage decreased (-0.05%) to 87.807%

Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/expr.rs 1 94.23%
qiskit/circuit/_add_control.py 1 97.08%
crates/circuit/src/symbol_expr.rs 3 75.16%
crates/qasm2/src/lex.rs 4 91.98%
crates/qasm2/src/parse.rs 6 97.61%
Totals Coverage Status
Change from base Build 15296293022: -0.05%
Covered Lines: 79457
Relevant Lines: 90491

💛 - Coveralls

We can have a subclass of say XGate that sets _standard_gate = None, yet we
expect the definition of XGate
Copy link
Member

@ShellyGarion ShellyGarion left a comment

Choose a reason for hiding this comment

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

Looks great! thanks for doing all this effort!
I have a few minor comments.

# q_0: ───────■───────────────────■───────────────────
# ┌───┐┌─┴─┐┌─────────────┐┌─┴─┐┌───────────────┐
# q_1: ┤ S ├┤ X ├┤ U(-θ/2,0,0) ├┤ X ├┤ U(θ/2,-π/2,0) ├
# └───┘└───┘└─────────────┘└───┘└───────────────┘
Copy link
Member

Choose a reason for hiding this comment

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

perhaps this definition could be simplified? I will look into it

Copy link
Member

Choose a reason for hiding this comment

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

the equivalence library also has this definition:

# CRXGate
#
# q_0: ────■────     q_0: ───────■────────────────■────────────────────
#      ┌───┴───┐  ≡       ┌───┐┌─┴─┐┌──────────┐┌─┴─┐┌─────────┐┌─────┐
# q_1: ┤ Rx(ϴ) ├     q_1: ┤ S ├┤ X ├┤ Ry(-ϴ/2) ├┤ X ├┤ Ry(ϴ/2) ├┤ Sdg ├
#      └───────┘          └───┘└───┘└──────────┘└───┘└─────────┘└─────┘

Copy link
Member Author

@alexanderivrii alexanderivrii May 25, 2025

Choose a reason for hiding this comment

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

Good point, this definition is a bit simpler and a bit more powerful than the other one (in the sense that is uses single-parameter RY-gates instead of the more general U-gates). I will update the (default) definition.

Copy link
Member

Choose a reason for hiding this comment

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

In the above picture it still uses U and not Ry (but the definition should be correct now?)

self.definition = qc
self.definition = QuantumCircuit._from_circuit_data(
StandardGate.C3SX._get_definition(self.params), add_regs=True, name=self.name
)
Copy link
Member

Choose a reason for hiding this comment

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

maybe add an image of the circuit?

Copy link
Member Author

Choose a reason for hiding this comment

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

The definitions for the 3-controlled circuits are quite large and don't git on a single page. This is why I have provided the definitions for almost all circuits but not the very large ones.

self.definition = qc
self.definition = QuantumCircuit._from_circuit_data(
StandardGate.C3X._get_definition(self.params), add_regs=True, name=self.name
)
Copy link
Member

Choose a reason for hiding this comment

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

maybe add an image of the circuit?

Copy link
Member Author

Choose a reason for hiding this comment

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

Please see the answer above.

self.definition = qc
self.definition = QuantumCircuit._from_circuit_data(
StandardGate.RC3X._get_definition(self.params), add_regs=True, name=self.name
)
Copy link
Member

Choose a reason for hiding this comment

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

maybe add an image of the circuit?

Copy link
Member Author

Choose a reason for hiding this comment

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

Please see the answer above.


# This is not a standard gate in Rust
Copy link
Member

Choose a reason for hiding this comment

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

maybe add an image of the circuit?

Copy link
Member Author

Choose a reason for hiding this comment

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

Please see the answer above.

@alexanderivrii
Copy link
Member Author

Thanks @ShellyGarion, I have addressed your comments modulo adding images for circuits with many gates: such circuits do not nicely fit on one screen and (imho) are not very illuminating. Can you please take another look?

Copy link
Member

@ShellyGarion ShellyGarion left a comment

Choose a reason for hiding this comment

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

Amazing work! A few last comments and I think it's ready to go.

# q_0: ───────■───────────────────■───────────────────
# ┌───┐┌─┴─┐┌─────────────┐┌─┴─┐┌───────────────┐
# q_1: ┤ S ├┤ X ├┤ U(-θ/2,0,0) ├┤ X ├┤ U(θ/2,-π/2,0) ├
# └───┘└───┘└─────────────┘└───┘└───────────────┘
Copy link
Member

Choose a reason for hiding this comment

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

In the above picture it still uses U and not Ry (but the definition should be correct now?)

* When available, a definition using Clifford gates is preferred over
one that includes non-Clifford gates.
* The use of ``PhaseGate`` is preferred over ``U1Gate``.
* The use of ``UGate`` is preferred over ``U3Gate``.
Copy link
Member

Choose a reason for hiding this comment

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

also over U2Gate, right?

Copy link
Member

Choose a reason for hiding this comment

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

Also using T/Tdg is preferable over PhaseGate

Copy link
Member

@ShellyGarion ShellyGarion left a comment

Choose a reason for hiding this comment

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

LGTM. tnx!

@ShellyGarion ShellyGarion added this pull request to the merge queue May 28, 2025
@ShellyGarion ShellyGarion added Changelog: New Feature Include in the "Added" section of the changelog mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library labels May 28, 2025
Merged via the queue into Qiskit:main with commit 1cbef64 May 28, 2025
26 checks passed
rahaman-quantum pushed a commit to rahaman-quantum/qiskit that referenced this pull request Jun 20, 2025
* ECR

* CRX

* CS

* CSdg

* CSX

* RYY

* XX-YY

* XX+YY

* RCCX

* RC3X

* Changing Python-side definitions as well.

We have explicit Rust tests that make sure that Python-side and Rust-side definitions are
identical.

* u1 -> phase, cu1 -> cphase, etc.

* lint

* fixing tests

* Bug fix

* undoing changes to a test

* remove stray prints and blank lines

* reno

* docs

* Replacing Python definition by Rust definition; fixing problematic definitions for SX and SXdg in Rust

* updating python definitions

We can have a subclass of say XGate that sets _standard_gate = None, yet we
expect the definition of XGate

* Adding visualization for definition circuits

* addressing review comments

* improving release notes

* Changing the picture for RCX gate to be consistent with the new definition

* improving release notes
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: circuit Related to the core of the `QuantumCircuit` class or the circuit library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants