コード例 #1
0
def assert_optimizes(before,
                     after,
                     measure_only_moment=True,
                     with_context=False):
    context = cirq.TransformerContext(
        tags_to_ignore=(NO_COMPILE_TAG, )) if with_context else None
    transformed_circuit = cirq.synchronize_terminal_measurements(
        before, context=context, after_other_operations=measure_only_moment)
    cirq.testing.assert_same_circuits(transformed_circuit, after)

    # Test nested circuit ops.
    context = cirq.TransformerContext(
        tags_to_ignore=("ignore", ) +
        tuple([NO_COMPILE_TAG] if with_context else []),
        deep=True)
    c_nested = cirq.Circuit(
        before,
        cirq.CircuitOperation(before.freeze()).repeat(5).with_tags("ignore"),
        before,
        cirq.CircuitOperation(
            before.freeze()).repeat(6).with_tags("preserve_tag"),
        before,
    )
    c_expected = cirq.Circuit(
        before,
        cirq.CircuitOperation(before.freeze()).repeat(5).with_tags("ignore"),
        before,
        cirq.CircuitOperation(
            after.freeze()).repeat(6).with_tags("preserve_tag"),
        after,
    )
    transformed_circuit = cirq.synchronize_terminal_measurements(
        c_nested, context=context, after_other_operations=measure_only_moment)
    cirq.testing.assert_same_circuits(transformed_circuit, c_expected)
コード例 #2
0
def test_transformer_decorator_with_defaults(transformer):
    circuit = cirq.Circuit(cirq.X(cirq.NamedQubit("a")))
    context = cirq.TransformerContext(tags_to_ignore=("tags", "to", "ignore"))
    transformer(circuit)
    transformer.mock.assert_called_with(circuit, cirq.TransformerContext(), 1e-4, CustomArg())
    transformer(circuit, context=context, atol=1e-3)
    transformer.mock.assert_called_with(circuit, context, 1e-3, CustomArg())
    transformer(circuit, context=context, custom_arg=CustomArg(10))
    transformer.mock.assert_called_with(circuit, context, 1e-4, CustomArg(10))
    transformer(circuit, context=context, atol=1e-2, custom_arg=CustomArg(12))
    transformer.mock.assert_called_with(circuit, context, 1e-2, CustomArg(12))
コード例 #3
0
def test_transformer_decorator_adds_support_for_deep(transformer, supports_deep):
    q = cirq.NamedQubit("q")
    c_nested_x = cirq.FrozenCircuit(cirq.X(q))
    c_nested_y = cirq.FrozenCircuit(cirq.Y(q))
    c_nested_xy = cirq.FrozenCircuit(
        cirq.CircuitOperation(c_nested_x).repeat(5).with_tags("ignore"),
        cirq.CircuitOperation(c_nested_y).repeat(7).with_tags("preserve_tag"),
    )
    c_nested_yx = cirq.FrozenCircuit(
        cirq.CircuitOperation(c_nested_y).repeat(7).with_tags("ignore"),
        cirq.CircuitOperation(c_nested_x).repeat(5).with_tags("preserve_tag"),
    )
    c_orig = cirq.Circuit(
        cirq.CircuitOperation(c_nested_xy).repeat(4),
        cirq.CircuitOperation(c_nested_x).repeat(5).with_tags("ignore"),
        cirq.CircuitOperation(c_nested_y).repeat(6),
        cirq.CircuitOperation(c_nested_yx).repeat(7),
    )
    context = cirq.TransformerContext(tags_to_ignore=["ignore"], deep=True)
    transformer(c_orig, context=context)
    expected_calls = [mock.call(c_orig, context)]
    if supports_deep:
        expected_calls = [
            mock.call(c_nested_y, context),  # c_orig --> xy --> y
            mock.call(c_nested_xy, context),  # c_orig --> xy
            mock.call(c_nested_y, context),  # c_orig --> y
            mock.call(c_nested_x, context),  # c_orig --> yx --> x
            mock.call(c_nested_yx, context),  # c_orig --> yx
            mock.call(c_orig, context),  # c_orig
        ]
    transformer.mock.assert_has_calls(expected_calls)
コード例 #4
0
def test_drop_empty_moments():
    q1, q2 = cirq.LineQubit.range(2)
    c_nested = cirq.FrozenCircuit(cirq.Moment(), cirq.Moment(),
                                  cirq.Moment([cirq.CNOT(q1, q2)]),
                                  cirq.Moment())
    c_nested_dropped = cirq.FrozenCircuit(cirq.CNOT(q1, q2))
    c_orig = cirq.Circuit(
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(6).with_tags("nocompile"),
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(5).with_tags("preserve_tag"),
        c_nested,
    )
    c_expected = cirq.Circuit(
        c_nested_dropped,
        cirq.CircuitOperation(c_nested).repeat(6).with_tags("nocompile"),
        c_nested_dropped,
        cirq.CircuitOperation(c_nested_dropped).repeat(5).with_tags(
            "preserve_tag"),
        c_nested_dropped,
    )
    context = cirq.TransformerContext(tags_to_ignore=("nocompile", ),
                                      deep=True)
    cirq.testing.assert_same_circuits(
        cirq.drop_empty_moments(c_orig, context=context), c_expected)
