Example #1
0
def test_transform_cirq_circuit_to_pyquil_program_with_qubit_id_map(
    bell_circuit_with_qids: Tuple[cirq.Circuit, List[cirq.Qid]],
) -> None:
    """test that a user can transform a `cirq.Circuit` to a `pyquil.Program`
    functionally with explicit physical qubit address mapping.
    """

    bell_circuit, qubits = bell_circuit_with_qids

    qubit_id_map = {
        qubits[1]: "11",
        qubits[0]: "13",
    }
    transformer = transformers.build(qubit_id_map=qubit_id_map)
    program, _ = transformer(circuit=bell_circuit)

    assert H(13) in program.instructions, "bell circuit should include Hadamard"
    assert CNOT(13, 11) in program.instructions, "bell circuit should include CNOT"
    assert (
        DECLARE("m0", memory_size=2) in program.instructions
    ), "executable should declare a read out bit"
    assert (
        MEASURE(13, ("m0", 0)) in program.instructions
    ), "executable should measure the first qubit to the first read out bit"
    assert (
        MEASURE(11, ("m0", 1)) in program.instructions
    ), "executable should measure the second qubit to the second read out bit"
Example #2
0
def test_transform_cirq_circuit_with_explicit_decompose(
    parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Linspace],
) -> None:
    """test that a user add a custom circuit decomposition function"""

    parametric_circuit, param_resolvers = parametric_circuit_with_params
    parametric_circuit.append(cirq.I(cirq.GridQubit(0, 0)))
    parametric_circuit.append(cirq.I(cirq.GridQubit(0, 1)))
    parametric_circuit.append(
        cirq.measure(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), key='m'),
    )
    circuit = cirq.protocols.resolve_parameters(parametric_circuit, param_resolvers[1])

    def decompose_operation(operation: cirq.Operation) -> List[cirq.Operation]:
        operations = [operation]
        if isinstance(operation.gate, cirq.MeasurementGate) and operation.gate.num_qubits() == 1:
            operations.append(cirq.I(operation.qubits[0]))
        return operations

    program, _ = transformers.build(
        decompose_operation=decompose_operation,
    )(circuit=circuit)

    assert (
        RX(np.pi / 2, 2) in program.instructions
    ), "executable should contain an RX(pi) 0 instruction"
    assert I(0) in program.instructions, "executable should contain an I(0) instruction"
    assert I(1) in program.instructions, "executable should contain an I(1) instruction"
    assert I(2) in program.instructions, "executable should contain an I(2) instruction"
    assert DECLARE("m0") in program.instructions, "executable should declare a read out bit"
    assert (
        MEASURE(0, ("m0", 0)) in program.instructions
    ), "executable should measure the read out bit"
Example #3
0
def test_transform_with_post_transformation_hooks(
    bell_circuit_with_qids: Tuple[cirq.Circuit, List[cirq.Qid]],
) -> None:
    """test that a user can transform a `cirq.Circuit` to a `pyquil.Program`
    functionally with explicit physical qubit address mapping.
    """
    bell_circuit, qubits = bell_circuit_with_qids

    def reset_hook(program, measurement_id_map):
        program._instructions.insert(0, Reset())
        return program, measurement_id_map

    reset_hook_spec = create_autospec(
        reset_hook,
        side_effect=reset_hook,
    )

    pragma = Pragma('INTIAL_REWIRING', freeform_string='GREEDY')

    def rewire_hook(program, measurement_id_map):
        program._instructions.insert(0, pragma)
        return program, measurement_id_map

    rewire_hook_spec = create_autospec(
        rewire_hook,
        side_effect=rewire_hook,
    )
    transformer = transformers.build(
        qubits=tuple(qubits),
        post_transformation_hooks=[reset_hook_spec, rewire_hook_spec],
    )
    program, _ = transformer(circuit=bell_circuit)

    assert 1 == reset_hook_spec.call_count
    assert Reset() in program.instructions, "hook should add reset"

    assert 1 == rewire_hook_spec.call_count
    assert pragma in program.instructions, "hook should add pragma"

    assert H(0) in program.instructions, "bell circuit should include Hadamard"
    assert CNOT(0, 1) in program.instructions, "bell circuit should include CNOT"
    assert (
        DECLARE("m0", memory_size=2) in program.instructions
    ), "executable should declare a read out bit"
    assert (
        MEASURE(0, ("m0", 0)) in program.instructions
    ), "executable should measure the first qubit to the first read out bit"
    assert (
        MEASURE(1, ("m0", 1)) in program.instructions
    ), "executable should measure the second qubit to the second read out bit"
Example #4
0
def test_invalid_pyquil_region_measurement(
    mock_qpu_implementer: Any,
    parametric_circuit_with_params: Tuple[cirq.Circuit, cirq.Sweepable],
) -> None:
    """test that executors raise `ValueError` if the measurement_id_map
    does not exist.
    """

    parametric_circuit, sweepable = parametric_circuit_with_params
    repetitions = 2

    param_resolvers = [r for r in cirq.to_resolvers(sweepable)]
    expected_results = [
        np.ones((repetitions, )) * (params["t"] if "t" in params else i)
        for i, params in enumerate(param_resolvers)
    ]
    quantum_computer = mock_qpu_implementer.implement_passive_quantum_computer_with_results(
        expected_results)

    def broken_hook(
            program: Program,
            measurement_id_map: Dict[str,
                                     str]) -> Tuple[Program, Dict[str, str]]:
        return program, {
            cirq_key: f'{cirq_key}-doesnt-exist'
            for cirq_key in measurement_id_map
        }

    transformer = circuit_transformers.build(
        post_transformation_hooks=[broken_hook],  # type: ignore
    )

    with pytest.raises(ValueError):
        _ = executors.with_quilc_compilation_and_cirq_parameter_resolution(
            transformer=transformer,
            quantum_computer=quantum_computer,
            circuit=parametric_circuit,
            resolvers=param_resolvers,  # ignore: type
            repetitions=repetitions,
        )
def test_readout_on_reassigned_qubits(
    circuit_data: Tuple[cirq.Circuit, List[cirq.LineQubit], cirq.Linspace]
) -> None:
    """test that RigettiQCSSampler can properly readout qubits after quilc has
    reassigned those qubits in the compiled native Quil.
    """
    qc = get_qc('9q-square', as_qvm=True)
    circuit, qubits, sweepable = circuit_data

    transformer = circuit_transformers.build(qubit_id_map={
        qubits[0]: '100',
        qubits[1]: '101',
    })
    sampler = RigettiQCSSampler(quantum_computer=qc, transformer=transformer)

    # set the seed so we get a deterministic set of results.
    qvm = cast(QVM, qc.qam)
    qvm.random_seed = 11

    repetitions = 10

    results = sampler.run_sweep(program=circuit,
                                params=sweepable,
                                repetitions=repetitions)
    assert len(sweepable) == len(results)

    for i, result in enumerate(results):
        assert isinstance(result, cirq.study.Result)
        assert sweepable[i] == result.params

        assert 'm' in result.measurements
        assert (repetitions, 2) == result.measurements['m'].shape

        counter = result.histogram(key='m')
        assert 2 == len(counter)
        assert 3 == counter.get(0)
        assert 7 == counter.get(2)
def test_explicit_qubit_id_map(
    mock_qpu_implementer: Any,
    bell_circuit_with_qids: Tuple[cirq.Circuit, List[cirq.LineQubit]],
    result_builder: _ResultBuilder,
) -> None:
    """test that RigettiQCSService and RigettiQCSSampler accept explicit ``qubit_id_map``
    to map ``cirq.Qid`` s to physical qubits.
    """
    bell_circuit, qubits = bell_circuit_with_qids

    qubit_id_map = {qubits[1]: "11", qubits[0]: "13"}
    param_resolvers = [cirq.ParamResolver({})]
    results, quantum_computer, expected_results, param_resolvers = result_builder(
        mock_qpu_implementer,
        bell_circuit,
        param_resolvers,
        transformer=transformers.build(
            qubit_id_map=qubit_id_map),  # type: ignore
    )

    assert len(param_resolvers) == len(
        results), "should return a result for every element in sweepable"

    for i, param_resolver in enumerate(param_resolvers):
        result = results[i]
        assert param_resolver == result.params
        assert np.allclose(
            result.measurements["m"], expected_results[i]
        ), "should return an ordered list of results with correct set of measurements"

    def test_executable(program: Program) -> None:
        assert H(
            13) in program.instructions, "bell circuit should include Hadamard"
        assert CNOT(
            13, 11) in program.instructions, "bell circuit should include CNOT"
        assert (DECLARE("m0", memory_size=2) in program.instructions
                ), "executable should declare a read out bit"
        assert (
            MEASURE(13, ("m0", 0)) in program.instructions
        ), "executable should measure the first qubit to the first read out bit"
        assert (
            MEASURE(11, ("m0", 1)) in program.instructions
        ), "executable should measure the second qubit to the second read out bit"

    param_sweeps = len(param_resolvers)
    assert param_sweeps == quantum_computer.compiler.quil_to_native_quil.call_count  # type: ignore
    for i, call_args in enumerate(
            quantum_computer.compiler.quil_to_native_quil.
            call_args_list  # type: ignore
    ):
        test_executable(call_args[0][0])

    assert (param_sweeps == quantum_computer.compiler.
            native_quil_to_executable.call_count  # type: ignore
            )
    for i, call_args in enumerate(
            quantum_computer.compiler.native_quil_to_executable.
            call_args_list  # type: ignore
    ):
        test_executable(call_args[0][0])

    assert param_sweeps == quantum_computer.qam.run.call_count  # type: ignore
    for i, call_args in enumerate(
            quantum_computer.qam.run.call_args_list):  # type: ignore
        test_executable(call_args[0][0])