Ejemplo n.º 1
0
 def _layout_from_raw(initial_layout, circuit):
     if initial_layout is None or isinstance(initial_layout, Layout):
         return initial_layout
     elif isinstancelist(initial_layout):
         if all(isinstanceint(elem) for elem in initial_layout):
             initial_layout = Layout.from_intlist(initial_layout, *circuit.qregs)
         elif all(elem is None or isinstance(elem, Qubit) for elem in initial_layout):
             initial_layout = Layout.from_qubit_list(initial_layout)
     elif isinstance(initial_layout, dict):
         initial_layout = Layout(initial_layout)
     else:
         raise TranspilerError("The initial_layout parameter could not be parsed")
     return initial_layout
Ejemplo n.º 2
0
    def _compose_non_swap_nodes(self, accumulator: DAGCircuit, layout: Layout,
                                new_dag: DAGCircuit) -> DAGCircuit:
        """Add all the non-swap strategy nodes that we have accumulated up to now.

        This method also resets the node accumulator to an empty dag.

        Args:
            layout: The current layout that keeps track of the swaps.
            new_dag: The new dag that we are building up.
            accumulator: A DAG to keep track of nodes that do not decompose
                using swap strategies.

        Returns:
            A new accumulator with the same registers as ``new_dag``.
        """
        # Add all the non-swap strategy nodes that we have accumulated up to now.
        order = layout.reorder_bits(new_dag.qubits)
        order_bits = [None] * len(layout)
        for idx, val in enumerate(order):
            order_bits[val] = idx

        new_dag.compose(accumulator, qubits=order_bits)

        # Re-initialize the node accumulator
        return new_dag.copy_empty_like()
Ejemplo n.º 3
0
    def test_all_single_qubit(self):
        """Test all trivial layers."""
        coupling = CouplingMap([[0, 1], [1, 2], [1, 3]])
        qr = QuantumRegister(2, 'q')
        ar = QuantumRegister(2, 'a')
        cr = ClassicalRegister(4, 'c')
        circ = QuantumCircuit(qr, ar, cr)
        circ.h(qr)
        circ.h(ar)
        circ.s(qr)
        circ.s(ar)
        circ.t(qr)
        circ.t(ar)
        circ.measure(qr[0], cr[0])  # intentional duplicate
        circ.measure(qr[0], cr[0])
        circ.measure(qr[1], cr[1])
        circ.measure(ar[0], cr[2])
        circ.measure(ar[1], cr[3])
        dag = circuit_to_dag(circ)

        layout = Layout({qr[0]: 0, qr[1]: 1, ar[0]: 2, ar[1]: 3})

        pass_ = StochasticSwap(coupling, layout, 20, 13)
        after = pass_.run(dag)
        self.assertEqual(dag, after)
Ejemplo n.º 4
0
    def test_multiple_registers_with_layout_adjust(self):
        """
        Test two registers + measurements using a layout.
        The mapper will adjust the initial layout so that
        all of the gates can be done without swaps.
        """
        coupling = CouplingMap([[0, 1], [1, 2]])

        qr_q = QuantumRegister(2, 'q')
        qr_a = QuantumRegister(1, 'a')
        cr_c = ClassicalRegister(3, 'c')
        circ = QuantumCircuit(qr_q, qr_a, cr_c)
        circ.cx(qr_q[0], qr_a[0])
        circ.cx(qr_q[1], qr_a[0])
        circ.measure(qr_q[0], cr_c[0])
        circ.measure(qr_q[1], cr_c[1])
        circ.measure(qr_a[0], cr_c[2])
        dag = circuit_to_dag(circ)

        layout = Layout({qr_q[0]: 0, qr_q[1]: 1, qr_a[0]: 2})

        pass_ = StochasticSwap(coupling, layout, 20, 13)
        after = pass_.run(dag)

        self.assertEqual(dag, after)
