def test_custom_usual_topologies(self) -> None: """ Tests Sabre on common circuit for some usual custom topologies for different number of qubits. """ for nbqbit in range(2 * min_nbqbit, max_nbqbit): nbqbit_circuit = rd.randint(nbqbit // 2, nbqbit) circuit = generate_random_circuit(nbqbit_circuit) observable = generate_random_observable(nbqbit_circuit) qpu_1 = PyLinalg() measure_1 = qpu_1.submit( circuit.to_job("OBS", observable=observable, nbshots=5)) for topology in generate_custom_topologies(nbqbit): qpu_2 = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) measure_2 = qpu_2.submit( circuit.to_job("OBS", observable=observable, nbshots=5)) check_measures_equality(measure_1, measure_2) if nbqbit % 2 == 0: topology = Topology.from_nx( nx.grid_2d_graph(nbqbit // 2, nbqbit // 2)) qpu_2 = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) measure_2 = qpu_2.submit( circuit.to_job("OBS", observable=observable, nbshots=5)) check_measures_equality(measure_1, measure_2)
def test_custom_usual_topologies(self) -> None: """ Tests Sabre on common circuit for some usual custom topologies for different number of qubits. """ for nbqbit in range(2 * min_nbqbit, max_nbqbit): nbqbit_circuit = rd.randint(nbqbit // 2, nbqbit) circuit = generate_random_circuit(nbqbit_circuit) nb_measured_qubits = rd.randint(1, nbqbit_circuit) measured_qubits = rd.sample(range(nbqbit_circuit), nb_measured_qubits) measured_qubits.sort() qpu_1 = PyLinalg() result_1 = qpu_1.submit(circuit.to_job(qubits=measured_qubits)) for topology in generate_custom_topologies(nbqbit): qpu_2 = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) result_2 = qpu_2.submit(circuit.to_job(qubits=measured_qubits)) check_results_equality(result_1, result_2, amplitude=False) if nbqbit % 2 == 0: topology = Topology.from_nx( nx.grid_2d_graph(nbqbit // 2, nbqbit // 2)) qpu_2 = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) result_2 = qpu_2.submit(circuit.to_job(qubits=measured_qubits)) check_results_equality(result_1, result_2, amplitude=False)
def test_sample_2qb(self): qpu = PyLinalg() prog = Program() qbits = prog.qalloc(2) prog.apply(X, qbits[0]) circ = prog.to_circ() obs = Observable(2, pauli_terms=[Term(1., "ZZ", [0, 1])]) job = circ.to_job("OBS", observable=obs) result = qpu.submit(job) self.assertAlmostEqual(result.value, -1) prog = Program() qbits = prog.qalloc(2) prog.apply(X, qbits[0]) prog.apply(X, qbits[1]) circ = prog.to_circ() obs = Observable(2, pauli_terms=[Term(1., "ZZ", [0, 1])]) job = circ.to_job("OBS", observable=obs) result = qpu.submit(job) self.assertAlmostEqual(result.value, 1)
def test_basic(self): with self.assertRaises(QPUException): prog = Program() qbits = prog.qalloc(1) prog.apply(X, qbits) circ = prog.to_circ() obs = Observable(1, pauli_terms=[Term(1., "Z", [0])]) job = circ.to_job("OBS", observable=obs, nbshots=10) qpu = PyLinalg() result = qpu.submit(job)
def check_basic(self, vec): SP = AbstractGate("STATE_PREPARATION", [np.ndarray]) prog = Program() reg = prog.qalloc(4) prog.apply(SP(vec), reg) qpu = PyLinalg() res = qpu.submit(prog.to_circ().to_job()) statevec = np.zeros(2**4, np.complex) for sample in res: statevec[sample.state.int] = sample.amplitude assert (np.linalg.norm(vec - statevec) < 1e-16)
def test_qft_lnn(self) -> None: """ Tests Sabre on a QFT for LNN topologies for different number of qubits. """ for nbqbit in range(3, max_nbqbit): circuit = generate_qft_circuit(nbqbit) qpu_1 = PyLinalg() result_1 = qpu_1.submit(circuit.to_job()) qpu_2 = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.LNN)) | PyLinalg()) result_2 = qpu_2.submit(circuit.to_job()) check_results_equality(result_1, result_2)
def test3_qlm_backend_run_2_circuit(self): """ Here two circuits run into a QLM QPU by using the QLMBacked object. """ nbqubits = 2 qreg = QuantumRegister(nbqubits) creg = ClassicalRegister(nbqubits) qiskit_circuit_1 = QuantumCircuit(qreg, creg) qiskit_circuit_1.h(qreg[0]) qiskit_circuit_1.cx(qreg[0], qreg[1]) qiskit_circuit_1.measure(qreg, creg) qiskit_circuit_2 = QuantumCircuit(qreg, creg) qiskit_circuit_2.h(qreg[0]) qiskit_circuit_2.h(qreg[1]) qiskit_circuit_2.measure(qreg, creg) backend = QiskitConnector() | PyLinalg() qiskit_circuits = [] qiskit_circuits.append(qiskit_circuit_1) qiskit_circuits.append(qiskit_circuit_2) qobj = assemble(qiskit_circuits) result = backend.run(qobj).result() LOGGER.debug( "\nQPUToBackend test with a list of QLM jobs sent into a QLM qpu:") LOGGER.debug(result.results) self.assertEqual(2, len(result.results))
def test_lnn_topology(self) -> None: """ Tests Sabre on common circuit for LNN topologies for different number of qubits. """ for nbqbit in range(2 * min_nbqbit, max_nbqbit): circuit = generate_random_circuit(rd.randint(nbqbit // 2, nbqbit)) qpu_1 = PyLinalg() result_1 = qpu_1.submit(circuit.to_job()) qpu_2 = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.LNN)) | PyLinalg()) result_2 = qpu_2.submit(circuit.to_job()) check_results_equality(result_1, result_2)
def test_no_state_modification_circuit(self) -> None: """ We apply Sabre on a circuit which doesn't modify the initial state (|0^n> here) and we verify Sabre circuit modifications don't modify the state. """ for nbqbit in range(min_nbqbit, max_nbqbit): prog = Program() qbits = prog.qalloc(nbqbit) random_angles = [ rd.random() * 2 * np.pi for _ in range(3 * nbqbit) ] for i in range(len(qbits)): prog.apply(RX(random_angles[3 * i]), qbits[i]) prog.apply(RX(random_angles[3 * i + 1]), qbits[i]) prog.apply(RX(random_angles[3 * i + 2]), qbits[i]) prog.apply(QFT(nbqbit), qbits) prog.apply(QFT(nbqbit).dag(), qbits) for i in range(len(qbits)): prog.apply(RX(random_angles[3 * i]).dag(), qbits[i]) prog.apply(RX(random_angles[3 * i + 1]).dag(), qbits[i]) prog.apply(RX(random_angles[3 * i + 2]).dag(), qbits[i]) circuit = prog.to_circ(inline=True) for topology in generate_custom_topologies(nbqbit): qpu = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) result = qpu.submit(circuit.to_job()) assert result.raw_data[0].state.int == 0
def test_normal_launch_mode_with_nbshots(self): # Create a small program prog = Program() qubits = prog.qalloc(2) prog.apply(H, qubits[0]) prog.apply(CNOT, qubits) circ = prog.to_circ() # Simulate job = circ.to_job(nbshots=4, aggregate_data=False) qpu = PyLinalg() result = qpu.submit_job(job) self.assertEqual(len(result.raw_data), 4) self.assertEqual(result.raw_data[0].probability, None) #no prob if not aggregating data
def test_unknown_topology_type(self) -> None: """ Checks Sabre raises PluginException for an unknown topology type. """ with pytest.raises(PluginException): circuit = generate_qft_circuit(max_nbqbit) qpu = Sabre() | (QuameleonPlugin(topology=Topology(type=-5)) | PyLinalg()) qpu.submit(circuit.to_job())
def test_algorithm(circuit, iterations=(1000000)): """ Tests a circuit by submitting it to both aer_simulator and PyLinalg. """ linalg = PyLinalg() qlm_circ, _ = qiskit_to_qlm(circuit, sep_measures=True) test_job = qlm_circ.to_job(nbshots=0, aggregate_data=False) expected = linalg.submit(test_job) qiskit_qpu = BackendToQPU(Aer.get_backend('aer_simulator')) test_job.nbshots = iterations result = qiskit_qpu.submit(test_job) dist_calc = compare_results(expected, result, aggregate=False) distance = analyze_distance(dist_calc) print("Distance is {}".format(distance)) return distance
def test_gate_more_two_qubits(self) -> None: """ Checks Sabre raises PluginException if there is a circuit containing a gate with more than two qubits. """ with pytest.raises(PluginException): circuit = generate_qft_circuit(max_nbqbit, inline=False) qpu = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.LNN)) | PyLinalg()) qpu.submit(circuit.to_job())
def test_qft_custom_usual_topologies(self) -> None: """ Tests Sabre on a QFT for some usual custom topologies for different number of qubits. """ for nbqbit in range(5, max_nbqbit): circuit = generate_qft_circuit(nbqbit) qpu_1 = PyLinalg() result_1 = qpu_1.submit(circuit.to_job()) for topology in generate_custom_topologies(nbqbit): print('Number of qubits : ', nbqbit) print('Current topology : ', topology) qpu_2 = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) result_2 = qpu_2.submit(circuit.to_job()) check_results_equality(result_1, result_2)
def test_custom_topology_without_graph(self) -> None: """ Checks Sabre raises PluginException if TopologyType is CUSTOM but no graph is provided. """ with pytest.raises(PluginException): circuit = generate_qft_circuit(max_nbqbit) qpu = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.CUSTOM)) | PyLinalg()) qpu.submit(circuit.to_job())
def test_measure(self): """test that state indexing is same as other simulation services""" # program with final state: qbit 0 : 0 or 1 with 50% proba prog = Program() reg = prog.qalloc(1) creg = prog.calloc(1) prog.apply(H, reg) prog.measure(reg, creg) circ = prog.to_circ() qpu = PyLinalg() result = qpu.submit(circ.to_job(nbshots=5, aggregate_data=False)) for res in result: self.assertAlmostEqual( res.intermediate_measurements[0].probability, 0.5, delta=1e-10) self.assertEqual(res.intermediate_measurements[0].cbits[0], res.state.int)
def test_normal_launch_mode(self): # Create a small program prog = Program() qubits = prog.qalloc(2) prog.apply(H, qubits[0]) prog.apply(CNOT, qubits) circ = prog.to_circ() # Simulate job = circ.to_job() qpu = PyLinalg() result = qpu.submit_job(job) self.assertEqual(len(result.raw_data), 2) self.assertAlmostEqual(result.raw_data[0].probability, 0.5) self.assertTrue(result.raw_data[0].state.int in [0, 3]) self.assertTrue(result.raw_data[1].state.int in [0, 3])
def test_normal_launch_mode_with_nbshots_and_qbs(self): # Create a small program prog = Program() qubits = prog.qalloc(2) prog.apply(H, qubits[0]) prog.apply(CNOT, qubits) circ = prog.to_circ() # Simulate job = circ.to_job(nbshots=4, qubits=[0], aggregate_data=False) qpu = PyLinalg() result = qpu.submit_job(job) self.assertEqual(len(result.raw_data), 4) self.assertEqual(result.raw_data[0].probability, None) #No probability if not aggregating data for rd in result.raw_data: self.assertTrue(rd.state.int in [0, 1], msg="state= %s" % rd.state)
def test_lnn_topology(self) -> None: """ Tests Sabre on common circuit for LNN topologies for different number of qubits. """ for nbqbit in range(2 * min_nbqbit, max_nbqbit): nbqbit_circuit = rd.randint(nbqbit // 2, nbqbit) circuit = generate_random_circuit(nbqbit_circuit) observable = generate_random_observable(nbqbit_circuit) qpu_1 = PyLinalg() measure_1 = qpu_1.submit( circuit.to_job("OBS", observable=observable)) qpu_2 = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.LNN)) | PyLinalg()) measure_2 = qpu_2.submit( circuit.to_job("OBS", observable=observable)) check_measures_equality(measure_1, measure_2)
def test_too_much_qubits(self) -> None: """ Checks Sabre raises PluginException if there are more qubits in the circuit than in the topology. """ with pytest.raises(PluginException): circuit = generate_qft_circuit(max_nbqbit) qpu = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.CUSTOM, graph={ 0: [1], 1: [0] })) | PyLinalg()) qpu.submit(circuit.to_job())
def test_lnn_topology(self) -> None: """ Tests Sabre on common circuit for LNN topologies for different number of qubits. """ for nbqbit in range(2 * min_nbqbit, max_nbqbit): nbqbit_circuit = rd.randint(nbqbit // 2, nbqbit) circuit = generate_random_circuit(nbqbit_circuit) nb_measured_qubits = rd.randint(1, nbqbit_circuit) measured_qubits = rd.sample(range(nbqbit_circuit), nb_measured_qubits) measured_qubits.sort() qpu_1 = PyLinalg() result_1 = qpu_1.submit(circuit.to_job(qubits=measured_qubits)) qpu_2 = Sabre() | (QuameleonPlugin(topology=Topology( type=TopologyType.LNN)) | PyLinalg()) result_2 = qpu_2.submit(circuit.to_job(qubits=measured_qubits)) check_results_equality(result_1, result_2, amplitude=False)
def test_qft(self): """ Testing simulation of inlined/not-inlined QFT """ prog = Program() qbits = prog.qalloc(5) prog.apply(QFT(5), qbits) circuit_default = prog.to_circ() circuit_inlined = prog.to_circ(inline=True) qpu = PyLinalg() psi_d = wavefunction(circuit_default, qpu) psi_i = wavefunction(circuit_inlined, qpu) self.assertAlmostEqual(np.linalg.norm(psi_d - psi_i), 0.)
def test2_qlm_backend_run_1_circuit(self): """ Here a circuit runs into a QLM QPU by using the QLMBacked object. """ nbqubits = 2 qreg = QuantumRegister(nbqubits) creg = ClassicalRegister(nbqubits) qiskit_circuit = QuantumCircuit(qreg, creg) qiskit_circuit.h(qreg[0]) qiskit_circuit.cx(qreg[0], qreg[1]) qiskit_circuit.measure(qreg, creg) backend = QiskitConnector() | PyLinalg() result = backend.run(qiskit_circuit).result() LOGGER.debug("\nQPUToBackend test with a QLM job sent into a QLM qpu:") LOGGER.debug(result.results) self.assertEqual(1, len(result.results))
def test1_qlm_backend_connector(self): """ The QPUToBackend object is here generated by using the QiskitConnector. """ nbqubits = 2 qreg = QuantumRegister(nbqubits) creg = ClassicalRegister(nbqubits) qiskit_circuit = QuantumCircuit(qreg, creg) qiskit_circuit.h(qreg[0]) qiskit_circuit.cx(qreg[0], qreg[1]) qiskit_circuit.measure(qreg, creg) backend = QiskitConnector() | PyLinalg() result = execute(qiskit_circuit, backend, shots=15).result() LOGGER.debug("\nQPUToBackend test via QiskitConnector:") LOGGER.debug(result.results) self.assertEqual(1, len(result.results))
def test0_qlm_backend(self): """ Simple test for QPUToBackend object generation and basic use. """ nbqubits = 2 qreg = QuantumRegister(nbqubits) creg = ClassicalRegister(nbqubits) qiskit_circuit = QuantumCircuit(qreg, creg) qiskit_circuit.h(qreg[0]) qiskit_circuit.cx(qreg[0], qreg[1]) qiskit_circuit.measure(qreg, creg) qpu = PyLinalg() backend = QPUToBackend(qpu) result = execute(qiskit_circuit, backend, shots=15).result() LOGGER.debug("\nQPUToBackend test:") LOGGER.debug(result.results) self.assertEqual(1, len(result.results))
def test_sample_1qb_Y(self): prog = Program() qbits = prog.qalloc(1) prog.apply(H, qbits) prog.apply(PH(-np.pi / 2), qbits) circ = prog.to_circ() obs = Observable(1, pauli_terms=[Term(1., "Y", [0])]) job = circ.to_job("OBS", observable=obs) qpu = PyLinalg() result = qpu.submit(job) self.assertAlmostEqual(result.value, -1) obs = Observable(1, pauli_terms=[Term(18., "Y", [0])]) job = circ.to_job("OBS", observable=obs) result = qpu.submit(job) self.assertAlmostEqual(result.value, -18) prog = Program() qbits = prog.qalloc(1) prog.apply(H, qbits) prog.apply(PH(np.pi / 2), qbits) circ = prog.to_circ() obs = Observable(1, pauli_terms=[Term(1., "Y", [0])]) job = circ.to_job("OBS", observable=obs) result = qpu.submit(job) self.assertAlmostEqual(result.value, 1) obs = Observable(1, pauli_terms=[Term(18., "Y", [0])]) job = circ.to_job("OBS", observable=obs) result = qpu.submit(job) self.assertAlmostEqual(result.value, 18)