コード例 #5
0
ファイル: align_test.py プロジェクト: dstrain115/Cirq-1
def test_align_left_no_compile_context():
    q1 = cirq.NamedQubit('q1')
    q2 = cirq.NamedQubit('q2')
    cirq.testing.assert_same_circuits(
        cirq.align_left(
            cirq.Circuit(
                [
                    cirq.Moment([cirq.X(q1)]),
                    cirq.Moment([cirq.Y(q1), cirq.X(q2)]),
                    cirq.Moment([cirq.X(q1), cirq.Y(q2).with_tags("nocompile")]),
                    cirq.Moment([cirq.Y(q1)]),
                    cirq.measure(*[q1, q2], key='a'),
                ]
            ),
            context=cirq.TransformerContext(tags_to_ignore=["nocompile"]),
        ),
        cirq.Circuit(
            [
                cirq.Moment([cirq.X(q1), cirq.X(q2)]),
                cirq.Moment([cirq.Y(q1)]),
                cirq.Moment([cirq.X(q1), cirq.Y(q2).with_tags("nocompile")]),
                cirq.Moment([cirq.Y(q1)]),
                cirq.measure(*[q1, q2], key='a'),
            ]
        ),
    )
コード例 #6
0
def test_merge_single_qubit_gates_into_phased_x_z_deep():
    a = cirq.NamedQubit("a")
    c_nested = cirq.FrozenCircuit(cirq.H(a), cirq.Z(a),
                                  cirq.H(a).with_tags("ignore"))
    c_nested_merged = cirq.FrozenCircuit(
        cirq.PhasedXPowGate(phase_exponent=-0.5, exponent=0.5).on(a),
        cirq.H(a).with_tags("ignore"))
    c_orig = cirq.Circuit(
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(4).with_tags("ignore"),
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(5).with_tags("preserve_tags"),
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(6),
    )
    c_expected = cirq.Circuit(
        c_nested_merged,
        cirq.CircuitOperation(c_nested).repeat(4).with_tags("ignore"),
        c_nested_merged,
        cirq.CircuitOperation(c_nested_merged).repeat(5).with_tags(
            "preserve_tags"),
        c_nested_merged,
        cirq.CircuitOperation(c_nested_merged).repeat(6),
    )
    context = cirq.TransformerContext(tags_to_ignore=["ignore"], deep=True)
    c_new = cirq.merge_single_qubit_gates_to_phased_x_and_z(c_orig,
                                                            context=context)
    cirq.testing.assert_same_circuits(c_new, c_expected)
コード例 #7
0
def test_decompose_operations_to_target_gateset_default():
    q = cirq.LineQubit.range(2)
    c_orig = cirq.Circuit(
        cirq.T(q[0]),
        cirq.SWAP(*q),
        cirq.T(q[0]),
        cirq.SWAP(*q).with_tags("ignore"),
        cirq.measure(q[0], key="m"),
        cirq.X(q[1]).with_classical_controls("m"),
        cirq.Moment(cirq.T.on_each(*q)),
        cirq.SWAP(*q),
        cirq.T.on_each(*q),
    )
    cirq.testing.assert_has_diagram(
        c_orig,
        '''
0: ───T───×───T───×['ignore']───M───────T───×───T───
          │       │             ║           │
1: ───────×───────×─────────────╫───X───T───×───T───
                                ║   ║
m: ═════════════════════════════@═══^═══════════════''',
    )
    context = cirq.TransformerContext(tags_to_ignore=("ignore",))
    c_new = _decompose_operations_to_target_gateset(c_orig, context=context)
    cirq.testing.assert_has_diagram(
        c_new,
        '''
0: ───T────────────@───Y^-0.5───@───Y^0.5────@───────────T───×['ignore']───M───────T────────────@───Y^-0.5───@───Y^0.5────@───────────T───
                   │            │            │               │             ║                    │            │            │
1: ───────Y^-0.5───@───Y^0.5────@───Y^-0.5───@───Y^0.5───────×─────────────╫───X───T───Y^-0.5───@───Y^0.5────@───Y^-0.5───@───Y^0.5───T───
                                                                           ║   ║
m: ════════════════════════════════════════════════════════════════════════@═══^══════════════════════════════════════════════════════════
''',
    )
コード例 #8
0
def test_dephase_nocompile_context():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(
        cirq.CircuitOperation(
            cirq.FrozenCircuit(
                cirq.CX(q1, q0),
                cirq.measure(q0, key='a').with_tags('nocompile'),
                cirq.CX(q0, q1),
                cirq.measure(q1, key='b'),
            )))
    dephased = cirq.dephase_measurements(
        circuit,
        context=cirq.TransformerContext(tags_to_ignore=('nocompile', )))
    cirq.testing.assert_same_circuits(
        dephased,
        cirq.Circuit(
            cirq.CircuitOperation(
                cirq.FrozenCircuit(
                    cirq.CX(q1, q0),
                    cirq.measure(q0, key='a').with_tags('nocompile'),
                    cirq.CX(q0, q1),
                    cirq.KrausChannel.from_channel(cirq.phase_damp(1),
                                                   key='b')(q1),
                ))),
    )