Ejemplo n.º 5
0
def test_multi_alap():
    qr0 = QuantumRegister(2)
    qr1 = QuantumRegister(2)
    qc = QuantumCircuit(qr0, qr1)

    qc.cx(qr0[0], qr0[1])

    qc.cx(qr1[0], qr1[1])
    qc.cx(qr1[1], qr1[0])
    qc.cx(qr1[0], qr1[1])

    qc.measure_all()

    layout = Layout({
        qr0[0]: 0,
        qr0[1]: 1,
        qr1[0]: 2,
        qr1[1]: 3,
    })
    durations = InstructionDurations([('cx', None, 1000),
                                      ('measure', None, 1000)])

    transpiled_qc = transpile(qc, initial_layout=layout)
    dag = circuit_to_dag(transpiled_qc)

    malap_dag = MultiALAPSchedule(durations).run(dag, time_unit="dt")

    print(dag_to_circuit(malap_dag))
    assert (malap_dag.duration == 4000)
Ejemplo n.º 6
0
    def test_move_measurements(self):
        """Measurements applied AFTER swap mapping.
        """
        backend = FakeRueschlikon()
        cmap = backend.configuration().coupling_map
        circ = QuantumCircuit.from_qasm_file(
            self._get_resource_path('move_measurements.qasm', Path.QASMS))

        lay = Layout({
            ('qa', 0): ('q', 0),
            ('qa', 1): ('q', 1),
            ('qb', 0): ('q', 15),
            ('qb', 1): ('q', 2),
            ('qb', 2): ('q', 14),
            ('qN', 0): ('q', 3),
            ('qN', 1): ('q', 13),
            ('qN', 2): ('q', 4),
            ('qc', 0): ('q', 12),
            ('qNt', 0): ('q', 5),
            ('qNt', 1): ('q', 11),
            ('qt', 0): ('q', 6)
        })
        out = transpile(circ, initial_layout=lay, coupling_map=cmap)
        out_dag = circuit_to_dag(out)
        meas_nodes = out_dag.named_nodes('measure')
        for meas_node in meas_nodes:
            is_last_measure = all([
                after_measure.type == 'out'
                for after_measure in out_dag.quantum_successors(meas_node)
            ])
            self.assertTrue(is_last_measure)
Ejemplo n.º 7
0
    def run(self, dag):
        """
        If `dag` is mapped and the direction is correct the property
        `is_direction_mapped` is set to True (or to False otherwise).

        Args:
            dag (DAGCircuit): DAG to check.
        """
        if self.layout is None:
            if self.property_set["layout"]:
                self.layout = self.property_set["layout"]
            else:
                self.layout = Layout.generate_trivial_layout(
                    *dag.qregs.values())

        self.property_set['is_direction_mapped'] = True
        edges = self.coupling_map.get_edges()

        for gate in dag.twoQ_gates():
            physical_q0 = self.layout[gate.qargs[0]]
            physical_q1 = self.layout[gate.qargs[1]]

            if isinstance(gate.op,
                          (CXBase, CnotGate)) and (physical_q0,
                                                   physical_q1) not in edges:
                self.property_set['is_direction_mapped'] = False
                return
