Пример #1
0
 def test_objective_function(self):
     """Test if ``objective`` functions priorities metrics correctly."""
     qc = QuantumCircuit(4)
     qc.dcx(0, 1)
     qc.cx(2, 3)
     qc.dcx(0, 2)
     qc.cx(1, 3)
     qc.dcx(0, 1)
     qc.cx(2, 3)
     coupling = CouplingMap(FakeLima().configuration().coupling_map)
     dep_opt = BIPMapping(coupling,
                          objective="depth",
                          qubit_subset=[0, 1, 3, 4])(qc)
     err_opt = BIPMapping(
         coupling,
         objective="gate_error",
         qubit_subset=[0, 1, 3, 4],
         backend_prop=FakeLima().properties(),
     )(qc)
     # depth = number of su4 layers (mirrored gates have to be consolidated as single su4 gates)
     pm_ = PassManager(
         [Collect2qBlocks(),
          ConsolidateBlocks(basis_gates=["cx"])])
     dep_opt = pm_.run(dep_opt)
     err_opt = pm_.run(err_opt)
     self.assertLessEqual(dep_opt.depth(), err_opt.depth())
     # count CNOTs after synthesized
     dep_opt = UnitarySynthesis(basis_gates=["cx"])(dep_opt)
     err_opt = UnitarySynthesis(basis_gates=["cx"])(err_opt)
     self.assertGreater(dep_opt.count_ops()["cx"],
                        err_opt.count_ops()["cx"])
Пример #2
0
    def test_swaps_in_dummy_steps(self):
        """Test the case when swaps are inserted in dummy steps."""
        circuit = QuantumCircuit(4)
        circuit.cx(0, 1)
        circuit.cx(2, 3)
        circuit.h([0, 1, 2, 3])
        circuit.barrier()
        circuit.cx(0, 3)
        circuit.cx(1, 2)
        circuit.barrier()
        circuit.cx(0, 2)
        circuit.cx(1, 3)

        coupling = CouplingMap.from_line(4)
        property_set = {}
        actual = BIPMapping(coupling, objective="depth")(circuit, property_set)
        self.assertEqual(7, actual.depth())

        CheckMap(coupling)(actual, property_set)
        self.assertTrue(property_set["is_swap_mapped"])

        # no swaps before the first barrier
        for inst, _, _ in actual.data:
            if isinstance(inst, Barrier):
                break
            self.assertFalse(isinstance(inst, SwapGate))
Пример #3
0
    def test_no_swap_multi_layer(self):
        """Can find the best layout for a circuit with multiple layers."""
        coupling = CouplingMap([[0, 1], [1, 2], [2, 3]])

        qr = QuantumRegister(4, name="qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[1], qr[0])
        circuit.cx(qr[0], qr[3])

        property_set = {}
        actual = BIPMapping(coupling, objective="depth")(circuit, property_set)
        self.assertEqual(2, actual.depth())

        CheckMap(coupling)(actual, property_set)
        self.assertTrue(property_set["is_swap_mapped"])
Пример #4
0
    def test_never_modify_mapped_circuit(self):
        """Test that the mapping is idempotent.
        It should not modify a circuit which is already compatible with the
        coupling map, and can be applied repeatedly without modifying the circuit.
        """
        coupling = CouplingMap([[0, 1], [0, 2]])

        circuit = QuantumCircuit(3, 2)
        circuit.cx(1, 2)
        circuit.measure(1, 0)
        circuit.measure(2, 1)
        dag = circuit_to_dag(circuit)

        mapped_dag = BIPMapping(coupling).run(dag)
        remapped_dag = BIPMapping(coupling).run(mapped_dag)

        self.assertEqual(mapped_dag, remapped_dag)
Пример #5
0
    def test_unconnected_qubit_subset(self):
        """Fails if qubits in `qubit_subset` are not connected."""
        circuit = QuantumCircuit(3)
        circuit.cx(0, 1)

        coupling = CouplingMap([(0, 1), (1, 3), (3, 2)])
        with self.assertRaises(TranspilerError):
            BIPMapping(coupling, qubit_subset=[0, 1, 2])(circuit)
Пример #6
0
    def test_different_number_of_virtual_and_physical_qubits(self):
        """Test the case when number of virtual and physical qubits are different."""
        circuit = QuantumCircuit(4)
        circuit.cx(0, 1)
        circuit.cx(2, 3)
        circuit.cx(0, 3)
        circuit.cx(1, 2)

        coupling = CouplingMap.from_line(5)
        with self.assertRaises(TranspilerError):
            BIPMapping(coupling)(circuit)
Пример #7
0
    def test_multi_cregs(self):
        """Test for multiple ClassicalRegisters."""

        #                      ┌───┐ ░ ┌─┐
        # qr_0: ──■────────────┤ X ├─░─┤M├─────────
        #       ┌─┴─┐     ┌───┐└─┬─┘ ░ └╥┘┌─┐
        # qr_1: ┤ X ├──■──┤ H ├──■───░──╫─┤M├──────
        #       └───┘┌─┴─┐└───┘      ░  ║ └╥┘┌─┐
        # qr_2: ──■──┤ X ├───────────░──╫──╫─┤M├───
        #       ┌─┴─┐└───┘           ░  ║  ║ └╥┘┌─┐
        # qr_3: ┤ X ├────────────────░──╫──╫──╫─┤M├
        #       └───┘                ░  ║  ║  ║ └╥┘
        #  c: 2/════════════════════════╩══╬══╩══╬═
        #                               0  ║  1  ║
        #                                  ║     ║
        #  d: 2/═══════════════════════════╩═════╩═
        #                                  0     1
        qr = QuantumRegister(4, "qr")
        cr1 = ClassicalRegister(2, "c")
        cr2 = ClassicalRegister(2, "d")
        circuit = QuantumCircuit(qr, cr1, cr2)
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[2], qr[3])
        circuit.cx(qr[1], qr[2])
        circuit.h(qr[1])
        circuit.cx(qr[1], qr[0])
        circuit.barrier(qr)
        circuit.measure(qr[0], cr1[0])
        circuit.measure(qr[1], cr2[0])
        circuit.measure(qr[2], cr1[1])
        circuit.measure(qr[3], cr2[1])

        coupling = CouplingMap([[0, 1], [0, 2], [2, 3]])  # linear [1, 0, 2, 3]
        property_set = {}
        actual = BIPMapping(coupling, objective="depth")(circuit, property_set)
        self.assertEqual(5, actual.depth())

        CheckMap(coupling)(actual, property_set)
        self.assertTrue(property_set["is_swap_mapped"])
Пример #8
0
    def test_no_two_qubit_gates(self):
        """Returns the original circuit if the circuit has no 2q-gates
        q0:--[H]--
        q1:-------
        CouplingMap map: [0]--[1]
        """
        coupling = CouplingMap([[0, 1]])

        circuit = QuantumCircuit(2)
        circuit.h(0)

        actual = BIPMapping(coupling)(circuit)

        self.assertEqual(circuit, actual)
Пример #9
0
    def test_no_swap(self):
        """Adding no swap if not giving initial layout"""
        coupling = CouplingMap([[0, 1], [0, 2]])

        circuit = QuantumCircuit(3)
        circuit.cx(1, 2)

        actual = BIPMapping(coupling)(circuit)

        q = QuantumRegister(3, name="q")
        expected = QuantumCircuit(q)
        expected.cx(q[0], q[1])

        self.assertEqual(expected, actual)
Пример #10
0
    def test_ignore_initial_layout(self):
        """Ignoring initial layout even when it is supplied"""
        coupling = CouplingMap([[0, 1], [0, 2]])

        circuit = QuantumCircuit(3)
        circuit.cx(1, 2)

        property_set = {"layout": Layout.generate_trivial_layout(*circuit.qubits)}
        actual = BIPMapping(coupling)(circuit, property_set)

        q = QuantumRegister(3, name="q")
        expected = QuantumCircuit(q)
        expected.cx(q[0], q[1])

        self.assertEqual(expected, actual)
Пример #11
0
    def test_unmappable_cnots_in_a_layer(self):
        """Test mapping of a circuit with 2 cnots in a layer into T-shape coupling,
        which BIPMapping cannot map."""
        qr = QuantumRegister(4, "q")
        cr = ClassicalRegister(4, "c")
        circuit = QuantumCircuit(qr, cr)
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[2], qr[3])
        circuit.measure(qr, cr)

        coupling = CouplingMap([[0, 1], [1, 2], [1, 3]])  # {0: [1], 1: [2, 3]}
        actual = BIPMapping(coupling)(circuit)

        # Fails to map and returns the original circuit
        self.assertEqual(circuit, actual)
Пример #12
0
    def test_swaps_in_dummy_steps(self):
        """Test the case when swaps are inserted in dummy steps."""

        #           ┌───┐ ░            ░
        # q_0: ──■──┤ H ├─░───■────────░───■───────
        #      ┌─┴─┐├───┤ ░   │        ░   │
        # q_1: ┤ X ├┤ H ├─░───┼────■───░───┼────■──
        #      └───┘├───┤ ░   │  ┌─┴─┐ ░ ┌─┴─┐  │
        # q_2: ──■──┤ H ├─░───┼──┤ X ├─░─┤ X ├──┼──
        #      ┌─┴─┐├───┤ ░ ┌─┴─┐└───┘ ░ └───┘┌─┴─┐
        # q_3: ┤ X ├┤ H ├─░─┤ X ├──────░──────┤ X ├
        #      └───┘└───┘ ░ └───┘      ░      └───┘
        circuit = QuantumCircuit(4)
        circuit.cx(0, 1)
        circuit.cx(2, 3)
        circuit.h([0, 1, 2, 3])
        circuit.barrier()
        circuit.cx(0, 3)
        circuit.cx(1, 2)
        circuit.barrier()
        circuit.cx(0, 2)
        circuit.cx(1, 3)

        coupling = CouplingMap.from_line(4)
        property_set = {}
        actual = BIPMapping(coupling, objective="depth")(circuit, property_set)
        self.assertEqual(7, actual.depth())

        CheckMap(coupling)(actual, property_set)
        self.assertTrue(property_set["is_swap_mapped"])

        # no swaps before the first barrier
        for inst, _, _ in actual.data:
            if isinstance(inst, Barrier):
                break
            self.assertFalse(isinstance(inst, SwapGate))
Пример #13
0
    def test_multi_cregs(self):
        """Test for multiple ClassicalRegisters."""
        qr = QuantumRegister(4, "qr")
        cr1 = ClassicalRegister(2, "c")
        cr2 = ClassicalRegister(2, "d")
        circuit = QuantumCircuit(qr, cr1, cr2)
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[2], qr[3])
        circuit.cx(qr[1], qr[2])
        circuit.h(qr[1])
        circuit.cx(qr[1], qr[0])
        circuit.barrier(qr)
        circuit.measure(qr[0], cr1[0])
        circuit.measure(qr[1], cr2[0])
        circuit.measure(qr[2], cr1[1])
        circuit.measure(qr[3], cr2[1])

        coupling = CouplingMap([[0, 1], [0, 2], [2, 3]])  # linear [1, 0, 2, 3]
        property_set = {}
        actual = BIPMapping(coupling, objective="depth")(circuit, property_set)
        self.assertEqual(5, actual.depth())

        CheckMap(coupling)(actual, property_set)
        self.assertTrue(property_set["is_swap_mapped"])
