def test_topological_order_preserved(self): """the original topological order of nodes is preserved ______ q0:--[u1]-------.---- q0:-------------| |-- | ______ | U2 | q1:--[u2]--(+)-(+)--- = q1:---| |--|______|-- | | U1 | q2:---------.-------- q2:---|______|------------ """ qr = QuantumRegister(3, "qr") qc = QuantumCircuit(qr) qc.u1(0.5, qr[0]) qc.u2(0.2, 0.6, qr[1]) qc.cx(qr[2], qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks() topo_ops = list(dag.topological_op_nodes()) block_1 = [topo_ops[1], topo_ops[2]] block_2 = [topo_ops[0], topo_ops[3]] pass_.property_set['block_list'] = [block_1, block_2] new_dag = pass_.run(dag) new_topo_ops = [ i for i in new_dag.topological_op_nodes() if i.type == 'op' ] self.assertEqual(len(new_topo_ops), 2) self.assertEqual(new_topo_ops[0].qargs, [qr[1], qr[2]]) self.assertEqual(new_topo_ops[1].qargs, [qr[0], qr[1]])
def test_block_spanning_two_regs(self): """blocks spanning wires on different quantum registers work.""" # ┌────────┐ # qr0: ──────┤ P(0.5) ├───────■── # ┌─────┴────────┴────┐┌─┴─┐ # qr1: ┤ U(1.5708,0.2,0.6) ├┤ X ├ # └───────────────────┘└───┘ qr0 = QuantumRegister(1, "qr0") qr1 = QuantumRegister(1, "qr1") qc = QuantumCircuit(qr0, qr1) qc.p(0.5, qr0[0]) qc.u(1.5708, 0.2, 0.6, qr1[0]) qc.cx(qr0[0], qr1[0]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set["block_list"] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) unitary = Operator(qc) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(Operator(new_dag.op_nodes()[0].op), unitary) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_topological_order_preserved(self): """the original topological order of nodes is preserved ______ q0:--[p]-------.---- q0:-------------| |-- | ______ | U2 | q1:--[u2]--(+)-(+)-- = q1:---| |--|______|-- | | U1 | q2:---------.------- q2:---|______|------------ """ qr = QuantumRegister(3, "qr") qc = QuantumCircuit(qr) qc.p(0.5, qr[0]) qc.u(1.5708, 0.2, 0.6, qr[1]) qc.cx(qr[2], qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) topo_ops = list(dag.topological_op_nodes()) block_1 = [topo_ops[1], topo_ops[2]] block_2 = [topo_ops[0], topo_ops[3]] pass_.property_set["block_list"] = [block_1, block_2] new_dag = pass_.run(dag) new_topo_ops = list(new_dag.topological_op_nodes()) self.assertEqual(len(new_topo_ops), 2) self.assertEqual(new_topo_ops[0].qargs, (qr[1], qr[2])) self.assertEqual(new_topo_ops[1].qargs, (qr[0], qr[1]))
def test_3q_blocks(self): """blocks of more than 2 qubits work.""" # ┌────────┐ # qr_0: ──────┤ P(0.5) ├────────────■── # ┌─────┴────────┴────┐┌───┐┌─┴─┐ # qr_1: ┤ U(1.5708,0.2,0.6) ├┤ X ├┤ X ├ # └───────────────────┘└─┬─┘└───┘ # qr_2: ───────────────────────■─────── qr = QuantumRegister(3, "qr") qc = QuantumCircuit(qr) qc.p(0.5, qr[0]) qc.u(1.5708, 0.2, 0.6, qr[1]) qc.cx(qr[2], qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set["block_list"] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) unitary = Operator(qc) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(Operator(new_dag.op_nodes()[0].op), unitary) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_no_kak_in_basis(self): """Test that pass just returns the input dag without a KAK gate.""" qc = QuantumCircuit(1) qc.h(0) dag = circuit_to_dag(qc) consolidate_blocks_pass = ConsolidateBlocks(basis_gates=["u3"]) res = consolidate_blocks_pass.run(dag) self.assertEqual(res, dag)
def test_wire_order(self): """order of qubits and the corresponding unitary is correct""" qr = QuantumRegister(2, "qr") qc = QuantumCircuit(qr) qc.cx(qr[1], qr[0]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set["block_list"] = [dag.op_nodes()] new_dag = pass_.run(dag) new_node = new_dag.op_nodes()[0] self.assertEqual(new_node.qargs, [qr[0], qr[1]]) unitary = Operator(qc) fidelity = process_fidelity(Operator(new_node.op), unitary) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_consolidate_small_block(self): """test a small block of gates can be turned into a unitary on same wires""" qr = QuantumRegister(2, "qr") qc = QuantumCircuit(qr) qc.p(0.5, qr[0]) qc.u(1.5708, 0.2, 0.6, qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set['block_list'] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) unitary = Operator(qc) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(Operator(new_dag.op_nodes()[0].op), unitary) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_wire_order(self): """order of qubits and the corresponding unitary is correct""" qr = QuantumRegister(2, "qr") qc = QuantumCircuit(qr) qc.cx(qr[1], qr[0]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks() pass_.property_set['block_list'] = [dag.op_nodes()] new_dag = pass_.run(dag) new_node = new_dag.op_nodes()[0] self.assertEqual(new_node.qargs, [qr[0], qr[1]]) # the canonical CNOT matrix occurs when the control is more # significant than target, which is the case here fidelity = process_fidelity( new_node.op.representation, np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_consolidate_small_block(self): """test a small block of gates can be turned into a unitary on same wires""" qr = QuantumRegister(2, "qr") qc = QuantumCircuit(qr) qc.u1(0.5, qr[0]) qc.u2(0.2, 0.6, qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set['block_list'] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) sim = UnitarySimulatorPy() result = execute(qc, sim).result() unitary = UnitaryGate(result.get_unitary()) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(new_dag.op_nodes()[0].op.to_matrix(), unitary.to_matrix()) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_block_spanning_two_regs(self): """blocks spanning wires on different quantum registers work.""" qr0 = QuantumRegister(1, "qr0") qr1 = QuantumRegister(1, "qr1") qc = QuantumCircuit(qr0, qr1) qc.u1(0.5, qr0[0]) qc.u2(0.2, 0.6, qr1[0]) qc.cx(qr0[0], qr1[0]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set['block_list'] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) sim = UnitarySimulatorPy() result = execute(qc, sim).result() unitary = UnitaryGate(result.get_unitary()) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(new_dag.op_nodes()[0].op.to_matrix(), unitary.to_matrix()) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_3q_blocks(self): """blocks of more than 2 qubits work.""" qr = QuantumRegister(3, "qr") qc = QuantumCircuit(qr) qc.u1(0.5, qr[0]) qc.u2(0.2, 0.6, qr[1]) qc.cx(qr[2], qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set['block_list'] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) sim = UnitarySimulatorPy() result = execute(qc, sim).result() unitary = UnitaryGate(result.get_unitary()) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(new_dag.op_nodes()[0].op.to_matrix(), unitary.to_matrix()) self.assertAlmostEqual(fidelity, 1.0, places=7)
def test_block_spanning_two_regs_different_index(self): """blocks spanning wires on different quantum registers work when the wires could have conflicting indices. This was raised in #2806 when a CX was applied across multiple registers and their indices collided, raising an error.""" qr0 = QuantumRegister(1, "qr0") qr1 = QuantumRegister(2, "qr1") qc = QuantumCircuit(qr0, qr1) qc.cx(qr0[0], qr1[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set['block_list'] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) original_unitary = UnitaryGate(Operator(qc)) from qiskit.converters import dag_to_circuit new_unitary = UnitaryGate(Operator(dag_to_circuit(new_dag))) self.assertEqual(original_unitary, new_unitary)