def compile_circuit ( circuit ): pm = PassManager() pm.append( CXCancellation() ) pm.append( Optimize1qGates() ) pm.append( CXCancellation() ) pm.append( Optimize1qGates() ) pm.append( CXCancellation() ) pm.append( Optimize1qGates() ) return transpile( circuit, basis_gates = ['u1', 'u2', 'u3', 'cx'], optimization_level = 2 )
def default_pass_manager(transpile_config): """ The default pass manager that maps to the coupling map. Args: transpile_config (TranspileConfig) Returns: PassManager: A pass manager to map and optimize. """ basis_gates = transpile_config.basis_gates coupling_map = transpile_config.coupling_map initial_layout = transpile_config.initial_layout seed_transpiler = transpile_config.seed_transpiler pass_manager = PassManager() pass_manager.append(SetLayout(initial_layout)) pass_manager.append(Unroller(basis_gates)) # Use the trivial layout if no layout is found pass_manager.append( TrivialLayout(coupling_map), condition=lambda property_set: not property_set['layout']) # if the circuit and layout already satisfy the coupling_constraints, use that layout # otherwise layout on the most densely connected physical qubit subset pass_manager.append(CheckMap(coupling_map)) pass_manager.append( DenseLayout(coupling_map), condition=lambda property_set: not property_set['is_swap_mapped']) # Extend the the dag/layout with ancillas using the full coupling map pass_manager.append(FullAncillaAllocation(coupling_map)) pass_manager.append(EnlargeWithAncilla()) # Circuit must only contain 1- or 2-qubit interactions for swapper to work pass_manager.append(Unroll3qOrMore()) # Swap mapper pass_manager.append(BarrierBeforeFinalMeasurements()) pass_manager.append( LegacySwap(coupling_map, trials=20, seed=seed_transpiler)) # Expand swaps pass_manager.append(Decompose(SwapGate)) # Change CX directions pass_manager.append(CXDirection(coupling_map)) # Simplify single qubit gates and CXs simplification_passes = [ Optimize1qGates(), CXCancellation(), RemoveResetInZeroState() ] pass_manager.append( simplification_passes + [Depth(), FixedPoint('depth')], do_while=lambda property_set: not property_set['depth_fixed_point']) return pass_manager
def test_optimize_1q_gates_sympy_expressions(self): """optimizes single qubit gate sequences with sympy expressions. See: https://github.com/Qiskit/qiskit-terra/issues/172 """ qr = QuantumRegister(4) cr = ClassicalRegister(4) circ = QuantumCircuit(qr, cr) # unary circ.u1(-sympy.pi, qr[0]) circ.u1(-sympy.pi / 2, qr[0]) # binary circ.u1(0.2 * sympy.pi + 0.3 * sympy.pi, qr[1]) circ.u1(1.3 - 0.3, qr[1]) circ.u1(0.1 * sympy.pi / 2, qr[1]) # extern circ.u1(sympy.sin(0.2 + 0.3 - sympy.pi), qr[2]) # power circ.u1(sympy.pi, qr[3]) circ.u1(0.3 + (-sympy.pi)**2, qr[3]) dag = circuit_to_dag(circ) simplified_dag = Optimize1qGates().run(dag) params = set() for node in simplified_dag.named_nodes('u1'): params.add(node.op.params[0]) expected_params = { -3 * np.pi / 2, 1.0 + 0.55 * np.pi, -0.479425538604203, 0.3 + np.pi + np.pi**2 } self.assertEqual(params, expected_params)
def test_parameterized_expressions_in_circuits(self): """Expressions of Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') phi = Parameter('phi') sum_ = theta + phi product_ = theta * phi qc.u1(0.3, qr) qc.u1(0.4, qr) qc.u1(theta, qr) qc.u1(phi, qr) qc.u1(sum_, qr) qc.u1(product_, qr) qc.u1(0.3, qr) qc.u1(0.2, qr) dag = circuit_to_dag(qc) expected = QuantumCircuit(qr) expected.u1(0.7, qr) expected.u1(theta, qr) expected.u1(phi, qr) expected.u1(sum_, qr) expected.u1(product_, qr) expected.u1(0.5, qr) after = Optimize1qGates().run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_parameterized_expressions_in_circuits(self): """Expressions of Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter("theta") phi = Parameter("phi") sum_ = theta + phi product_ = theta * phi qc.append(U1Gate(0.3), [qr]) qc.append(U1Gate(0.4), [qr]) qc.append(U1Gate(theta), [qr]) qc.append(U1Gate(phi), [qr]) qc.append(U1Gate(sum_), [qr]) qc.append(U1Gate(product_), [qr]) qc.append(U1Gate(0.3), [qr]) qc.append(U1Gate(0.2), [qr]) dag = circuit_to_dag(qc) expected = QuantumCircuit(qr) expected.append(U1Gate(0.7), [qr]) expected.append(U1Gate(theta), [qr]) expected.append(U1Gate(phi), [qr]) expected.append(U1Gate(sum_), [qr]) expected.append(U1Gate(product_), [qr]) expected.append(U1Gate(0.5), [qr]) after = Optimize1qGates().run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_parameterized_circuits(self): """Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter("theta") qc.append(U1Gate(0.3), [qr]) qc.append(U1Gate(0.4), [qr]) qc.append(U1Gate(theta), [qr]) qc.append(U1Gate(0.1), [qr]) qc.append(U1Gate(0.2), [qr]) qc.append(U1Gate(theta), [qr]) qc.append(U1Gate(0.3), [qr]) qc.append(U1Gate(0.2), [qr]) dag = circuit_to_dag(qc) expected = QuantumCircuit(qr) expected.append(U1Gate(0.7), [qr]) expected.append(U1Gate(theta), [qr]) expected.append(U1Gate(0.3), [qr]) expected.append(U1Gate(theta), [qr]) expected.append(U1Gate(0.5), [qr]) after = Optimize1qGates().run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_ignores_conditional_rotations_phase_gates(self): """Conditional rotations should not be considered in the chain. qr0:--[U1]-[U1]-[U1]-[U1]- qr0:--[U1]-[U1]- || || || || cr0:===.================== == cr0:===.====.=== || || cr1:========.============= cr1:========.=== """ qr = QuantumRegister(1, "qr") cr = ClassicalRegister(2, "cr") circuit = QuantumCircuit(qr, cr) circuit.append(PhaseGate(0.1), [qr]).c_if(cr, 1) circuit.append(PhaseGate(0.2), [qr]).c_if(cr, 3) circuit.append(PhaseGate(0.3), [qr]) circuit.append(PhaseGate(0.4), [qr]) dag = circuit_to_dag(circuit) expected = QuantumCircuit(qr, cr) expected.append(PhaseGate(0.1), [qr]).c_if(cr, 1) expected.append(PhaseGate(0.2), [qr]).c_if(cr, 3) expected.append(PhaseGate(0.7), [qr]) pass_ = Optimize1qGates(["p", "u2", "u", "cx", "id"]) after = pass_.run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_parameterized_circuits(self): """Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') qc.u1(0.3, qr) qc.u1(0.4, qr) qc.u1(theta, qr) qc.u1(0.1, qr) qc.u1(0.2, qr) qc.u1(theta, qr) qc.u1(0.3, qr) qc.u1(0.2, qr) dag = circuit_to_dag(qc) expected = QuantumCircuit(qr) expected.u1(0.7, qr) expected.u1(theta, qr) expected.u1(0.3, qr) expected.u1(theta, qr) expected.u1(0.5, qr) after = Optimize1qGates().run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_optimize_1q_gates_collapse_identity(self): """test optimize_1q_gates removes u1(2*pi) rotations. See: https://github.com/Qiskit/qiskit-terra/issues/159 """ qr = QuantumRegister(2, 'qr') cr = ClassicalRegister(2, 'cr') qc = QuantumCircuit(qr, cr) qc.h(qr[0]) qc.cx(qr[1], qr[0]) qc.u1(2 * sympy.pi, qr[0]) # TODO: this identity should be removed (but is not) qc.cx(qr[1], qr[0]) qc.u1(sympy.pi / 2, qr[0]) # these three should combine qc.u1(sympy.pi, qr[0]) # to identity then qc.u1(sympy.pi / 2, qr[0]) # optimized away. qc.cx(qr[1], qr[0]) qc.u1(np.pi, qr[1]) # this doesn't become precisely 0, so should qc.u1(np.pi, qr[1]) # combine but stay, until an approximate optimizer. qc.measure(qr[0], cr[0]) qc.measure(qr[1], cr[1]) dag = circuit_to_dag(qc) simplified_dag = Optimize1qGates().run(dag) num_u1_gates_remaining = len(simplified_dag.get_named_nodes('u1')) self.assertEqual(num_u1_gates_remaining, 2)
def test_ignores_conditional_rotations(self): """Conditional rotations should not be considered in the chain. qr0:--[U1]-[U1]-[U1]-[U1]- qr0:--[U1]-[U1]- || || || || cr0:===.================== == cr0:===.====.=== || || cr1:========.============= cr1:========.=== """ qr = QuantumRegister(1, 'qr') cr = ClassicalRegister(2, 'cr') circuit = QuantumCircuit(qr, cr) circuit.u1(0.1, qr).c_if(cr, 1) circuit.u1(0.2, qr).c_if(cr, 3) circuit.u1(0.3, qr) circuit.u1(0.4, qr) dag = circuit_to_dag(circuit) expected = QuantumCircuit(qr, cr) expected.u1(0.1, qr).c_if(cr, 1) expected.u1(0.2, qr).c_if(cr, 3) expected.u1(0.7, qr) pass_ = Optimize1qGates() after = pass_.run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_optimize_1q_gates_collapse_identity_equivalent_phase_gate(self): """test optimize_1q_gates removes u1(2*pi) rotations. See: https://github.com/Qiskit/qiskit-terra/issues/159 """ qr = QuantumRegister(2, "qr") cr = ClassicalRegister(2, "cr") qc = QuantumCircuit(qr, cr) qc.h(qr[0]) qc.cx(qr[1], qr[0]) qc.append(PhaseGate(2 * np.pi), [qr[0]]) qc.cx(qr[1], qr[0]) qc.append(PhaseGate(np.pi / 2), [qr[0]]) # these three should combine qc.append(PhaseGate(np.pi), [qr[0]]) # to identity then qc.append(PhaseGate(np.pi / 2), [qr[0]]) # optimized away. qc.cx(qr[1], qr[0]) qc.append(PhaseGate(np.pi), [qr[1]]) qc.append(PhaseGate(np.pi), [qr[1]]) qc.measure(qr[0], cr[0]) qc.measure(qr[1], cr[1]) dag = circuit_to_dag(qc) simplified_dag = Optimize1qGates(["p", "u2", "u", "cx", "id"]).run(dag) num_u1_gates_remaining = len(simplified_dag.named_nodes("p")) self.assertEqual(num_u1_gates_remaining, 0)
def test_optimize_1q_gates_collapse_identity(self): """test optimize_1q_gates removes u1(2*pi) rotations. See: https://github.com/Qiskit/qiskit-terra/issues/159 """ qr = QuantumRegister(2, 'qr') cr = ClassicalRegister(2, 'cr') qc = QuantumCircuit(qr, cr) qc.h(qr[0]) qc.cx(qr[1], qr[0]) qc.u1(2 * sympy.pi, qr[0]) qc.cx(qr[1], qr[0]) qc.u1(sympy.pi / 2, qr[0]) # these three should combine qc.u1(sympy.pi, qr[0]) # to identity then qc.u1(sympy.pi / 2, qr[0]) # optimized away. qc.cx(qr[1], qr[0]) qc.u1(np.pi, qr[1]) qc.u1(np.pi, qr[1]) qc.measure(qr[0], cr[0]) qc.measure(qr[1], cr[1]) dag = circuit_to_dag(qc) simplified_dag = Optimize1qGates().run(dag) num_u1_gates_remaining = len(simplified_dag.named_nodes('u1')) self.assertEqual(num_u1_gates_remaining, 0)
def create_optimize_only_pass_manager(device): # type: (BaseBackend) -> PassManager basis = device.configuration().basis_gates pm = PassManager() pm.append(Unroller(basis=basis)) pm.append(Optimize1qGates()) return pm
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_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_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_global_phase_u_on_left(self): """Check proper phase accumulation with instruction with no definition.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) u1 = U1Gate(0.1) u1.definition.global_phase = np.pi / 2 qc.append(u1, [0]) qc.global_phase = np.pi / 3 qc.append(UGate(0.1, 0.2, 0.3), [0]) dag = circuit_to_dag(qc) after = Optimize1qGates(["u1", "u2", "u", "cx"]).run(dag) self.assertAlmostEqual(after.global_phase, 5 * np.pi / 6, 8)
def test_optimize_id(self): """ qr0:--[id]-- == qr0:------ """ qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.iden(qr) circuit.iden(qr) dag = circuit_to_dag(circuit) expected = QuantumCircuit(qr) pass_ = Optimize1qGates() after = pass_.run(dag) self.assertEqual(circuit_to_dag(expected), after)
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_optimize_u3_basis_u(self): """U3(pi/2, pi/3, pi/4) (basis[u3]) -> U(pi/2, pi/3, pi/4)""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.append(U3Gate(np.pi / 2, np.pi / 3, np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(['u'])) result = passmanager.run(circuit) expected = QuantumCircuit(qr) expected.append(UGate(np.pi / 2, np.pi / 3, np.pi / 4), [qr[0]]) self.assertEqual(expected, result)
def test_optimize_u1_basis_u2_u(self): """U1(pi/4) -> U3(0, 0, pi/4). Basis [u2, u3].""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.append(U1Gate(np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(UGate(0, 0, np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(['u2', 'u'])) result = passmanager.run(circuit) self.assertEqual(expected, result)
def test_optimize_u3_basis_u2_phase_gate(self): """U3(pi/2, 0, pi/4) -> U2(0, pi/4). Basis [u2, p].""" qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.append(U3Gate(np.pi / 2, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(U2Gate(0, np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(['u2', 'p'])) result = passmanager.run(circuit) self.assertEqual(expected, result)
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)
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.append(U3Gate(0, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(U1Gate(np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(["u1"])) result = passmanager.run(circuit) self.assertEqual(expected, result)
def test_global_phase_u3_on_left(self): """Check proper phase accumulation with instruction with no definition.""" from qiskit.circuit.library.standard_gates import U1Gate qr = QuantumRegister(1) qc = QuantumCircuit(qr) u1 = U1Gate(0.1) u1.definition.global_phase = np.pi / 2 qc.append(u1, [0]) qc.global_phase = np.pi / 3 qc.u3(0.1, 0.2, 0.3, 0) dag = circuit_to_dag(qc) after = Optimize1qGates().run(dag) self.assertAlmostEqual(after.global_phase, 5 * np.pi / 6, 8)
def test_optimize_u3_to_u2(self): """U3(pi/2, pi/3, pi/4) -> U2(pi/3, pi/4)""" qr = QuantumRegister(1, "qr") circuit = QuantumCircuit(qr) circuit.append(U3Gate(np.pi / 2, np.pi / 3, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(U2Gate(np.pi / 3, np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates()) result = passmanager.run(circuit) self.assertEqual(expected, result)
def test_optimize_u3_to_phase_round(self): """U3(1e-16, 1e-16, pi/4) -> U1(pi/4)""" qr = QuantumRegister(1, "qr") circuit = QuantumCircuit(qr) circuit.append(U3Gate(1e-16, 1e-16, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(PhaseGate(np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(["p", "u2", "u", "cx", "id"])) result = passmanager.run(circuit) self.assertEqual(expected, result)
def test_optimize_u3_to_phase_gate(self): """U3(0, 0, pi/4) -> U1(pi/4)""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.append(U3Gate(0, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(PhaseGate(np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(['p', 'u2', 'u', 'cx', 'id'])) result = passmanager.run(circuit) self.assertEqual(expected, result)
def test_optimize_u_basis_phase_gate(self): """U(0, 0, pi/4) -> p(pi/4). Basis [p].""" qr = QuantumRegister(2, "qr") circuit = QuantumCircuit(qr) circuit.append(UGate(0, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(PhaseGate(np.pi / 4), [qr[0]]) passmanager = PassManager() passmanager.append(Optimize1qGates(["p"])) result = passmanager.run(circuit) self.assertEqual(expected, result)
def test_optimize_u3_to_u1_round(self): """U3(1e-16, 1e-16, pi/4) -> U1(pi/4)""" qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr) circuit.u3(1e-16, 1e-16, np.pi / 4, qr[0]) expected = QuantumCircuit(qr) expected.u1(np.pi / 4, qr[0]) passmanager = PassManager() passmanager.append(Optimize1qGates()) result = passmanager.run(circuit) self.assertEqual(expected, result)