コード例 #9
0
def optimized_for_sycamore(
    circuit: cirq.Circuit,
    *,
    qubit_map: Callable[[cirq.Qid], cirq.GridQubit] = lambda e: cast(cirq.GridQubit, e),
    optimizer_type: str = 'sqrt_iswap',
    tolerance: float = 1e-5,
    tabulation_resolution: Optional[float] = None,
) -> cirq.Circuit:
    """Optimizes a circuit for Google devices.

    Uses a set of optimizers that will compile to the proper gateset for the
    device (xmon, sqrt_iswap, or sycamore gates) and then use optimizers to
    compress the gate depth down as much as is easily algorithmically possible
    by merging rotations, ejecting Z gates, etc.

    Args:
        circuit: The circuit to optimize.
        qubit_map: Transforms the qubits (e.g. so that they are GridQubits).
        optimizer_type: A string defining the optimizations to apply.
            Possible values are  'xmon', 'xmon_partial_cz', 'sqrt_iswap',
            'sycamore'
        tolerance: The tolerance passed to the various circuit optimization
            passes.
        tabulation_resolution: If provided, compute a gateset tabulation
            with the specified resolution and use it to approximately
            compile arbitrary two-qubit gates for which an analytic compilation
            is not known.
    Returns:
        The optimized circuit.

    Raises:
        ValueError: If the `optimizer_type` is not a supported type.
    """
    copy = circuit.copy()
    if optimizer_type not in _TARGET_GATESETS:
        raise ValueError(
            f'{optimizer_type} is not an allowed type.  Allowed '
            f'types are: {_TARGET_GATESETS.keys()}'
        )

    tabulation: Optional[cirq.TwoQubitGateTabulation] = None
    if tabulation_resolution is not None:
        tabulation = _gate_product_tabulation_cached(optimizer_type, tabulation_resolution)

    if optimizer_type in _TARGET_GATESETS:
        copy = cirq.optimize_for_target_gateset(
            circuit,
            gateset=_TARGET_GATESETS[optimizer_type](tolerance, tabulation),
            context=cirq.TransformerContext(deep=True),
        )
    copy = cirq.merge_single_qubit_gates_to_phxz(copy, atol=tolerance)
    copy = cirq.eject_phased_paulis(copy, atol=tolerance)
    copy = cirq.eject_z(copy, atol=tolerance)
    copy = cirq.drop_negligible_operations(copy, atol=tolerance)

    ret = cirq.Circuit(
        (op.transform_qubits(qubit_map) for op in copy.all_operations()),
        strategy=cirq.InsertStrategy.EARLIEST,
    )
    return ret
コード例 #10
0
def test_two_qubit_compilation_merge_and_replace_to_target_gateset():
    q = cirq.LineQubit.range(2)
    c_orig = cirq.Circuit(
        cirq.Moment(cirq.Z(q[1]), cirq.X(q[0])),
        cirq.Moment(cirq.CZ(*q).with_tags("no_compile")),
        cirq.Moment(cirq.Z.on_each(*q)),
        cirq.Moment(cirq.X(q[0])),
        cirq.Moment(cirq.CZ(*q)),
        cirq.Moment(cirq.Z.on_each(*q)),
        cirq.Moment(cirq.X(q[0])),
    )
    cirq.testing.assert_has_diagram(
        c_orig,
        '''
0: ───X───@['no_compile']───Z───X───@───Z───X───
          │                         │
1: ───Z───@─────────────────Z───────@───Z───────
''',
    )
    c_new = cirq.optimize_for_target_gateset(
        c_orig,
        gateset=DummyCXTargetGateset(),
        context=cirq.TransformerContext(tags_to_ignore=("no_compile", )),
    )
    cirq.testing.assert_has_diagram(
        c_new,
        '''
0: ───X───@['no_compile']───X───@───Y───@───Z───
          │                     │       │
1: ───Z───@─────────────────X───X───Y───X───Z───
''',
    )
コード例 #11
0
def assert_optimizes(
    before: cirq.Circuit,
    expected: cirq.Circuit,
    eject_parameterized: bool = False,
    *,
    with_context: bool = False,
):
    if cirq.has_unitary(before):
        cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
            before, expected, atol=1e-8)
    context = cirq.TransformerContext(
        tags_to_ignore=("nocompile", )) if with_context else None
    circuit = cirq.eject_z(before,
                           eject_parameterized=eject_parameterized,
                           context=context)
    expected = cirq.eject_z(expected,
                            eject_parameterized=eject_parameterized,
                            context=context)
    cirq.testing.assert_same_circuits(circuit, expected)

    # And it should be idempotent.
    circuit = cirq.eject_z(before,
                           eject_parameterized=eject_parameterized,
                           context=context)
    cirq.testing.assert_same_circuits(circuit, expected)
