I'm having a problem in IBM Qiskit with my qubit identities switching places during transpilation. I've been told by developers on the Qiskit slack server that there's currently no built-in way to fix this problem. I'm wondering if anyone has found one themselves.
The issue is that I'd like to perform an algorithm like so:
- Prepare in an initial state
- Apply a circuit
U
repeatedly n_iter times - Measure
I also want this algorithm to:
- Be reasonably efficient with gates (specifically noisy CNOTs)
- Have the same error for
U
for each iteration of it
This turns out to be a headche. When U
is complicated, it becomes difficult for the transpiler to efficiently decompose it to native gates. This difficulty goes up for U*U
and U*U*U
since they're longer. So if I were to transpile the whole algorithm at once (with many U
's), it certainly won't give an efficient gate decomposition, and won't have the same error for each iteration of U
.
The solution I thought would be reasonable is to transpile U
on its own, then compose it with itself. But this hits a problem. The transpiler likes to switch qubit identities (and add global phase, and maybe more?) while searching for a more efficient circuit. So if I follow my algorithm as stated above, U
will not line up correctly with the prep or measurement, and my results will be wrong.
I've been told by developers on the slack that there's currently no built-in way to fix this. The transpiler does not report a final_layout
of the qubits.
I've been trying to determine the final_layout
by hand by comparing the transpiler output to my intended circuit plus swap gates (up to a global phase), but I'm even failing at this.
Does anyone have either working code to determine the final_layout
, or a better approach to implementing this algorithm?
EDIT: Code and more info is included in my partial answer below
EDIT 2: See further clarification here: Qubit identities get swapped in IBM Qiskit (This issue is remarkably difficult to communicate clearly)
transpile(..., seed_transpiler=42, ...)
, does it help? $\endgroup$assemble()
and thenbackend.run()
$\endgroup$