Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.28k stars 2.37k forks source link

Optimization level 2 and 3 result in a deeper circuit with 1.3.0rc1 and main branch #13438

Closed t-imamichi closed 5 hours ago

t-imamichi commented 5 days ago

Environment

What is happening?

Transpilation with optimization level 2 and 3 result in a deeper circuit than optimization level 1. The circuit of level 2 is deeper than that of level 1. The circuit of level 3 is deeper than that of level 2. This does not happen with Qiskit 1.2.4.

How can we reproduce the issue?

from qiskit import generate_preset_pass_manager, QuantumCircuit

qc = QuantumCircuit(2)
qc.cz(0, 1)
qc.sx([0, 1])
qc.cz(0, 1)

for level in [1, 2, 3]:
    pm = generate_preset_pass_manager(optimization_level=level, basis_gates=["rz", "rzz", "sx", "x", "rx"])
    qc2 = pm.run(qc)
    print('optimization level', level)
    print(qc2)
    print()
# 1.2.4
optimization level 1
global phase: π
     ┌─────────┐           ┌─────────┐┌─────────┐
q_0: ┤ Rz(π/2) ├─■─────────┤ Rx(π/2) ├┤ Rz(π/2) ├─■─────────
     ├─────────┤ │ZZ(-π/2) ├─────────┤├─────────┤ │ZZ(-π/2)
q_1: ┤ Rz(π/2) ├─■─────────┤ Rx(π/2) ├┤ Rz(π/2) ├─■─────────
     └─────────┘           └─────────┘└─────────┘

optimization level 2
global phase: π
     ┌─────────┐           ┌─────────┐┌─────────┐
q_0: ┤ Rz(π/2) ├─■─────────┤ Rx(π/2) ├┤ Rz(π/2) ├─■─────────
     ├─────────┤ │ZZ(-π/2) ├─────────┤├─────────┤ │ZZ(-π/2)
q_1: ┤ Rz(π/2) ├─■─────────┤ Rx(π/2) ├┤ Rz(π/2) ├─■─────────
     └─────────┘           └─────────┘└─────────┘

optimization level 3
global phase: π
     ┌─────────┐           ┌─────────┐┌─────────┐
q_0: ┤ Rz(π/2) ├─■─────────┤ Rx(π/2) ├┤ Rz(π/2) ├─■─────────
     ├─────────┤ │ZZ(-π/2) ├─────────┤├─────────┤ │ZZ(-π/2)
q_1: ┤ Rz(π/2) ├─■─────────┤ Rx(π/2) ├┤ Rz(π/2) ├─■─────────
     └─────────┘           └─────────┘└─────────┘
# 1.3.0rc1 and main branch
optimization level 1
global phase: 7π/4
               ┌──────────┐   ┌────┐            ┌──────────┐
q_0: ─■────────┤ Rz(-π/2) ├───┤ √X ├───■────────┤ Rz(-π/2) ├
      │ZZ(π/2) ├──────────┤┌──┴────┴─┐ │ZZ(π/2) ├──────────┤
q_1: ─■────────┤ Rz(-π/2) ├┤ Rx(π/2) ├─■────────┤ Rz(-π/2) ├
               └──────────┘└─────────┘          └──────────┘

optimization level 2
global phase: 3π/2
                                                     ┌──────────┐ ┌─────────┐ ┌─────────┐              ┌──────────┐  ┌─────────┐┌─────────┐
q_0: ──────────────────────────────────────■─────────┤ Rz(-π/2) ├─┤ Rx(π/2) ├─┤ Rz(π/2) ├───■──────────┤ Rz(-π/2) ├──┤ Rx(π/2) ├┤ Rz(π/2) ├
     ┌──────────┐┌─────────┐┌────────────┐ │ZZ(π/2) ┌┴──────────┴┐├─────────┤┌┴─────────┴─┐ │ZZ(π/2) ┌─┴──────────┴─┐└┬───────┬┘└─────────┘
q_1: ┤ Rz(-π/2) ├┤ Rx(π/2) ├┤ Rz(1.6719) ├─■────────┤ Rz(1.4697) ├┤ Rx(π/2) ├┤ Rz(1.6719) ├─■────────┤ Rz(-0.10111) ├─┤ Rx(π) ├────────────
     └──────────┘└─────────┘└────────────┘          └────────────┘└─────────┘└────────────┘          └──────────────┘ └───────┘

optimization level 3
global phase: π
     ┌─────────────┐┌────┐  ┌───────┐   ┌────┐┌────────────┐                                      ┌──────────┐┌─────────┐   ┌────┐  ┌──────────┐»
q_0: ┤ Rz(-1.9513) ├┤ √X ├──┤ Rz(π) ├───┤ √X ├┤ Rz(11.376) ├─────────────────────────────■────────┤ Rz(-π/2) ├┤ Rz(π/2) ├───┤ √X ├──┤ Rz(3π/2) ├»
     └─┬─────────┬─┘├────┤┌─┴───────┴──┐├────┤└┬──────────┬┘┌─────────┐┌────┐┌─────────┐ │ZZ(π/2) ├─────────┬┘└──┬────┬─┘┌──┴────┴─┐├──────────┤»
