예제 #1
0
def test_scope_extern_wrapping_with_non_repeating_subcircuits():
    def wrap(*ops):
        return cirq.CircuitOperation(cirq.FrozenCircuit(*ops))

    def wrap_frozen(*ops):
        return cirq.FrozenCircuit(wrap(*ops))

    q = cirq.LineQubit(0)
    inner = wrap_frozen(wrap(cirq.measure(q, key='a')),
                        wrap(cirq.X(q).with_classical_controls('b')))
    middle = wrap_frozen(
        wrap(cirq.measure(q, key=cirq.MeasurementKey('b'))),
        wrap(cirq.CircuitOperation(inner, repetitions=2)),
    )
    outer_subcircuit = cirq.CircuitOperation(middle, repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['0:b', '0:b', '1:b', '1:b']
    assert not cirq.control_keys(outer_subcircuit)
    assert not cirq.control_keys(circuit)
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ─────M───M('0:0:a')───X───M('0:1:a')───X───M───M('1:0:a')───X───M('1:1:a')───X───
        ║                ║                ║   ║                ║                ║
0:b: ═══@════════════════^════════════════^═══╬════════════════╬════════════════╬═══
                                              ║                ║                ║
1:b: ═════════════════════════════════════════@════════════════^════════════════^═══
""",
        use_unicode_characters=True,
    )
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
예제 #2
0
def test_control_key():
    class Named:
        def _control_keys_(self):
            return frozenset([cirq.MeasurementKey('key')])

    class NoImpl:
        def _control_keys_(self):
            return NotImplemented

    assert cirq.control_keys(Named()) == {cirq.MeasurementKey('key')}
    assert not cirq.control_keys(NoImpl())
    assert not cirq.control_keys(5)
예제 #3
0
def test_parameterized_repeat_side_effects_when_not_using_rep_ids():
    q = cirq.LineQubit(0)
    op = cirq.CircuitOperation(
        cirq.FrozenCircuit(
            cirq.X(q).with_classical_controls('c'), cirq.measure(q, key='m')),
        repetitions=sympy.Symbol('a'),
        use_repetition_ids=False,
    )
    assert cirq.control_keys(op) == {cirq.MeasurementKey('c')}
    assert cirq.parameter_names(op.with_params({'a': 1})) == {'a'}
    assert set(map(str, cirq.measurement_key_objs(op))) == {'m'}
    assert cirq.measurement_key_names(op) == {'m'}
    assert cirq.measurement_key_names(
        cirq.with_measurement_key_mapping(op, {'m': 'm2'})) == {'m2'}
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        op.mapped_circuit()
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.decompose(op)
    with pytest.raises(ValueError,
                       match='repetition ids with parameterized repetitions'):
        op.with_repetition_ids(['x', 'y'])
    with pytest.raises(ValueError,
                       match='repetition ids with parameterized repetitions'):
        op.repeat(repetition_ids=['x', 'y'])
예제 #4
0
def test_condition_stacking():
    q0 = cirq.LineQubit(0)
    op = cirq.X(q0).with_classical_controls('a').with_tags(
        't').with_classical_controls('b')
    assert set(map(str, cirq.control_keys(op))) == {'a', 'b'}
    assert set(map(str, op.classical_controls)) == {'a', 'b'}
    assert not op.tags
예제 #5
0
def test_control_key_enumerable_deprecated():
    class Deprecated:
        def _control_keys_(self):
            return [cirq.MeasurementKey('key')]

    with cirq.testing.assert_deprecated('frozenset', deadline='v0.16'):
        assert cirq.control_keys(Deprecated()) == {cirq.MeasurementKey('key')}
예제 #6
0
def test_condition_removal():
    q0 = cirq.LineQubit(0)
    op = (cirq.X(q0).with_tags('t1').with_classical_controls('a').with_tags(
        't2').with_classical_controls('b'))
    op = op.without_classical_controls()
    assert not cirq.control_keys(op)
    assert not op.classical_controls
    assert not op.tags
예제 #7
0
def test_scope_extern_mismatch():
    q = cirq.LineQubit(0)
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls('b'),
    )
    middle = cirq.Circuit(
        cirq.measure(q, key=cirq.MeasurementKey('b', ('0', ))),
        cirq.CircuitOperation(inner.freeze(), repetitions=2),
    )
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['b', 'b', 'b', 'b']
    assert cirq.control_keys(outer_subcircuit) == {cirq.MeasurementKey('b')}
    assert cirq.control_keys(circuit) == {cirq.MeasurementKey('b')}
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [                  [ 0: ───M('a')───X─── ]             ]
      [ 0: ───M('0:b')───[                ║    ]──────────── ]
0: ───[                  [ b: ════════════^═══ ](loops=2)    ]────────────
      [                  ║                                   ]
      [ b: ══════════════╩══════════════════════════════════ ](loops=2)
      ║
b: ═══╩═══════════════════════════════════════════════════════════════════
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───M('0:0:b')───M('0:0:a')───X───M('0:1:a')───X───M('1:0:b')───M('1:0:a')───X───M('1:1:a')───X───
                                ║                ║                             ║                ║
b: ═════════════════════════════^════════════════^═════════════════════════════^════════════════^═══
""",
        use_unicode_characters=True,
    )
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
예제 #8
0
def test_scope_local():
    q = cirq.LineQubit(0)
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls('a'),
    )
    middle = cirq.Circuit(cirq.CircuitOperation(inner.freeze(), repetitions=2))
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['0:0:a', '0:1:a', '1:0:a', '1:1:a']
    assert not cirq.control_keys(outer_subcircuit)
    assert not cirq.control_keys(circuit)
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [       [ 0: ───M───X─── ]             ]
0: ───[ 0: ───[       ║   ║    ]──────────── ]────────────
      [       [ a: ═══@═══^═══ ](loops=2)    ](loops=2)
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───────M───X───M───X───M───X───M───X───
          ║   ║   ║   ║   ║   ║   ║   ║
0:0:a: ═══@═══^═══╬═══╬═══╬═══╬═══╬═══╬═══
                  ║   ║   ║   ║   ║   ║
0:1:a: ═══════════@═══^═══╬═══╬═══╬═══╬═══
                          ║   ║   ║   ║
1:0:a: ═══════════════════@═══^═══╬═══╬═══
                                  ║   ║
1:1:a: ═══════════════════════════@═══^═══
""",
        use_unicode_characters=True,
    )
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
예제 #9
0
def test_scope_flatten_both():
    q = cirq.LineQubit(0)
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls('a'),
    )
    middle = cirq.Circuit(
        cirq.CircuitOperation(inner.freeze(),
                              repetitions=2,
                              use_repetition_ids=False))
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(),
                                             repetitions=2,
                                             use_repetition_ids=False)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_control_keys = [
        str(condition) for op in circuit.all_operations()
        for condition in cirq.control_keys(op)
    ]
    assert internal_control_keys == ['a', 'a', 'a', 'a']
    assert not cirq.control_keys(outer_subcircuit)
    assert not cirq.control_keys(circuit)
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [       [ 0: ───M───X─── ]                         ]
0: ───[ 0: ───[       ║   ║    ]──────────────────────── ]────────────────────────
      [       [ a: ═══@═══^═══ ](loops=2, no_rep_ids)    ](loops=2, no_rep_ids)
""",
        use_unicode_characters=True,
    )
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───M───X───M───X───M───X───M───X───
      ║   ║   ║   ║   ║   ║   ║   ║
