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

Transformation pass discards layout information #8622

Open eendebakpt opened 2 years ago

eendebakpt commented 2 years ago

Environment

What is happening?

Applying a transformation pass discards information about the layout of a quantum circuit.

How can we reproduce the issue?

A minimal example is:

from qiskit.circuit.quantumcircuit import QuantumCircuit
from qiskit.compiler import transpile
from qiskit.transpiler import CouplingMap
from qiskit.transpiler.passmanager import PassManager
from qiskit.transpiler.passes import Decompose

qc=QuantumCircuit(3)
qc.cx(0, 2)    

coupling_map = CouplingMap([[0,1], [1,2],  [1,0], [2,1]])
print(qc.draw())    

qc_base = qc
qc_base = transpile(qc_base, basis_gates=['cz', 'cx', 'u3', 'u2', 'u1'], coupling_map=coupling_map,  optimization_level=2)
print(qc_base.draw()) 

d=Decompose(gates_to_decompose=None)
pm = PassManager([d, ])
qc_base2= pm.run(qc_base)
print(qc_base2.draw()) # here we seem to have lost the mapping information

Output:

q_0: ──■──
       │  
q_1: ──┼──
     ┌─┴─┐
q_2: ┤ X ├
     └───┘
         ┌───┐
q_2 -> 0 ┤ X ├
         └─┬─┘
q_0 -> 1 ──■──

q_1 -> 2 ─────

     ┌───┐
q_0: ┤ X ├
     └─┬─┘
q_1: ──■──

q_2: ─────

What should happen?

I want to apply a series of passes (including passes that deal with the coupling map) to obtain a circuit that I can execute on the specified topology, but with an unchanged qubit ordering.

It is fine if the passes change the order of the qubits (which happens in the minimal example for circuit qc_base where the qubits 0, 1, 2 are re-ordered to 1, 2, 0), as long as I have the information to map this circuit back to a circuit with the original qubit ordering.

Any suggestions?

No response

jakelishman commented 2 years ago

There's a few "magic" properties on QuantumCircuit that are written out from similarly magic properties in the property sets of running pass managers. The layout is one of them.

It's not immediately clear to me if there are significant problematic implications around RunningPassManager.run propagating these magic properties from an input circuit to an output circuit (if they don't appear in the output property set). I suspect the layout is probably ok, since in the preset pass managers, the layout is set very early on in the process, and subsequent passes don't invalidate it. The other magic properties are to do with scheduling, and those probably can't be safely restored, because almost every pass would invalidate them.

As an immediate workaround, you can just do qc_base2._layout = qc_base._layout to restore the layout.

kdk commented 1 year ago

Agree. It looks like PassManager.run will only write circuit._layout if a layout is generated in the property_set, so at least it should be possible to carry _layout forward when no layout passes are run, and raise/warn if there's both a existing ._layout and the one trying to be set by the PassManager.

https://github.com/Qiskit/qiskit-terra/blob/fb2e0e5e9459b8754e350d6a121c29a5a0e25065/qiskit/transpiler/runningpassmanager.py#L105