Edit: Improved code a bit
Edit 2: After corresponding with a Qiskit developer, this issue was considered not a bug per se but a missing functionality that has not yet been implemented (and will be difficult to do so). The proscribed solution is to not transpile partial circuits. In practice I find one can transpile partial circuits then check for qubit identity swapping and fix as needed. The correspondence is here: https://github.com/Qiskit/qiskit-terra/issues/7472
This is a condensed description of the IBM bug that was a problem here, to make it more clear.
The following code compiles to a correct circuit when the measurement is present, but not when the measurement is absent:
from qiskit.compiler import transpile
from qiskit import QuantumCircuit, IBMQ
provider = IBMQ.load_account()
lima = provider.get_backend('ibmq_lima')
n_q = 3
qc_foo = QuantumCircuit(n_q, n_q)
qubit_list = [0,1,2]
qc_foo.swap(0,1)
qc_foo.swap(0,2)
qc_foo.barrier()
qc_foo.measure(qubit_list, qubit_list)
qc_foo_trans = transpile(qc_foo, backend=lima, optimization_level=3
, initial_layout=qubit_list, seed_transpiler=101)
qc_foo_trans.draw()
With measurement the circuit is:
And without measurement (comment out .measure
line in code):
Notice the latter circuit is not equivalent to the intended circuit. The reason is that in both cases part of the work is moved to the measurements by swapping them i.e. q1->c0 and q0->c1. But when there are no measurements, that extra work disappears and the final qubit identities are wrong. It is further strange that a barrier does not stop this in either case.
This is an especially big problem when trying to perform a circuit multiple times in a row before measurement. In that case the circuit itself has to be correct, and simple solutions like remapping state prep or measurements won't help.
(This is mostly a bug report, to make the problem more visible to Qiskit contributors. But temporary solutions are welcome.)