a: ═══@═══^═══@═══^═══@═══^═══@═══^═══
""",
        use_unicode_characters=True,
    )
def test_repeat_until_sympy(sim):
    q1, q2 = cirq.LineQubit.range(2)
    circuitop = cirq.CircuitOperation(
        cirq.FrozenCircuit(cirq.X(q2), cirq.measure(q2, key='b')),
        use_repetition_ids=False,
        repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol('a'), sympy.Symbol('b'))),
    )
    c = cirq.Circuit(cirq.measure(q1, key='a'), circuitop)
    # Validate commutation
    assert len(c) == 2
    assert cirq.control_keys(circuitop) == {cirq.MeasurementKey('a')}
    measurements = sim.run(c).records['b'][0]
    assert len(measurements) == 2
    assert measurements[0] == (1,)
    assert measurements[1] == (0,)
예제 #11
0
def test_control_keys_caching():
    q0, q1, q2, q3 = cirq.LineQubit.range(4)
    m = cirq.Moment(cirq.X(q0).with_classical_controls('foo'))
    assert m._control_keys is None
    keys = cirq.control_keys(m)
    assert m._control_keys == keys

    # Make sure it gets updated when adding an operation.
    m = m.with_operation(cirq.X(q1).with_classical_controls('bar'))
    assert m._control_keys == {
        cirq.MeasurementKey(name='bar'),
        cirq.MeasurementKey(name='foo')
    }
    # Or multiple operations.
    m = m.with_operations(
        cirq.X(q2).with_classical_controls('doh'),
        cirq.X(q3).with_classical_controls('baz'))
    assert m._control_keys == {
        cirq.MeasurementKey(name='bar'),
        cirq.MeasurementKey(name='foo'),
        cirq.MeasurementKey(name='doh'),
        cirq.MeasurementKey(name='baz'),
    }
예제 #12
0
def test_parameterized_repeat_side_effects():
    q = cirq.LineQubit(0)
    op = cirq.CircuitOperation(
        cirq.FrozenCircuit(
            cirq.X(q).with_classical_controls('c'), cirq.measure(q, key='m')),
        repetitions=sympy.Symbol('a'),
    )

    # Control keys can be calculated because they only "lift" if there's a matching
    # measurement, in which case they're not returned here.
    assert cirq.control_keys(op) == {cirq.MeasurementKey('c')}

    # "local" params do not bind to the repetition param.
    assert cirq.parameter_names(op.with_params({'a': 1})) == {'a'}

    # Check errors that require unrolling the circuit.
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.measurement_key_objs(op)
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.measurement_key_names(op)
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        op.mapped_circuit()
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.decompose(op)

    # Not compatible with repetition ids
    with pytest.raises(ValueError,
                       match='repetition ids with parameterized repetitions'):
        op.with_repetition_ids(['x', 'y'])
    with pytest.raises(ValueError,
                       match='repetition ids with parameterized repetitions'):
        op.repeat(repetition_ids=['x', 'y'])

    # TODO(daxfohl): This should work, but likely requires a new protocol that returns *just* the
    # name of the measurement keys. (measurement_key_names returns the full serialized string).
    with pytest.raises(
            ValueError,
            match='Cannot unroll circuit due to nondeterministic repetitions'):
        cirq.with_measurement_key_mapping(op, {'m': 'm2'})

    # Everything should work once resolved
    op = cirq.resolve_parameters(op, {'a': 2})
    assert set(map(str, cirq.measurement_key_objs(op))) == {'0:m', '1:m'}
    assert op.mapped_circuit() == cirq.Circuit(
        cirq.X(q).with_classical_controls('c'),
        cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('0:m')),
        cirq.X(q).with_classical_controls('c'),
        cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('1:m')),
    )
    assert cirq.decompose(op) == cirq.decompose(
        cirq.Circuit(
            cirq.X(q).with_classical_controls('c'),
            cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('0:m')),
            cirq.X(q).with_classical_controls('c'),
            cirq.measure(q, key=cirq.MeasurementKey.parse_serialized('1:m')),
        ))
예제 #13
0
def test_sympy_scope():
    q = cirq.LineQubit(0)
    a, b, c, d = sympy.symbols('a b c d')
    inner = cirq.Circuit(
        cirq.measure(q, key='a'),
        cirq.X(q).with_classical_controls(a & b).with_classical_controls(c
                                                                         | d),
    )
    middle = cirq.Circuit(
        cirq.measure(q, key='b'),
        cirq.measure(q, key=cirq.MeasurementKey('c', ('0', ))),
        cirq.CircuitOperation(inner.freeze(), repetitions=2),
    )
    outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
    circuit = outer_subcircuit.mapped_circuit(deep=True)
    internal_controls = [
        str(k) for op in circuit.all_operations()
        for k in cirq.control_keys(op)
    ]
    assert set(internal_controls) == {
        '0:0:a', '0:1:a', '1:0:a', '1:1:a', '0:b', '1:b', 'c', 'd'
    }
    assert cirq.control_keys(outer_subcircuit) == {'c', 'd'}
    assert cirq.control_keys(circuit) == {'c', 'd'}
    assert circuit == cirq.Circuit(cirq.decompose(outer_subcircuit))
    cirq.testing.assert_has_diagram(
        cirq.Circuit(outer_subcircuit),
        """
      [                      [ 0: ───M───X(conditions=[c | d, a & b])─── ]             ]
      [                      [       ║   ║                               ]             ]
      [                      [ a: ═══@═══^══════════════════════════════ ]             ]
      [                      [           ║                               ]             ]
      [ 0: ───M───M('0:c')───[ b: ═══════^══════════════════════════════ ]──────────── ]
      [       ║              [           ║                               ]             ]
      [       ║              [ c: ═══════^══════════════════════════════ ]             ]
