def test_optimize_u_to_p_sx_p(self): """U(pi/2, 0, pi/4) -> p(-pi/4)-sx-p(p/2). Basis [p, sx].""" qr = QuantumRegister(2, "qr") circuit = QuantumCircuit(qr) circuit.append(UGate(np.pi / 2, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr, global_phase=-np.pi / 4) expected.append(PhaseGate(-np.pi / 4), [qr[0]]) expected.append(SXGate(), [qr[0]]) expected.append(PhaseGate(np.pi / 2), [qr[0]]) basis = ["p", "sx"] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) msg = f"expected:\n{expected}\nresult:\n{result}" self.assertEqual(expected, result, msg=msg)
def test_pass_manager_empty(self): """Test passing an empty PassManager() to the transpiler. It should perform no transformations on the circuit. """ qr = QuantumRegister(2) circuit = QuantumCircuit(qr) circuit.h(qr[0]) circuit.h(qr[0]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[0], qr[1]) dag_circuit = circuit_to_dag(circuit) resources_before = dag_circuit.count_ops() pass_manager = PassManager() dag_circuit = transpile_dag(dag_circuit, pass_manager=pass_manager) resources_after = dag_circuit.count_ops() self.assertDictEqual(resources_before, resources_after)
def test_vqe_2_iqpe(self): backend = get_aer_backend('qasm_simulator') num_qbits = self.algo_input.qubit_op.num_qubits var_form = RYRZ(num_qbits, 3) optimizer = SPSA(max_trials=10) # optimizer.set_options(**{'max_trials': 500}) algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'paulis') quantum_instance = QuantumInstance(backend) result = algo.run(quantum_instance) self.log.debug('VQE result: {}.'.format(result)) self.ref_eigenval = -1.85727503 num_time_slices = 50 num_iterations = 11 state_in = VarFormBased(var_form, result['opt_params']) iqpe = IQPE(self.algo_input.qubit_op, state_in, num_time_slices, num_iterations, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) run_config = RunConfig(shots=100, max_credits=10, memory=False) quantum_instance = QuantumInstance(backend, run_config, pass_manager=PassManager(), seed_mapper=self.random_seed) result = iqpe.run(quantum_instance) self.log.debug('top result str label: {}'.format(result['top_measurement_label'])) self.log.debug('top result in decimal: {}'.format(result['top_measurement_decimal'])) self.log.debug('stretch: {}'.format(result['stretch'])) self.log.debug('translation: {}'.format(result['translation'])) self.log.debug('final eigenvalue from QPE: {}'.format(result['energy'])) self.log.debug('reference eigenvalue: {}'.format(self.ref_eigenval)) self.log.debug('ref eigenvalue (transformed): {}'.format( (self.ref_eigenval + result['translation']) * result['stretch']) ) self.log.debug('reference binary str label: {}'.format(decimal_to_binary( (self.ref_eigenval + result['translation']) * result['stretch'], max_num_digits=num_iterations + 3, fractional_part_only=True ))) np.testing.assert_approx_equal(self.ref_eigenval, result['energy'], significant=2)
def test_real_eval(self): depth = 1 var_form = RYRZ(self.qubitOp.num_qubits, depth) circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters))) # self.qubitOp.coloring = None run_config_ref = {'shots': 1} run_config = {'shots': 10000} reference = self.qubitOp.eval('matrix', circuit, get_aer_backend( 'statevector_simulator'), run_config=run_config_ref)[0] reference = reference.real backend = get_aer_backend('qasm_simulator') paulis_mode = self.qubitOp.eval('paulis', circuit, backend, run_config=run_config) grouped_paulis_mode = self.qubitOp.eval('grouped_paulis', circuit, backend, run_config=run_config) paulis_mode_p_3sigma = paulis_mode[0] + 3 * paulis_mode[1] paulis_mode_m_3sigma = paulis_mode[0] - 3 * paulis_mode[1] grouped_paulis_mode_p_3sigma = grouped_paulis_mode[0] + 3 * grouped_paulis_mode[1] grouped_paulis_mode_m_3sigma = grouped_paulis_mode[0] - 3 * grouped_paulis_mode[1] self.assertLessEqual(reference, paulis_mode_p_3sigma.real) self.assertGreaterEqual(reference, paulis_mode_m_3sigma.real) self.assertLessEqual(reference, grouped_paulis_mode_p_3sigma.real) self.assertGreaterEqual(reference, grouped_paulis_mode_m_3sigma.real) run_config = {'shots': 10000} compile_config = {'pass_manager': PassManager()} paulis_mode = self.qubitOp.eval('paulis', circuit, backend, run_config=run_config, compile_config=compile_config) grouped_paulis_mode = self.qubitOp.eval('grouped_paulis', circuit, backend, run_config=run_config, compile_config=compile_config) paulis_mode_p_3sigma = paulis_mode[0] + 3 * paulis_mode[1] paulis_mode_m_3sigma = paulis_mode[0] - 3 * paulis_mode[1] grouped_paulis_mode_p_3sigma = grouped_paulis_mode[0] + 3 * grouped_paulis_mode[1] grouped_paulis_mode_m_3sigma = grouped_paulis_mode[0] - 3 * grouped_paulis_mode[1] self.assertLessEqual(reference, paulis_mode_p_3sigma.real, "Without any pass manager") self.assertGreaterEqual(reference, paulis_mode_m_3sigma.real, "Without any pass manager") self.assertLessEqual(reference, grouped_paulis_mode_p_3sigma.real, "Without any pass manager") self.assertGreaterEqual(reference, grouped_paulis_mode_m_3sigma.real, "Without any pass manager")
def test_optimize_h_gates_pass_manager(self): """Transpile: qr:--[H]-[H]-[H]-- == qr:--[u2]-- """ qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.h(qr[0]) circuit.h(qr[0]) circuit.h(qr[0]) expected = QuantumCircuit(qr) expected.u2(0, np.pi, qr[0]) passmanager = PassManager() passmanager.append(Unroller(['u2'])) passmanager.append(Optimize1qGates()) result = transpile(circuit, FakeRueschlikon(), pass_manager=passmanager) self.assertEqual(expected, result)
def test_callback(self): """Test the callback parameter.""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr, name='MyCircuit') circuit.h(qr[0]) circuit.h(qr[0]) circuit.h(qr[0]) expected_start = QuantumCircuit(qr) expected_start.u2(0, np.pi, qr[0]) expected_start.u2(0, np.pi, qr[0]) expected_start.u2(0, np.pi, qr[0]) expected_start_dag = circuit_to_dag(expected_start) expected_end = QuantumCircuit(qr) expected_end.u2(0, np.pi, qr[0]) expected_end_dag = circuit_to_dag(expected_end) calls = [] def callback(**kwargs): out_dict = kwargs out_dict['dag'] = copy.deepcopy(kwargs['dag']) calls.append(out_dict) passmanager = PassManager() passmanager.append(Unroller(['u2'])) passmanager.append(Optimize1qGates()) transpile(circuit, FakeRueschlikon(), pass_manager=passmanager, callback=callback) self.assertEqual(len(calls), 2) self.assertEqual(len(calls[0]), 5) self.assertEqual(calls[0]['count'], 0) self.assertEqual(calls[0]['pass_'].name(), 'Unroller') self.assertEqual(expected_start_dag, calls[0]['dag']) self.assertIsInstance(calls[0]['time'], float) self.assertEqual(calls[0]['property_set'], PropertySet()) self.assertEqual('MyCircuit', calls[0]['dag'].name) self.assertEqual(len(calls[1]), 5) self.assertEqual(calls[1]['count'], 1) self.assertEqual(calls[1]['pass_'].name(), 'Optimize1qGates') self.assertEqual(expected_end_dag, calls[1]['dag']) self.assertIsInstance(calls[0]['time'], float) self.assertEqual(calls[0]['property_set'], PropertySet()) self.assertEqual('MyCircuit', calls[1]['dag'].name)
def test_deprecated_align_measure(self): """Test if old AlignMeasures can be still used and warning is raised.""" circuit = QuantumCircuit(1, 1) circuit.x(0) circuit.delay(100) circuit.measure(0, 0) with self.assertWarns(PendingDeprecationWarning): pm_old = PassManager([ ALAPSchedule(durations=self.instruction_durations), AlignMeasures(alignment=16), ]) pm_new = PassManager([ ALAPSchedule(durations=self.instruction_durations), AlignMeasures(alignment=16), ]) self.assertEqual(pm_old.run(circuit), pm_new.run(circuit))
def test_alignment_is_not_processed(self): """Test avoid pass processing if delay is aligned.""" circuit = QuantumCircuit(2, 2) circuit.x(0) circuit.delay(160, 0, unit="dt") circuit.measure(0, 0) circuit.cx(0, 1) circuit.measure(1, 1) circuit.cx(0, 1) circuit.measure(0, 0) # pre scheduling is not necessary because alignment is skipped # this is to minimize breaking changes to existing code. pm = PassManager() pm.append(InstructionDurationCheck(acquire_alignment=16)) pm.run(circuit) self.assertFalse(pm.property_set["reschedule_required"])
def test_do_not_merge_conditioned_gates(self): """Validate that classically conditioned gates are never considered for inclusion in a block. Note that there are cases where gates conditioned on the same (register, value) pair could be correctly merged, but this is not yet implemented. ┌─────────┐┌─────────┐┌─────────┐ ┌───┐ qr_0: |0>┤ U1(0.1) ├┤ U1(0.2) ├┤ U1(0.3) ├──■───┤ X ├────■─── └─────────┘└────┬────┘└────┬────┘┌─┴─┐ └─┬─┘ ┌─┴─┐ qr_1: |0>────────────────┼──────────┼─────┤ X ├───■────┤ X ├─ │ │ └───┘ │ └─┬─┘ qr_2: |0>────────────────┼──────────┼─────────────┼──────┼─── ┌──┴──┐ ┌──┴──┐ ┌──┴──┐┌──┴──┐ cr_0: 0 ═════════════╡ ╞════╡ ╞═══════╡ ╞╡ ╞ │ = 0 │ │ = 0 │ │ = 0 ││ = 1 │ cr_1: 0 ═════════════╡ ╞════╡ ╞═══════╡ ╞╡ ╞ └─────┘ └─────┘ └─────┘└─────┘ Previously the blocks collected were : [['u1', 'u1', 'u1', 'cx', 'cx', 'cx']] This is now corrected to : [['cx']] """ # ref: https://github.com/Qiskit/qiskit-terra/issues/3215 print("BEGIN MERGE CONDITION ") qr = QuantumRegister(3, "qr") cr = ClassicalRegister(2, "cr") qc = QuantumCircuit(qr, cr) qc.u1(0.1, 0) qc.u1(0.2, 0).c_if(cr, 0) qc.u1(0.3, 0).c_if(cr, 0) qc.cx(0, 1) qc.cx(1, 0).c_if(cr, 0) qc.cx(0, 1).c_if(cr, 1) pass_manager = PassManager() pass_manager.append(CollectMultiQBlocks()) pass_manager.run(qc) for block in pass_manager.property_set["block_list"]: self.assertTrue(len(block) <= 1)
def test_do_not_merge_conditioned_gates(self): """Validate that classically conditioned gates are never considered for inclusion in a block. Note that there are cases where gates conditioned on the same (register, value) pair could be correctly merged, but this is not yet implemented. ┌────────┐┌────────┐┌────────┐ ┌───┐ qr_0: |0>┤ P(0.1) ├┤ P(0.2) ├┤ P(0.3) ├──■───┤ X ├────■─── └────────┘└───┬────┘└───┬────┘┌─┴─┐ └─┬─┘ ┌─┴─┐ qr_1: |0>──────────────┼─────────┼─────┤ X ├───■────┤ X ├─ │ │ └───┘ │ └─┬─┘ qr_2: |0>──────────────┼─────────┼─────────────┼──────┼─── ┌──┴──┐ ┌──┴──┐ ┌──┴──┐┌──┴──┐ cr_0: 0 ═══════════╡ ╞═══╡ ╞═══════╡ ╞╡ ╞ │ = 0 │ │ = 0 │ │ = 0 ││ = 1 │ cr_1: 0 ═══════════╡ ╞═══╡ ╞═══════╡ ╞╡ ╞ └─────┘ └─────┘ └─────┘└─────┘ Previously the blocks collected were : [['p', 'p', 'p', 'cx', 'cx', 'cx']] This is now corrected to : [['cx']] """ # ref: https://github.com/Qiskit/qiskit-terra/issues/3215 qr = QuantumRegister(3, 'qr') cr = ClassicalRegister(2, 'cr') qc = QuantumCircuit(qr, cr) qc.p(0.1, 0) qc.p(0.2, 0).c_if(cr, 0) qc.p(0.3, 0).c_if(cr, 0) qc.cx(0, 1) qc.cx(1, 0).c_if(cr, 0) qc.cx(0, 1).c_if(cr, 1) pass_manager = PassManager() pass_manager.append(Collect2qBlocks()) pass_manager.run(qc) self.assertEqual( [['cx']], [[n.name for n in block] for block in pass_manager.property_set['block_list']])
def test_do_not_go_across_barrier(self): """Validate that blocks are not collected across barriers ░ q_0: ──■───░───■── ┌─┴─┐ ░ ┌─┴─┐ q_1: ┤ X ├─░─┤ X ├ └───┘ ░ └───┘ q_2: ──────░────── ░ """ qr = QuantumRegister(3, "qr") qc = QuantumCircuit(qr) qc.cx(0, 1) qc.barrier() qc.cx(0, 1) pass_manager = PassManager() pass_manager.append(CollectMultiQBlocks()) pass_manager.run(qc) for block in pass_manager.property_set["block_list"]: self.assertTrue(len(block) <= 1)
def pick_label(circ, backend, coupling_map, optimization_level, show=False): ''' Funzione che restituisce il dizionario con il mapping, scegliendo come label layout quello che minimizza la depth del circuito tra dense layout e noise_adaptive sommata alla depth delle operazioni dopo il routing. In questa maniera tengo anche conto di qual'è il layout che permette di minimizzare le operazioni di swap ''' new_circ_lv3 = transpile(circ, backend=backend, optimization_level=optimization_level) new_circ_lv3_na = transpile(circ, backend=backend, optimization_level=optimization_level, layout_method='noise_adaptive') #plot_circuit_layout(new_circ_lv3_na, backend).show() #plot_circuit_layout(new_circ_lv3, backend).show() cp = CouplingMap(couplinglist=coupling_map) depths = [] for qc in [new_circ_lv3_na, new_circ_lv3]: depth = qc.depth() pass_manager = PassManager(LookaheadSwap(coupling_map=cp)) lc_qc = pass_manager.run(qc) pass_manager = PassManager(StochasticSwap(coupling_map=cp)) st_qc = pass_manager.run(qc) depths.append(depth + lc_qc.depth()) depths.append(depth + st_qc.depth()) #print('depth=', depth, ' depth + routing_lc_qc= ', depth + lc_qc.depth(), ' depth + routing_st_qc=',depth + st_qc.depth()) if depths.index(min(depths)) < 2: print('na') if show == True: plot_circuit_layout(new_circ_lv3_na, backend).show() return new_circ_lv3_na._layout.get_physical_bits() if depths.index(min(depths)) >= 2: print('not na') if show == True: plot_circuit_layout(new_circ_lv3, backend).show() return new_circ_lv3._layout.get_physical_bits()