Ejemplo n.º 8
0
    def test_already_mapped_1(self):
        """Circuit not remapped if matches topology.

        See: https://github.com/Qiskit/qiskit-terra/issues/342
        """
        backend = FakeRueschlikon()
        coupling_map = backend.configuration().coupling_map
        basis_gates = backend.configuration().basis_gates

        qr = QuantumRegister(16, 'qr')
        cr = ClassicalRegister(16, 'cr')
        qc = QuantumCircuit(qr, cr)
        qc.cx(qr[3], qr[14])
        qc.cx(qr[5], qr[4])
        qc.h(qr[9])
        qc.cx(qr[9], qr[8])
        qc.x(qr[11])
        qc.cx(qr[3], qr[4])
        qc.cx(qr[12], qr[11])
        qc.cx(qr[13], qr[4])
        qc.measure(qr, cr)

        new_qc = transpile(qc,
                           coupling_map=coupling_map,
                           basis_gates=basis_gates,
                           initial_layout=Layout.generate_trivial_layout(qr))
        cx_qubits = [
            qargs for (gate, qargs, _) in new_qc.data if gate.name == "cx"
        ]
        cx_qubits_physical = [[ctrl.index, tgt.index]
                              for [ctrl, tgt] in cx_qubits]
        self.assertEqual(sorted(cx_qubits_physical),
                         [[3, 4], [3, 14], [5, 4], [9, 8], [12, 11], [13, 4]])
    def test_3q_circuit_5q_coupling(self):
        """Allocates 2 ancillas for a 3q circuit in a 5q coupling map

                    0 -> q0
        q0 -> 0     1 -> q1
        q1 -> 1  => 2 -> q2
        q2 -> 2     3 -> ancilla0
                    4 -> ancilla1
        """
        qr = QuantumRegister(3, 'q')
        circ = QuantumCircuit(qr)
        dag = circuit_to_dag(circ)

        initial_layout = Layout()
        initial_layout[0] = qr[0]
        initial_layout[1] = qr[1]
        initial_layout[2] = qr[2]

        pass_ = FullAncillaAllocation(self.cmap5)
        pass_.property_set['layout'] = initial_layout

        pass_.run(dag)
        after_layout = pass_.property_set['layout']

        ancilla = QuantumRegister(2, 'ancilla')

        self.assertEqual(after_layout[0], qr[0])
        self.assertEqual(after_layout[1], qr[1])
        self.assertEqual(after_layout[2], qr[2])
        self.assertEqual(after_layout[3], ancilla[0])
        self.assertEqual(after_layout[4], ancilla[1])
    def test_3q_with_holes_5q_coupling(self):
        """Allocates 3 ancillas for a 2q circuit on a 5q coupling, with holes

                       0 -> q0
        q0 -> 0        1 -> ancilla0
        q1 -> 2    =>  2 ->  q2
                       3 -> ancilla1
                       4 -> ancilla2
        """
        qr = QuantumRegister(2, 'q')
        circ = QuantumCircuit(qr)
        dag = circuit_to_dag(circ)

        initial_layout = Layout()
        initial_layout[0] = qr[0]
        initial_layout[2] = qr[1]

        pass_ = FullAncillaAllocation(self.cmap5)
        pass_.property_set['layout'] = initial_layout
        pass_.run(dag)
        after_layout = pass_.property_set['layout']

        ancilla = QuantumRegister(3, 'ancilla')

        self.assertEqual(after_layout[0], qr[0])
        self.assertEqual(after_layout[1], ancilla[0])
        self.assertEqual(after_layout[2], qr[1])
        self.assertEqual(after_layout[3], ancilla[1])
        self.assertEqual(after_layout[4], ancilla[2])
    def test_only_output_cx_and_swaps_in_coupling_map(self):
        """Test that output DAG contains only 2q gates from the the coupling map."""

        coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
        qr = QuantumRegister(4, 'q')
        cr = ClassicalRegister(4, 'c')
        circuit = QuantumCircuit(qr, cr)
        circuit.h(qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[2])
        circuit.cx(qr[0], qr[3])
        circuit.measure(qr, cr)
        dag = circuit_to_dag(circuit)

        layout = Layout({qr[0]: 0, qr[1]: 1, qr[2]: 2, qr[3]: 3})

        pass_ = StochasticSwap(coupling, layout, 20, 5)
        after = pass_.run(dag)

        valid_couplings = [
            set([layout[a], layout[b]]) for (a, b) in coupling.get_edges()
        ]

        for _2q_gate in after.twoQ_gates():
            self.assertIn(set(_2q_gate.qargs), valid_couplings)
