Skip to content

Commit

Permalink
Add max_trials parameter to VF2PostLayout. (Qiskit#9963)
Browse files Browse the repository at this point in the history
* Add max_trials parameter to VF2PostLayout.

* Fix formatting.

* Fix spacing.

* Update release note based on review.

* Revert vf2_layout.py.
  • Loading branch information
kevinhartman authored and king-p3nguin committed May 22, 2023
1 parent 415191e commit 8fb5baf
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
9 changes: 9 additions & 0 deletions qiskit/transpiler/passes/layout/vf2_post_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def __init__(
call_limit=None,
time_limit=None,
strict_direction=True,
max_trials=0,
):
"""Initialize a ``VF2PostLayout`` pass instance
Expand All @@ -131,6 +132,8 @@ def __init__(
However, if ``strict_direction=True`` the pass expects the input
:class:`~.DAGCircuit` object to :meth:`~.VF2PostLayout.run` to be in
the target set of instructions.
max_trials (int): The maximum number of trials to run VF2 to find
a layout. A value of ``0`` (the default) means 'unlimited'.
Raises:
TypeError: At runtime, if neither ``coupling_map`` or ``target`` are provided.
Expand All @@ -141,6 +144,7 @@ def __init__(
self.properties = properties
self.call_limit = call_limit
self.time_limit = time_limit
self.max_trials = max_trials
self.seed = seed
self.strict_direction = strict_direction
self.avg_error_map = None
Expand Down Expand Up @@ -310,6 +314,11 @@ def run(self, dag):
)
chosen_layout = layout
chosen_layout_score = layout_score

if self.max_trials and trials >= self.max_trials:
logger.debug("Trial %s is >= configured max trials %s", trials, self.max_trials)
break

elapsed_time = time.time() - start_time
if self.time_limit is not None and elapsed_time >= self.time_limit:
logger.debug(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
features:
- |
Added a new parameter ``max_trials`` to pass :class:`~.VF2PostLayout`
which, when specified, limits the number of layouts discovered and
compared when searching for the best layout.
This differs from existing parameters ``call_limit`` and ``time_limit``
(which are used to limit the number of state visits performed by the VF2
algorithm and the total time spent by pass :class:`~.VF2PostLayout`,
respectively) in that it is used to place an upper bound on the time
spent scoring potential layouts, which may be useful for larger
devices.
33 changes: 33 additions & 0 deletions test/python/transpiler/test_vf2_post_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,39 @@ def test_2q_circuit_5q_backend_controlflow(self):
self.assertLayout(dag, cmap, pass_.property_set)
self.assertNotEqual(pass_.property_set["post_layout"], initial_layout)

def test_2q_circuit_5q_backend_max_trials(self):
"""A simple example, without considering the direction
0 - 1
qr1 - qr0
"""
max_trials = 11
backend = FakeYorktown()

qr = QuantumRegister(2, "qr")
circuit = QuantumCircuit(qr)
circuit.cx(qr[1], qr[0]) # qr1 -> qr0
tqc = transpile(circuit, backend, layout_method="dense")
initial_layout = tqc._layout
dag = circuit_to_dag(tqc)
cmap = CouplingMap(backend.configuration().coupling_map)
props = backend.properties()
pass_ = VF2PostLayout(
coupling_map=cmap, properties=props, seed=self.seed, max_trials=max_trials
)

with self.assertLogs(
"qiskit.transpiler.passes.layout.vf2_post_layout", level="DEBUG"
) as cm:
pass_.run(dag)
self.assertIn(
f"DEBUG:qiskit.transpiler.passes.layout.vf2_post_layout:Trial {max_trials} "
f"is >= configured max trials {max_trials}",
cm.output,
)

self.assertLayout(dag, cmap, pass_.property_set)
self.assertNotEqual(pass_.property_set["post_layout"], initial_layout)

def test_best_mapping_ghz_state_full_device_multiple_qregs_v2(self):
"""Test best mappings with multiple registers"""
backend = FakeLimaV2()
Expand Down

0 comments on commit 8fb5baf

Please sign in to comment.