コード例 #12
0
ファイル: align_test.py プロジェクト: dstrain115/Cirq-1
def test_align_left_deep():
    q1, q2 = cirq.LineQubit.range(2)
    c_nested = cirq.FrozenCircuit(
        [
            cirq.Moment([cirq.X(q1)]),
            cirq.Moment([cirq.Y(q2)]),
            cirq.Moment([cirq.Z(q1), cirq.Y(q2).with_tags("nocompile")]),
            cirq.Moment([cirq.Y(q1)]),
            cirq.measure(q2, key='a'),
            cirq.Z(q1).with_classical_controls('a'),
        ]
    )
    c_nested_aligned = cirq.FrozenCircuit(
        cirq.Moment(cirq.X(q1), cirq.Y(q2)),
        cirq.Moment(cirq.Z(q1)),
        cirq.Moment([cirq.Y(q1), cirq.Y(q2).with_tags("nocompile")]),
        cirq.measure(q2, key='a'),
        cirq.Z(q1).with_classical_controls('a'),
    )
    c_orig = cirq.Circuit(
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(6).with_tags("nocompile"),
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(5).with_tags("preserve_tag"),
    )
    c_expected = cirq.Circuit(
        c_nested_aligned,
        cirq.CircuitOperation(c_nested).repeat(6).with_tags("nocompile"),
        c_nested_aligned,
        cirq.CircuitOperation(c_nested_aligned).repeat(5).with_tags("preserve_tag"),
    )
    context = cirq.TransformerContext(tags_to_ignore=["nocompile"], deep=True)
    cirq.testing.assert_same_circuits(cirq.align_left(c_orig, context=context), c_expected)
コード例 #13
0
def test_transformer_stats_logger_show_levels(capfd):
    q = cirq.LineQubit.range(2)
    context = cirq.TransformerContext(logger=cirq.TransformerLogger())
    initial_circuit = cirq.Circuit(cirq.H.on_each(*q), cirq.CNOT(*q))
    _ = t1(initial_circuit, context=context)
    info_line = 'LogLevel.INFO Second INFO Log of T1'
    debug_line = 'LogLevel.DEBUG First Verbose Log of T1'
    warning_line = 'LogLevel.WARNING Third WARNING Log of T1'

    for level in [LogLevel.ALL, LogLevel.DEBUG]:
        context.logger.show(level)
        out, _ = capfd.readouterr()
        assert all(line in out for line in [info_line, debug_line, warning_line])

    context.logger.show(LogLevel.INFO)
    out, _ = capfd.readouterr()
    assert info_line in out and warning_line in out and debug_line not in out

    context.logger.show(LogLevel.DEBUG)
    out, _ = capfd.readouterr()
    assert info_line in out and warning_line in out and debug_line in out

    context.logger.show(LogLevel.NONE)
    out, _ = capfd.readouterr()
    assert all(line not in out for line in [info_line, debug_line, warning_line])
コード例 #14
0
ファイル: align_test.py プロジェクト: towynlin/Cirq
def test_align_left_subset_of_operations():
    q1 = cirq.NamedQubit('q1')
    q2 = cirq.NamedQubit('q2')
    tag = "op_to_align"
    c_orig = cirq.Circuit([
        cirq.Moment([cirq.Y(q1)]),
        cirq.Moment([cirq.X(q2)]),
        cirq.Moment([cirq.X(q1).with_tags(tag)]),
        cirq.Moment([cirq.Y(q2)]),
        cirq.measure(*[q1, q2], key='a'),
    ])
    c_exp = cirq.Circuit([
        cirq.Moment([cirq.Y(q1)]),
        cirq.Moment([cirq.X(q1).with_tags(tag),
                     cirq.X(q2)]),
        cirq.Moment(),
        cirq.Moment([cirq.Y(q2)]),
        cirq.measure(*[q1, q2], key='a'),
    ])
    cirq.testing.assert_same_circuits(
        cirq.toggle_tags(
            cirq.align_left(
                cirq.toggle_tags(c_orig, [tag]),
                context=cirq.TransformerContext(tags_to_ignore=[tag]),
            ),
            [tag],
        ),
        c_exp,
    )