0: ───[       ║              [           ║                               ]             ]────────────
      [       ║              [ d: ═══════^══════════════════════════════ ](loops=2)    ]
      [       ║              ║                                                         ]
      [ b: ═══@══════════════╬════════════════════════════════════════════════════════ ]
      [                      ║                                                         ]
      [ c: ══════════════════╬════════════════════════════════════════════════════════ ]
      [                      ║                                                         ]
      [ d: ══════════════════╩════════════════════════════════════════════════════════ ](loops=2)
      ║
c: ═══╬═════════════════════════════════════════════════════════════════════════════════════════════
      ║
d: ═══╩═════════════════════════════════════════════════════════════════════════════════════════════
""",
        use_unicode_characters=True,
    )

    # pylint: disable=line-too-long
    cirq.testing.assert_has_diagram(
        circuit,
        """
0: ───────M───M('0:0:c')───M───X(conditions=[c | d, 0:0:a & 0:b])───M───X(conditions=[c | d, 0:1:a & 0:b])───M───M('1:0:c')───M───X(conditions=[c | d, 1:0:a & 1:b])───M───X(conditions=[c | d, 1:1:a & 1:b])───
          ║                ║   ║                                    ║   ║                                    ║                ║   ║                                    ║   ║
0:0:a: ═══╬════════════════@═══^════════════════════════════════════╬═══╬════════════════════════════════════╬════════════════╬═══╬════════════════════════════════════╬═══╬════════════════════════════════════
          ║                    ║                                    ║   ║                                    ║                ║   ║                                    ║   ║
0:1:a: ═══╬════════════════════╬════════════════════════════════════@═══^════════════════════════════════════╬════════════════╬═══╬════════════════════════════════════╬═══╬════════════════════════════════════
          ║                    ║                                        ║                                    ║                ║   ║                                    ║   ║
0:b: ═════@════════════════════^════════════════════════════════════════^════════════════════════════════════╬════════════════╬═══╬════════════════════════════════════╬═══╬════════════════════════════════════
                               ║                                        ║                                    ║                ║   ║                                    ║   ║
1:0:a: ════════════════════════╬════════════════════════════════════════╬════════════════════════════════════╬════════════════@═══^════════════════════════════════════╬═══╬════════════════════════════════════
                               ║                                        ║                                    ║                    ║                                    ║   ║
1:1:a: ════════════════════════╬════════════════════════════════════════╬════════════════════════════════════╬════════════════════╬════════════════════════════════════@═══^════════════════════════════════════
                               ║                                        ║                                    ║                    ║                                        ║
1:b: ══════════════════════════╬════════════════════════════════════════╬════════════════════════════════════@════════════════════^════════════════════════════════════════^════════════════════════════════════
                               ║                                        ║                                                         ║                                        ║
c: ════════════════════════════^════════════════════════════════════════^═════════════════════════════════════════════════════════^════════════════════════════════════════^════════════════════════════════════
                               ║                                        ║                                                         ║                                        ║
d: ════════════════════════════^════════════════════════════════════════^═════════════════════════════════════════════════════════^════════════════════════════════════════^════════════════════════════════════
""",
        use_unicode_characters=True,
    )
예제 #14
0
def test_sympy_path_prefix():
    q = cirq.LineQubit(0)
    op = cirq.X(q).with_classical_controls(sympy.Symbol('b'))
    prefixed = cirq.with_key_path_prefix(op, ('0', ))
    assert cirq.control_keys(prefixed) == {'0:b'}