Ejemplo n.º 12
0
    def test_initial_layout_in_different_qregs(self):
        """ Using an initial_layout, and with several qregs
         0:q1_0:--(+)--
                   |
         1:q0_0:---|---
                   |
         2:q2_0:---.---

         CouplingMap map: [0]--[1]--[2]

         0:q1_0:--X-------
                  |
         1:q0_0:--X---.---
                      |
         2:q2_0:-----(+)--
        """
        coupling = CouplingMap([[0, 1], [1, 2]])

        qr0 = QuantumRegister(1, 'q0')
        qr1 = QuantumRegister(1, 'q1')
        qr2 = QuantumRegister(1, 'q2')
        circuit = QuantumCircuit(qr0, qr1, qr2)
        circuit.cx(qr1[0], qr2[0])
        dag = circuit_to_dag(circuit)
        layout = Layout({qr1[0]: 0, qr0[0]: 1, qr2[0]: 2})

        expected = QuantumCircuit(qr0, qr1, qr2)
        expected.swap(qr1[0], qr0[0])
        expected.cx(qr0[0], qr2[0])

        pass_ = BasicSwap(coupling, initial_layout=layout)
        after = pass_.run(dag)

        self.assertEqual(circuit_to_dag(expected), after)
Ejemplo n.º 13
0
    def test_initial_layout(self):
        """ Using an initial_layout
         0:q1:--(+)--
                 |
         1:q0:---|---
                 |
         2:q2:---.---

         CouplingMap map: [0]--[1]--[2]

         0:q1:--X-------
                |
         1:q0:--X---.---
                    |
         2:q2:-----(+)--

        """
        coupling = CouplingMap([[0, 1], [1, 2]])

        qr = QuantumRegister(3, 'q')
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[1], qr[2])
        dag = circuit_to_dag(circuit)
        layout = Layout({qr[1]: 0, qr[0]: 1, qr[2]: 2})

        expected = QuantumCircuit(qr)
        expected.swap(qr[1], qr[0])
        expected.cx(qr[0], qr[2])

        pass_ = BasicSwap(coupling, initial_layout=layout)
        after = pass_.run(dag)

        self.assertEqual(circuit_to_dag(expected), after)
    def test_3q_out_of_order_5q_coupling(self):
        """Allocates 2 ancillas a 3q circuit on a 5q coupling map, out of order

                       0 <- q0
        q0 -> 0        1 <- ancilla0
        q1 -> 3   =>   2 <- q2
        q2 -> 2        3 <- q1
                       4 <- ancilla1
        """
        qr = QuantumRegister(3, 'q')
        circ = QuantumCircuit(qr)
        dag = circuit_to_dag(circ)

        initial_layout = Layout()
        initial_layout[0] = qr[0]
        initial_layout[3] = qr[1]
        initial_layout[2] = qr[2]

        pass_ = FullAncillaAllocation(self.cmap5)
        pass_.property_set['layout'] = initial_layout
        pass_.run(dag)
        after_layout = pass_.property_set['layout']

        ancilla = QuantumRegister(2, 'ancilla')

        self.assertEqual(after_layout[0], qr[0])
        self.assertEqual(after_layout[1], ancilla[0])
        self.assertEqual(after_layout[2], qr[2])
        self.assertEqual(after_layout[3], qr[1])
        self.assertEqual(after_layout[4], ancilla[1])
    def test_with_extension(self):
        """There are 2 virtual qubit to extend."""
        ancilla = QuantumRegister(2, 'ancilla')

        layout = Layout({0: self.qr3[0], 1: ancilla[0],
                         2: self.qr3[1], 3: ancilla[1],
                         4: self.qr3[2]})
        layout.add_register(ancilla)

        pass_ = EnlargeWithAncilla()
        pass_.property_set['layout'] = layout
        after = pass_.run(self.dag)

        qregs = list(after.qregs.values())
        self.assertEqual(2, len(qregs))
        self.assertEqual(self.qr3, qregs[0])
        self.assertEqual(ancilla, qregs[1])
