def test_identity_u3(self): """Test lone identity gates in u3 basis are removed.""" circuit = QuantumCircuit(1) circuit.append(U3Gate(0, 0, 0), [0]) basis = ['cx', 'u3'] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) self.assertEqual([], result.data)
def test_empty_dag(self): """Empty DAG.""" circuit = QuantumCircuit() passmanager = PassManager() passmanager.append(ResourceEstimation()) passmanager.run(circuit) self.assertEqual(passmanager.property_set["size"], 0) self.assertEqual(passmanager.property_set["depth"], 0) self.assertEqual(passmanager.property_set["width"], 0) self.assertDictEqual(passmanager.property_set["count_ops"], {})
def test_euler_decomposition_worse_2(self): """Ensure we don't decompose to a deeper circuit in an edge case.""" circuit = QuantumCircuit(1) circuit.rz(0.13, 0) circuit.ry(-0.14, 0) basis = ["ry", "rz"] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) self.assertEqual(circuit, result, f"Circuit:\n{circuit}\nResult:\n{result}")
def test_cnot_cascade1(self): """ A cascade of CNOTs that equals identity, with rotation gates inserted. """ qr = QuantumRegister(10, 'qr') circuit = QuantumCircuit(qr) circuit.rx(np.pi, qr[0]) circuit.rx(np.pi, qr[1]) circuit.rx(np.pi, qr[2]) circuit.rx(np.pi, qr[3]) circuit.rx(np.pi, qr[4]) circuit.rx(np.pi, qr[5]) circuit.rx(np.pi, qr[6]) circuit.rx(np.pi, qr[7]) circuit.rx(np.pi, qr[8]) circuit.rx(np.pi, qr[9]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[1], qr[2]) circuit.cx(qr[2], qr[3]) circuit.cx(qr[3], qr[4]) circuit.cx(qr[4], qr[5]) circuit.cx(qr[5], qr[6]) circuit.cx(qr[6], qr[7]) circuit.cx(qr[7], qr[8]) circuit.cx(qr[8], qr[9]) circuit.cx(qr[8], qr[9]) circuit.cx(qr[7], qr[8]) circuit.cx(qr[6], qr[7]) circuit.cx(qr[5], qr[6]) circuit.cx(qr[4], qr[5]) circuit.cx(qr[3], qr[4]) circuit.cx(qr[2], qr[3]) circuit.cx(qr[1], qr[2]) circuit.cx(qr[0], qr[1]) circuit.rx(np.pi, qr[0]) circuit.rx(np.pi, qr[1]) circuit.rx(np.pi, qr[2]) circuit.rx(np.pi, qr[3]) circuit.rx(np.pi, qr[4]) circuit.rx(np.pi, qr[5]) circuit.rx(np.pi, qr[6]) circuit.rx(np.pi, qr[7]) circuit.rx(np.pi, qr[8]) circuit.rx(np.pi, qr[9]) passmanager = PassManager() # passmanager.append(CommutativeCancellation()) passmanager.append([CommutationAnalysis(), CommutativeCancellation(), Size(), FixedPoint('size')], do_while=lambda property_set: not property_set['size_fixed_point']) new_circuit = passmanager.run(circuit) expected = QuantumCircuit(qr) self.assertEqual(expected, new_circuit)
def test_optimize_u3_basis_u3(self): """U3(pi/2, pi/3, pi/4) (basis[u3]) -> U3(pi/2, pi/3, pi/4)""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.u3(np.pi / 2, np.pi / 3, np.pi / 4, qr[0]) passmanager = PassManager() passmanager.append(Optimize1qGates(['u3'])) result = passmanager.run(circuit) self.assertEqual(circuit, result)
def test_control_flow_plugin(self): """ Dump passes in a custom flow controller. """ passmanager = PassManager() FlowController.add_flow_controller('do_x_times', DoXTimesController) passmanager.append( [PassB_TP_RA_PA(), PassC_TP_RA_PA()], do_x_times=lambda x: 3) self.assertPassLog(passmanager, [ 'PassA_TP_NR_NP', 'PassB_TP_RA_PA', 'PassC_TP_RA_PA', 'PassB_TP_RA_PA', 'PassC_TP_RA_PA', 'PassB_TP_RA_PA', 'PassC_TP_RA_PA' ])
def assertEqualUnroll(self, basis, circuit, expected, pass_=None): """ Compares the dags after unrolling to basis """ passmanager = PassManager() unrollpass = Unroller(basis) if pass_ is not None: for passes in pass_: passmanager.append(passes) passmanager.append(unrollpass) circuit_result = passmanager.run(circuit) expected_result = passmanager.run(expected) self.assertEqual(circuit_result, expected_result)
def test_conditional_and_loop(self): """ Dump passes with a conditional and a loop""" passmanager = PassManager() passmanager.append(PassE_AP_NR_NP(True)) passmanager.append( [PassK_check_fixed_point_property(), PassA_TP_NR_NP(), PassF_reduce_dag_property()], do_while=lambda property_set: not property_set['property_fixed_point'], condition=lambda property_set: property_set['property_fixed_point']) self.assertPassLog(passmanager, ['PassE_AP_NR_NP'])
def test_identity_zxz(self): """Test lone identity gates in rx rz basis are removed.""" circuit = QuantumCircuit(2) circuit.rx(0, 1) circuit.rz(0, 0) basis = ['cz', 'rx', 'rz'] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) self.assertEqual([], result.data)
def test_empty_dag(self): """ Empty DAG.""" circuit = QuantumCircuit() passmanager = PassManager() passmanager.append(ResourceEstimation()) _ = transpile(circuit, FakeRueschlikon(), pass_manager=passmanager) self.assertEqual(passmanager.property_set['size'], 0) self.assertEqual(passmanager.property_set['depth'], 0) self.assertEqual(passmanager.property_set['width'], 0) self.assertDictEqual(passmanager.property_set['count_ops'], {})
def test_identity_u1x(self): """Test lone identity gates in u1 rx basis are removed.""" circuit = QuantumCircuit(2) circuit.u1(0, 0) circuit.rx(0, 1) basis = ["cx", "u1", "rx"] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) self.assertEqual([], result.data)
def test_optimize_u_basis_u(self): """U(pi/2, pi/3, pi/4) (basis[u3]) -> U(pi/2, pi/3, pi/4)""" qr = QuantumRegister(1, "qr") circuit = QuantumCircuit(qr) circuit.append(UGate(np.pi / 2, np.pi / 3, np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(["u"])) result = passmanager.run(circuit) self.assertEqual(circuit, result)
def test_single_gate_block_outside_basis(self): """Test that a single gate block outside the configured basis gets converted.""" qc = QuantumCircuit(2) qc.swap(0, 1) consolidate_block_pass = ConsolidateBlocks(basis_gates=["id", "cx", "rz", "sx", "x"]) pass_manager = PassManager() pass_manager.append(Collect2qBlocks()) pass_manager.append(consolidate_block_pass) expected = QuantumCircuit(2) expected.unitary(np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]), [0, 1]) self.assertEqual(expected, pass_manager.run(qc))
def test_pass_option_precedence(self): """The precedence of options is, in order of priority: - The passset option - The Pass Manager option - Default """ passmanager = PassManager(max_iteration=10) tp_pass = PassA_TP_NR_NP() passmanager.append(tp_pass, max_iteration=5) pass_in_workinglist = next(iter(passmanager.working_list)) self.assertEqual(pass_in_workinglist.options['max_iteration'], 5)
def test_inverted_cx(self): """Test that CX order dependence is respected.""" qr = QuantumRegister(4) circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) circuit.cx(qr[1], qr[0]) circuit.cx(qr[0], qr[1]) pass_manager = PassManager() pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) self.assertEqual(out_circuit, circuit)
def test_control_flow_plugin(self): """Dump passes in a custom flow controller.""" passmanager = PassManager() FlowController.add_flow_controller('do_x_times', DoXTimesController) passmanager.append( [PassB_TP_RA_PA(), PassC_TP_RA_PA()], do_x_times=lambda x: 3) expected = [{ 'passes': [PassB_TP_RA_PA(), PassC_TP_RA_PA()], 'flow_controllers': {'do_x_times'} }] self.assertEqual(expected, passmanager.passes())
def test_pass_option_precedence(self): """ The precedence of options is, in order of priority: - The passset option - The Pass Manager option - Default """ passmanager = PassManager(ignore_preserves=False, ignore_requires=True) tp_pass = PassA_TP_NR_NP() passmanager.append(tp_pass, ignore_preserves=True) the_pass_in_the_workinglist = next(iter(passmanager.working_list)) self.assertTrue(the_pass_in_the_workinglist.options['ignore_preserves']) self.assertTrue(the_pass_in_the_workinglist.options['ignore_requires'])
def test_pass_non_idempotence_pm(self): """ A pass manager that considers every pass as not idempotent, allows the immediate repetition of a pass""" passmanager = PassManager(ignore_preserves=True) passmanager.append(PassA_TP_NR_NP()) passmanager.append(PassA_TP_NR_NP()) # Normally removed for optimization, not here. passmanager.append(PassB_TP_RA_PA()) # Normally required is ignored for optimization, # not here self.assertScheduler(self.dag, passmanager, ['run transformation pass PassA_TP_NR_NP', 'run transformation pass PassA_TP_NR_NP', 'run transformation pass PassA_TP_NR_NP', 'run transformation pass PassB_TP_RA_PA'])
def test_commutative_circuit3(self): """ A simple circuit where three CNOTs commute, the first and the last cancel, also two X gates cancel and two Rz gates combine. qr0:-------.------------------.------------- qr0:------------- | | qr1:------(+)------(+)--[X]--(+)-------[X]-- = qr1:--------(+)-- | | qr2:------[Rz]--.---.----.---[Rz]-[T]--[S]-- qr2:--[U1]---.--- | | qr3:-[Rz]--[X]-(+)------(+)--[X]-[Rz]------- qr3:--[Rz]------- """ qr = QuantumRegister(4, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) circuit.rz(np.pi / 3, qr[2]) circuit.rz(np.pi / 3, qr[3]) circuit.x(qr[3]) circuit.cx(qr[2], qr[3]) circuit.cx(qr[2], qr[1]) circuit.cx(qr[2], qr[3]) circuit.rz(np.pi / 3, qr[2]) circuit.t(qr[2]) circuit.x(qr[3]) circuit.rz(np.pi / 3, qr[3]) circuit.s(qr[2]) circuit.x(qr[1]) circuit.cx(qr[0], qr[1]) circuit.x(qr[1]) passmanager = PassManager() passmanager.append( [ CommutationAnalysis(), CommutativeCancellation(), Size(), FixedPoint("size") ], do_while=lambda property_set: not property_set["size_fixed_point"], ) new_circuit = passmanager.run(circuit) expected = QuantumCircuit(qr) expected.append(RZGate(np.pi * 17 / 12), [qr[2]]) expected.append(RZGate(np.pi * 2 / 3), [qr[3]]) expected.cx(qr[2], qr[1]) self.assertEqual( expected, new_circuit, msg=f"expected:\n{expected}\nnew_circuit:\n{new_circuit}")
def test_swapped_cx(self): """Test that CX isn't cancelled if there are intermediary ops.""" qr = QuantumRegister(4) circuit = QuantumCircuit(qr) circuit.cx(qr[1], qr[0]) circuit.swap(qr[1], qr[2]) circuit.cx(qr[1], qr[0]) pass_manager = PassManager() pass_manager.append(CXCancellation()) out_circuit = pass_manager.run(circuit) self.assertEqual(out_circuit, circuit)
def test_u_rewrites_to_phase(self): """Test that a phase-like U-gate gets rewritten into an RZ gate.""" qc = QuantumCircuit(1) qc.u(0, 0, np.pi / 6, 0) basis = ["sx", "p"] passmanager = PassManager() passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(qc) expected = QuantumCircuit(1) expected.p(np.pi / 6, 0) msg = f"expected:\n{expected}\nresult:\n{result}" self.assertEqual(expected, result, msg=msg)
def test_overcomplete_basis(self): """Test optimization with an overcomplete basis.""" circuit = random_circuit(3, 3, seed=42) basis = ["rz", "rxx", "rx", "ry", "p", "sx", "u", "cx"] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) basis_translated = passmanager.run(circuit) passmanager = PassManager() passmanager.append(Optimize1qGatesDecomposition(basis)) result_full = passmanager.run(basis_translated) self.assertTrue(Operator(circuit).equiv(Operator(result_full))) self.assertGreater(basis_translated.depth(), result_full.depth())
def remap_apply_layout_virtual_qubit_registers(circuit: QuantumCircuit, coupling_map: CouplingMap, layout: Layout) -> \ Optional[QuantumCircuit]: dag = circuit_to_dag(circuit) if not check_dag_circuit_compatible(dag, coupling_map): return print("FINALIZE LAYOUT:", layout) remap_pass_manager = PassManager() remap_pass_manager.append(SetLayout(layout)) remap_pass_manager.append(ApplyLayout()) remap_circ = remap_pass_manager.run(circuit) return remap_circ
def test_optimize_u1_basis_u2(self): """U1(pi/4) -> Raises. Basis [u2]""" qr = QuantumRegister(1, "qr") circuit = QuantumCircuit(qr) circuit.append(U1Gate(np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(U3Gate(0, 0, np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(["u2"])) with self.assertRaises(TranspilerError): _ = passmanager.run(circuit)
def test_euler_decomposition_worse(self): """Ensure we don't decompose to a deeper circuit.""" circuit = QuantumCircuit(1) circuit.rx(-np.pi / 2, 0) circuit.rz(-np.pi / 2, 0) basis = ['rx', 'rz'] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) # decomposition of circuit will result in 3 gates instead of 2 # assert optimization pass doesn't use it. self.assertEqual(result, circuit)
def test_passes(self): """Dump passes in different FlowControllerLinear""" passmanager = PassManager() passmanager.append(PassC_TP_RA_PA()) passmanager.append(PassB_TP_RA_PA()) expected = [{'options': {'max_iteration': 1000}, 'passes': [PassC_TP_RA_PA()], 'type': FlowControllerLinear}, {'options': {'max_iteration': 1000}, 'passes': [PassB_TP_RA_PA()], 'type': FlowControllerLinear}] self.assertEqual(expected, passmanager.passes())
def test_optimize_u1_basis_u2(self): """U1(pi/4) -> Raises. Basis [u2]""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.u1(np.pi / 4, qr[0]) expected = QuantumCircuit(qr) expected.u3(0, 0, np.pi / 4, qr[0]) passmanager = PassManager() passmanager.append(Optimize1qGates(['u2'])) with self.assertRaises(TranspilerError): _ = passmanager.run(circuit)
def test_short_string(self): """Test that a shorter-than-universal string is still rewritten.""" qc = QuantumCircuit(1) qc.h(0) qc.ry(np.pi / 2, 0) basis = ["sx", "rz"] passmanager = PassManager() passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(qc) expected = QuantumCircuit(1) expected.sx(0) expected.sx(0) msg = f"expected:\n{expected}\nresult:\n{result}" self.assertEqual(expected, result, msg=msg)
def test_y_simplification_rz_sx_x(self): """Test that a y gate gets decomposed to x-zx with ibmq basis.""" qc = QuantumCircuit(1) qc.y(0) basis = ["id", "rz", "sx", "x", "cx"] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(qc) expected = QuantumCircuit(1) expected.rz(-np.pi, 0) expected.x(0) msg = f"expected:\n{expected}\nresult:\n{result}" self.assertEqual(expected, result, msg=msg)
def test_optimize_u3_basis_u1(self): """U3(0, 0, pi/4) -> U1(pi/4). Basis [u1].""" qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.u3(0, 0, np.pi / 4, qr[0]) expected = QuantumCircuit(qr) expected.u1(np.pi / 4, qr[0]) passmanager = PassManager() passmanager.append(Optimize1qGates(['u1'])) result = passmanager.run(circuit) self.assertEqual(expected, result)