コード例 #15
0
def test_merge_swap_rzz_and_2q_unitaries():
    q = cirq.LineQubit.range(3)
    c_orig = cirq.Circuit(
        cirq.SWAP(*q[:2]),
        cirq.ZZ(*q[:2]) ** 0.5,
        cirq.ZZ(*q[:2]) ** 0.25,
        cirq.SWAP(*q[:2]),
        cirq.SWAP(q[0], q[2]).with_tags("ignore"),
        cirq.ZZ(q[0], q[2]) ** 0.75,
        cirq.Moment(cirq.H.on_each(*q)),
        cirq.CNOT(q[0], q[2]),
        cirq.CircuitOperation(
            cirq.FrozenCircuit(
                cirq.CNOT(*q[0:2]),
                cirq.H(q[0]),
                cirq.CZ(*q[:2]),
            )
        ),
        cirq.CNOT(*q[1:3]),
        cirq.X(q[0]),
        cirq.ZZ(*q[:2]) ** 0.15,
        cirq.SWAP(*q[:2]),
        cirq.Moment(cirq.X(q[0]).with_tags("ignore"), cirq.Y(q[1])),
        cirq.CNOT(*q[:2]),
        strategy=cirq.InsertStrategy.NEW,
    )
    cirq.testing.assert_has_diagram(
        c_orig,
        '''
                                                                 [ 0: ───@───H───@─── ]
0: ───×───ZZ───────ZZ────────×───×['ignore']───ZZ────────H───@───[       │       │    ]───────X───ZZ────────×───X['ignore']───@───
      │   │        │         │   │             │             │   [ 1: ───X───────@─── ]           │         │                 │
      │   │        │         │   │             │             │   │                                │         │                 │
1: ───×───ZZ^0.5───ZZ^0.25───×───┼─────────────┼─────────H───┼───#2───────────────────────@───────ZZ^0.15───×───Y─────────────X───
                                 │             │             │                            │
2: ──────────────────────────────×─────────────ZZ^0.75───H───X────────────────────────────X───────────────────────────────────────
''',
    )

    c_new = sycamore_gateset.merge_swap_rzz_and_2q_unitaries(
        c_orig,
        context=cirq.TransformerContext(tags_to_ignore=("ignore",)),
        merged_swap_rzz_tag='swap_rzz',
        merged_2q_component_tag='2q_component',
    )
    cirq.testing.assert_has_diagram(
        c_new,
        '''
                                                                                                                                                                [           [ 0: ───@───H───@─── ]        ]
      [ 0: ───×───ZZ─────── ]                   [ 0: ───ZZ────────×─── ]                                 [ 0: ───ZZ────────H───@─── ]                           [ 0: ───────[       │       │    ]───X─── ]                           [ 0: ───ZZ────────×─── ]                                 [ 0: ───────@─── ]
0: ───[       │   │         ]───────────────────[       │         │    ]───────────────────×['ignore']───[       │             │    ]───────────────────────────[           [ 1: ───X───────@─── ]        ]───────────────────────────[       │         │    ]───────────────────X['ignore']───[           │    ]───────────────────
      [ 1: ───×───ZZ^0.5─── ]['swap_rzz']       [ 1: ───ZZ^0.25───×─── ]['swap_rzz']       │             [ 2: ───ZZ^0.75───H───X─── ]['2q_component']           [           │                             ]                           [ 1: ───ZZ^0.15───×─── ]['swap_rzz']                     [ 1: ───Y───X─── ]['2q_component']
      │                                         │                                          │             │                                                      [ 1: ───H───#2─────────────────────────── ]['2q_component']           │                                                        │
      │                                         │                                          │             │                                                      │                                                                     │                                                        │
1: ───#2────────────────────────────────────────#2─────────────────────────────────────────┼─────────────┼──────────────────────────────────────────────────────#2────────────────────────────────────────────────────────────@───────#2───────────────────────────────────────────────────────#2───────────────────────────────────
                                                                                           │             │                                                                                                                    │
2: ────────────────────────────────────────────────────────────────────────────────────────×─────────────#2───────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────────────────────────────────────────────────────────────────────────────────────────────────
''',
    )
コード例 #16
0
 def func(
     circuit: cirq.AbstractCircuit,
     *,
     context: Optional[cirq.TransformerContext] = cirq.TransformerContext(),
     atol: float = 1e-4,
     custom_arg: CustomArg = CustomArg(),
 ) -> cirq.FrozenCircuit:
     my_mock(circuit, context, atol, custom_arg)
     return circuit.freeze()
コード例 #17
0
def assert_optimizes(
    before: cirq.Circuit,
    expected: cirq.Circuit,
    compare_unitaries: bool = True,
    eject_parameterized: bool = False,
    *,
    with_context: bool = False,
):
    context = cirq.TransformerContext(tags_to_ignore=("nocompile",)) if with_context else None
    circuit = cirq.eject_phased_paulis(
        before, eject_parameterized=eject_parameterized, context=context
    )

    # They should have equivalent effects.
    if compare_unitaries:
        if cirq.is_parameterized(circuit):
            for a in (0, 0.1, 0.5, -1.0, np.pi, np.pi / 2):
                params = {'x': a, 'y': a / 2, 'z': -2 * a}
                (
                    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
                        cirq.resolve_parameters(circuit, params),
                        cirq.resolve_parameters(expected, params),
                        1e-8,
                    )
                )
        else:
            (
                cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
                    circuit, expected, 1e-8
                )
            )

    # And match the expected circuit.
    assert circuit == expected, (
        "Circuit wasn't optimized as expected.\n"
        "INPUT:\n"
        "{}\n"
        "\n"
        "EXPECTED OUTPUT:\n"
        "{}\n"
        "\n"
        "ACTUAL OUTPUT:\n"
        "{}\n"
        "\n"
        "EXPECTED OUTPUT (detailed):\n"
        "{!r}\n"
        "\n"
        "ACTUAL OUTPUT (detailed):\n"
        "{!r}"
    ).format(before, expected, circuit, expected, circuit)

    # And it should be idempotent.
    circuit = cirq.eject_phased_paulis(
        circuit, eject_parameterized=eject_parameterized, context=context
    )
    assert circuit == expected
コード例 #18
0
 def __call__(
     self,
     circuit: cirq.AbstractCircuit,
     *,
     context: Optional[cirq.TransformerContext] = cirq.TransformerContext(),
     atol: float = 1e-4,
     custom_arg: CustomArg = CustomArg(),
 ) -> cirq.AbstractCircuit:
     self.mock(circuit, context, atol, custom_arg)
     return circuit[::-1]