Ejemplo n.º 16
0
    def test_final_measurement_barrier_for_devices(self, mock_pass):
        """Verify BarrierBeforeFinalMeasurements pass is called in default pipeline for devices."""

        circ = QuantumCircuit.from_qasm_file(self._get_resource_path('example.qasm', Path.QASMS))
        layout = Layout.generate_trivial_layout(*circ.qregs)
        transpile(circ, coupling_map=FakeRueschlikon().configuration().coupling_map,
                  initial_layout=layout)

        self.assertTrue(mock_pass.called)
Ejemplo n.º 17
0
    def create_passmanager(self, coupling_map, initial_layout=None):
        """Returns a PassManager using self.pass_class(coupling_map, initial_layout)"""
        passmanager = PassManager()
        if initial_layout:
            passmanager.append(SetLayout(Layout(initial_layout)))

        # pylint: disable=not-callable
        passmanager.append(self.pass_class(CouplingMap(coupling_map), **self.additional_args))
        return passmanager
Ejemplo n.º 18
0
def _remap_circuit_faulty_backend(circuit, num_qubits, backend_prop,
                                  faulty_qubits_map):
    faulty_qubits = backend_prop.faulty_qubits() if backend_prop else []
    disconnected_qubits = {
        k
        for k, v in faulty_qubits_map.items() if v is None
    }.difference(faulty_qubits)
    faulty_qubits_map_reverse = {v: k for k, v in faulty_qubits_map.items()}
    if faulty_qubits:
        faulty_qreg = circuit._create_qreg(len(faulty_qubits), 'faulty')
    else:
        faulty_qreg = []
    if disconnected_qubits:
        disconnected_qreg = circuit._create_qreg(len(disconnected_qubits),
                                                 'disconnected')
    else:
        disconnected_qreg = []

    new_layout = Layout()
    faulty_qubit = 0
    disconnected_qubit = 0

    for real_qubit in range(num_qubits):
        if faulty_qubits_map[real_qubit] is not None:
            new_layout[real_qubit] = circuit._layout[
                faulty_qubits_map[real_qubit]]
        else:
            if real_qubit in faulty_qubits:
                new_layout[real_qubit] = faulty_qreg[faulty_qubit]
                faulty_qubit += 1
            else:
                new_layout[real_qubit] = disconnected_qreg[disconnected_qubit]
                disconnected_qubit += 1
    physical_layout_dict = {}
    for qubit in circuit.qubits:
        physical_layout_dict[qubit] = faulty_qubits_map_reverse[qubit.index]
    for qubit in faulty_qreg[:] + disconnected_qreg[:]:
        physical_layout_dict[qubit] = new_layout[qubit]
    dag_circuit = circuit_to_dag(circuit)
    apply_layout_pass = ApplyLayout()
    apply_layout_pass.property_set['layout'] = Layout(physical_layout_dict)
    circuit = dag_to_circuit(apply_layout_pass.run(dag_circuit))
    circuit._layout = new_layout
    return circuit
