Skip to content

VF2PostLayout corrupts final_layout output #10457

@mtreinish

Description

@mtreinish

Environment

  • Qiskit Terra version: 0.24.1 (but it also should affect 0.24.2 and main)
  • Python version: 3.11
  • Operating system: Linux

What is happening?

When running transpile() if the VF2PostLayout pass finds a better letter and re-applies the initial layout the final layout is not adjusted to correct for that change in initial position. This previously was not an issue because the final layout was an internal implementation detail (primarily used only for sabre layout) and we were done using it after layout in the transpiler. But now we're returning the final layout as part of the public interface in a QuantumCircuit.

How can we reproduce the issue?

from qiskit import QuantumCircuit, transpile
from qiskit.providers.fake_provider import FakeVigo
from qiskit_aer import AerSimulator

backend = AerSimulator.from_backend(FakeVigo())
qubits = 3
qc = QuantumCircuit(qubits)
for i in range(5):
    qc.cx(i % qubits, int(i + qubits / 2) % qubits)

tqc = transpile(qc, backend=backend, callback=callback)
print(tqc)
print(tqc.layout)

What should happen?

In that example if VF2PostLayout runs the final layout will potentially point to incorrect qubits. One example incorrect output is:

ancilla_0 -> 0 ───────────────────────────────────────────────────────
                    ┌───┐     ┌───┐┌───┐     ┌───┐     ┌───┐┌───┐     
      q_0 -> 1 ──■──┤ X ├──■──┤ X ├┤ X ├──■──┤ X ├──■──┤ X ├┤ X ├──■──
               ┌─┴─┐└─┬─┘  │  └─┬─┘└─┬─┘  │  └─┬─┘┌─┴─┐└─┬─┘└─┬─┘┌─┴─┐
      q_1 -> 2 ┤ X ├──┼────┼────┼────■────┼────■──┤ X ├──■────┼──┤ X ├
               └───┘  │  ┌─┴─┐  │       ┌─┴─┐     └───┘       │  └───┘
      q_2 -> 3 ───────■──┤ X ├──■───────┤ X ├─────────────────■───────
                         └───┘          └───┘                         
ancilla_1 -> 4 ───────────────────────────────────────────────────────
TranspileLayout(initial_layout=Layout({
1: Qubit(QuantumRegister(3, 'q'), 0),
2: Qubit(QuantumRegister(3, 'q'), 1),
3: Qubit(QuantumRegister(3, 'q'), 2),
0: Qubit(QuantumRegister(2, 'ancilla'), 0),
4: Qubit(QuantumRegister(2, 'ancilla'), 1)
}), input_qubit_mapping={Qubit(QuantumRegister(3, 'q'), 0): 0, Qubit(QuantumRegister(3, 'q'), 1): 1, Qubit(QuantumRegister(3, 'q'), 2): 2, Qubit(QuantumRegister(2, 'ancilla'), 0): 3, Qubit(QuantumRegister(2, 'ancilla'), 1): 4}, final_layout=Layout({
0: Qubit(QuantumRegister(5, 'q'), 0),
3: Qubit(QuantumRegister(5, 'q'), 1),
2: Qubit(QuantumRegister(5, 'q'), 2),
4: Qubit(QuantumRegister(5, 'q'), 3),
1: Qubit(QuantumRegister(5, 'q'), 4)
}))

In this case the final layout is incorrect because it's not taking into account that vf2postlayout changed the initial layout. Instead it should be:

Layout({
0: Qubit(QuantumRegister(5, 'q'), 0),
3: Qubit(QuantumRegister(5, 'q'), 1),
1: Qubit(QuantumRegister(5, 'q'), 2),
2: Qubit(QuantumRegister(5, 'q'), 3),
4: Qubit(QuantumRegister(5, 'q'), 4)
}))

(I was running without seeds set so it was random failure based on sabre's output)

Any suggestions?

We should update the ApplyLayout pass to also update the final_layout in the property set if it's present, just like it does for the layout field.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions