def test_from_circuit_constructor_reverse_user_specified_layout(self): """Test initialization from a circuit with a user specified reverse layout.""" # Test tensor product of 1-qubit gates circuit = QuantumCircuit(3) circuit.h(2) circuit.x(1) circuit.ry(np.pi / 2, 0) layout = Layout({circuit.qubits[2]: 0, circuit.qubits[1]: 1, circuit.qubits[0]: 2}) op = Operator.from_circuit(circuit, layout=layout) y90 = (1 / np.sqrt(2)) * np.array([[1, -1], [1, 1]]) target = np.kron(y90, np.kron(self.UX, self.UH)) global_phase_equivalent = matrix_equal(op.data, target, ignore_phase=True) self.assertTrue(global_phase_equivalent) # Test decomposition of Controlled-Phase gate lam = np.pi / 4 circuit = QuantumCircuit(2) circuit.cp(lam, 1, 0) layout = Layout({circuit.qubits[1]: 0, circuit.qubits[0]: 1}) op = Operator.from_circuit(circuit, layout=layout) target = np.diag([1, 1, 1, np.exp(1j * lam)]) global_phase_equivalent = matrix_equal(op.data, target, ignore_phase=True) self.assertTrue(global_phase_equivalent) # Test decomposition of controlled-H gate circuit = QuantumCircuit(2) circuit.ch(1, 0) layout = Layout({circuit.qubits[1]: 0, circuit.qubits[0]: 1}) op = Operator.from_circuit(circuit, layout=layout) target = np.kron(self.UI, np.diag([1, 0])) + np.kron(self.UH, np.diag([0, 1])) global_phase_equivalent = matrix_equal(op.data, target, ignore_phase=True) self.assertTrue(global_phase_equivalent)
def test_layout_combine(self): """combine_into_edge_map() method""" layout = Layout() layout.add((self.qr, 0)) layout.add((self.qr, 1)) another_layout = Layout() another_layout.add((self.qr, 1)) another_layout.add((self.qr, 0)) edge_map = layout.combine_into_edge_map(another_layout) self.assertDictEqual(edge_map, {(self.qr, 0): (self.qr, 1), (self.qr, 1): (self.qr, 0)})
def test_layout_combine(self): """combine_into_edge_map() method""" layout = Layout() layout.add(self.qr[0]) layout.add(self.qr[1]) another_layout = Layout() another_layout.add(self.qr[1]) another_layout.add(self.qr[0]) edge_map = layout.combine_into_edge_map(another_layout) self.assertDictEqual(edge_map, {self.qr[0]: self.qr[1], self.qr[1]: self.qr[0]})
def test_layout_combine_smaller(self): """combine_into_edge_map() method with another_layout is smaller and raises an Error""" layout = Layout() layout.add(self.qr[0]) layout.add(self.qr[1]) layout.add(self.qr[2]) another_layout = Layout() another_layout.add(self.qr[1]) another_layout.add(self.qr[0]) with self.assertRaises(LayoutError): _ = layout.combine_into_edge_map(another_layout)
def test_layout_combine_bigger(self): """combine_into_edge_map() method with another_layout is bigger""" layout = Layout() layout.add(self.qr[0]) layout.add(self.qr[1]) another_layout = Layout() another_layout.add(self.qr[1]) another_layout.add(self.qr[0]) another_layout.add(self.qr[2]) edge_map = layout.combine_into_edge_map(another_layout) self.assertDictEqual(edge_map, { (self.qr, 0): (self.qr, 1), (self.qr, 1): (self.qr, 0) })
def test_layout_avoid_dangling_virtual(self): """ No dangling pointers for virtual qubits.""" layout = Layout({(self.qr, 0): 0}) self.assertEqual(layout[0], (self.qr, 0)) layout[0] = (self.qr, 1) with self.assertRaises(KeyError): _ = layout[(self.qr, 0)]
def test_from_circuit_constructor_ghz_out_of_order_layout(self): """Test an out of order ghz state with a layout set.""" circuit = QuantumCircuit(5) circuit.h(3) circuit.cx(3, 4) circuit.cx(3, 2) circuit.cx(3, 0) circuit.cx(3, 1) circuit._layout = Layout( { circuit.qubits[3]: 0, circuit.qubits[4]: 1, circuit.qubits[2]: 2, circuit.qubits[0]: 3, circuit.qubits[1]: 4, } ) result = Operator.from_circuit(circuit) expected = QuantumCircuit(5) expected.h(0) expected.cx(0, 1) expected.cx(0, 2) expected.cx(0, 3) expected.cx(0, 4) expected_op = Operator(expected) self.assertTrue(expected_op.equiv(result))
def test_set_virtual_without_physical(self): """When adding a virtual without care in which physical is going""" layout = Layout() layout.add((self.qr, 1), 2) layout.add((self.qr, 0)) self.assertDictEqual(layout.get_virtual_bits(), {(self.qr, 0): 1, (self.qr, 1): 2})
def test_layout_swap(self): """swap() method""" layout = Layout() layout.add((self.qr, 0)) layout.add((self.qr, 1)) layout.swap(0, 1) self.assertDictEqual(layout.get_virtual_bits(), {(self.qr, 0): 1, (self.qr, 1): 0})
def test_layout_get_bits(self): """Get the map from the (qu)bits view""" layout_dict = {(self.qr, 0): 0, (self.qr, 1): 1, (self.qr, 2): 2} layout = Layout(layout_dict) self.assertDictEqual(layout_dict, layout.get_virtual_bits())
def test_set_virtual_without_physical(self): """When adding a virtual without care in which physical is going""" layout = Layout() layout.add(self.qr[1], 2) layout.add(self.qr[0]) self.assertDictEqual(layout.get_virtual_bits(), {self.qr[0]: 1, self.qr[1]: 2})
def test_layout_swap_error(self): """swap() method error""" layout = Layout() layout.add((self.qr, 0)) layout.add((self.qr, 1)) with self.assertRaises(LayoutError): layout.swap(0, (self.qr, 0))
def test_layout_swap(self): """swap() method""" layout = Layout() layout.add(self.qr[0]) layout.add(self.qr[1]) layout.swap(0, 1) self.assertDictEqual(layout.get_virtual_bits(), {self.qr[0]: 1, self.qr[1]: 0})
def test_layout_from_intlist(self): """Create a layout from a list of integers. virtual physical q1_0 -> 4 q2_0 -> 5 q2_1 -> 6 q3_0 -> 8 q3_1 -> 9 q3_2 -> 10 """ qr1 = QuantumRegister(1, 'qr1') qr2 = QuantumRegister(2, 'qr2') qr3 = QuantumRegister(3, 'qr3') intlist_layout = [4, 5, 6, 8, 9, 10] layout = Layout.from_intlist(intlist_layout, qr1, qr2, qr3) expected = Layout({ 4: qr1[0], 5: qr2[0], 6: qr2[1], 8: qr3[0], 9: qr3[1], 10: qr3[2] }) self.assertDictEqual(layout._p2v, expected._p2v) self.assertDictEqual(layout._v2p, expected._v2p)
def test_layout_from_intlist_short(self): """If the intlist is longer that your quantum register, map them to None. virtual physical q1_0 -> 4 q2_0 -> 5 q2_1 -> 6 None -> 8 None -> 9 None -> 10 """ qr1 = QuantumRegister(1, 'qr1') qr2 = QuantumRegister(2, 'qr2') intlist_layout = [4, 5, 6, 8, 9, 10] layout = Layout.from_intlist(intlist_layout, qr1, qr2) expected = Layout({ 4: qr1[0], 5: qr2[0], 6: qr2[1], 8: None, 9: None, 10: None }) self.assertDictEqual(layout._p2v, expected._p2v) self.assertDictEqual(layout._v2p, expected._v2p)
def test_virtual_keyerror(self): """When asking for an unexistant virtual qubit, KeyError""" layout = Layout() layout[self.qr[0]] = 1 with self.assertRaises(KeyError): _ = layout[self.qr[1]]
def test_copy(self): """Test copy methods return equivalent layouts.""" layout = Layout() layout.add(self.qr[0]) layout.add(self.qr[1]) layout_dict_copy = layout.copy() self.assertTrue(isinstance(layout_dict_copy, Layout)) self.assertDictEqual(layout.get_physical_bits(), layout_dict_copy.get_physical_bits()) self.assertDictEqual(layout.get_virtual_bits(), layout_dict_copy.get_virtual_bits()) layout_copy_copy = copy.copy(layout) self.assertTrue(isinstance(layout_copy_copy, Layout)) self.assertDictEqual(layout.get_physical_bits(), layout_dict_copy.get_physical_bits()) self.assertDictEqual(layout.get_virtual_bits(), layout_dict_copy.get_virtual_bits()) layout_copy_deepcopy = copy.deepcopy(layout) self.assertTrue(isinstance(layout_copy_deepcopy, Layout)) self.assertDictEqual(layout.get_physical_bits(), layout_dict_copy.get_physical_bits()) self.assertDictEqual(layout.get_virtual_bits(), layout_dict_copy.get_virtual_bits())
def test_layout_swap_error(self): """swap() method error""" layout = Layout() layout.add(self.qr[0]) layout.add(self.qr[1]) with self.assertRaises(LayoutError): layout.swap(0, self.qr[0])
def _compose_layouts(self, initial_layout, pass_final_layout, qregs): """Return the real final_layout resulting from the composition of an initial_layout with the final_layout reported by a pass. The routing passes internally start with a trivial layout, as the layout gets applied to the circuit prior to running them. So the "final_layout" they report must be amended to account for the actual initial_layout that was selected. """ trivial_layout = Layout.generate_trivial_layout(*qregs) pass_final_layout = Layout({trivial_layout[v.index]: p for v, p in pass_final_layout.get_virtual_bits().items()}) qubit_map = Layout.combine_into_edge_map(initial_layout, trivial_layout) final_layout = {v: pass_final_layout[qubit_map[v]] for v, _ in initial_layout.get_virtual_bits().items()} return Layout(final_layout)
def test_physical_keyerror(self): """When asking for an unexistant physical qubit, KeyError""" layout = Layout() layout[(self.qr, 0)] = 1 with self.assertRaises(KeyError): _ = layout[0]
def layout_test(): q0 = QuantumRegister(1, name='x') q1 = QuantumRegister(1, name='y') q2 = QuantumRegister(1, name='z') q3 = QuantumRegister(1, name='h') cr = ClassicalRegister(4) qc = QuantumCircuit(q0, q1, q2, q3, cr) qc.x(q0[0]) qc.y(q1[0]) qc.z(q2[0]) qc.h(q3[0]) qc.measure(q0, cr[0]) # qc = random_circuit(4, 1, measure=True) print(qc) q = qc.qubits print(q) input_dict = {} input_dict[q0[0]] = 3 input_dict[q1[0]] = 2 input_dict[q2[0]] = 1 input_dict[q3[0]] = 0 # input_dict[q[0]] = 3 # input_dict[q[1]] = 2 # input_dict[q[2]] = 1 # input_dict[q[3]] = 0 layout = Layout(input_dict=input_dict) print(layout) qc._layout = layout print(qc) print(qc._layout)
def run(self, dag): """Run the SabreLayout pass on `dag`. Args: dag (DAGCircuit): DAG to find layout for. Raises: TranspilerError: if dag wider than self.coupling_map """ if len(dag.qubits) > self.coupling_map.size(): raise TranspilerError("More virtual qubits exist than physical.") # Choose a random initial_layout. if self.seed is None: self.seed = np.random.randint(0, np.iinfo(np.int32).max) rng = np.random.default_rng(self.seed) physical_qubits = rng.choice(self.coupling_map.size(), len(dag.qubits), replace=False) physical_qubits = rng.permutation(physical_qubits) initial_layout = Layout( {q: dag.qubits[i] for i, q in enumerate(physical_qubits)}) if self.routing_pass is None: self.routing_pass = SabreSwap(self.coupling_map, "decay", seed=self.seed, fake_run=True) else: self.routing_pass.fake_run = True # Do forward-backward iterations. circ = dag_to_circuit(dag) rev_circ = circ.reverse_ops() for _ in range(self.max_iterations): for _ in ("forward", "backward"): pm = self._layout_and_route_passmanager(initial_layout) new_circ = pm.run(circ) # Update initial layout and reverse the unmapped circuit. pass_final_layout = pm.property_set["final_layout"] final_layout = self._compose_layouts( initial_layout, pass_final_layout, new_circ.qregs # pylint: disable=no-member ) initial_layout = final_layout circ, rev_circ = rev_circ, circ # Diagnostics logger.info("new initial layout") logger.info(initial_layout) for qreg in dag.qregs.values(): initial_layout.add_register(qreg) self.property_set["layout"] = initial_layout self.routing_pass.fake_run = False
def test_layout_avoid_dangling_virtual(self): """ No dangling pointers for virtual qubits.""" layout = Layout({self.qr[0]: 0}) self.assertEqual(layout[0], self.qr[0]) layout[0] = self.qr[1] with self.assertRaises(KeyError): _ = layout[self.qr[0]]
def test_layout_add(self): """add() method""" layout = Layout() layout[self.qr[0]] = 0 layout.add(self.qr[1]) self.assertEqual(layout[self.qr[1]], 1)
def test_layout_len_with_idle(self): """Length of the layout is the amount of physical bits""" layout = Layout() self.assertEqual(len(layout), 0) layout.add((self.qr, 2)) self.assertEqual(len(layout), 1) layout.add((self.qr, 1), 3) self.assertEqual(len(layout), 2)
def test_layout_get_physical_bits(self): """Get the map from the physical bits view""" layout = Layout({self.qr[0]: 0, self.qr[1]: 1, self.qr[2]: 2}) self.assertDictEqual(layout.get_physical_bits(), { 0: self.qr[0], 1: self.qr[1], 2: self.qr[2] })
def test_layout_repr_with_holes(self): """A non-bijective Layout repr reproduces layout""" qr = QuantumRegister(5, 'qr') layout = Layout({qr[0]: 0, qr[1]: 3, qr[2]: 4, qr[3]: 5, qr[4]: 6}) repr_layout = eval(layout.__repr__()) # pylint: disable=eval-used self.assertDictEqual(layout._p2v, repr_layout._p2v) self.assertDictEqual(layout._v2p, repr_layout._v2p)
def test_layout_get_physical_bits(self): """Get the map from the physical bits view""" layout = Layout({(self.qr, 0): 0, (self.qr, 1): 1, (self.qr, 2): 2}) self.assertDictEqual(layout.get_physical_bits(), { 0: (self.qr, 0), 1: (self.qr, 1), 2: (self.qr, 2) })
def test_layout_len(self): """Length of the layout is the amount of physical bits""" layout = Layout() self.assertEqual(len(layout), 0) layout.add(self.qr[2]) self.assertEqual(len(layout), 1) layout.add(self.qr[1], 3) self.assertEqual(len(layout), 2)
def test_layout_add(self): """add() method""" layout = Layout() layout[(self.qr, 0)] = 0 layout.add((self.qr, 1)) self.assertEqual(layout[(self.qr, 1)], 1) self.assertEqual(layout[1], (self.qr, 1))