Ejemplo n.º 19
0
def _remap_layout_faulty_backend(layout, faulty_qubits_map):
    if layout is None:
        return layout
    new_layout = Layout()
    for virtual, physical in layout.get_virtual_bits().items():
        if faulty_qubits_map[physical] is None:
            raise TranspilerError("The initial_layout parameter refers to faulty"
                                  " or disconnected qubits")
        new_layout[virtual] = faulty_qubits_map[physical]
    return new_layout
    def test_full_connected_coupling_map(self):
        """Test if the permutation {0->3,1->0,2->1,3->2} in a fully connected map."""
        v = QuantumRegister(4, "v")  # virtual qubits
        from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2, v[3]: 3})
        to_layout = Layout({v[0]: 3, v[1]: 0, v[2]: 1, v[3]: 2})
        ltpass = LayoutTransformation(coupling_map=None,
                                      from_layout=from_layout,
                                      to_layout=to_layout,
                                      seed=42)
        qc = QuantumCircuit(4)  # input (empty) physical circuit
        dag = circuit_to_dag(qc)
        output_dag = ltpass.run(dag)

        expected = QuantumCircuit(4)
        expected.swap(1, 0)
        expected.swap(2, 1)
        expected.swap(3, 2)

        self.assertEqual(circuit_to_dag(expected), output_dag)
    def test_three_qubit(self):
        """Test if the permutation {0->2,1->0,2->1} is implemented correctly."""
        v = QuantumRegister(3, "v")  # virtual qubits
        coupling = CouplingMap([[0, 1], [1, 2]])
        from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2})
        to_layout = Layout({v[0]: 2, v[1]: 0, v[2]: 1})
        ltpass = LayoutTransformation(coupling_map=coupling,
                                      from_layout=from_layout,
                                      to_layout=to_layout,
                                      seed=42)
        qc = QuantumCircuit(3)
        dag = circuit_to_dag(qc)
        output_dag = ltpass.run(dag)

        expected = QuantumCircuit(3)
        expected.swap(1, 0)
        expected.swap(1, 2)

        self.assertEqual(circuit_to_dag(expected), output_dag)
Ejemplo n.º 22
0
    def test_no_extension(self):
        """There are no virtual qubits to extend."""
        layout = Layout({self.qr3[0]: 0, self.qr3[1]: 1, self.qr3[2]: 2})

        pass_ = EnlargeWithAncilla(layout)
        after = pass_.run(self.dag)

        qregs = list(after.qregs.values())
        self.assertEqual(1, len(qregs))
        self.assertEqual(self.qr3, qregs[0])
Ejemplo n.º 23
0
    def run(self, quantum_circuit):

        dag_circuit = circuit_to_dag(quantum_circuit)

        init_time = time.time()
        self.parameters["TIME_START"] = init_time

        initial_mapping = []
        if self.parameters["initial_map"] == K7MInitialMapping.RANDOM:
            # Only the first positions which correspond to the circuit qubits
            initial_mapping = numpy.random.permutation(
                self.parameters["nisq_qubits"])
            initial_mapping = initial_mapping[:dag_circuit.num_qubits()]
        elif self.parameters["initial_map"] == K7MInitialMapping.LINEAR:
            initial_mapping = list(range(dag_circuit.num_qubits()))
        elif self.parameters["initial_map"] == K7MInitialMapping.HEURISTIC:
            initial_mapping = cuthill_order(dag_circuit, self.coupling_obj,
                                            self.parameters)

        init_time = time.time() - init_time

        if initial_mapping is None:
            return None, init_time, None

        # print(initial_mapping)
        #
        # return quantum_circuit
        print("                       .......")

        original_pm = PassManager()
        optimal_layout = Layout()
        for c_idx, p_idx in enumerate(initial_mapping):
            optimal_layout.add(quantum_circuit.qregs[0][c_idx], p_idx)

        original_pm.append([
            SetLayout(optimal_layout),
            ApplyLayout(),
            StochasticSwap(self.coupling_obj.coupling, seed=0),
            Decompose(gate=qiskit.extensions.SwapGate)
        ])

        return original_pm.run(quantum_circuit), init_time, initial_mapping
