def test_add_qreg_creg(self): """ add_qreg() and add_creg() methods""" dag = DAGCircuit() dag.add_qreg(QuantumRegister(2, 'qr')) dag.add_creg(ClassicalRegister(1, 'cr')) self.assertDictEqual(dag.qregs, {'qr': QuantumRegister(2, 'qr')}) self.assertDictEqual(dag.cregs, {'cr': ClassicalRegister(1, 'cr')})
def test_add_reg_duplicate_name(self): """Adding quantum registers with the same name is not allowed.""" dag = DAGCircuit() qr1 = QuantumRegister(3, 'qr') dag.add_qreg(qr1) qr2 = QuantumRegister(2, 'qr') self.assertRaises(DAGCircuitError, dag.add_qreg, qr2)
def setUp(self): self.qr1 = QuantumRegister(4, 'qr1') self.qr2 = QuantumRegister(2, 'qr2') circ1 = QuantumCircuit(self.qr2, self.qr1) circ1.h(self.qr1[0]) circ1.cx(self.qr1[2], self.qr1[3]) circ1.h(self.qr1[2]) circ1.t(self.qr1[2]) circ1.ch(self.qr1[2], self.qr1[1]) circ1.u2(0.1, 0.2, self.qr1[3]) circ1.ccx(self.qr2[0], self.qr2[1], self.qr1[0]) self.dag1 = DAGCircuit.fromQuantumCircuit(circ1)
def setUp(self): qr1 = QuantumRegister(4) qr2 = QuantumRegister(2) circ = QuantumCircuit(qr1, qr2) circ.h(qr1[0]) circ.cx(qr1[2], qr1[3]) circ.h(qr1[2]) circ.t(qr1[2]) circ.ch(qr1[2], qr1[1]) circ.u2(0.1, 0.2, qr1[3]) circ.ccx(qr2[0], qr2[1], qr1[0]) self.dag = DAGCircuit.fromQuantumCircuit(circ)
def _define_decompositions(self): """ gate cu3(theta,phi,lambda) c, t { u1((lambda-phi)/2) t; cx c,t; u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t; u3(theta/2,phi,0) t; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) decomposition.add_basis_element("u3", 1, 0, 3) decomposition.add_basis_element("cx", 2, 0, 0) rule = [ U1Gate((self.param[2] - self.param[1]) / 2, q[1]), CnotGate(q[0], q[1]), U3Gate(-self.param[0] / 2, 0, -(self.param[1] + self.param[2]) / 2, q[1]), CnotGate(q[0], q[1]), U3Gate(self.param[0] / 2, self.param[1], 0, q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_create(self): """ Creation using add_basis_element(), add_qreg(), add_creg(), and apply_operation_back().""" qreg = QuantumRegister(2, 'qr') creg = ClassicalRegister(2, 'cr') qubit0 = ('qr', 0) qubit1 = ('qr', 1) clbit0 = ('cr', 0) clbit1 = ('cr', 1) condition = ('cr', 3) dag = DAGCircuit() dag.add_basis_element('h', 1, number_classical=0, number_parameters=0) dag.add_basis_element('cx', 2) dag.add_basis_element('x', 1) dag.add_basis_element('measure', 1, number_classical=1, number_parameters=0) dag.add_qreg(qreg) dag.add_creg(creg) dag.apply_operation_back('h', [qubit0], [], [], condition=None) dag.apply_operation_back('cx', [qubit0, qubit1], [], [], condition=None) dag.apply_operation_back('measure', [qubit1], [clbit1], [], condition=None) dag.apply_operation_back('x', [qubit1], [], [], condition=condition) dag.apply_operation_back('measure', [qubit0], [clbit0], [], condition=None) dag.apply_operation_back('measure', [qubit1], [clbit1], [], condition=None) self.assertEqual(len(dag.multi_graph.nodes), 14) self.assertEqual(len(dag.multi_graph.edges), 16)
def test_rename_register(self): """The rename_register() method. """ dag = DAGCircuit() qr = QuantumRegister(2, 'qr') dag.add_qreg(qr) dag.rename_register('qr', 'v') self.assertTrue('v' in dag.qregs) self.assertEqual(dag.qregs['v'], qr)
def _define_decompositions(self): decomposition = DAGCircuit() q = QuantumRegister(1, "q") decomposition.add_qreg(q) decomposition.add_basis_element("U", 1, 0, 3) rule = [UBase(0, 0, 0, q[0])] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define_decompositions(self): """ gate cx c,t { CX c,t; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) decomposition.add_basis_element("CX", 2, 0, 0) rule = [CXBase(q[0], q[1])] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_nodes_in_topological_order(self): dag = DAGCircuit() dag.add_basis_element('h', 1, number_classical=0, number_parameters=0) dag.add_basis_element('cx', 2) dag.add_qreg(QuantumRegister(3, "q")) dag.apply_operation_back('cx', [('q', 0), ('q', 1)]) dag.apply_operation_back('h', [('q', 0)]) dag.apply_operation_back('cx', [('q', 2), ('q', 1)]) dag.apply_operation_back('cx', [('q', 0), ('q', 2)]) dag.apply_operation_back('h', [('q', 2)]) named_nodes = dag.node_nums_in_topological_order() self.assertEqual([5, 3, 1, 7, 9, 4, 8, 10, 11, 6, 2], [i for i in named_nodes])
def _define_decompositions(self): """ gate cy a,b { sdg b; cx a,b; s b; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) decomposition.add_basis_element("s", 1, 0, 0) decomposition.add_basis_element("sdg", 1, 0, 0) decomposition.add_basis_element("cx", 2, 0, 0) rule = [SdgGate(q[1]), CnotGate(q[0], q[1]), SGate(q[1])] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define_decompositions(self): """ gate rzz(theta) a, b { cx a, b; u1(theta) b; cx a, b; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) decomposition.add_basis_element("cx", 2, 0, 0) rule = [ CnotGate(q[0], q[1]), U1Gate(self.param[0], q[0]), CnotGate(q[0], q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def setUp(self): self.dag = DAGCircuit() qreg = QuantumRegister(3, 'qr') creg = ClassicalRegister(2, 'cr') self.dag.add_qreg(qreg) self.dag.add_creg(creg) self.dag.add_basis_element(name='h', number_qubits=1, number_classical=0, number_parameters=0) self.dag.add_basis_element('cx', 2, 0, 0) self.dag.add_basis_element('x', 1, 0, 0) self.dag.add_basis_element('measure', 1, 1, 0) self.dag.add_basis_element('reset', 1, 0, 0) self.qubit0 = qreg[0] self.qubit1 = qreg[1] self.qubit2 = qreg[2] self.clbit0 = creg[0] self.clbit1 = creg[1] self.condition = (creg, 3)
def test_substitute_circuit_one_middle(self): """The method substitute_circuit_one() replaces a in-the-middle node with a DAG.""" cx_node = self.dag.get_op_nodes(op=CnotGate(self.qubit0, self.qubit1)).pop() flipped_cx_circuit = DAGCircuit() v = QuantumRegister(2, "v") flipped_cx_circuit.add_qreg(v) flipped_cx_circuit.add_basis_element("cx", 2) flipped_cx_circuit.add_basis_element("h", 1) flipped_cx_circuit.apply_operation_back(HGate(v[0])) flipped_cx_circuit.apply_operation_back(HGate(v[1])) flipped_cx_circuit.apply_operation_back(CnotGate(v[1], v[0])) flipped_cx_circuit.apply_operation_back(HGate(v[0])) flipped_cx_circuit.apply_operation_back(HGate(v[1])) self.dag.substitute_circuit_one(cx_node, input_circuit=flipped_cx_circuit, wires=[v[0], v[1]]) self.assertEqual(self.dag.count_ops()['h'], 5)
def test_layers_basic(self): """ The layers() method.""" qreg = QuantumRegister(2, 'qr') creg = ClassicalRegister(2, 'cr') qubit0 = ('qr', 0) qubit1 = ('qr', 1) clbit0 = ('cr', 0) clbit1 = ('cr', 1) condition = ('cr', 3) dag = DAGCircuit() dag.add_basis_element('h', 1, number_classical=0, number_parameters=0) dag.add_basis_element('cx', 2) dag.add_basis_element('x', 1) dag.add_basis_element('measure', 1, number_classical=1, number_parameters=0) dag.add_qreg(qreg) dag.add_creg(creg) dag.apply_operation_back('h', [qubit0], [], [], condition=None) dag.apply_operation_back('cx', [qubit0, qubit1], [], [], condition=None) dag.apply_operation_back('measure', [qubit1], [clbit1], [], condition=None) dag.apply_operation_back('x', [qubit1], [], [], condition=condition) dag.apply_operation_back('measure', [qubit0], [clbit0], [], condition=None) dag.apply_operation_back('measure', [qubit1], [clbit1], [], condition=None) layers = list(dag.layers()) self.assertEqual(5, len(layers)) name_layers = [[ node[1]["name"] for node in layer["graph"].multi_graph.nodes(data=True) if node[1]["type"] == "op" ] for layer in layers] self.assertEqual( [['h'], ['cx'], ['measure'], ['x'], ['measure', 'measure']], name_layers)
def _define_decompositions(self): """ gate cswap a,b,c { cx c,b; ccx a,b,c; cx c,b; } """ decomposition = DAGCircuit() q = QuantumRegister(3, "q") decomposition.add_qreg(q) decomposition.add_basis_element("cx", 2, 0, 0) decomposition.add_basis_element("ccx", 3, 0, 0) rule = [ CnotGate(q[2], q[1]), ToffoliGate(q[0], q[1], q[2]), CnotGate(q[2], q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_get_named_nodes(self): qreg = QuantumRegister(3, 'q') dag = DAGCircuit() dag.add_basis_element('h', 1, number_classical=0, number_parameters=0) dag.add_basis_element('cx', 2) dag.add_qreg(qreg) dag.apply_operation_back('cx', [('q', 0), ('q', 1)]) dag.apply_operation_back('h', [('q', 0)]) dag.apply_operation_back('cx', [('q', 2), ('q', 1)]) dag.apply_operation_back('cx', [('q', 0), ('q', 2)]) dag.apply_operation_back('h', [('q', 2)]) # The ordering is not assured, so we only compare the output (unordered) sets. # We use tuples because lists aren't hashable. named_nodes = dag.get_named_nodes('cx') node_qargs = {tuple(dag.multi_graph.node[node_id]["qargs"]) for node_id in named_nodes} expected_gates = { (('q', 0), ('q', 1)), (('q', 2), ('q', 1)), (('q', 0), ('q', 2))} self.assertEqual(expected_gates, node_qargs)
def _define_decompositions(self): """ gate ccx a,b,c { h c; cx b,c; tdg c; cx a,c; t c; cx b,c; tdg c; cx a,c; t b; t c; h c; cx a,b; t a; tdg b; cx a,b;} """ decomposition = DAGCircuit() q = QuantumRegister(3, "q") decomposition.add_qreg(q) decomposition.add_basis_element("h", 1, 0, 0) decomposition.add_basis_element("cx", 2, 0, 0) decomposition.add_basis_element("t", 1, 0, 0) decomposition.add_basis_element("tdg", 1, 0, 0) decomposition.add_basis_element("s", 1, 0, 0) decomposition.add_basis_element("sdg", 1, 0, 0) rule = [ HGate(q[2]), CnotGate(q[1], q[2]), TdgGate(q[2]), CnotGate(q[0], q[2]), TGate(q[2]), CnotGate(q[1], q[2]), TdgGate(q[2]), CnotGate(q[0], q[2]), TGate(q[1]), TGate(q[2]), HGate(q[2]), CnotGate(q[0], q[1]), TGate(q[0]), TdgGate(q[1]), CnotGate(q[0], q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_layers_basic(self): """ The layers() method returns a list of layers, each of them with a list of nodes.""" qreg = QuantumRegister(2, 'qr') creg = ClassicalRegister(2, 'cr') qubit0 = qreg[0] qubit1 = qreg[1] clbit0 = creg[0] clbit1 = creg[1] condition = (creg, 3) dag = DAGCircuit() dag.add_basis_element('h', 1, 0, 0) dag.add_basis_element('cx', 2, 0, 0) dag.add_basis_element('x', 1, 0, 0) dag.add_basis_element('measure', 1, 1, 0) dag.add_qreg(qreg) dag.add_creg(creg) dag.apply_operation_back(HGate(qubit0)) dag.apply_operation_back(CnotGate(qubit0, qubit1), condition=None) dag.apply_operation_back(Measure(qubit1, clbit1), condition=None) dag.apply_operation_back(XGate(qubit1), condition=condition) dag.apply_operation_back(Measure(qubit0, clbit0), condition=None) dag.apply_operation_back(Measure(qubit1, clbit1), condition=None) layers = list(dag.layers()) self.assertEqual(5, len(layers)) name_layers = [ [node[1]["op"].name for node in layer["graph"].multi_graph.nodes(data=True) if node[1]["type"] == "op"] for layer in layers] self.assertEqual([ ['h'], ['cx'], ['measure'], ['x'], ['measure', 'measure'] ], name_layers)
def _process_node(self, node): """Carry out the action associated with node n.""" if node.type == "program": self._process_children(node) elif node.type == "qreg": qreg = QuantumRegister(node.index, node.name) self.qregs[node.name] = qreg self.backend.new_qreg(qreg) elif node.type == "creg": creg = ClassicalRegister(node.index, node.name) self.cregs[node.name] = creg self.backend.new_creg(creg) elif node.type == "id": raise UnrollerError("internal error: _process_node on id") elif node.type == "int": raise UnrollerError("internal error: _process_node on int") elif node.type == "real": raise UnrollerError("internal error: _process_node on real") elif node.type == "indexed_id": raise UnrollerError("internal error: _process_node on indexed_id") elif node.type == "id_list": # We process id_list nodes when they are leaves of barriers. return [ self._process_bit_id(node_children) for node_children in node.children ] elif node.type == "primary_list": # We should only be called for a barrier. return [self._process_bit_id(m) for m in node.children] elif node.type == "gate": self._process_gate(node) elif node.type == "custom_unitary": self._process_custom_unitary(node) elif node.type == "universal_unitary": args = self._process_node(node.children[0]) qid = self._process_bit_id(node.children[1]) for element in qid: self.backend.u(args, element) elif node.type == "cnot": self._process_cnot(node) elif node.type == "expression_list": return node.children elif node.type == "binop": raise UnrollerError("internal error: _process_node on binop") elif node.type == "prefix": raise UnrollerError("internal error: _process_node on prefix") elif node.type == "measure": self._process_measure(node) elif node.type == "format": self.version = node.version() self.backend.version(node.version()) elif node.type == "barrier": ids = self._process_node(node.children[0]) self.backend.barrier(ids) elif node.type == "reset": id0 = self._process_bit_id(node.children[0]) for i, _ in enumerate(id0): self.backend.reset(id0[i]) elif node.type == "if": self._process_if(node) elif node.type == "opaque": self._process_gate(node, opaque=True) elif node.type == "external": raise UnrollerError("internal error: _process_node on external") else: raise UnrollerError("internal error: undefined node type", node.type, "line=%s" % node.line, "file=%s" % node.file) return None
def test_dag_get_qubits(self): """ get_qubits() method """ dag = DAGCircuit() dag.add_qreg(QuantumRegister(1, 'qr1')) dag.add_qreg(QuantumRegister(1, 'qr10')) dag.add_qreg(QuantumRegister(1, 'qr0')) dag.add_qreg(QuantumRegister(1, 'qr3')) dag.add_qreg(QuantumRegister(1, 'qr4')) dag.add_qreg(QuantumRegister(1, 'qr6')) self.assertListEqual(dag.get_qubits(), [(QuantumRegister(1, 'qr1'), 0), (QuantumRegister(1, 'qr10'), 0), (QuantumRegister(1, 'qr0'), 0), (QuantumRegister(1, 'qr3'), 0), (QuantumRegister(1, 'qr4'), 0), (QuantumRegister(1, 'qr6'), 0)])
def test_add_reg_duplicate(self): """ add_qreg with the same register twice is not allowed.""" dag = DAGCircuit() qr = QuantumRegister(2) dag.add_qreg(qr) self.assertRaises(DAGCircuitError, dag.add_qreg, qr)