コード例 #19
0
def test_respects_nocompile_tags():
    q = cirq.NamedQubit("q")
    c = cirq.Circuit(
        [cirq.Z(q), cirq.H(q), cirq.X(q), cirq.H(q), cirq.X(q).with_tags("nocompile"), cirq.H(q)]
    )
    context = cirq.TransformerContext(tags_to_ignore=("nocompile",))
    c = cirq.drop_empty_moments(cirq.merge_k_qubit_unitaries(c, k=1, context=context))
    assert len(c) == 3
    cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(c[0]), np.eye(2), atol=1e-7)
    assert c[1][q] == cirq.X(q).with_tags("nocompile")
    assert isinstance(c[-1][q].gate, cirq.MatrixGate)
コード例 #20
0
def test_nocompile_context_leaves_invalid_circuit():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(
        cirq.measure(q0, key='a').with_tags('nocompile'),
        cirq.X(q1).with_classical_controls('a'),
        cirq.measure(q1, key='b'),
    )
    with pytest.raises(ValueError, match='Deferred measurement for key=a not found'):
        _ = cirq.defer_measurements(
            circuit, context=cirq.TransformerContext(tags_to_ignore=('nocompile',))
        )
コード例 #21
0
def test_does_not_clear_small_no_compile():
    a = cirq.NamedQubit('a')
    circuit = cirq.Circuit(
        cirq.Moment((cirq.Z(a)**0.000001).with_tags(NO_COMPILE_TAG)))
    cirq.testing.assert_same_circuits(
        cirq.drop_negligible_operations(
            circuit,
            context=cirq.TransformerContext(tags_to_ignore=(NO_COMPILE_TAG, )),
            atol=0.001),
        circuit,
    )
コード例 #22
0
def test_optimize_for_target_gateset():
    q = cirq.LineQubit.range(4)
    c_orig = cirq.Circuit(
        cirq.QuantumFourierTransformGate(4).on(*q),
        cirq.Y(q[0]).with_tags("ignore"),
        cirq.Y(q[1]).with_tags("ignore"),
        cirq.CNOT(*q[2:]).with_tags("ignore"),
        cirq.measure(*q[:2], key="m"),
        cirq.CZ(*q[2:]).with_classical_controls("m"),
        cirq.inverse(cirq.QuantumFourierTransformGate(4).on(*q)),
    )

    cirq.testing.assert_has_diagram(
        c_orig,
        '''
0: ───qft───Y['ignore']───M───────qft^-1───
      │                   ║       │
1: ───#2────Y['ignore']───M───────#2───────
      │                   ║       │
2: ───#3────@['ignore']───╫───@───#3───────
      │     │             ║   ║   │
3: ───#4────X─────────────╫───@───#4───────
                          ║   ║
m: ═══════════════════════@═══^════════════
''',
    )
    gateset = MatrixGateTargetGateset()
    context = cirq.TransformerContext(tags_to_ignore=("ignore", ))
    c_new = cirq.optimize_for_target_gateset(c_orig,
                                             gateset=gateset,
                                             context=context)
    cirq.testing.assert_has_diagram(
        c_new,
        '''
                                         ┌────────┐                         ┌────────┐                 ┌────────┐
0: ───M[1]──────────M[1]──────────────────────M[1]────Y['ignore']───M────────M[1]───────────────────────────M[1]────M[1]───M[1]───
      │             │                         │                     ║        │                              │       │      │
1: ───M[2]───M[1]───┼─────────────M[1]────M[1]┼───────Y['ignore']───M────────┼───M[1]───────────M[1]────M[1]┼───────┼──────M[2]───
             │      │             │       │   │                     ║        │   │              │       │   │       │
2: ──────────M[2]───M[2]───M[1]───┼───────M[2]┼───────@['ignore']───╫───@────┼───M[2]────M[1]───┼───────M[2]┼───────M[2]──────────
                           │      │           │       │             ║   ║    │           │      │           │
3: ────────────────────────M[2]───M[2]────────M[2]────X─────────────╫───@────M[2]────────M[2]───M[2]────────M[2]──────────────────
                                                                    ║   ║
m: ═════════════════════════════════════════════════════════════════@═══^═════════════════════════════════════════════════════════
                                         └────────┘                         └────────┘                 └────────┘
        ''',
    )

    with pytest.raises(ValueError, match="Unable to convert"):
        # Raises an error due to CCO and Measurement gate, which are not part of the gateset.
        _ = cirq.optimize_for_target_gateset(c_orig,
                                             gateset=gateset,
                                             context=context,
                                             ignore_failures=False)
コード例 #23
0
def test_nocompile_context():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(
        cirq.measure(q0, key='a').with_tags('nocompile'),
        cirq.X(q1).with_classical_controls('a').with_tags('nocompile'),
        cirq.measure(q1, key='b'),
    )
    deferred = cirq.defer_measurements(
        circuit,
        context=cirq.TransformerContext(tags_to_ignore=('nocompile', )))
    cirq.testing.assert_same_circuits(deferred, circuit)
