Пример #1
0
def assert_optimizes(
    before: cirq.Circuit,
    expected: cirq.Circuit,
    pre_opts: Iterable[cirq.OptimizationPass] = (cg.ConvertToXmonGates(
        ignore_failures=True), ),
    post_opts: Iterable[cirq.OptimizationPass] = (cg.ConvertToXmonGates(
        ignore_failures=True), cirq.DropEmptyMoments())):
    opt = cg.EjectZ()

    if cirq.has_unitary(before):
        cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
            before, expected, atol=1e-8)

    circuit = before.copy()
    for pre in pre_opts:
        pre.optimize_circuit(circuit)
    opt.optimize_circuit(circuit)
    for post in post_opts:
        post.optimize_circuit(circuit)
        post.optimize_circuit(expected)

    cirq.testing.assert_same_circuits(circuit, expected)

    # And it should be idempotent.
    opt.optimize_circuit(circuit)
    cirq.testing.assert_same_circuits(circuit, expected)
Пример #2
0
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit, **kwargs):
    """Check that optimizing the circuit ``before`` produces the circuit ``expected``.

    The optimized circuit is cleaned up with follow up optimizations to make the
    comparison more robust to extra moments or extra gates nearly equal to
    identity that don't matter.

    Args:
        before: The input circuit to optimize.
        expected: The expected result of optimization to compare against.
        kwargs: Any extra arguments to pass to the
            ``MergeInteractionsToSqrtIswap`` constructor.
    """
    actual = before.copy()
    opt = cirq.MergeInteractionsToSqrtIswap(**kwargs)
    opt.optimize_circuit(actual)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations: List[Callable[[cirq.Circuit], None]] = [
        cirq.merge_single_qubit_gates_into_phased_x_z,
        cirq.EjectPhasedPaulis().optimize_circuit,
        cirq.EjectZ().optimize_circuit,
        cirq.DropNegligible().optimize_circuit,
        cirq.DropEmptyMoments().optimize_circuit,
    ]
    for post in followup_optimizations:
        post(actual)
        post(expected)

    assert actual == expected, f'ACTUAL {actual} : EXPECTED {expected}'
Пример #3
0
def test_post_clean_up():
    class Marker(cirq.TwoQubitGate):
        pass

    a, b = cirq.LineQubit.range(2)
    c_orig = cirq.Circuit.from_ops(
        cirq.CZ(a, b),
        cirq.CZ(a, b),
        cirq.CZ(a, b),
        cirq.CZ(a, b),
        cirq.CZ(a, b),
    )
    circuit = cirq.Circuit(c_orig)

    def clean_up(operations):
        yield Marker()(a, b)
        yield operations
        yield Marker()(a, b)

    optimizer = cirq.MergeInteractions(allow_partial_czs=False,
                                       post_clean_up=clean_up)
    optimizer.optimize_circuit(circuit)
    cirq.DropEmptyMoments().optimize_circuit(circuit)

    assert isinstance(circuit[0].operations[0].gate, Marker)
    assert isinstance(circuit[-1].operations[0].gate, Marker)

    u_before = c_orig.unitary()
    u_after = circuit[1:-1].unitary()
    cirq.testing.assert_allclose_up_to_global_phase(u_before,
                                                    u_after,
                                                    atol=1e-8)
Пример #4
0
def assert_optimizes(
    before: cirq.Circuit,
    expected: cirq.Circuit,
    pre_opts: Iterable[cirq.OptimizationPass] = (cg.ConvertToXmonGates(
        ignore_failures=True), ),
    post_opts: Iterable[cirq.OptimizationPass] = (cg.ConvertToXmonGates(
        ignore_failures=True), cirq.DropEmptyMoments())):
    opt = cg.EjectZ()

    circuit = before.copy()
    for pre in pre_opts:
        pre.optimize_circuit(circuit)
    opt.optimize_circuit(circuit)
    for post in post_opts:
        post.optimize_circuit(circuit)
        post.optimize_circuit(expected)

    if circuit != expected:
        # coverage: ignore
        print("BEFORE")
        print(before)
        print("AFTER")
        print(circuit)
        print("EXPECTED")
        print(expected)
    assert circuit == expected

    # And it should be idempotent.
    opt.optimize_circuit(circuit)
    assert circuit == expected
