예제 #1
0
def test_validate_well_structured():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit([
        cirq.Moment([cirq.PhasedXPowGate(phase_exponent=0).on(q0)]),
        cirq.Moment([
            cirq.ZPowGate(exponent=0.5).on(q0),
        ]),
        cirq.Moment([cg.SYC(q0, q1)]),
        cirq.measure(q0, q1, key='z'),
    ])
    validate_well_structured(circuit)
def test_zz_as_syc_2():
    q1, q2 = cirq.LineQubit.range(2)
    zz = cirq.ZZPowGate(exponent=0.123)
    circuit = zz_as_syc(zz.exponent * np.pi / 2, q1, q2)
    assert len(circuit) == 3 * 2 + 2
    validate_well_structured(circuit)
    cirq.testing.assert_has_diagram(circuit, """
0: ───PhX(1)^0.483───Z^(1/12)─────SYC────────────────────────SYC───PhX(0.917)^0.483───Z^(1/12)───
                                  │                          │
1: ───PhX(-0.583)────Z^(-11/12)───SYC───PhX(0)^0.873───Z^0───SYC───PhX(0)─────────────T^-1───────
""")
예제 #3
0
def test_validate_well_structured_non_term_meas():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit([
        cirq.Moment([cirq.PhasedXPowGate(phase_exponent=0).on(q0)]),
        cirq.Moment([
            cirq.PhasedXPowGate(phase_exponent=0.5).on(q0), ]),
        cirq.measure(q0, q1, key='z'),
        cirq.Moment([cg.SYC(q0, q1)]),
    ])

    with pytest.raises(BadlyStructuredCircuitError) as e:
        validate_well_structured(circuit)
    assert e.match('Measurements must be terminal')
예제 #4
0
def test_validate_well_structured_too_many():
    q0, q1 = cirq.LineQubit.range(2)
    circuit = cirq.Circuit([
        cirq.Moment([cirq.PhasedXPowGate(phase_exponent=0).on(q0)]),
        cirq.Moment([
            cirq.PhasedXPowGate(phase_exponent=0.5).on(q0), ]),
        cirq.Moment([cg.SYC(q0, q1)]),
        cirq.measure(q0, q1, key='z'),
    ])

    with pytest.raises(BadlyStructuredCircuitError) as e:
        validate_well_structured(circuit)
    assert e.match('Too many PhX')
예제 #5
0
def test_compile_to_non_negligible():
    qubits = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(ZZSwap(zz_exponent=0.123).on(*qubits))
    c1 = compile_to_syc(circuit)
    validate_well_structured(c1)
    assert len(c1) == 3 * 3 + 2

    c2 = compile_to_non_negligible(c1)
    assert c1 != c2
    # KAK instability (https://github.com/quantumlib/Cirq/issues/1647)
    # means the first layer of PhX gets removed on mpharrigan's machine
    # but not in docker / in CI.
    assert len(c2) in [9, 10]
예제 #6
0
def test_get_compiled_grid_model_circuit():
    problem = _random_grid_model(2, 2, np.random.RandomState(0))
    qubits = cirq.GridQubit.rect(2, 2)
    circuit, final_qubits = get_compiled_hardware_grid_circuit(
        problem, qubits,
        gammas=[np.pi / 2, np.pi / 4],
        betas=[np.pi / 2, np.pi / 4],
    )
    assert final_qubits == qubits
    validate_well_structured(circuit)

    rc = get_routed_hardware_grid_circuit(
        problem.graph, qubits, problem.coordinates,
        gammas=[np.pi / 2, np.pi / 4],
        betas=[np.pi / 2, np.pi / 4],
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(
        rc + cirq.measure(*qubits), circuit, atol=1e-5)
예제 #7
0
def test_compile_to_syc(p):
    problem = nx.complete_graph(n=5)
    problem = random_plus_minus_1_weights(problem)
    qubits = cirq.LineQubit.range(5)
    c1 = cirq.Circuit(cirq.H.on_each(qubits), [[
        ProblemUnitary(problem, gamma=np.random.random()).on(*qubits),
        DriverUnitary(5, beta=np.random.random()).on(*qubits)
    ] for _ in range(p)])
    c2 = compile_problem_unitary_to_swap_network(c1)
    c3 = compile_swap_network_to_zzswap(c2)
    c4 = compile_driver_unitary_to_rx(c3)
    c5 = compile_to_syc(c4)
    validate_well_structured(c5, allow_terminal_permutations=True)

    np.testing.assert_allclose(c1.unitary(), c2.unitary())
    np.testing.assert_allclose(c1.unitary(), c3.unitary())
    np.testing.assert_allclose(c1.unitary(), c4.unitary())
    # Single qubit throws out global phase
    cirq.testing.assert_allclose_up_to_global_phase(c1.unitary(),
                                                    c5.unitary(),
                                                    atol=1e-8)
def test_measure_with_final_permutation(p):
    problem = nx.complete_graph(n=5)
    problem = random_plus_minus_1_weights(problem)
    qubits = cirq.LineQubit.range(5)
    c1 = cirq.Circuit(
        cirq.H.on_each(qubits),
        [
            [
                ProblemUnitary(problem, gamma=np.random.random()).on(*qubits),
                DriverUnitary(5, beta=np.random.random()).on(*qubits)
            ]
            for _ in range(p)
        ]
    )
    c2 = compile_problem_unitary_to_swap_network(c1)
    c3 = compile_swap_network_to_zzswap(c2)
    c4 = compile_driver_unitary_to_rx(c3)
    c5 = compile_to_syc(c4)
    validate_well_structured(c5, allow_terminal_permutations=True)
    c6, final_qubits = measure_with_final_permutation(c5, qubits)
    validate_well_structured(c6, allow_terminal_permutations=False)

    if p % 2 == 1:
        assert final_qubits == qubits[::-1]
    else:
        assert final_qubits == qubits

    permutation = []
    for q in qubits:
        permutation.append(final_qubits.index(q))
    c1_prime = (
            c1
            + QuirkQubitPermutationGate('', '', permutation).on(*qubits)
            + cirq.measure(*qubits, key='z')
    )
    cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(c1_prime, c6, atol=1e-5)
예제 #9
0
def measure_with_final_permutation(
        circuit: cirq.Circuit,
        qubits: List[cirq.Qid],
        *,
        mutate=False) -> Tuple[cirq.Circuit, List[cirq.Qid]]:
    """Apply a measurement gate at the end of a circuit and classically
    permute qubit indices.

    If the circuit contains a permutation gate at its end, the input
    argument `qubits` will be permuted and returned as the second return
    value.


    Args:
        circuit: The circuit
        qubits: Which qubits to measure
        mutate: By default, return a copy of the circuit. Otherwise,
            mutate in place.

    Returns:
        circuit: The output circuit with measurement
        final_qubits: The input list of qubits permuted according to the
            final permutation gate.
    """
    if mutate:
        c2 = circuit
    else:
        c2 = circuit.copy()

    mom_classes, stats = validate_well_structured(
        c2, allow_terminal_permutations=True)
    if stats.has_measurement:
        raise ValueError("Circuit already has measurements")

    mapping = {}
    if stats.has_permutation:
        for op in c2.moments[-1].operations:
            if cirq.op_gate_of_type(op, QuirkQubitPermutationGate):
                # do something with it
                permuted_qs = op.qubits
                gate = op.gate  # type: QuirkQubitPermutationGate
                for i, q in enumerate(permuted_qs):
                    mapping[q] = permuted_qs[gate.permutation[i]]
        c2.moments.pop(-1)

    final_qubits = [mapping.get(q, q) for q in qubits]
    c2.append(cirq.measure(*qubits, key='z'))
    return c2, final_qubits
예제 #10
0
def test_structured():
    qubits = cirq.LineQubit.range(2)
    circuit = cirq.Circuit(ZZSwap(zz_exponent=0.123).on(*qubits))
    circuit = compile_to_syc(circuit)
    validate_well_structured(circuit)