q_1: ──┤ Rz(π/2) ├──┤ √X ├┤ Rz(3.2427) ├┤ √X ├─┤ Rz(5π/2) ├─┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├─■────────┤ Rz(π/2) ├────┤ √X ├──┤ Rz(π/2) ├┤ Rx(-π/2) ├»
       └─────────┘  └────┘└────────────┘└────┘ └──────────┘ └─────────┘└────┘└─────────┘          └─────────┘    └────┘  └─────────┘└──────────┘»
«          ┌────┐    ┌────────┐                                                                        ┌──────────┐┌─────────┐   ┌────┐  ┌──────────┐»
«q_0: ─────┤ √X ├────┤ Rz(3π) ├───────────────────────────────────────────────────────────────■────────┤ Rz(-π/2) ├┤ Rz(π/2) ├───┤ √X ├──┤ Rz(3π/2) ├»
«     ┌────┴────┴───┐└─┬────┬─┘┌────────────┐┌────┐┌────────────┐┌─────────┐┌────┐┌─────────┐ │ZZ(π/2) ├─────────┬┘└──┬────┬─┘┌──┴────┴─┐├──────────┤»
«q_1: ┤ Rz(-3.1314) ├──┤ √X ├──┤ Rz(4.6118) ├┤ √X ├┤ Rz(10.894) ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├─■────────┤ Rz(π/2) ├────┤ √X ├──┤ Rz(π/2) ├┤ Rx(-π/2) ├»
«     └─────────────┘  └────┘  └────────────┘└────┘└────────────┘└─────────┘└────┘└─────────┘          └─────────┘    └────┘  └─────────┘└──────────┘»
«       ┌────┐  ┌────────┐
«q_0: ──┤ √X ├──┤ Rz(2π) ├────────────────────────────────
«     ┌─┴────┴─┐└─┬────┬─┘┌──────────┐┌────┐┌────────────┐
«q_1: ┤ Rz(-π) ├──┤ √X ├──┤ Rz(3π/2) ├┤ √X ├┤ Rz(7.7529) ├
«     └────────┘  └────┘  └──────────┘└────┘└────────────┘

What should happen?

Circuits of level 2 and 3 should be the same size as that of level 1 to be compatible with 1.2.4.

Any suggestions?

No response

mtreinish commented 3 days ago

I took a brief look at this, I expect it's a bug introduced by #13141 when you don't use a Target for the backend's constraints. Since you just used basis_gates it's causing the UnitarySynthesis pass to not correctly synthesize the circuit. If you look at the circuit coming out of the BasisTranslator into the optimization loop at optimization_level=3 you see:

global phase: 3π/2
                                                                       ┌──────────┐┌────┐                                                                                                                 »
q_0: ─────────────────────────────────────────────────────────■────────┤ Rz(-π/2) ├┤ √X ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────»
     ┌─────────┐┌────┐┌─────────┐┌─────────┐┌────┐┌─────────┐ │ZZ(π/2) ├─────────┬┘├────┤┌─────────┐┌──────────┐┌─────────┐┌────┐┌─────────┐┌────┐┌─────────┐┌────┐┌─────────┐┌─────────┐┌────┐┌─────────┐»
q_1: ┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├─■────────┤ Rz(π/2) ├─┤ √X ├┤ Rz(π/2) ├┤ Rx(-π/2) ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├»
     └─────────┘└────┘└─────────┘└─────────┘└────┘└─────────┘          └─────────┘ └────┘└─────────┘└──────────┘└─────────┘└────┘└─────────┘└────┘└─────────┘└────┘└─────────┘└─────────┘└────┘└─────────┘»
«               ┌──────────┐
«q_0: ─■────────┤ Rz(-π/2) ├─────────────────────────────────────────────────────────
«      │ZZ(π/2) ├─────────┬┘┌────┐┌─────────┐┌──────────┐┌─────────┐┌────┐┌─────────┐
«q_1: ─■────────┤ Rz(π/2) ├─┤ √X ├┤ Rz(π/2) ├┤ Rx(-π/2) ├┤ Rz(π/2) ├┤ √X ├┤ Rz(π/2) ├
«               └─────────┘ └────┘└─────────┘└──────────┘└─────────┘└────┘└─────────┘

Then the first thing the optimization stage runs is consolidate blocks which collects the entire 2q circuit into a single unitary:

global phase: 3π/2
     ┌──────────┐
q_0: ┤0         ├
     │  Unitary │
q_1: ┤1         ├
     └──────────┘

and immediately after unitary synthesis runs and does nothing with the circuit:

<qiskit.transpiler.passes.synthesis.unitary_synthesis.UnitarySynthesis object at 0x7111761906e0>
None
global phase: 3π/2
     ┌──────────┐
q_0: ┤0         ├
     │  Unitary │
q_1: ┤1         ├
     └──────────┘

Then that unitary gate for the circuit means none of the other optimization passes can do anything with the circuit, until we get to the if statement in the optimization loop looking for gates outside the basis which runs basis translation again to yield the returned circuit instead of optimizing the output as expected. @ElePT might have some thoughts on where this is going wrong.