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

Incorrect transpilation with RY gate with a small angle #13547

Open
t-imamichi opened this issue Dec 10, 2024 · 4 comments
Open

Incorrect transpilation with RY gate with a small angle #13547

t-imamichi opened this issue Dec 10, 2024 · 4 comments
Labels
bug Something isn't working mod: transpiler Issues and PRs related to Transpiler
Milestone

Comments

@t-imamichi
Copy link
Member

t-imamichi commented Dec 10, 2024

Environment

  • Qiskit version: 1.3.0, main
  • Python version: 3.12.8
  • Operating system: macOS 15.1.1

What is happening?

Transpilation with optimization level 2 and 3 results in a incorrect circuit for circuits with RY gate with a small angle.

Note that the following code does not have issue with 1.2.4.

How can we reproduce the issue?

from qiskit import QuantumCircuit, generate_preset_pass_manager, __version__
from qiskit.quantum_info import Operator

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.ry(1e-6, 1)
qc.cx(0, 1)

pm = generate_preset_pass_manager(optimization_level=2)
tqc = pm.run(qc)

print(__version__)
print(qc)
print(tqc)

print("equivalent?", Operator(qc).equiv(tqc))
2.0.0.dev0+841cb29
     ┌───┐
q_0: ┤ H ├──■─────────────────■──
     └───┘┌─┴─┐┌───────────┐┌─┴─┐
q_1: ─────┤ X ├┤ Ry(1e-06) ├┤ X ├
          └───┘└───────────┘└───┘
         ┌───┐
q_0: ────┤ H ├────
     ┌───┴───┴───┐
q_1: ┤ Ry(1e-06) ├
     └───────────┘
equivalent? False
1.3.0
     ┌───┐
q_0: ┤ H ├──■─────────────────■──
     └───┘┌─┴─┐┌───────────┐┌─┴─┐
q_1: ─────┤ X ├┤ Ry(1e-06) ├┤ X ├
          └───┘└───────────┘└───┘
         ┌───┐
q_0: ────┤ H ├────
     ┌───┴───┴───┐
q_1: ┤ Ry(1e-06) ├
     └───────────┘
equivalent? False
1.2.4
     ┌───┐
q_0: ┤ H ├──■─────────────────■──
     └───┘┌─┴─┐┌───────────┐┌─┴─┐
q_1: ─────┤ X ├┤ Ry(1e-06) ├┤ X ├
          └───┘└───────────┘└───┘
     ┌───┐
q_0: ┤ H ├──■─────────────────■──
     └───┘┌─┴─┐┌───────────┐┌─┴─┐
q_1: ─────┤ X ├┤ Ry(1e-06) ├┤ X ├
          └───┘└───────────┘└───┘
equivalent? True

What should happen?

The transpiled circuit should be same as the input circuit as 1.2.4 does.

Another example

The following example fails with 1.2.4, 1.3.0, and main branch probably due to a similar reason.

from qiskit import QuantumCircuit, generate_preset_pass_manager, __version__
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp, Operator

qc = QuantumCircuit(2)
op = SparsePauliOp(["XX"], coeffs=[1])
evo = PauliEvolutionGate(op, 1e-6)
qc.append(evo, qargs=qc.qregs[0])

pm = generate_preset_pass_manager(optimization_level=2, basis_gates=["rz", "cx", "sx", "x"])
tqc = pm.run(qc)

print(__version__)
print(qc)
print(tqc)

print("equivalent?", Operator(qc).equiv(tqc))
2.0.0.dev0+841cb29
     ┌─────────────────────┐
q_0: ┤0                    ├
     │  exp(-it XX)(1e-06) │
q_1: ┤1                    ├
     └─────────────────────┘
global phase: π/2

q_0: ─────────────────────────────────────────────────
     ┌─────────┐┌────┐┌─────────────┐┌────┐┌─────────┐
q_1: ┤ Rz(π/2) ├┤ √X ├┤ Rz(-3.1416) ├┤ √X ├┤ Rz(π/2) ├
     └─────────┘└────┘└─────────────┘└────┘└─────────┘
equivalent? False
1.2.4
     ┌─────────────────────┐
q_0: ┤0                    ├
     │  exp(-it XX)(1e-06) │
q_1: ┤1                    ├
     └─────────────────────┘
global phase: π/2

q_0: ─────────────────────────────────────────────────
     ┌─────────┐┌────┐┌─────────────┐┌────┐┌─────────┐
q_1: ┤ Rz(π/2) ├┤ √X ├┤ Rz(-3.1416) ├┤ √X ├┤ Rz(π/2) ├
     └─────────┘└────┘└─────────────┘└────┘└─────────┘
equivalent? False

Any suggestions?

No response

@t-imamichi t-imamichi added bug Something isn't working mod: transpiler Issues and PRs related to Transpiler labels Dec 10, 2024
@Cryoris
Copy link
Contributor

Cryoris commented Dec 10, 2024

The true problem here is that cutoff tolerances are handled differently in different parts of Qiskit. For example, also on 1.2.4 a small enough angle will remove the CX gates (and the RY):

     ┌───┐
q_0: ┤ H ├──■─────────────────■──
     └───┘┌─┴─┐┌───────────┐┌─┴─┐
q_1: ─────┤ X ├┤ Ry(2e-08) ├┤ X ├
          └───┘└───────────┘└───┘
global phase: 0
     ┌──────────────┐
q_0: ┤ U3(π/2,0,-π) ├
     └──────────────┘
q_1: ────────────────

but this seems to match the tolerance in Operator.equiv, since this prints

equivalent? True

We need to ensure that our processes use the same tolerance algorithm. I'm thinking of CommutationAnalysis/Checker, UnitarySynthesis, RemoveIdentityEquivalent and Operator.equiv, but maybe there are also others. From offline discussions, doing what UnitarySynthesis and RemoveIdentityEquivalent do seems to be the best-motivated choice: consider a gate as the identity, if the process fidelity is below machine epsilon.

@t-imamichi
Copy link
Member Author

Thank you for investigating this issue. The transpilation behavior change between 1.2.4 and 1.3.0 breaks our client code.
Could you suggest me how to configure transpiler to behave in the same way as 1.2.4?

@Cryoris
Copy link
Contributor

Cryoris commented Dec 11, 2024

Unfortunately there's currently no way to directly adjust the threshold below which the commutation checker assumes anything commutes with a rotation Ry(epsilon). There's two suboptimal workarounds:

  • you could either increase the tolerance in Operator.equiv, or
  • if you directly set the angle to 1e-6 (or whatever the angle is) you could first build the circuit with parameters in the Ry, then transpile, and then bind the values. The commutation checker will then not assume that things commute.

We're working on a fix but I don't think it will make it for 1.3.1, which is scheduled tomorrow.

@Cryoris Cryoris added this to the 1.3.2 milestone Dec 11, 2024
@t-imamichi
Copy link
Member Author

Thank you for your advice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mod: transpiler Issues and PRs related to Transpiler
Projects
None yet
Development

No branches or pull requests

2 participants