コード例 #24
0
def assert_optimizes(before, after, measure_only_moment=True, with_context=False):
    transformed_circuit = (
        cirq.synchronize_terminal_measurements(before, after_other_operations=measure_only_moment)
        if not with_context
        else cirq.synchronize_terminal_measurements(
            before,
            context=cirq.TransformerContext(tags_to_ignore=(NO_COMPILE_TAG,)),
            after_other_operations=measure_only_moment,
        )
    )
    cirq.testing.assert_same_circuits(transformed_circuit, after)
コード例 #25
0
def test_merge_single_qubit_moments_to_phxz_deep():
    q = cirq.LineQubit.range(3)
    x_t_y = cirq.FrozenCircuit(
        cirq.Moment(cirq.X.on_each(*q[:2])),
        cirq.Moment(cirq.T.on_each(*q[1:])),
        cirq.Moment(cirq.Y.on_each(*q[:2])),
    )
    c_nested = cirq.FrozenCircuit(
        x_t_y,
        cirq.Moment(cirq.CZ(*q[:2]), cirq.Y(q[2])),
        x_t_y,
        cirq.Moment(cirq.Y(q[0]).with_tags("ignore"), cirq.Z.on_each(*q[1:])),
    )

    c_nested_merged = cirq.FrozenCircuit(
        [
            _phxz(-0.25, 0.0, 0.75)(q[1]),
            _phxz(0.25, 0.0, 0.25)(q[2]),
            _phxz(-0.5, 0.0, -1.0)(q[0])
        ],
        [cirq.CZ(q[0], q[1]), cirq.Y(q[2])],
        [
            _phxz(-0.25, 0.0, 0.75)(q[1]),
            _phxz(0.25, 0.0, 0.25)(q[2]),
            _phxz(-0.5, 0.0, -1.0)(q[0])
        ],
        cirq.Moment(cirq.Y(q[0]).with_tags("ignore"), cirq.Z.on_each(*q[1:])),
    )
    c_orig = cirq.Circuit(
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(4).with_tags("ignore"),
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(5).with_tags("preserve_tags"),
        c_nested,
        cirq.CircuitOperation(c_nested).repeat(6),
    )
    c_expected = cirq.Circuit(
        c_nested_merged,
        cirq.CircuitOperation(c_nested).repeat(4).with_tags("ignore"),
        c_nested_merged,
        cirq.CircuitOperation(c_nested_merged).repeat(5).with_tags(
            "preserve_tags"),
        c_nested_merged,
        cirq.CircuitOperation(c_nested_merged).repeat(6),
    )
    context = cirq.TransformerContext(tags_to_ignore=["ignore"], deep=True)
    c_new = cirq.merge_single_qubit_moments_to_phxz(c_orig, context=context)
    cirq.testing.assert_allclose_up_to_global_phase(c_new.unitary(),
                                                    c_expected.unitary(),
                                                    atol=1e-7)
コード例 #26
0
def test_decompose_operations_raises_on_stuck():
    c_orig = cirq.Circuit(cirq.X(cirq.NamedQubit("q")).with_tags("ignore"))
    gateset = cirq.Gateset(cirq.Y)
    with pytest.raises(ValueError, match="Unable to convert"):
        _ = _decompose_operations_to_target_gateset(c_orig, gateset=gateset, ignore_failures=False)

    # Gates marked with a no-compile tag are completely ignored.
    c_new = _decompose_operations_to_target_gateset(
        c_orig,
        context=cirq.TransformerContext(tags_to_ignore=("ignore",)),
        gateset=gateset,
        ignore_failures=False,
    )
    cirq.testing.assert_same_circuits(c_orig, c_new)
コード例 #27
0
def test_optimize_for_target_gateset_deep():
    q0, q1 = cirq.LineQubit.range(2)
    c_nested = cirq.FrozenCircuit(cirq.CX(q0, q1))
    c_orig = cirq.Circuit(
        cirq.CircuitOperation(
            cirq.FrozenCircuit(
                cirq.H(q0),
                cirq.CircuitOperation(c_nested).repeat(3))).repeat(5))
    c_expected = cirq.Circuit(
        cirq.CircuitOperation(
            cirq.FrozenCircuit(
                cirq.single_qubit_matrix_to_phxz(cirq.unitary(
                    cirq.H(q0))).on(q0),
                cirq.CircuitOperation(
                    cirq.FrozenCircuit(
                        cirq.MatrixGate(c_nested.unitary(qubit_order=[q0, q1]),
                                        name="M").on(q0, q1))).repeat(3),
            )).repeat(5))
    gateset = MatrixGateTargetGateset()
    context = cirq.TransformerContext(deep=True)
    c_new = cirq.optimize_for_target_gateset(c_orig,
                                             gateset=gateset,
                                             context=context)
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        c_new, c_expected)
    cirq.testing.assert_has_diagram(
        c_orig,
        '''
      [           [ 0: ───@─── ]             ]
      [ 0: ───H───[       │    ]──────────── ]
0: ───[           [ 1: ───X─── ](loops=3)    ]────────────
      [           │                          ]
      [ 1: ───────#2──────────────────────── ](loops=5)
      │
1: ───#2──────────────────────────────────────────────────
''',
    )
    cirq.testing.assert_has_diagram(
        c_new,
        '''
      [                                 [ 0: ───M[1]─── ]             ]
      [ 0: ───PhXZ(a=-0.5,x=0.5,z=-1)───[       │       ]──────────── ]
0: ───[                                 [ 1: ───M[2]─── ](loops=3)    ]────────────
      [                                 │                             ]
      [ 1: ─────────────────────────────#2─────────────────────────── ](loops=5)
      │
1: ───#2───────────────────────────────────────────────────────────────────────────
''',
    )
