Skip to content

Controlled empty subroutine causes ValueError on simulator #6730

@IlanIwumbwe

Description

@IlanIwumbwe

Benny and I found this bug

Description of the issue
Controlled empty subroutine causes ValueError on simulator

How to reproduce the issue

from cirq import (Circuit, CNOT, CZ, Y, Simulator,
    NamedQubit, InsertStrategy, CircuitOperation, measure)
from pathlib import Path

from pyqir import qubit
from helpers.cirq_helpers import compare_circuits, individual_pass
from cirq.transformers import *

# Adding qubits 
qubits = NamedQubit.range(4, prefix="q")

subcirc1 = Circuit()
subcirc1.append(CZ(qubits[0],qubits[3]), strategy = InsertStrategy.INLINE)
subcirc1.append(CZ(qubits[3],qubits[0]), strategy = InsertStrategy.INLINE)
subcirc1.append(CNOT(qubits[3],qubits[0]), strategy = InsertStrategy.EARLIEST)
subcirc1_op = CircuitOperation(subcirc1.freeze())

subcirc2 = Circuit()
#subcirc2.append(Y(qubits[0]))
subcirc2_op = CircuitOperation(subcirc2.freeze())

main_circ = Circuit()
main_circ.append(measure(qubits[0], key="cbit0"))
main_circ.append(subcirc1_op.with_classical_controls('cbit0'))
main_circ.append(measure(qubits[1], key="cbit1"))
main_circ.append(subcirc2_op.with_classical_controls('cbit1'))

print(main_circ)
main_circ.append(measure(qubits, key="results"))

simulator = Simulator()
circ = simulator.run(main_circ, repetitions=10)

Uncommenting the Y gate within the subroutine makes this work. Although users may not do something like this, it would probably be nice if this was treated like an identity instead.

          ┌──┐
                 [ q0: ───@───@───X─── ]
q0: ───────M─────[        │   │   │    ]──────────────────────────────────
           ║     [ q3: ───@───@───@─── ].with_classical_controls(cbit0)
           ║     ║
q1: ───────╫M────╫────────────────────────────────────────────────────────
           ║║    ║
q3: ───────╫╫────#2───────────────────────────────────────────────────────
           ║║    ║
cbit0: ════@╬════╩════════════════════════════════════════════════════════
            ║
cbit1: ═════@═════════════════════════════════════════════════════════════
                 [  ].with_classical_controls(cbit1)
          └──┘
Traceback (most recent call last):
  File "quantum_circuits/circuit1.py", line 32, in <module>
    circ = simulator.run(main_circ, repetitions=10)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/work/sampler.py", line 63, in run
    return self.run_sweep(program, param_resolver, repetitions)[0]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/sim/simulator.py", line 72, in run_sweep
    return list(self.run_sweep_iter(program, params, repetitions))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/sim/simulator.py", line 103, in run_sweep_iter
    records = self._run(
              ^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/sim/simulator_base.py", line 245, in _run
    for step_result in self._core_iterator(circuit=prefix, sim_state=sim_state):
  File ".venv/lib/python3.11/site-packages/cirq/sim/simulator_base.py", line 220, in _core_iterator
    protocols.act_on(op, sim_state)
  File ".venv/lib/python3.11/site-packages/cirq/protocols/act_on_protocol.py", line 141, in act_on
    result = action_act_on(sim_state) if is_op else action_act_on(sim_state, qubits)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/ops/classically_controlled_operation.py", line 187, in _act_on_
    if all(c.resolve(sim_state.classical_data) for c in self._conditions):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/ops/classically_controlled_operation.py", line 187, in <genexpr>
    if all(c.resolve(sim_state.classical_data) for c in self._conditions):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/cirq/value/condition.py", line 104, in resolve
    raise ValueError(f'Measurement key {self.key} missing when testing classical control')
ValueError: Measurement key cbit1 missing when testing classical control

Cirq version
You can get the cirq version by printing cirq.__version__. From the command line:
1.4.1

Metadata

Metadata

Assignees

Labels

good for learningFor beginners in QC, this will help picking up some knowledge. Bit harder than "good first issues"kind/bug-reportSomething doesn't seem to work.triage/acceptedA consensus emerged that this bug report, feature request, or other action should be worked on

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions