Ejemplo n.º 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)
Ejemplo n.º 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}'
Ejemplo n.º 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)
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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)
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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)
Ejemplo n.º 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
Ejemplo n.º 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)
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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}'
Ejemplo n.º 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
Ejemplo n.º 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),
    ))
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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}'
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 25
0
def assert_optimizes(before, after):
    opt = cirq.DropEmptyMoments()
    opt.optimize_circuit(before)
    assert before == after
Ejemplo n.º 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