def test_seed(self):
        """Different seeds yield different results"""
        seed_1 = 42
        seed_2 = 45

        cmap5 = FakeTenerife().configuration().coupling_map

        qr = QuantumRegister(3, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[1], qr[0])  # qr1 -> qr0
        circuit.cx(qr[0], qr[2])  # qr0 -> qr2
        circuit.cx(qr[1], qr[2])  # qr1 -> qr2
        dag = circuit_to_dag(circuit)

        pass_1 = VF2Layout(CouplingMap(cmap5), seed=seed_1, max_trials=1)
        pass_1.run(dag)
        layout_1 = pass_1.property_set["layout"]
        self.assertEqual(pass_1.property_set["VF2Layout_stop_reason"],
                         VF2LayoutStopReason.SOLUTION_FOUND)

        pass_2 = VF2Layout(CouplingMap(cmap5), seed=seed_2, max_trials=1)
        pass_2.run(dag)
        layout_2 = pass_2.property_set["layout"]
        self.assertEqual(pass_2.property_set["VF2Layout_stop_reason"],
                         VF2LayoutStopReason.SOLUTION_FOUND)

        self.assertNotEqual(layout_1, layout_2)
 def test_no_properties(self):
     """Test scores with no properties."""
     vf2_pass = VF2Layout(
         CouplingMap([
             (0, 1),
             (0, 2),
             (0, 3),
             (1, 0),
             (1, 2),
             (1, 3),
             (2, 0),
             (2, 1),
             (2, 2),
             (2, 3),
             (3, 0),
             (3, 1),
             (3, 2),
             (4, 0),
             (0, 4),
             (5, 1),
             (1, 5),
         ]))
     qr = QuantumRegister(2)
     layout = Layout({qr[0]: 0, qr[1]: 1})
     score = vf2_pass._score_layout(layout)
     self.assertEqual(score, 16)
     better_layout = Layout({qr[0]: 4, qr[1]: 5})
     better_score = vf2_pass._score_layout(better_layout)
     self.assertEqual(4, better_score)
 def test_no_properties(self):
     """Test it finds the lowest degree perfect layout with no properties."""
     vf2_pass = VF2Layout(
         CouplingMap([
             (0, 1),
             (0, 2),
             (0, 3),
             (1, 0),
             (1, 2),
             (1, 3),
             (2, 0),
             (2, 1),
             (2, 2),
             (2, 3),
             (3, 0),
             (3, 1),
             (3, 2),
             (4, 0),
             (0, 4),
             (5, 1),
             (1, 5),
         ]))
     qr = QuantumRegister(2)
     qc = QuantumCircuit(qr)
     qc.x(qr)
     qc.measure_all()
     property_set = {}
     vf2_pass(qc, property_set)
     self.assertEqual(set(property_set["layout"].get_physical_bits()),
                      {5, 4})
    def test_3q_circuit_Tenerife_sd(self):
        """3 qubits in Tenerife, considering the direction
            1                       1
          ↙ ↑                    ↙  ↑
        0 ← 2 ← 3              0 ← qr2 ← qr1
            ↑ ↙                     ↑  ↙
            4                      qr0
        """
        cmap5 = CouplingMap(FakeTenerife().configuration().coupling_map)

        qr = QuantumRegister(3, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[1], qr[0])  # qr1 -> qr0
        circuit.cx(qr[0], qr[2])  # qr0 -> qr2
        circuit.cx(qr[1], qr[2])  # qr1 -> qr2

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap5,
                          strict_direction=True,
                          seed=self.seed,
                          max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag,
                          cmap5,
                          pass_.property_set,
                          strict_direction=True)
    def test_9q_circuit_Rueschlikon(self):
        """9 qubits in Rueschlikon, without considering the direction

        1 →  2 →  3 →  4 ←  5 ←  6 →  7 ← 8
        ↓    ↑    ↓    ↓    ↑    ↓    ↓   ↑
        0 ← 15 → 14 ← 13 ← 12 → 11 → 10 ← 9

          1 -- q1_0 - q1_1 - 4 --- 5 --  6  - 7 --- q0_1
          |    |      |      |     |     |    |      |
        q1_2 - q1_3 - q0_0 - 13 - q0_3 - 11 - q1_4 - q0_2
        """
        cmap16 = CouplingMap(FakeRueschlikon().configuration().coupling_map)

        qr0 = QuantumRegister(4, "q0")
        qr1 = QuantumRegister(5, "q1")
        circuit = QuantumCircuit(qr0, qr1)
        circuit.cx(qr0[1], qr0[2])  # q0[1] -> q0[2]
        circuit.cx(qr0[0], qr1[3])  # q0[0] -> q1[3]
        circuit.cx(qr1[4], qr0[2])  # q1[4] -> q0[2]

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap16,
                          strict_direction=False,
                          seed=self.seed,
                          max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag, cmap16, pass_.property_set)
    def test_time_limit_exceeded(self):
        """Test the pass stops after time_limit is reached."""
        backend = FakeYorktown()
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)
        qc.x(qr)
        qc.measure_all()
        cmap = CouplingMap(backend.configuration().coupling_map)
        properties = backend.properties()
        vf2_pass = VF2Layout(cmap,
                             properties=properties,
                             seed=-1,
                             time_limit=0.0)
        property_set = {}
        with self.assertLogs("qiskit.transpiler.passes.layout.vf2_layout",
                             level="DEBUG") as cm:
            vf2_pass(qc, property_set)
        for output in cm.output:
            if output.startswith(
                    "DEBUG:qiskit.transpiler.passes.layout.vf2_layout:VF2Layout has taken"
            ) and output.endswith("which exceeds configured max time: 0.0"):
                break
        else:
            self.fail("No failure debug log message found")

        self.assertEqual(set(property_set["layout"].get_physical_bits()),
                         {2, 0})
 def test_no_limits_with_negative(self):
     """Test that we're not enforcing a trial limit if set to negative."""
     backend = FakeYorktown()
     qc = QuantumCircuit(3)
     qc.h(0)
     cmap = CouplingMap(backend.configuration().coupling_map)
     implicit_max = len(cmap.graph.edge_list()) + 15
     properties = backend.properties()
     # Run without any limits set
     vf2_pass = VF2Layout(cmap,
                          properties=properties,
                          seed=42,
                          max_trials=0)
     property_set = {}
     with self.assertLogs("qiskit.transpiler.passes.layout.vf2_layout",
                          level="DEBUG") as cm:
         vf2_pass(qc, property_set)
     for output in cm.output:
         self.assertNotIn("is >= configured max trials", output)
     last_line = cm.output[-1]
     # The last line should be
     # DEBUG:qiskit.transpiler.passes.layout.vf2_layout: Trial n has score 0.122
     trials = int(last_line.split(" ")[1])
     self.assertGreater(trials, implicit_max)
     self.assertEqual(set(property_set["layout"].get_physical_bits()),
                      {3, 1, 0})
    def test_hexagonal_lattice_graph_9_in_25(self):
        """A 9x9 interaction map in 25x25 coupling map"""
        graph_9_9 = retworkx.generators.hexagonal_lattice_graph(9, 9)
        circuit = self.graph_state_from_pygraph(graph_9_9)

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(self.cmap25, seed=self.seed, max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag, self.cmap25, pass_.property_set)
 def test_neither_coupling_map_or_target(self):
     """Test that we raise if neither a target or coupling map is specified."""
     vf2_pass = VF2Layout(seed=123,
                          call_limit=1000,
                          time_limit=20,
                          max_trials=7)
     circuit = QuantumCircuit(2)
     dag = circuit_to_dag(circuit)
     with self.assertRaises(TranspilerError):
         vf2_pass.run(dag)
 def test_with_properties(self):
     """Test scores with properties."""
     backend = FakeYorktown()
     cmap = CouplingMap(backend.configuration().coupling_map)
     properties = backend.properties()
     vf2_pass = VF2Layout(cmap, properties=properties)
     qr = QuantumRegister(2)
     layout = Layout({qr[0]: 4, qr[1]: 2})
     bad_score = vf2_pass._score_layout(layout)
     self.assertAlmostEqual(0.4075, bad_score)
     better_layout = Layout({qr[0]: 1, qr[1]: 3})
     better_score = vf2_pass._score_layout(better_layout)
     self.assertAlmostEqual(0.0588, better_score)
    def test_call_limit(self):
        """Test that call limit is enforce."""
        cmap = CouplingMap([[0, 1], [1, 2], [2, 0]])

        qr = QuantumRegister(3, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[1])  # qr0-> qr1
        circuit.cx(qr[1], qr[2])  # qr1-> qr2

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap, seed=-1, call_limit=1)
        pass_.run(dag)
        self.assertEqual(pass_.property_set["VF2Layout_stop_reason"],
                         VF2LayoutStopReason.NO_SOLUTION_FOUND)
 def test_with_properties(self):
     """Test it finds the least noise perfect layout with no properties."""
     backend = FakeYorktown()
     qr = QuantumRegister(2)
     qc = QuantumCircuit(qr)
     qc.x(qr)
     qc.measure_all()
     cmap = CouplingMap(backend.configuration().coupling_map)
     properties = backend.properties()
     vf2_pass = VF2Layout(cmap, properties=properties)
     property_set = {}
     vf2_pass(qc, property_set)
     self.assertEqual(set(property_set["layout"].get_physical_bits()),
                      {1, 3})
    def test_3_q_gate(self):
        """The pass does not handle gates with more than 2 qubits"""
        seed_1 = 42

        cmap5 = FakeTenerife().configuration().coupling_map

        qr = QuantumRegister(3, "qr")
        circuit = QuantumCircuit(qr)
        circuit.ccx(qr[1], qr[0], qr[2])
        dag = circuit_to_dag(circuit)

        pass_1 = VF2Layout(CouplingMap(cmap5), seed=seed_1, max_trials=1)
        pass_1.run(dag)
        self.assertEqual(pass_1.property_set["VF2Layout_stop_reason"],
                         VF2LayoutStopReason.MORE_THAN_2Q)
    def test_3q_circuit_3q_coupling_non_induced(self):
        """A simple example, check for non-induced subgraph
            1         qr0 -> qr1 -> qr2
           / \
          0 - 2
        """
        cmap = CouplingMap([[0, 1], [1, 2], [2, 0]])

        qr = QuantumRegister(3, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[1])  # qr0-> qr1
        circuit.cx(qr[1], qr[2])  # qr1-> qr2

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap, seed=-1, max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag, cmap, pass_.property_set)
 def test_coupling_map_and_target(self):
     """Test that a Target is used instead of a CouplingMap if both are specified."""
     cmap = CouplingMap([[0, 1], [1, 2]])
     target = Target()
     target.add_instruction(CXGate(), {
         (0, 1): None,
         (1, 2): None,
         (1, 0): None
     })
     qr = QuantumRegister(3, "qr")
     circuit = QuantumCircuit(qr)
     circuit.cx(qr[0], qr[1])  # qr0-> qr1
     circuit.cx(qr[1], qr[2])  # qr1-> qr2
     circuit.cx(qr[1], qr[0])  # qr1-> qr0
     dag = circuit_to_dag(circuit)
     pass_ = VF2Layout(cmap, seed=-1, max_trials=1, target=target)
     pass_.run(dag)
     self.assertLayout(dag, target.build_coupling_map(), pass_.property_set)
    def test_2q_circuit_2q_coupling_sd(self):
        """A simple example, considering the direction
         0  -> 1
        qr1 -> qr0
        """
        cmap = CouplingMap([[0, 1]])

        qr = QuantumRegister(2, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[1], qr[0])  # qr1 -> qr0

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap,
                          strict_direction=True,
                          seed=self.seed,
                          max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag, cmap, pass_.property_set, strict_direction=True)
 def test_reasonable_limits_for_simple_layouts(self):
     """Test that the default trials is set to a reasonable number."""
     backend = FakeManhattan()
     qc = QuantumCircuit(5)
     qc.cx(0, 1)
     cmap = CouplingMap(backend.configuration().coupling_map)
     properties = backend.properties()
     # Run without any limits set
     vf2_pass = VF2Layout(cmap, properties=properties, seed=42)
     property_set = {}
     with self.assertLogs("qiskit.transpiler.passes.layout.vf2_layout",
                          level="DEBUG") as cm:
         vf2_pass(qc, property_set)
     self.assertIn(
         "DEBUG:qiskit.transpiler.passes.layout.vf2_layout:Trial 159 is >= configured max trials 159",
         cm.output,
     )
     self.assertEqual(set(property_set["layout"].get_physical_bits()),
                      {48, 49, 40, 47, 58})
    def test_perfect_fit_Manhattan(self):
        """A circuit that fits perfectly in Manhattan (65 qubits)
        See https://github.com/Qiskit/qiskit-terra/issues/5694"""
        manhattan_cm = FakeManhattan().configuration().coupling_map
        cmap65 = CouplingMap(manhattan_cm)

        rows = [x[0] for x in manhattan_cm]
        cols = [x[1] for x in manhattan_cm]

        adj_matrix = numpy.zeros((65, 65))
        adj_matrix[rows, cols] = 1

        circuit = GraphState(adj_matrix).decompose()
        circuit.measure_all()

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap65, seed=self.seed, max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag, cmap65, pass_.property_set)
    def test_4q_circuit_Tenerife_loose_nodes(self):
        """4 qubits in Tenerife, with loose nodes

            1
          ↙ ↑
        0 ← 2 ← 3
            ↑ ↙
            4
        """
        cmap5 = CouplingMap(FakeTenerife().configuration().coupling_map)

        qr = QuantumRegister(4, "q")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[1], qr[0])  # qr1 -> qr0
        circuit.cx(qr[0], qr[2])  # qr0 -> qr2

        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(cmap5, seed=self.seed, max_trials=1)
        pass_.run(dag)
        self.assertLayout(dag, cmap5, pass_.property_set)
 def test_no_limits_with_negative(self):
     """Test that we're not enforcing a trial limit if set to negative."""
     backend = FakeYorktown()
     qc = QuantumCircuit(3)
     qc.h(0)
     cmap = CouplingMap(backend.configuration().coupling_map)
     properties = backend.properties()
     # Run without any limits set
     vf2_pass = VF2Layout(
         cmap,
         properties=properties,
         seed=42,
         max_trials=0,
     )
     property_set = {}
     with self.assertLogs("qiskit.transpiler.passes.layout.vf2_layout",
                          level="DEBUG") as cm:
         vf2_pass(qc, property_set)
     for output in cm.output:
         self.assertNotIn("is >= configured max trials", output)
     self.assertEqual(set(property_set["layout"].get_physical_bits()),
                      {3, 1, 2})
    def test_5q_circuit_Rueschlikon_no_solution(self):
        """5 qubits in Rueschlikon, no solution

        q0[1] ↖     ↗ q0[2]
               q0[0]
        q0[3] ↙     ↘ q0[4]
        """
        cmap16 = FakeRueschlikon().configuration().coupling_map

        qr = QuantumRegister(5, "q")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[2])
        circuit.cx(qr[0], qr[3])
        circuit.cx(qr[0], qr[4])
        dag = circuit_to_dag(circuit)
        pass_ = VF2Layout(CouplingMap(cmap16), seed=self.seed, max_trials=1)
        pass_.run(dag)
        layout = pass_.property_set["layout"]
        self.assertIsNone(layout)
        self.assertEqual(pass_.property_set["VF2Layout_stop_reason"],
                         VF2LayoutStopReason.NO_SOLUTION_FOUND)
 def test_max_trials_exceeded(self):
     """Test it exits when max_trials is reached."""
     backend = FakeYorktown()
     qr = QuantumRegister(2)
     qc = QuantumCircuit(qr)
     qc.x(qr)
     qc.measure_all()
     cmap = CouplingMap(backend.configuration().coupling_map)
     properties = backend.properties()
     vf2_pass = VF2Layout(cmap,
                          properties=properties,
                          seed=-1,
                          max_trials=1)
     property_set = {}
     with self.assertLogs("qiskit.transpiler.passes.layout.vf2_layout",
                          level="DEBUG") as cm:
         vf2_pass(qc, property_set)
     self.assertIn(
         "DEBUG:qiskit.transpiler.passes.layout.vf2_layout:Trial 1 is >= configured max trials 1",
         cm.output,
     )
     self.assertEqual(set(property_set["layout"].get_physical_bits()),
                      {2, 0})