Ejemplo n.º 24
0
    def run(self, dag):
        """
        Flips the cx nodes to match the directed coupling map.
        Args:
            dag (DAGCircuit): DAG to map.
        Returns:
            DAGCircuit: The rearranged dag for the coupling map

        Raises:
            TranspilerError: If the circuit cannot be mapped just by flipping the
                cx nodes.
        """
        new_dag = DAGCircuit()

        if self.layout is None:
            # LegacySwap renames the register in the DAG and does not match the property set
            self.layout = Layout.generate_trivial_layout(*dag.qregs.values())

        for layer in dag.serial_layers():
            subdag = layer['graph']

            for cnot_node in subdag.named_nodes('cx', 'CX'):
                control = cnot_node.qargs[0]
                target = cnot_node.qargs[1]

                physical_q0 = self.layout[control]
                physical_q1 = self.layout[target]
                if self.coupling_map.distance(physical_q0, physical_q1) != 1:
                    raise TranspilerError(
                        'The circuit requires a connection between physical '
                        'qubits %s and %s' % (physical_q0, physical_q1))

                if (physical_q0,
                        physical_q1) not in self.coupling_map.get_edges():
                    # A flip needs to be done

                    # Create the involved registers
                    if control[0] not in subdag.qregs.values():
                        subdag.add_qreg(control[0])
                    if target[0] not in subdag.qregs.values():
                        subdag.add_qreg(target[0])

                    # Add H gates around
                    subdag.apply_operation_back(HGate(), [target], [])
                    subdag.apply_operation_back(HGate(), [control], [])
                    subdag.apply_operation_front(HGate(), [target], [])
                    subdag.apply_operation_front(HGate(), [control], [])

                    # Flips the CX
                    cnot_node.qargs[0], cnot_node.qargs[1] = target, control

            new_dag.extend_back(subdag)

        return new_dag
    def test_default_pass_manager_two(self):
        """Test default_pass_manager.run(circuitS).

        circuit1 and circuit2:
        qr0:-[H]--.------------  -> 1
                  |
        qr1:-----(+)--.--------  -> 2
                      |
        qr2:---------(+)--.----  -> 3
                          |
        qr3:-------------(+)---  -> 5

        device:
        0  -  1  -  2  -  3  -  4  -  5  -  6

              |     |     |     |     |     |

              13 -  12  - 11 -  10 -  9  -  8  -   7
        """
        qr = QuantumRegister(4, "qr")
        circuit1 = QuantumCircuit(qr)
        circuit1.h(qr[0])
        circuit1.cx(qr[0], qr[1])
        circuit1.cx(qr[1], qr[2])
        circuit1.cx(qr[2], qr[3])

        circuit2 = QuantumCircuit(qr)
        circuit2.cx(qr[1], qr[2])
        circuit2.cx(qr[0], qr[1])
        circuit2.cx(qr[2], qr[3])

        coupling_map = FakeMelbourne().configuration().coupling_map
        basis_gates = FakeMelbourne().configuration().basis_gates
        initial_layout = [None, qr[0], qr[1], qr[2], None, qr[3]]

        pass_manager = level_1_pass_manager(
            PassManagerConfig(
                basis_gates=basis_gates,
                coupling_map=CouplingMap(coupling_map),
                initial_layout=Layout.from_qubit_list(initial_layout),
                seed_transpiler=42,
            ))
        new_circuits = pass_manager.run([circuit1, circuit2])

        for new_circuit in new_circuits:
            bit_indices = {
                bit: idx
                for idx, bit in enumerate(new_circuit.qregs[0])
            }

            for gate, qargs, _ in new_circuit.data:
                if isinstance(gate, CXGate):
                    self.assertIn([bit_indices[x] for x in qargs],
                                  coupling_map)
 def test_empty_score(self):
     """Test error rate is 0 for empty circuit."""
     bit_map = {}
     reverse_bit_map = {}
     im_graph = retworkx.PyDiGraph()
     backend = FakeYorktownV2()
     vf2_pass = VF2PostLayout(target=backend.target)
     layout = Layout()
     score = vf2_pass._score_layout(layout, bit_map, reverse_bit_map,
                                    im_graph)
     self.assertEqual(0, score)
