def test_readout_symmetrization(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) noise_model = decoherence_noise_with_asymmetric_ro(quantum_processor.to_compiler_isa()) qc = QuantumComputer( name="testy!", qam=QVM(client_configuration=client_configuration, noise_model=noise_model), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) prog = Program( Declare("ro", "BIT", 2), I(0), X(1), MEASURE(0, MemoryReference("ro", 0)), MEASURE(1, MemoryReference("ro", 1)), ) prog.wrap_in_numshots_loop(1000) bs1 = qc.run(prog) avg0_us = np.mean(bs1[:, 0]) avg1_us = 1 - np.mean(bs1[:, 1]) diff_us = avg1_us - avg0_us assert diff_us > 0.03 prog = Program( I(0), X(1), ) bs2 = qc.run_symmetrized_readout(prog, 1000) avg0_s = np.mean(bs2[:, 0]) avg1_s = 1 - np.mean(bs2[:, 1]) diff_s = avg1_s - avg0_s assert diff_s < 0.05
def test_measure_bitstrings(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(2)) dummy_compiler = DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration) qc_pyqvm = QuantumComputer(name="testy!", qam=PyQVM(n_qubits=2), compiler=dummy_compiler) qc_forest = QuantumComputer( name="testy!", qam=QVM(client_configuration=client_configuration, gate_noise=(0.00, 0.00, 0.00)), compiler=dummy_compiler, ) prog = Program(I(0), I(1)) meas_qubits = [0, 1] sym_progs, flip_array = _symmetrization(prog, meas_qubits, symm_type=-1) results = _measure_bitstrings(qc_pyqvm, sym_progs, meas_qubits, num_shots=1) # test with pyQVM answer = [ np.array([[0, 0]]), np.array([[0, 1]]), np.array([[1, 0]]), np.array([[1, 1]]) ] assert all([np.allclose(x, y) for x, y in zip(results, answer)]) # test with regular QVM results = _measure_bitstrings(qc_forest, sym_progs, meas_qubits, num_shots=1) assert all([np.allclose(x, y) for x, y in zip(results, answer)])
def _get_qvm_with_topology( *, client_configuration: QCSClientConfiguration, name: str, topology: nx.Graph, noisy: bool, qvm_type: str, compiler_timeout: float, execution_timeout: float, ) -> QuantumComputer: """Construct a QVM with the provided topology. :param client_configuration: Client configuration. :param name: A name for your quantum computer. This field does not affect behavior of the constructed QuantumComputer. :param topology: A graph representing the desired qubit connectivity. :param noisy: Whether to include a generic noise model. If you want more control over the noise model, please construct your own :py:class:`NoiseModel` and use :py:func:`_get_qvm_qc` instead of this function. :param qvm_type: The type of QVM. Either 'qvm' or 'pyqvm'. :param compiler_timeout: Time limit for compilation requests, in seconds. :param execution_timeout: Time limit for execution requests, in seconds. :return: A pre-configured QuantumComputer """ # Note to developers: consider making this function public and advertising it. quantum_processor = NxQuantumProcessor(topology=topology) if noisy: noise_model: Optional[ NoiseModel] = decoherence_noise_with_asymmetric_ro( isa=quantum_processor.to_compiler_isa()) else: noise_model = None return _get_qvm_qc( client_configuration=client_configuration, name=name, qvm_type=qvm_type, quantum_processor=quantum_processor, noise_model=noise_model, compiler_timeout=compiler_timeout, execution_timeout=execution_timeout, )
def test_run_pyqvm_noisy(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=3, post_gate_noise_probabilities={"relaxation": 0.01}), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) prog = Program(H(0), CNOT(0, 1), CNOT(1, 2)) ro = prog.declare("ro", "BIT", 3) for q in range(3): prog += MEASURE(q, ro[q]) bitstrings = qc.run(prog.wrap_in_numshots_loop(1000)) assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert 0 < np.mean(parity) < 0.15
def test_run_with_bad_parameters(client_configuration: QCSClientConfiguration, param): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=QVM(client_configuration=client_configuration), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) executable = Program( Declare(name="theta", memory_type="REAL"), Declare(name="ro", memory_type="BIT"), RX(MemoryReference("theta"), 0), MEASURE(0, MemoryReference("ro")), ).wrap_in_numshots_loop(1000) with pytest.raises(TypeError, match=r"Parameter must be"): executable.write_memory(region_name="theta", value=param)
def test_run_pyqvm_noiseless(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=3), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) prog = Program(H(0), CNOT(0, 1), CNOT(1, 2)) ro = prog.declare("ro", "BIT", 3) for q in range(3): prog += MEASURE(q, ro[q]) result = qc.run(prog.wrap_in_numshots_loop(1000)) bitstrings = result.readout_data.get("ro") assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert np.mean(parity) == 0
def test_run_with_parameters(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=QVM(client_configuration=client_configuration), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) bitstrings = qc.run( executable=Program( Declare(name="theta", memory_type="REAL"), Declare(name="ro", memory_type="BIT"), RX(MemoryReference("theta"), 0), MEASURE(0, MemoryReference("ro")), ).wrap_in_numshots_loop(1000), memory_map={"theta": [np.pi]}, ) assert bitstrings.shape == (1000, 1) assert all([bit == 1 for bit in bitstrings])
def test_reset(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=QVM(client_configuration=client_configuration), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) p = Program( Declare(name="theta", memory_type="REAL"), Declare(name="ro", memory_type="BIT"), RX(MemoryReference("theta"), 0), MEASURE(0, MemoryReference("ro")), ).wrap_in_numshots_loop(10) p.write_memory(region_name="theta", value=np.pi) result = qc.qam.run(p) aref = ParameterAref(name="theta", index=0) assert p._memory.values[aref] == np.pi assert result.readout_data["ro"].shape == (10, 1) assert all([bit == 1 for bit in result.readout_data["ro"]])
def test_for_negative_probabilities( client_configuration: QCSClientConfiguration): # trivial program to do state tomography on prog = Program(I(0)).wrap_in_numshots_loop(3000) # make an Experiment expt_settings = [ ExperimentSetting(zeros_state([0]), pt) for pt in [sI(0), sX(0), sY(0), sZ(0)] ] experiment_1q = Experiment(settings=expt_settings, program=prog) # make a quantum computer object device = NxQuantumProcessor(nx.complete_graph(1)) qc_density = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator), compiler=DummyCompiler(quantum_processor=device, client_configuration=client_configuration), ) # initialize with a pure state initial_density = np.array([[1.0, 0.0], [0.0, 0.0]]) qc_density.qam.wf_simulator.density = initial_density try: list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q)) except ValueError as e: # the error is from np.random.choice by way of self.rs.choice in ReferenceDensitySimulator assert str(e) != "probabilities are not non-negative" # initialize with a mixed state initial_density = np.array([[0.9, 0.0], [0.0, 0.1]]) qc_density.qam.wf_simulator.density = initial_density try: list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q)) except ValueError as e: assert str(e) != "probabilities are not non-negative"
def test_run(client_configuration: QCSClientConfiguration): quantum_processor = NxQuantumProcessor(nx.complete_graph(3)) qc = QuantumComputer( name="testy!", qam=QVM(client_configuration=client_configuration, gate_noise=(0.01, 0.01, 0.01)), compiler=DummyCompiler(quantum_processor=quantum_processor, client_configuration=client_configuration), ) bitstrings = qc.run( Program( Declare("ro", "BIT", 3), H(0), CNOT(0, 1), CNOT(1, 2), MEASURE(0, MemoryReference("ro", 0)), MEASURE(1, MemoryReference("ro", 1)), MEASURE(2, MemoryReference("ro", 2)), ).wrap_in_numshots_loop(1000) ) assert bitstrings.shape == (1000, 3) parity = np.sum(bitstrings, axis=1) % 3 assert 0 < np.mean(parity) < 0.15
def test_set_initial_state(client_configuration: QCSClientConfiguration): # That is test the assigned state matrix in ReferenceDensitySimulator is persistent between # rounds of run. rho1 = np.array([[0.0, 0.0], [0.0, 1.0]]) # run prog prog = Program(I(0)) ro = prog.declare("ro", "BIT", 1) prog += MEASURE(0, ro[0]) # make a quantum computer object device = NxQuantumProcessor(nx.complete_graph(1)) qc_density = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator), compiler=DummyCompiler(quantum_processor=device, client_configuration=client_configuration), ) qc_density.qam.wf_simulator.set_initial_state(rho1).reset() out = [qc_density.run(prog).readout_data['ro'] for _ in range(0, 4)] ans = [np.array([[1]]), np.array([[1]]), np.array([[1]]), np.array([[1]])] assert all([np.allclose(x, y) for x, y in zip(out, ans)]) # Run and measure style progRAM = prog.copy().wrap_in_numshots_loop(10) results = qc_density.run(qc_density.compile(progRAM)) ans = {0: np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])} assert np.allclose(results.readout_data['ro'][0], ans[0]) # test reverting ReferenceDensitySimulator to the default state rho0 = np.array([[1.0, 0.0], [0.0, 0.0]]) qc_density.qam.wf_simulator.set_initial_state(rho0).reset() assert np.allclose(qc_density.qam.wf_simulator.density, rho0) assert np.allclose(qc_density.qam.wf_simulator.initial_density, rho0)
def quantum_processor() -> AbstractQuantumProcessor: topology = nx.convert_node_labels_to_integers(nx.grid_2d_graph(3, 3)) return NxQuantumProcessor(topology=topology)