Skip to content

Flattened conditional circuits give incorrect results #6583

@chriseclectic

Description

@chriseclectic

Information

  • Qiskit Terra version:
  • Python version:
  • Operating system:

What is the current behavior?

Flattening a conditional circuit gives incorrect results. It looks like the issue is probably in how the conditionals are implemented:

Steps to reproduce the problem

Manually adding an additional registers to a teleport circuit works:

def teleport_circuit():
    """Teleport qubit 0 -> 2"""
    qr = QuantumRegister(3)
    c0 = ClassicalRegister(1)
    c1 = ClassicalRegister(1)
    teleport = QuantumCircuit(qr, c0, c1)
    teleport.h(qr[1])
    teleport.cx(qr[1], qr[2])
    teleport.cx(qr[0], qr[1])
    teleport.h(qr[0])
    teleport.measure(qr[0], c0[0])
    teleport.measure(qr[1], c1[0])
    teleport.z(qr[2]).c_if(c0, 1)
    teleport.x(qr[2]).c_if(c1, 1)
    return teleport

# Add extra register for measuring qubit-2
c2 = ClassicalRegister(1)
circ = teleport_circuit()
circ.add_register(c2)
circ.measure(2, c2)

# Run
counts = AerSimulator().run(circ).result().get_counts(0)
marginal_counts(counts, [2])

# Marginal Counts (correct)
{'0': 1024}

But composing and flattening gives wrong answer:

# Compose with larger circuit
circ = QuantumCircuit(3, 3)
circ = circ.compose(teleport_circuit(), range(3), range(2))
circ.measure(2, 2)

# Run
counts = AerSimulator().run(circ).result().get_counts(0)
marginal_counts(counts, [2])

# Marginal Counts (incorrect)
{'1': 228, '0': 796}

What is the expected behavior?

Flattening the conditional circuit should implement the same circuit.

Suggested solutions

From the drawer it looks liek the flattened circuit is handling conditions on the joint circuit wrong:

                    ┌───┐┌─┐              
q_0: ────────────■──┤ H ├┤M├──────────────
     ┌───┐     ┌─┴─┐└┬─┬┘└╥┘              
q_1: ┤ H ├──■──┤ X ├─┤M├──╫───────────────
     └───┘┌─┴─┐└───┘ └╥┘  ║  ┌───┐  ┌───┐ 
q_2: ─────┤ X ├───────╫───╫──┤ Z ├──┤ X ├─
          └───┘       ║   ║  └─╥─┘  └─╥─┘ 
                      ║   ║ ┌──╨──┐┌──╨──┐
c: 3/═════════════════╩═══╩═╡ = 1 ╞╡ = 2 ╞
                      1   0 └─────┘└─────┘

Looks like conditions are triggering on creg values 01 and 10, but nothing on 11 which should trigger both conditional gates.

Looking at the qobj that gets assembled from these circuits we can see the difference:

Multi-register assembled qobj instructions:
assemble(circ).experiments[0].instructions =

[QasmQobjInstruction(name='h', qubits=[1]),
 QasmQobjInstruction(name='cx', qubits=[1, 2]),
 QasmQobjInstruction(name='cx', qubits=[0, 1]),
 QasmQobjInstruction(name='h', qubits=[0]),
 QasmQobjInstruction(name='measure', qubits=[0], register=[0], memory=[0]),
 QasmQobjInstruction(name='measure', qubits=[1], register=[1], memory=[1]),
 QasmQobjInstruction(name='bfunc', register=3, mask="0x1", relation="==", val="0x1"),
 QasmQobjInstruction(name='z', qubits=[2], conditional=3),
 QasmQobjInstruction(name='bfunc', register=4, mask="0x2", relation="==", val="0x2"),
 QasmQobjInstruction(name='x', qubits=[2], conditional=4),
 QasmQobjInstruction(name='measure', qubits=[2], register=[2], memory=[2])]

Flattened circuit assembled qobj instructions:

[QasmQobjInstruction(name='h', qubits=[1]),
 QasmQobjInstruction(name='cx', qubits=[1, 2]),
 QasmQobjInstruction(name='cx', qubits=[0, 1]),
 QasmQobjInstruction(name='h', qubits=[0]),
 QasmQobjInstruction(name='measure', qubits=[0], register=[0], memory=[0]),
 QasmQobjInstruction(name='measure', qubits=[1], register=[1], memory=[1]),
 QasmQobjInstruction(name='bfunc', register=3, mask="0x7", relation="==", val="0x1"),
 QasmQobjInstruction(name='z', qubits=[2], conditional=3),
 QasmQobjInstruction(name='bfunc', register=4, mask="0x7", relation="==", val="0x2"),
 QasmQobjInstruction(name='x', qubits=[2], conditional=4),
 QasmQobjInstruction(name='measure', qubits=[2], register=[2], memory=[2])]

You can see that in the second case the mask value is being set incorrectly to 0x7 = 0b111 in both case to the full 3-bit register rather than the the single bit values.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions