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.21k stars 2.36k forks source link

preset_passmanager transpilation bug if used >2 times with optimisation level 3: transpiled circuit is different and refers to unknown registers #11861

Closed loicdewitte closed 7 months ago

loicdewitte commented 8 months ago

Environment

What is happening?

Hello,

As part of a research project, I have developed multi-step quantum algorithms and implemented them in Qiskit. In every step, I transpile a circuit first then run it on the backend (qasm_simulator). This can be simplified as (I do not wish to publish the full code directly as it is yet to be published):

backend = qiskit.Aer.get_backend('qasm_simulator')
cct_s1 = qiskit.circuit.QuantumCircuit(qr,cr)                        # creates circuit
... # builds circuit
t_cct_s1 = qiskit.transpile(cct_s1,backend=backend,optimization_level=optimisation_level)           # transpiles circuit
job_s1 = backend.run(t_cct_s1,shots=n_shots)    # runs transpiled circuit

I then post-process the counts dictionary to obtain the required information. The algorithms and every step work as expected and intended.

In order to reduce computation time, I was suggested by IBM staff to use a pass_manager generated as

transpiler_pm = qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager(optimisation_level,backend=backend)

My transpilation-run step then becomes

backend = qiskit.Aer.get_backend('qasm_simulator')
transpiler_pm = qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager(optimisation_level,backend=backend)
cct_s1 = qiskit.circuit.QuantumCircuit(qr,cr)                        # creates circuit
... # builds circuit
t_cct_s1 = transpiler_pm.run(cct_s1)                            # transpiles circuit
job_s1 = backend.run(t_cct_s1,shots=n_shots)    # runs transpiled circuit

This works fine with optimisation levels 0, 1 and 2. With optimisation level 3, it works fine if I only use the pass_manager once or twice per algorithm, i.e., if I replace at most 2 transpilations in any algorithm. The pass_manager returns virtually the same transpiled circuit as that returned by qiskit.transpile().

However, with optimisation level 3, if I replace an additional occurence of qiskit.transpile() by the pass_manager transpilation, the transpiled circuit is completely different. While the circuit transpiled by qiskit.transpile() is made of the correct number of qubits (4 in the example) and contains only H, X, P, U, U2, U3 and measurement gates, the circuit transpiled by the pass_manager contains fewer qubits (3 here) and also contains Ry gates. The depth is also much shorter. See below the circuits used in the example, and notice how the qubits of the wrongly transpiled circuit refer to another register (which is not created in the algorithm).

Interestingly, this issue happens consistently, whatever transpilation step I replace.

Circuits used in the example:

Original (not transpiled) circuit

q85_0: ┤ H ├──■────■────■──┤ X ├»
       └───┘┌─┴─┐  │    │  └───┘»
q85_1: ─────┤ H ├──┼────┼───────»
            └───┘┌─┴─┐  │       »
q85_2: ──────────┤ H ├──┼───────»
                 └───┘┌─┴─┐     »
q85_3: ───────────────┤ H ├─────»
                      └───┘     »
 c3: 4/═════════════════════════»
                                »
«                                                                                                                                                     »
«q85_0: ──────────────────────────────────────────────────────────────────────■───────────────────────────────────────────────────────────────────────»
«       ┌─────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────┐»
«q85_1: ┤0                                                                                                                                           ├»
«       │                                                                                                                                            │»
«q85_2: ┤1 State Preparation(0.0521j,-0.17045+0.14327j,0.28014+0.26774j,0.294+0.40694j,-0.30615j,-0.294+0.40694j,-0.28014+0.26774j,0.17045+0.14327j) ├»
«       │                                                                                                                                            │»
«q85_3: ┤2                                                                                                                                           ├»
«       └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘»
« c3: 4/══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                                                     »
«       ┌─────────┐┌─────┐┌───┐   ┌─┐
«q85_0: ┤0        ├┤ Sdg ├┤ H ├───┤M├
«       │         │└─┬─┬─┘└───┘   └╥┘
«q85_1: ┤1        ├──┤M├───────────╫─
«       │  c_IQFT │  └╥┘   ┌─┐     ║
«q85_2: ┤2        ├───╫────┤M├─────╫─
«       │         │   ║    └╥┘ ┌─┐ ║
«q85_3: ┤3        ├───╫─────╫──┤M├─╫─
«       └─────────┘   ║     ║  └╥┘ ║
« c3: 4/══════════════╩═════╩═══╩══╩═
«                     0     1   2  3

Circuit transpiled by qiskit.transpile() (correct transpiled circuit)

