-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Conversation
One or more of the following people are relevant to this code:
|
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. |
We have explicit Rust tests that make sure that Python-side and Rust-side definitions are identical.
Pull Request Test Coverage Report for Build 15296780896Details
💛 - Coveralls |
…finitions for SX and SXdg in Rust
We can have a subclass of say XGate that sets _standard_gate = None, yet we expect the definition of XGate
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.
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) ├ | ||
# └───┘└───┘└─────────────┘└───┘└───────────────┘ |
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.
perhaps this definition could be simplified? I will look into 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.
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 ├
# └───────┘ └───┘└───┘└──────────┘└───┘└─────────┘└─────┘
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.
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.
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.
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 | ||
) |
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.
maybe add an image of the circuit?
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.
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 | ||
) |
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.
maybe add an image of the circuit?
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.
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 | ||
) |
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.
maybe add an image of the circuit?
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.
Please see the answer above.
|
||
# This is not a standard gate in Rust |
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.
maybe add an image of the circuit?
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.
Please see the answer above.
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? |
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.
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) ├ | ||
# └───┘└───┘└─────────────┘└───┘└───────────────┘ |
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.
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``. |
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.
also over U2Gate, right?
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.
Also using T/Tdg is preferable over PhaseGate
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.
LGTM. tnx!
* 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
Summary
This PR slightly modernizes the definitions for standard gates:
U1(-pi/4)
have been replaced byTdg()
, instances ofRZ(pi/2)
have been replaced byS()
with an update to the global phase, and so on.ECRGate
, following Jake's basis-constructor. In particular, ECR is now defined using1
rather than4
CX-gates.U1
gates are replaced byPhase
gates,U2
andU3
gates are replaced byU
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?