Is it necessary to hold off on measurement key remapping in `CircuitOperation`?
See original GitHub issueIs your design idea/issue related to a use case or problem? Please describe.
Currently, CircuitOperation
keeps a local Dict of measurement key remappings and does not propagate it to the actual underlying circuit, even though a new CircuitOperation
is created on each with_measurement_key_mapping
call. I suspect this was done for efficiency to avoid iterating over the circuit or create a copy of it.
But this behavior leads to some inconsistencies and additional complexity if you try to work with the underlying circuit
, leading me to wonder if this optimization is worth it. Most of the interface of Circuit
and CircuitOperation
is consistent but this logic introduces some counter-intuitive behavior unless you know this implementation detail of CircuitOperation
.
import cirq
q=cirq.LineQubit(0)
c = cirq.Circuit([cirq.MeasurementGate(1, key='a')(q)])
c_op = cirq.CircuitOperation(c.freeze())
remapped_c = cirq.with_measurement_key_mapping(c, {'a':'b'})
remapped_c_op = cirq.with_measurement_key_mapping(c_op, {'a':'b'})
print(remapped_c.all_measurement_keys()) # {'b'}
print(remapped_c_op.circuit.all_measurement_keys()) # {'a'} May be unexpected
print(cirq.measurement_keys(remapped_c)) # {'b'}
print(cirq.measurement_keys(remapped_c_op.circuit)) # {'a'} May be unexpected
# But the below works as expected.
print(cirq.measurement_keys(remapped_c_op)) # {'b'}
Describe your design idea/issue
Rather than keeping a Dict of mappings in CircuitOperation
, we can pass down the remapping of keys to the underlying Circuit
similar to how key remapping on a Circuit
passes it on to Moment
s and then Operation
s. This will make the behavior consistent and easier to understand but there is a (small?) performance penalty at the time of circuit construction in the python code.
This will also make other logic or additional features dealing with measurements in CircuitOperations
cleaner.
Note: This does not include the repetition_id
path update on the keys during “unrolling” of the sub-circuit. That is purely a CircuitOperation
feature and should be kept local to CircuitOperation
unless needed elsewhere.
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (2 by maintainers)
Not propagating measurement key changes to the underlying circuit is intentional, as it allows us to reference the same FrozenCircuit object across multiple CircuitOperations. Without this, we would be unable to concisely serialize multiple copies of a measurement-containing CircuitOperation.
mapped_circuit(..., deep=False)
and changingparent_path
are used to facilitateCircuitOperation._decompose_
. This is currently used bycirq_google.optimize_for_sycamore
to convert the contents of aCircuitOperation
to Sycamore-friendly gates while preserving theCircuitOperation
structure which contains them.It might be possible to do this without
deep=False
, but it would effectively involve doing decomposition work outside of the decomposition protocol.