Пример #5
0
def assert_optimizes(
        before: cirq.Circuit,
        expected: cirq.Circuit,
        optimizer: Optional[Callable[[cirq.Circuit], None]] = None):
    if optimizer is None:
        optimizer = cirq.MergeSingleQubitGates().optimize_circuit
    optimizer(before)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations = [
        cirq.DropNegligible(),
        cirq.DropEmptyMoments()
    ]
    for post in followup_optimizations:
        post(before)  # type: ignore #  error: "object" not callable
        post(expected)  # type: ignore #  error: "object" not callable

    try:
        assert before == expected
    except AssertionError:  # coverage: ignore
        # coverage: ignore
        print("BEFORE")
        print(before)
        print("EXPECTED")
        print(expected)
        raise
Пример #6
0
def test_tensor_density_matrix_gridqubit():
    qubits = cirq.GridQubit.rect(2, 2)
    circuit = cirq.testing.random_circuit(qubits=qubits, n_moments=10, op_density=0.8)
    cirq.DropEmptyMoments().optimize_circuit(circuit)
    noise_model = cirq.ConstantQubitNoiseModel(cirq.DepolarizingChannel(p=1e-3))
    circuit = cirq.Circuit(noise_model.noisy_moments(circuit.moments, qubits))
    rho1 = cirq.final_density_matrix(circuit, dtype=np.complex128)
    rho2 = ccq.tensor_density_matrix(circuit, qubits)
    np.testing.assert_allclose(rho1, rho2, atol=1e-8)
Пример #7
0
def assert_equal_mod_empty(expected, actual):
    drop_empty = cirq.DropEmptyMoments()
    drop_empty.optimize_circuit(actual)
    if expected != actual:
        # coverage: ignore
        print('EXPECTED')
        print(expected)
        print('ACTUAL')
        print(actual)
    assert expected == actual
Пример #8
0
def optimize(c):
        cirq.ConvertToCzAndSingleGates().optimize_circuit(circuit=c)
        cirq.MergeSingleQubitGates().optimize_circuit(circuit=c)
        cirq.EjectZ().optimize_circuit(circuit=c)
        cirq.EjectPhasedPaulis().optimize_circuit(circuit=c)
        cirq.MergeSingleQubitGates().optimize_circuit(circuit=c)
        cirq.DropNegligible().optimize_circuit(circuit=c)
        cirq.DropEmptyMoments().optimize_circuit(circuit=c)
        c2=cirq.Circuit()
        for g in c:
                for g2 in g:
        #               print(g2)
                        c2.append(g2,strategy=cirq.InsertStrategy.EARLIEST)
        return c2
Пример #9
0
def test_swap():
    a, b = cirq.LineQubit.range(2)
    original = cirq.Circuit.from_ops([cirq.Rz(.123).on(a), cirq.SWAP(a, b)])
    optimized = original.copy()

    cirq.EjectZ().optimize_circuit(optimized)
    cirq.DropEmptyMoments().optimize_circuit(optimized)

    assert optimized[0].operations == (cirq.SWAP(a, b),)
    # Note: EjectZ drops `global_phase` from Rz turning it into a Z
    assert optimized[1].operations == (cirq.Z(b)**(.123 / np.pi),)
    cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(original),
                                                    cirq.unitary(optimized),
                                                    atol=1e-8)
Пример #10
0
def test_drop_negligible():
    q0, = _make_qubits(1)
    sym = cirq.Symbol('a')
    circuit = cirq.Circuit.from_ops(
        PauliStringPhasor(cirq.PauliString({q0: cirq.Z}))**0.25,
        PauliStringPhasor(cirq.PauliString({q0: cirq.Z}))**1e-10,
        PauliStringPhasor(cirq.PauliString({q0: cirq.Z}))**sym,
    )
    expected = cirq.Circuit.from_ops(
        PauliStringPhasor(cirq.PauliString({q0: cirq.Z}))**0.25,
        PauliStringPhasor(cirq.PauliString({q0: cirq.Z}))**sym,
    )
    cirq.DropNegligible().optimize_circuit(circuit)
    cirq.DropEmptyMoments().optimize_circuit(circuit)
    assert circuit == expected
Пример #11
0
def assert_optimizes(
    before: cirq.Circuit,
    expected: cirq.Circuit,
    optimizer: Optional[Callable[[cirq.Circuit], None]] = None,
):
    if optimizer is None:
        optimizer = cirq.MergeSingleQubitGates().optimize_circuit
    optimizer(before)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations = [cirq.DropNegligible(), cirq.DropEmptyMoments()]
    for post in followup_optimizations:
        post(before)  # type: ignore #  error: "object" not callable
        post(expected)  # type: ignore #  error: "object" not callable

    assert before == expected, 'BEFORE:\n{}\nEXPECTED:\n{}'.format(before, expected)
Пример #12
0
def compile_to_syc(circuit: cirq.Circuit, *, mutate=False) -> cirq.Circuit:
    """Compile a QAOA circuit to SYC gates.

    Args:
        circuit: The circuit
        mutate: By default, return a copy of the circuit. Otherwise,
            mutate in place.
    """
    if mutate:
        c2 = circuit
    else:
        c2 = circuit.copy()
    _TwoQubitOperationsAsSYC().optimize_circuit(c2)
    _SingleQubitGates().optimize_circuit(c2)
    cirq.DropEmptyMoments().optimize_circuit(c2)
    return c2
Пример #13
0
def assert_optimizes(before, after, optimizer=None):
    if optimizer is None:
        optimizer = cirq.google.MergeRotations()
    optimizer.optimize_circuit(before)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations = [cirq.DropNegligible(), cirq.DropEmptyMoments()]
    for post in followup_optimizations:
        post.optimize_circuit(before)
        post.optimize_circuit(after)

    if before != after:
        # coverage: ignore
        print("before:", before)
        print("after:", after)
    assert before == after
Пример #14
0
def compile_single_qubit_gates(circuit: cirq.Circuit,
                               *,
                               mutate=False) -> cirq.Circuit:
    """Compile single qubit gates to constant-depth PhX and Z gates

    Args:
        circuit: The circuit
        mutate: By default, return a copy of the circuit. Otherwise,
            mutate in place.
    """
    if mutate:
        c2 = circuit
    else:
        c2 = circuit.copy()
    _SingleQubitGates().optimize_circuit(c2)
    cirq.DropEmptyMoments().optimize_circuit(c2)
    return c2
Пример #15
0
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit):
    actual = cirq.Circuit(before)
    opt = cirq.MergeInteractions()
    opt.optimize_circuit(actual)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations: List[Callable[[cirq.Circuit], None]] = [
        cirq.merge_single_qubit_gates_into_phased_x_z,
        cirq.EjectPhasedPaulis().optimize_circuit,
        cirq.EjectZ().optimize_circuit,
        cirq.DropNegligible().optimize_circuit,
        cirq.DropEmptyMoments().optimize_circuit,
    ]
    for post in followup_optimizations:
        post(actual)
        post(expected)

    assert actual == expected, f'ACTUAL {actual} : EXPECTED {expected}'
Пример #16
0
def compile_out_virtual_z(circuit: cirq.Circuit,
                          *,
                          mutate=False) -> cirq.Circuit:
    """Eject Z gates from the circuit.

    This is a wrapper around cirq.EjectZ()

    Args:
        circuit: The circuit
        mutate: By default, return a copy of the circuit. Otherwise,
            mutate in place.
    """
    if mutate:
        c2 = circuit
    else:
        c2 = circuit.copy()

    cirq.EjectZ().optimize_circuit(c2)
    cirq.DropEmptyMoments().optimize_circuit(c2)
    return c2
Пример #17
0
def test_rewrite():
    q0 = cirq.LineQubit(0)
    q1 = cirq.LineQubit(1)
    circuit = cirq.Circuit.from_ops(
        cirq.X(q0),
        cirq.X(q1),
        cirq.Y(q0),
        cirq.CZ(q0, q1),
        cirq.Y(q1),
    )
    cirq.MergeSingleQubitGates(
        rewriter=lambda ops: cirq.H(ops[0].qubits[0])
    ).optimize_circuit(circuit)
    cirq.DropEmptyMoments().optimize_circuit(circuit)

    cirq.testing.assert_same_circuits(circuit, cirq.Circuit.from_ops(
        cirq.H(q0),
        cirq.H(q1),
        cirq.CZ(q0, q1),
        cirq.H(q1),
    ))