q85_0: ─────┤ H ├────────■─────────────────────■─────────────────────■────┤ U3(π,-π,0) ├───■─────────────────────»
       ┌────┴───┴─────┐┌─┴─┐┌───────────────┐  │                     │    └────────────┘ ┌─┴─┐┌─────────────────┐»
q85_1: ┤ U2(π/4,-π/2) ├┤ X ├┤ U2(-π/2,3π/4) ├──┼─────────────────────┼───────────────────┤ X ├┤ U(-0.94978,0,0) ├»
       ├──────────────┤└───┘└───────────────┘┌─┴─┐┌───────────────┐  │                   └───┘└─────────────────┘»
q85_2: ┤ U2(π/4,-π/2) ├──────────────────────┤ X ├┤ U2(-π/2,3π/4) ├──┼───────────────────────────────────────────»
       ├──────────────┤                      └───┘└───────────────┘┌─┴─┐┌───────────────┐                        »
q85_3: ┤ U2(π/4,-π/2) ├────────────────────────────────────────────┤ X ├┤ U2(-π/2,3π/4) ├────────────────────────»
       └──────────────┘                                            └───┘└───────────────┘                        »
 c3: 4/══════════════════════════════════════════════════════════════════════════════════════════════════════════»
                                                                                                                 »
«                                                                                                                  »
«q85_0: ──■────■───────────────────────■──────────────────────■───────────────────────■────────────────────────────»
«       ┌─┴─┐  │   ┌────────────────┐  │                      │                       │                            »
«q85_1: ┤ X ├──┼───┤ U(0.94978,0,0) ├──┼──────────────────────┼───────────────────────┼────────────────────────────»
«       └───┘┌─┴─┐┌┴────────────────┤┌─┴─┐┌────────────────┐  │                       │                            »
«q85_2: ─────┤ X ├┤ U(-0.93731,0,0) ├┤ X ├┤ U(0.93731,0,0) ├──┼───────────────────────┼────────────────────────────»
«            └───┘└─────────────────┘└───┘└────────────────┘┌─┴─┐┌─────────────────┐┌─┴─┐┌────────────────────────┐»
«q85_3: ────────────────────────────────────────────────────┤ X ├┤ U(-0.83097,0,0) ├┤ X ├┤ U3(0.83097,-0.25223,0) ├»
«                                                           └───┘└─────────────────┘└───┘└────────────────────────┘»
« c3: 4/═══════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                  »
«                                                                                                    »
«q85_0: ──■──────────────────────■────■────■───────────────────────■──────────────────────────────■──»
«         │                      │    │    │                       │                              │  »
«q85_1: ──┼──────────────────────┼────┼────┼───────────────────────┼──────────────────────────────┼──»
«         │                      │  ┌─┴─┐┌─┴─┐┌─────────────────┐┌─┴─┐┌────────────────────────┐┌─┴─┐»
«q85_2: ──┼──────────────────────┼──┤ X ├┤ X ├┤ U(-0.28741,0,0) ├┤ X ├┤ U3(0.28741,-0.59471,0) ├┤ X ├»
«       ┌─┴─┐┌────────────────┐┌─┴─┐└─┬─┘└───┘└─────────────────┘└───┘└────────────────────────┘└───┘»
«q85_3: ┤ X ├┤ U(0,0,0.25223) ├┤ X ├──■──────────────────────────────────────────────────────────────»
«       └───┘└────────────────┘└───┘                                                                 »
« c3: 4/═════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                    »
«                                                                                                                 »
«q85_0: ────────────────────■────■───────────────────────■────────────────────────■────■────■─────────────────────»
«                           │    │                       │                        │  ┌─┴─┐┌─┴─┐┌─────────────────┐»
«q85_1: ────────────────────┼────┼───────────────────────┼────────────────────────┼──┤ X ├┤ X ├┤ U(-0.23229,0,0) ├»
«       ┌────────────────┐┌─┴─┐┌─┴─┐┌─────────────────┐┌─┴─┐┌──────────────────┐┌─┴─┐└─┬─┘└───┘└─────────────────┘»
«q85_2: ┤ U(0,0,0.59471) ├┤ X ├┤ X ├┤ U(0,0,0.018335) ├┤ X ├┤ U(0,0,-0.018335) ├┤ X ├──■──────────────────────────»
«       └────────────────┘└───┘└─┬─┘└─────────────────┘└───┘└──────────────────┘└───┘                             »
«q85_3: ─────────────────────────■────────────────────────────────────────────────────────────────────────────────»
«                                                                                                                 »
« c3: 4/══════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                 »
«                                                                                                                 »
«q85_0: ──■──────────────────────■────■───────────────────────■────────────────────────■────■─────────────────────»
«       ┌─┴─┐┌────────────────┐┌─┴─┐┌─┴─┐┌─────────────────┐┌─┴─┐┌──────────────────┐┌─┴─┐┌─┴─┐┌─────────────────┐»
«q85_1: ┤ X ├┤ U(0.23229,0,0) ├┤ X ├┤ X ├┤ U(0.018533,0,0) ├┤ X ├┤ U(-0.018533,0,0) ├┤ X ├┤ X ├┤ U(-0.17742,0,0) ├»
«       └───┘└────────────────┘└─┬─┘└───┘└─────────────────┘└───┘└──────────────────┘└─┬─┘└───┘└─────────────────┘»
«q85_2: ─────────────────────────┼─────────────────────────────────────────────────────■──────────────────────────»
«                                │                                                                                »
«q85_3: ─────────────────────────■────────────────────────────────────────────────────────────────────────────────»
«                                                                                                                 »
« c3: 4/══════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                 »
«                                                                                                                 »
«q85_0: ──■──────────────────────────────■──────────────────────■────■───────────────────────■────────────────────»
«       ┌─┴─┐┌────────────────────────┐┌─┴─┐┌────────────────┐┌─┴─┐┌─┴─┐┌─────────────────┐┌─┴─┐┌────────────────┐»
«q85_1: ┤ X ├┤ U3(0.17742,-0.12915,0) ├┤ X ├┤ U(0,0,0.12915) ├┤ X ├┤ X ├┤ U(0,0,-0.59471) ├┤ X ├┤ U(0,0,0.59471) ├»
«       └───┘└────────────────────────┘└───┘└────────────────┘└───┘└─┬─┘└─────────────────┘└───┘└────────────────┘»
«q85_2: ─────────────────────────────────────────────────────────────■────────────────────────────────────────────»
«                                                                                                                 »
«q85_3: ──────────────────────────────────────────────────────────────────────────────────────────────────────────»
«                                                                                                                 »
« c3: 4/══════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                 »
«                                                                                                            »
«q85_0: ──■────■──────────────────────■───────────────────────■────■──────────────────■───────────────────■──»
«       ┌─┴─┐┌─┴─┐┌────────────────┐┌─┴─┐┌─────────────────┐┌─┴─┐┌─┴─┐┌────────────┐┌─┴─┐┌─────────────┐┌─┴─┐»
«q85_1: ┤ X ├┤ X ├┤ U(0,0,0.76706) ├┤ X ├┤ U(0,0,-0.76706) ├┤ X ├┤ X ├┤ U(0,0,π/8) ├┤ X ├┤ U(0,0,-π/8) ├┤ X ├»
«       └───┘└─┬─┘└────────────────┘└───┘└─────────────────┘└───┘└─┬─┘└────────────┘└───┘└─────────────┘└───┘»
«q85_2: ───────┼───────────────────────────────────────────────────■─────────────────────────────────────────»
«              │                                                                                             »
«q85_3: ───────■─────────────────────────────────────────────────────────────────────────────────────────────»
«                                                                                                            »
« c3: 4/═════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                            »
«       ┌─────────┐                                                                                                »
«q85_0: ┤ P(3π/8) ├─■──────────■────■────■─────────■──────────■───■─────────■───■───────────────■─────────■────────»
«       └─────────┘ │          │  ┌─┴─┐  │  ┌──────┴───────┐┌─┴─┐ │P(π/4) ┌─┴─┐ │P(-π/4)        │         │        »
«q85_1: ────────────┼──────────■──┤ X ├──■──┤ U(π/2,0,π,0) ├┤ X ├─■───────┤ X ├─■───────────────┼─────────┼────────»
«                   │P(-π/4)   │  └─┬─┘  │  └──────────────┘└─┬─┘         └─┬─┘          ┌──────┴───────┐ │        »
«q85_2: ────────────■──────────┼────┼────┼────────────────────■─────────────■────────────┤ U(π/2,0,π,0) ├─┼────────»
«                            ┌─┴─┐  │  ┌─┴─┐                                             └──────────────┘ │P(-π/8) »
«q85_3: ─────────────────────┤ X ├──■──┤ X ├──────────────────────────────────────────────────────────────■────────»
«                            └───┘     └───┘                                                                       »
« c3: 4/═══════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                  »
«                                                                                              ┌───────────┐   ┌─┐
«q85_0: ──■───■─────────■───■─────────■─────────────■───■─────────■───■───────────────■────────┤ U2(0,π/2) ├───┤M├
«       ┌─┴─┐ │P(π/8) ┌─┴─┐ │P(-π/8)  │        ┌─┐  │   │         │   │               │        └───────────┘   └╥┘
«q85_1: ┤ X ├─■───────┤ X ├─■─────────┼────────┤M├──┼───┼─────────┼───┼───────────────┼─────────────────────────╫─
«       └─┬─┘         └─┬─┘           │        └╥┘┌─┴─┐ │P(π/4) ┌─┴─┐ │P(-π/4)        │             ┌─┐         ║
«q85_2: ──┼─────────────┼─────────────┼─────────╫─┤ X ├─■───────┤ X ├─■───────────────┼─────────────┤M├─────────╫─
«         │             │             │P(-π/4)  ║ └─┬─┘         └─┬─┘          ┌──────┴───────┐     └╥┘     ┌─┐ ║
«q85_3: ──■─────────────■─────────────■─────────╫───■─────────────■────────────┤ U(π/2,0,π,0) ├──────╫──────┤M├─╫─
«                                               ║                              └──────────────┘      ║      └╥┘ ║
« c3: 4/════════════════════════════════════════╩════════════════════════════════════════════════════╩═══════╩══╩═
«                                               0                                                    1       2  3

