def test_measurement_keys(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') m = cirq.Moment(cirq.X(a), cirq.X(b)) assert cirq.measurement_keys(m) == set() assert not cirq.is_measurement(m) m2 = cirq.Moment(cirq.measure(a, b, key='foo')) assert cirq.measurement_keys(m2) == {'foo'} assert cirq.is_measurement(m2)
def test_decompose_repeated_nested_measurements(): # Details of this test described at # https://tinyurl.com/measurement-repeated-circuitop#heading=h.sbgxcsyin9wt. a = cirq.LineQubit(0) op1 = (cirq.CircuitOperation(cirq.FrozenCircuit(cirq.measure( a, key='A'))).with_measurement_key_mapping({ 'A': 'B' }).repeat(2, ['zero', 'one'])) op2 = (cirq.CircuitOperation( cirq.FrozenCircuit(cirq.measure(a, key='P'), op1)).with_measurement_key_mapping({ 'B': 'C', 'P': 'Q' }).repeat(2, ['zero', 'one'])) op3 = (cirq.CircuitOperation( cirq.FrozenCircuit(cirq.measure(a, key='X'), op2)).with_measurement_key_mapping({ 'C': 'D', 'X': 'Y' }).repeat(2, ['zero', 'one'])) expected_measurement_keys_in_order = [ 'zero:Y', 'zero:zero:Q', 'zero:zero:zero:D', 'zero:zero:one:D', 'zero:one:Q', 'zero:one:zero:D', 'zero:one:one:D', 'one:Y', 'one:zero:Q', 'one:zero:zero:D', 'one:zero:one:D', 'one:one:Q', 'one:one:zero:D', 'one:one:one:D', ] assert cirq.measurement_keys(op3) == set( expected_measurement_keys_in_order) expected_circuit = cirq.Circuit() for key in expected_measurement_keys_in_order: expected_circuit.append( cirq.measure(a, key=cirq.MeasurementKey.parse_serialized(key))) assert cirq.Circuit(cirq.decompose(op3)) == expected_circuit assert cirq.measurement_keys(expected_circuit) == set( expected_measurement_keys_in_order) # Verify that mapped_circuit gives the same operations. assert op3.mapped_circuit(deep=True) == expected_circuit
def test_with_measurement_key_mapping(): a = cirq.LineQubit(0) op = cirq.measure(a, key='m') remap_op = cirq.with_measurement_key_mapping(op, {'m': 'k'}) assert cirq.measurement_keys(remap_op) == {'k'} assert cirq.with_measurement_key_mapping(op, {'x': 'k'}) is op
def test_measurement_keys(): class Composite(cirq.Gate): def _decompose_(self, qubits): yield cirq.measure(qubits[0], key='inner1') yield cirq.measure(qubits[1], key='inner2') yield cirq.reset(qubits[0]) def num_qubits(self) -> int: return 2 class MeasurementKeysGate(cirq.Gate): def _measurement_key_names_(self): return ['a', 'b'] def num_qubits(self) -> int: return 1 class DeprecatedMagicMethod(cirq.Gate): def _measurement_keys_(self): return ['a', 'b'] def num_qubits(self) -> int: return 1 a, b = cirq.LineQubit.range(2) assert cirq.is_measurement(Composite()) with cirq.testing.assert_deprecated(deadline="v0.13"): assert cirq.measurement_keys(Composite()) == {'inner1', 'inner2'} with cirq.testing.assert_deprecated(deadline="v0.13"): assert cirq.measurement_key_names( DeprecatedMagicMethod()) == {'a', 'b'} with cirq.testing.assert_deprecated(deadline="v0.13"): assert cirq.measurement_key_names( DeprecatedMagicMethod().on(a)) == {'a', 'b'} assert cirq.measurement_key_names(Composite()) == {'inner1', 'inner2'} assert cirq.measurement_key_names(Composite().on( a, b)) == {'inner1', 'inner2'} assert not cirq.is_measurement(Composite(), allow_decompose=False) assert cirq.measurement_key_names(Composite(), allow_decompose=False) == set() assert cirq.measurement_key_names(Composite().on(a, b), allow_decompose=False) == set() assert cirq.measurement_key_names(None) == set() assert cirq.measurement_key_names([]) == set() assert cirq.measurement_key_names(cirq.X) == set() assert cirq.measurement_key_names(cirq.X(a)) == set() assert cirq.measurement_key_names(None, allow_decompose=False) == set() assert cirq.measurement_key_names([], allow_decompose=False) == set() assert cirq.measurement_key_names(cirq.X, allow_decompose=False) == set() assert cirq.measurement_key_names(cirq.measure(a, key='out')) == {'out'} assert cirq.measurement_key_names(cirq.measure(a, key='out'), allow_decompose=False) == {'out'} assert cirq.measurement_key_names( cirq.Circuit(cirq.measure(a, key='a'), cirq.measure(b, key='2'))) == {'a', '2'} assert cirq.measurement_key_names(MeasurementKeysGate()) == {'a', 'b'} assert cirq.measurement_key_names( MeasurementKeysGate().on(a)) == {'a', 'b'}
def test_tagged_measurement(): a = cirq.LineQubit(0) op = cirq.measure(a, key='m').with_tags('tag') remap_op = cirq.with_measurement_key_mapping(op, {'m': 'k'}) assert remap_op.tags == ('tag',) assert cirq.measurement_keys(remap_op) == {'k'} assert cirq.with_measurement_key_mapping(op, {'x': 'k'}) == op
def test_with_key_path(): a = cirq.LineQubit(0) op = cirq.measure(a, key='m') remap_op = cirq.with_key_path(op, ('a', 'b')) assert cirq.measurement_keys(remap_op) == {'a:b:m'} assert cirq.with_key_path(remap_op, ('a', 'b')) is remap_op assert cirq.with_key_path(op, tuple()) is op assert cirq.with_key_path(cirq.X(a), ('a', 'b')) is NotImplemented
def test_tagged_measurement(): assert not cirq.is_measurement(cirq.GlobalPhaseOperation(coefficient=-1.0).with_tags('tag0')) a = cirq.LineQubit(0) op = cirq.measure(a, key='m').with_tags('tag') assert cirq.is_measurement(op) remap_op = cirq.with_measurement_key_mapping(op, {'m': 'k'}) assert remap_op.tags == ('tag',) assert cirq.is_measurement(remap_op) assert cirq.measurement_keys(remap_op) == {'k'} assert cirq.with_measurement_key_mapping(op, {'x': 'k'}) == op
def test_measurement_key_path(): class MultiKeyGate: def __init__(self, keys): self._keys = set( [cirq.MeasurementKey.parse_serialized(key) for key in keys]) def _measurement_keys_(self): return {str(key) for key in self._keys} def _with_key_path_(self, path): return MultiKeyGate( [str(key._with_key_path_(path)) for key in self._keys]) assert cirq.measurement_keys(MultiKeyGate([])) == set() assert cirq.measurement_keys(MultiKeyGate(['a'])) == {'a'} mkg_ab = MultiKeyGate(['a', 'b']) assert cirq.measurement_keys(mkg_ab) == {'a', 'b'} mkg_cd = cirq.with_key_path(mkg_ab, ('c', 'd')) assert cirq.measurement_keys(mkg_cd) == {'c:d:a', 'c:d:b'} assert cirq.with_key_path(cirq.X, ('c', 'd')) is NotImplemented
def test_with_measurement_keys(): a, b = cirq.LineQubit.range(2) circuit = cirq.FrozenCircuit( cirq.X(a), cirq.measure(b, key='mb'), cirq.measure(a, key='ma'), ) op_base = cirq.CircuitOperation(circuit) op_with_keys = op_base.with_measurement_key_mapping({'ma': 'pa', 'x': 'z'}) assert op_with_keys.base_operation() == op_base assert op_with_keys.measurement_key_map == {'ma': 'pa'} assert cirq.measurement_keys(op_with_keys) == {'pa', 'mb'} assert cirq.with_measurement_key_mapping(op_base, {'ma': 'pa'}) == op_with_keys # Two measurement keys cannot be mapped onto the same target string. with pytest.raises(ValueError): _ = op_base.with_measurement_key_mapping({'ma': 'mb'})
def test_measurement_key_mapping(): class MultiKeyGate: def __init__(self, keys): self._keys = set(keys) def _measurement_keys_(self): return self._keys def _with_measurement_key_mapping_(self, key_map): if not all(key in key_map for key in self._keys): raise ValueError('missing keys') return MultiKeyGate([key_map[key] for key in self._keys]) assert cirq.measurement_keys(MultiKeyGate([])) == set() assert cirq.measurement_keys(MultiKeyGate(['a'])) == {'a'} mkg_ab = MultiKeyGate(['a', 'b']) assert cirq.measurement_keys(mkg_ab) == {'a', 'b'} mkg_cd = cirq.with_measurement_key_mapping(mkg_ab, {'a': 'c', 'b': 'd'}) assert cirq.measurement_keys(mkg_cd) == {'c', 'd'} mkg_ac = cirq.with_measurement_key_mapping(mkg_ab, {'a': 'a', 'b': 'c'}) assert cirq.measurement_keys(mkg_ac) == {'a', 'c'} mkg_ba = cirq.with_measurement_key_mapping(mkg_ab, {'a': 'b', 'b': 'a'}) assert cirq.measurement_keys(mkg_ba) == {'a', 'b'} with pytest.raises(ValueError): cirq.with_measurement_key_mapping(mkg_ab, {'a': 'c'}) assert cirq.with_measurement_key_mapping(cirq.X, {'a': 'c'}) is NotImplemented mkg_cdx = cirq.with_measurement_key_mapping(mkg_ab, { 'a': 'c', 'b': 'd', 'x': 'y' }) assert cirq.measurement_keys(mkg_cdx) == {'c', 'd'}
def test_measurement_keys(): class Composite(cirq.Gate): def _decompose_(self, qubits): yield cirq.measure(qubits[0], key='inner1') yield cirq.measure(qubits[1], key='inner2') yield cirq.reset(qubits[0]) def num_qubits(self) -> int: return 2 class MeasurementKeysGate(cirq.Gate): def _measurement_keys_(self): return ['a', 'b'] def num_qubits(self) -> int: return 1 a, b = cirq.LineQubit.range(2) assert cirq.measurement_keys(Composite()) == {'inner1', 'inner2'} assert cirq.measurement_keys(Composite().on(a, b)) == {'inner1', 'inner2'} assert cirq.measurement_keys(Composite(), allow_decompose=False) == set() assert cirq.measurement_keys(Composite().on(a, b), allow_decompose=False) == set() assert cirq.measurement_keys(None) == set() assert cirq.measurement_keys([]) == set() assert cirq.measurement_keys(cirq.X) == set() assert cirq.measurement_keys(cirq.X(a)) == set() assert cirq.measurement_keys(None, allow_decompose=False) == set() assert cirq.measurement_keys([], allow_decompose=False) == set() assert cirq.measurement_keys(cirq.X, allow_decompose=False) == set() assert cirq.measurement_keys(cirq.measure(a, key='out')) == {'out'} assert cirq.measurement_keys(cirq.measure(a, key='out'), allow_decompose=False) == {'out'} assert cirq.measurement_keys( cirq.Circuit(cirq.measure(a, key='a'), cirq.measure(b, key='2'))) == {'a', '2'} assert cirq.measurement_keys(MeasurementKeysGate()) == {'a', 'b'} assert cirq.measurement_keys(MeasurementKeysGate().on(a)) == {'a', 'b'}