Ejemplo n.º 27
0
 def setUp(self):
     coupling = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
     coupling_map = CouplingMap(couplinglist=coupling)
     qr = QuantumRegister(7, 'q')
     layout = Layout({qr[i]: i for i in range(coupling_map.size())})
     self.config = TranspileConfig(optimization_level=1,
                                   basis_gates=['u1', 'u3', 'u2', 'cx'],
                                   initial_layout=layout,
                                   coupling_map=coupling_map,
                                   seed_transpiler=987,
                                   backend_properties=None)
    def test_four_qubit(self):
        """Test if the permutation {0->3,1->0,2->1,3->2} is implemented correctly."""
        v = QuantumRegister(4, "v")  # virtual qubits
        coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])
        from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2, v[3]: 3})
        to_layout = Layout({v[0]: 3, v[1]: 0, v[2]: 1, v[3]: 2})
        ltpass = LayoutTransformation(coupling_map=coupling,
                                      from_layout=from_layout,
                                      to_layout=to_layout,
                                      seed=42)
        qc = QuantumCircuit(4)  # input (empty) physical circuit
        dag = circuit_to_dag(qc)
        output_dag = ltpass.run(dag)

        expected = QuantumCircuit(4)
        expected.swap(1, 0)
        expected.swap(1, 2)
        expected.swap(2, 3)

        self.assertEqual(circuit_to_dag(expected), output_dag)
Ejemplo n.º 29
0
    def run(self, dag):
        """Run one pass of the lookahead mapper on the provided DAG.

        Args:
            dag (DAGCircuit): the directed acyclic graph to be mapped
        Returns:
            DAGCircuit: A dag mapped to be compatible with the coupling_map in
                the property_set.
        Raises:
            TranspilerError: if the coupling map or the layout are not
            compatible with the DAG
        """
        coupling_map = self._coupling_map
        ordered_virtual_gates = list(dag.serial_layers())

        if self.initial_layout is None:
            if self.property_set["layout"]:
                self.initial_layout = self.property_set["layout"]
            else:
                self.initial_layout = Layout.generate_trivial_layout(
                    *dag.qregs.values())

        if len(dag.qubits()) != len(self.initial_layout):
            raise TranspilerError(
                'The layout does not match the amount of qubits in the DAG')

        if len(self._coupling_map.physical_qubits) != len(self.initial_layout):
            raise TranspilerError(
                "Mappers require to have the layout to be the same size as the coupling map"
            )

        mapped_gates = []
        layout = self.initial_layout.copy()
        gates_remaining = ordered_virtual_gates.copy()

        while gates_remaining:
            best_step = _search_forward_n_swaps(layout, gates_remaining,
                                                coupling_map)

            layout = best_step['layout']
            gates_mapped = best_step['gates_mapped']
            gates_remaining = best_step['gates_remaining']

            mapped_gates.extend(gates_mapped)

        # Preserve input DAG's name, regs, wire_map, etc. but replace the graph.
        mapped_dag = _copy_circuit_metadata(dag, coupling_map)

        for node in mapped_gates:
            mapped_dag.apply_operation_back(op=node.op,
                                            qargs=node.qargs,
                                            cargs=node.cargs)

        return mapped_dag
 def test_three_qubit(self):
     """Test if the permutation {0->2,1->0,2->1} is implemented correctly."""
     np.random.seed(0)
     v = QuantumRegister(3, 'v')  # virtual qubits
     coupling = CouplingMap([[0, 1], [1, 2]])
     from_layout = Layout({v[0]: 0, v[1]: 1, v[2]: 2})
     to_layout = Layout({v[0]: 2, v[1]: 0, v[2]: 1})
     ltpass = LayoutTransformation(coupling_map=coupling,
                                   from_layout=from_layout,
                                   to_layout=to_layout)
     qc = QuantumCircuit(3)  # input (empty) physical circuit
     dag = circuit_to_dag(qc)
     q = dag.qubits()
     output_dag = ltpass.run(dag)
     # output_dag.draw()
     # Check that only two swaps were performed
     self.assertCountEqual(["swap"] * 2, [op.name for op in output_dag.topological_op_nodes()])
     # And check that the swaps were first performed on {q0,q1} then on {q1,q2}.
     self.assertEqual([frozenset([q[0], q[1]]), frozenset([q[1], q[2]])],
                      [frozenset(op.qargs) for op in output_dag.topological_op_nodes()])