Skip to content

defer_measurements ignores BitMaskKeyCondition.index and changes circuit behavior #8361

Description

@WindOctober

Describe the issue

cirq.defer_measurements does not preserve the record index of a BitMaskKeyCondition. When a measurement key is reused, a condition referring to an earlier record can become an unconditional operation after deferral, changing the measurement result.

The index should be preserved, or unsupported conditions should be rejected explicitly.

Explain how to reproduce the bug or problem

from collections import Counter
import cirq

q0, q1, q2 = cirq.LineQubit.range(3)
condition = cirq.BitMaskKeyCondition(
    cirq.MeasurementKey("a"), index=0, target_value=0, equal_target=True
)
circuit = cirq.Circuit(
    cirq.X(q0),
    cirq.measure(q0, key="a"),  # First record: 1.
    cirq.measure(q1, key="a"),  # Second record: 0.
    cirq.X(q2).with_classical_controls(condition),
    cirq.measure(q2, key="out"),
)

simulator = cirq.Simulator()
for label, candidate in [
    ("original", circuit),
    ("deferred", cirq.defer_measurements(circuit)),
]:
    result = simulator.run(candidate, repetitions=1000)
    print(label, Counter(result.records["out"].flatten().tolist()))

Observed output:

original Counter({0: 1000})
deferred Counter({1: 1000})

The condition tests whether the first record is zero, which is false. Both circuits should therefore measure out = 0 on every shot.

Tell us the version of Cirq where this happens

Cirq 1.7.0, Python 3.11.4, Linux.

Root cause

In measurement_transformers.py, defer_measurements preserves condition.index only for KeyCondition; BitMaskKeyCondition falls through to index -1. It therefore enumerates the latest record while the original condition still reads record 0, which is zero-filled in the synthetic datastore. In this example, the condition becomes true for every enumerated value.

Unlike #8360, where KeyCondition._qasm_ ignores the index during QASM export, this is a separate type-dispatch omission in the deferred-measurement transformer. No QASM conversion is involved, and deferral correctly preserves index=0 for KeyCondition in the corresponding test.

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

    kind/bug-reportSomething doesn't seem to work.skill/experiencedNeeds experience with Cirq developmenttriage/discussNeeds decision / discussion, bring these up during Cirq Cynque

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions