def test_lookahead_mode(self):
        """Test lookahead mode's lookahead finds single SWAP gate.
                  ┌───┐
        q_0: ──■──┤ H ├───────────────
             ┌─┴─┐└───┘
        q_1: ┤ X ├──■────■─────────■──
             └───┘┌─┴─┐  │         │
        q_2: ──■──┤ X ├──┼────■────┼──
             ┌─┴─┐└───┘┌─┴─┐┌─┴─┐┌─┴─┐
        q_3: ┤ X ├─────┤ X ├┤ X ├┤ X ├
             └───┘     └───┘└───┘└───┘
        q_4: ─────────────────────────

        """
        coupling = CouplingMap.from_line(5)

        qr = QuantumRegister(5, 'q')
        qc = QuantumCircuit(qr)
        qc.cx(0, 1)  # free
        qc.cx(2, 3)  # free
        qc.h(0)  # free
        qc.cx(1, 2)  # free
        qc.cx(1, 3)  # F
        qc.cx(2, 3)  # E
        qc.cx(1, 3)  # E

        pm = PassManager(SabreSwap(coupling, 'lookahead'))
        new_qc = pm.run(qc)

        self.assertEqual(new_qc.num_nonlocal_gates(), 7)
예제 #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_subgraph(self):
     coupling = CouplingMap.from_line(6, bidirectional=False)
     with self.assertWarns(DeprecationWarning):
         subgraph = coupling.subgraph([4, 2, 3, 5])
     self.assertEqual(subgraph.size(), 4)
     self.assertEqual([0, 1, 2, 3], subgraph.physical_qubits)
     edge_list = subgraph.get_edges()
     expected = [(0, 1), (1, 2), (2, 3)]
     self.assertEqual(expected, edge_list, f"{edge_list} does not match {expected}")
예제 #4
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)
예제 #5
0
 def test_target_too_small_for_circuit(self):
     """Test error is raised when target is too small for circuit."""
     target = Target()
     target.add_instruction(
         CXGate(),
         {edge: None
          for edge in CouplingMap.from_line(3).get_edges()})
     dag = circuit_to_dag(QuantumCircuit(5))
     layout_pass = DenseLayout(target=target)
     with self.assertRaises(TranspilerError):
         layout_pass.run(dag)
예제 #6
0
    def test_no_infinite_loop(self, method):
        """Test that the 'release value' mechanisms allow SabreSwap to make progress even on
        circuits that get stuck in a stable local minimum of the lookahead parameters."""
        qc = looping_circuit(3, 1)
        qc.measure_all()
        coupling_map = CouplingMap.from_line(qc.num_qubits)
        routing_pass = PassManager(SabreSwap(coupling_map, method))

        n_swap_gates = 0

        def leak_number_of_swaps(cls, *args, **kwargs):
            nonlocal n_swap_gates
            n_swap_gates += 1
            if n_swap_gates > 1_000:
                raise Exception("SabreSwap seems to be stuck in a loop")
            # pylint: disable=bad-super-call
            return super(SwapGate, cls).__new__(cls, *args, **kwargs)

        with unittest.mock.patch.object(SwapGate, "__new__", leak_number_of_swaps):
            routed = routing_pass.run(qc)

        routed_ops = routed.count_ops()
        del routed_ops["swap"]
        self.assertEqual(routed_ops, qc.count_ops())
        couplings = {
            tuple(routed.find_bit(bit).index for bit in instruction.qubits)
            for instruction in routed.data
            if len(instruction.qubits) == 2
        }
        # Asserting equality to the empty set gives better errors on failure than asserting that
        # `couplings <= coupling_map`.
        self.assertEqual(couplings - set(coupling_map.get_edges()), set())

        # Assert that the same keys are produced by a simulation - this is a test that the inserted
        # swaps route the qubits correctly.
        if not optionals.HAS_AER:
            return

        from qiskit import Aer

        sim = Aer.get_backend("aer_simulator")
        in_results = sim.run(qc, shots=4096).result().get_counts()
        out_results = sim.run(routed, shots=4096).result().get_counts()
        self.assertEqual(set(in_results), set(out_results))
예제 #7
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)
예제 #8
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))
예제 #9
0
 def test_line_factory(self):
     coupling = CouplingMap.from_line(4)
     edges = coupling.get_edges()
     expected = [(0, 1), (1, 0), (1, 2), (2, 1), (2, 3), (3, 2)]
     self.assertEqual(set(edges), set(expected))
 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")