Skip to content

Rework virtual gate propagation for MCMs #376

Description

@joshuasn

Description

With the release of 0.20.0, some circuits with MCMs that were previously buildable are no longer

from qiskit.circuit import QuantumCircuit
from samplomatic import build, Twirl
from samplomatic.transpiler import generate_boxing_pass_manager

circuit = QuantumCircuit(2, 1)
# Add mid-circuit measurement
circuit.measure(0, 0)
# Continue with more gates after measurement
circuit.cx(0, 1)

pm = generate_boxing_pass_manager(
    enable_gates=False,
    enable_measures=True,
    twirling_strategy="all",
    measure_annotations="change_basis"
)
boxed_circuit = pm.run(circuit)

build(boxed_circuit)

due to how measure propagates are handled.

The PreSamplex of the boxed circuit in 0.19.0 has its propagate CX node attached to both collectors:
Image
When calling finalize, the CX nodes get removed, and the resulting samplex produces the correct samples. However, this mechanism also allows the boxed circuit with

with boxed_circuit.box([Twirl(dressing="right")]):
     boxed_circuit.noop(0, 1)

appended to be buildable. The samples generated by this samplex are incorrect as Paulis travelling leftward end up ignoring the presence of a measurement. This circuit is (correctly) not buildable in 0.20.0.

Acceptance criteria

The first boxed circuit in the description is buildable, the appended boxed circuit is not, the following rules are implemented:

Rightward propagation

Optional danglers stay optional when being propagated so that fragments like

circuit = QuantumCircuit(1, 1)
with circuit.box([Twirl()]):
    circuit.measure(0, 0)
circuit.h(0)

are buildable.

Consider allowing implicit identities as well so that fragments like

circuit = QuantumCircuit(2, 1)
with circuit.box([Twirl()]):
    circuit.measure(0, 0)
circuit.cx(0, 1)

are buildable.

Leftward propagation

If a node doesn't find predecessor nodes with all its subsystems, cease propagation on those subsystems but don't error. The error will be raised by PreSamplex.add_emit_twirl when attempting to emit gates, otherwise the nodes get pruned in finalize. Fragments like the following

with circuit.box([ChangeBasis()]):
    circuit.measure(0, 0)
    circuit.noop(1)
circuit.cx(0, 1)

should be buildable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions