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"
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"
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"
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])