Circuit transpiled by the pass_manager

q31_0: ─────┤ Ry(2.0682) ├────────────────────────────────────────────────────────┤ X ├┤ Ry(-0.3868) ├┤ X ├»
            ├────────────┤    ┌───┐┌────────────────────────┐┌───┐┌──────────────┐└─┬─┘└─────────────┘└─┬─┘»
q31_1: ─────┤ Ry(1.3634) ├────┤ X ├┤ U3(0.57907,-0.15852,0) ├┤ X ├┤ Rz(-0.52708) ├──■───────────────────┼──»
       ┌────┴────────────┴───┐└─┬─┘└────────────────────────┘└─┬─┘└──────────────┘                      │  »
q31_2: ┤ U3(1.601,-2.0508,0) ├──■──────────────────────────────■────────────────────────────────────────■──»
       └─────────────────────┘                                                                             »
 c0: 3/════════════════════════════════════════════════════════════════════════════════════════════════════»
                                                                                                           »
«       ┌──────────────┐┌───┐┌────────────────────────┐┌───┐┌──────────────┐┌───┐┌─────────────┐┌───┐┌──────────┐»
«q31_0: ┤ Ry(-0.29439) ├┤ X ├┤ U3(0.042682,2.3678,-π) ├┤ X ├┤ Rz(-0.15852) ├┤ X ├┤ Rz(-1.0437) ├┤ X ├┤ Rz(-π/4) ├»
«       └──────────────┘└─┬─┘└────────────────────────┘└─┬─┘└──────────────┘└─┬─┘└─────────────┘└─┬─┘└──────────┘»
«q31_1: ──────────────────■──────────────────────────────■────────────────────┼───────────────────■──────────────»
«                                                                             │                                  »
«q31_2: ──────────────────────────────────────────────────────────────────────■──────────────────────────────────»
«                                                                                                                »
« c0: 3/═════════════════════════════════════════════════════════════════════════════════════════════════════════»
«                                                                                                                »
«          ┌───┐                                   ┌─┐
«q31_0: ─X─┤ H ├─■──────────────■──────────────────┤M├───────────
«        │ └───┘ │P(-π/2) ┌───┐ │                  └╥┘     ┌─┐
«q31_1: ─┼───────■────────┤ H ├─┼─────────■─────────╫──────┤M├───
«        │                └───┘ │P(-π/4)  │P(-π/2)  ║ ┌───┐└╥┘┌─┐
«q31_2: ─X──────────────────────■─────────■─────────╫─┤ H ├─╫─┤M├
«                                                   ║ └───┘ ║ └╥┘
« c0: 3/════════════════════════════════════════════╩═══════╩══╩═
«                                                   0       1  2

How can we reproduce the issue?

I can show/share my code in private with IBM staff. As mentioned, it is part of a yet-to-be-published research project. I had a meeting with Matthew Treinish in November who had a glimpse of it.

What should happen?

The circuit transpiled by the pass_manager should be virtually similar (or of similar 'quality') as that transpiled by qiskit.transpile().

Any suggestions?

I have tried to find the origin of the issue myself but could not pinpoint it. I reckon it is a niche problem but it might hide a bigger, underlying issue.

_An additional question I might have in the meantime is, how much speed-up could I expect from using the pass_manager rather than qiskit.transpile() when my transpilation options are always the same? Specifically, when transpiling a total of 400 circuits that use 5 qubits._

Thanks for the help and for the great work on Qiskit!

loicdewitte commented 7 months ago

Hello,

The issue is resolved in Qiskit 1.0.1.