Пример #14
0
    def test_qubit_subset(self):
        """Test if `qubit_subset` option works as expected."""
        circuit = QuantumCircuit(3)
        circuit.cx(0, 1)
        circuit.cx(1, 2)
        circuit.cx(0, 2)

        coupling = CouplingMap([(0, 1), (1, 3), (3, 2)])
        qubit_subset = [0, 1, 3]
        actual = BIPMapping(coupling, qubit_subset=qubit_subset)(circuit)
        # all used qubits are in qubit_subset
        bit_indices = {bit: index for index, bit in enumerate(actual.qubits)}
        for _, qargs, _ in actual.data:
            for q in qargs:
                self.assertTrue(bit_indices[q] in qubit_subset)
        # ancilla qubits are set in the resulting qubit
        idle = QuantumRegister(1, name="ancilla")
        self.assertEqual(idle[0], actual._layout[2])
Пример #15
0
    def test_can_map_measurements_correctly(self):
        """Verify measurement nodes are updated to map correct cregs to re-mapped qregs."""
        coupling = CouplingMap([[0, 1], [0, 2]])

        qr = QuantumRegister(3, "qr")
        cr = ClassicalRegister(2)
        circuit = QuantumCircuit(qr, cr)
        circuit.cx(qr[1], qr[2])
        circuit.measure(qr[1], cr[0])
        circuit.measure(qr[2], cr[1])

        actual = BIPMapping(coupling)(circuit)

        q = QuantumRegister(3, "q")
        expected = QuantumCircuit(q, cr)
        expected.cx(q[0], q[1])
        expected.measure(q[0], cr[0])  # <- changed due to initial layout change
        expected.measure(q[1], cr[1])  # <- changed due to initial layout change

        self.assertEqual(expected, actual)
Пример #16
0
    def test_trivial_case(self):
        """No need to have any swap, the CX are distance 1 to each other
        q0:--(+)-[H]-(+)-
              |       |
        q1:---.-------|--
                      |
        q2:-----------.--
        CouplingMap map: [1]--[0]--[2]
        """
        coupling = CouplingMap([[0, 1], [0, 2]])

        circuit = QuantumCircuit(3)
        circuit.cx(1, 0)
        circuit.h(0)
        circuit.cx(2, 0)

        actual = BIPMapping(coupling)(circuit)
        self.assertEqual(3, len(actual))
        for inst, _, _ in actual.data:  # there are no swaps
            self.assertFalse(isinstance(inst, SwapGate))
Пример #17
0
    def test_different_number_of_virtual_and_physical_qubits(self):
        """Test the case when number of virtual and physical qubits are different."""

        # q_0: ──■────■───────
        #      ┌─┴─┐  │
        # q_1: ┤ X ├──┼────■──
        #      └───┘  │  ┌─┴─┐
        # q_2: ──■────┼──┤ X ├
        #      ┌─┴─┐┌─┴─┐└───┘
        # q_3: ┤ X ├┤ X ├─────
        #      └───┘└───┘
        circuit = QuantumCircuit(4)
        circuit.cx(0, 1)
        circuit.cx(2, 3)
        circuit.cx(0, 3)
        circuit.cx(1, 2)

        coupling = CouplingMap.from_line(5)
        with self.assertRaises(TranspilerError):
            BIPMapping(coupling)(circuit)
Пример #18
0
 def test_empty(self):
     """Returns the original circuit if the circuit is empty."""
     coupling = CouplingMap([[0, 1]])
     circuit = QuantumCircuit(2)
     actual = BIPMapping(coupling)(circuit)
     self.assertEqual(circuit, actual)
 def test_initialize_gate_error_objective_without_backend_prop(self):
     """Fails if ``objective`` that requires ``backend_prop`` is specified but it is not supplied."""
     with self.assertRaises(TranspilerError):
         BIPMapping(coupling_map=CouplingMap.from_line(3),
                    objective="gate_error")