コード例 #28
0
def test_drop_terminal_nonterminal_error():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(
        cirq.CircuitOperation(
            cirq.FrozenCircuit(cirq.measure(q0, q1, key='a~b', invert_mask=[0, 1]), cirq.CX(q0, q1))
        )
    )
    with pytest.raises(ValueError, match='Circuit contains a non-terminal measurement'):
        _ = cirq.drop_terminal_measurements(circuit)

    with pytest.raises(ValueError, match='Context has `deep=False`'):
        _ = cirq.drop_terminal_measurements(circuit, context=cirq.TransformerContext(deep=False))

    with pytest.raises(ValueError, match='Context has `deep=False`'):
        _ = cirq.drop_terminal_measurements(circuit, context=None)
コード例 #29
0
def test_optimize_for_target_gateset_default():
    q = cirq.LineQubit.range(2)
    c_orig = cirq.Circuit(cirq.T(q[0]), cirq.SWAP(*q), cirq.T(q[0]),
                          cirq.SWAP(*q).with_tags("ignore"))
    context = cirq.TransformerContext(tags_to_ignore=("ignore", ))
    c_new = cirq.optimize_for_target_gateset(c_orig, context=context)
    cirq.testing.assert_has_diagram(
        c_new,
        '''
0: ───T────────────@───Y^-0.5───@───Y^0.5────@───────────T───×['ignore']───
                   │            │            │               │
1: ───────Y^-0.5───@───Y^0.5────@───Y^-0.5───@───Y^0.5───────×─────────────
''',
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        c_orig, c_new, atol=1e-6)
コード例 #30
0
def test_merge_swap_rzz_and_2q_unitaries_deep():
    q = cirq.LineQubit.range(3)
    swap_rzz = cirq.FrozenCircuit(cirq.SWAP(*q[:2]), cirq.ZZ(*q[:2]) ** 0.5)
    rzz_swap = cirq.FrozenCircuit(cirq.ZZ(*q[1:]) ** 0.25, cirq.SWAP(*q[1:]))
    x_cnot_x = cirq.FrozenCircuit(cirq.X(q[0]), cirq.CNOT(*q[:2]), cirq.X(q[0]))
    x_cz_x = cirq.FrozenCircuit(cirq.X(q[2]), cirq.CZ(*q[1:]), cirq.X(q[2]))
    c_orig = cirq.Circuit(
        cirq.CircuitOperation(swap_rzz).repeat(3).with_tags("ignore"),
        cirq.CircuitOperation(rzz_swap).repeat(5).with_tags("preserve_tag"),
        cirq.CircuitOperation(x_cnot_x).repeat(7).with_tags("ignore"),
        cirq.CircuitOperation(x_cz_x).repeat(9).with_tags("preserve_tag"),
        cirq.CircuitOperation(
            cirq.FrozenCircuit(
                [swap_rzz, rzz_swap, x_cnot_x, x_cz_x],
                cirq.Moment(cirq.Y(qq).with_tags("ignore") for qq in q),
            )
        ),
    )
    t_swap_rzz = "_merged_swap_rzz_tag"
    t_2q_cmp = "_merged_2q_unitaries_component"
    t_all = "_intermediate_result_tag_apply_to_all"

    def _wrap_cop(c: cirq.FrozenCircuit, *tags) -> cirq.FrozenCircuit:
        return cirq.FrozenCircuit(cirq.CircuitOperation(c).with_tags(*tags, t_all))

    c_expected = cirq.Circuit(
        cirq.CircuitOperation(swap_rzz).repeat(3).with_tags("ignore"),
        cirq.CircuitOperation(_wrap_cop(rzz_swap, t_swap_rzz)).repeat(5).with_tags("preserve_tag"),
        cirq.CircuitOperation(x_cnot_x).repeat(7).with_tags("ignore"),
        cirq.CircuitOperation(_wrap_cop(x_cz_x, t_2q_cmp)).repeat(9).with_tags("preserve_tag"),
        cirq.CircuitOperation(
            cirq.FrozenCircuit(
                [_wrap_cop(swap_rzz, t_swap_rzz), _wrap_cop(rzz_swap, t_swap_rzz)],
                [_wrap_cop(x_cnot_x, t_2q_cmp), _wrap_cop(x_cz_x, t_2q_cmp)],
                cirq.Moment(cirq.Y(qq).with_tags("ignore") for qq in q),
            )
        ),
    )
    context = cirq.TransformerContext(tags_to_ignore=["ignore"], deep=True)
    c_new = sycamore_gateset.merge_swap_rzz_and_2q_unitaries(
        c_orig,
        context=context,
        merged_swap_rzz_tag=t_swap_rzz,
        merged_2q_component_tag=t_2q_cmp,
        intermediate_result_tag=t_all,
    )
    cirq.testing.assert_same_circuits(cirq.drop_empty_moments(c_new, context=context), c_expected)