Пример #18
0
def assert_optimizes(before: cirq.Circuit,
                     expected: cirq.Circuit,
                     optimizer: cirq.OptimizationPass = None):
    if optimizer is None:
        optimizer = cirq.MergeSingleQubitGates()
    optimizer.optimize_circuit(before)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations = [cirq.DropNegligible(), cirq.DropEmptyMoments()]
    for post in followup_optimizations:
        post.optimize_circuit(before)
        post.optimize_circuit(expected)

    try:
        assert before == expected
    except AssertionError:  # coverage: ignore
        # coverage: ignore
        print("BEFORE")
        print(before)
        print("EXPECTED")
        print(expected)
        raise
Пример #19
0
def compile_to_non_negligible(circuit: cirq.Circuit,
                              *,
                              tolerance=1e-5,
                              mutate=False) -> cirq.Circuit:
    """Remove negligible gates from the circuit.

    This is a wrapper around cirq.DropNegligible(tolerance)

    Args:
        circuit: The circuit
        tolerance: Gates with trace distance below this value will be
            considered negligible.
        mutate: By default, return a copy of the circuit. Otherwise,
            mutate in place.
    """
    if mutate:
        c2 = circuit
    else:
        c2 = circuit.copy()

    cirq.DropNegligible(tolerance=tolerance).optimize_circuit(c2)
    cirq.DropEmptyMoments().optimize_circuit(c2)
    return c2
Пример #20
0
def simplify_expectation_value_circuit(circuit_sand: cirq.Circuit):
    """For low weight operators on low-degree circuits, we can simplify
    the circuit representation of an expectation value.

    In particular, this should be used on `circuit_for_expectation_value`
    circuits. It will merge single- and two-qubit gates from the "forwards"
    and "backwards" parts of the circuit outside of the operator's lightcone.

    This might be too slow in practice and you can just use quimb to simplify
    things for you.
    """
    n_op = sum(1 for _ in circuit_sand.all_operations())
    while True:
        MergeNQubitGates(n_qubits=1).optimize_circuit(circuit_sand)
        cirq.DropNegligible(tolerance=1e-6).optimize_circuit(circuit_sand)
        MergeNQubitGates(n_qubits=2).optimize_circuit(circuit_sand)
        cirq.DropNegligible(tolerance=1e-6)
        cirq.DropEmptyMoments().optimize_circuit(circuit_sand)
        new_n_op = sum(1 for _ in circuit_sand.all_operations())

        if new_n_op < n_op:
            n_op = new_n_op
        else:
            return
Пример #21
0
def assert_optimizes(before: cirq.Circuit, expected: cirq.Circuit):
    actual = cirq.Circuit(before)
    opt = cirq.MergeInteractions()
    opt.optimize_circuit(actual)

    # Ignore differences that would be caught by follow-up optimizations.
    followup_optimizations = [
        cg.MergeRotations(),
        cg.EjectFullW(),
        cg.EjectZ(),
        cirq.DropNegligible(),
        cirq.DropEmptyMoments()
    ]
    for post in followup_optimizations:
        post.optimize_circuit(actual)
        post.optimize_circuit(expected)

    if actual != expected:
        # coverage: ignore
        print('ACTUAL')
        print(actual)
        print('EXPECTED')
        print(expected)
    assert actual == expected
Пример #22
0
def assert_equal_mod_empty(expected, actual):
    drop_empty = cirq.DropEmptyMoments()
    drop_empty.optimize_circuit(actual)

    assert expected == actual, f'EXPECTED {expected} : ACTUAL {actual}'
Пример #23
0
def assert_optimizes(before, after):
    with cirq.testing.assert_deprecated("Use cirq.drop_empty_moments",
                                        deadline='v1.0'):
        opt = cirq.DropEmptyMoments()
        opt.optimize_circuit(before)
        assert before == after
Пример #24
0
def zz_as_syc(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.Circuit:
    """Return an Exp[i theta ZZ] circuit with two SYC gates."""
    swz = cirq.Circuit(rzz(theta, q0, q1))
    _SingleQubitGates().optimize_circuit(swz)
    cirq.DropEmptyMoments().optimize_circuit(swz)
    return swz
Пример #25
0
def assert_optimizes(before, after):
    opt = cirq.DropEmptyMoments()
    opt.optimize_circuit(before)
    assert before == after
Пример #26
0
def zzswap_as_syc(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.Circuit:
    """Return a composite Exp[i theta ZZ] SWAP circuit with three SYC gates."""
    swz = cirq.Circuit(swap_rzz(theta, q0, q1))
    _SingleQubitGates().optimize_circuit(swz)
    cirq.DropEmptyMoments().optimize_circuit(swz)
    return swz