Skip to content

Commit

Permalink
Increase heuristic effort for optimization level 2
Browse files Browse the repository at this point in the history
This commit tweaks the heuristic effort in optimization level 2 to be
more of a middle ground between level 1 and 3; with a better balance
between output quality and runtime. This places it to be a better
default for a pass manager we use if one isn't specified. The
tradeoff here is that the vf2layout and vf2postlayout search space is
reduced to be the same as level 1. There are diminishing margins of
return on the vf2 layout search especially for cases when there are a
large number of qubit permutations for the mapping found. Then the
number of sabre trials is brought up to the same level as optimization
level 3. As this can have a significant impact on output and the extra
runtime cost is minimal. The larger change is that the optimization
passes from level 3. This ends up mainly being 2q peephole optimization.
With the performance improvements from Qiskit#12010 and Qiskit#11946 and all the
follow-on PRs this is now fast enough to rely on in optimization level
2.
  • Loading branch information
mtreinish committed Apr 5, 2024
1 parent 97788f0 commit 11b290e
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 30 deletions.
35 changes: 11 additions & 24 deletions qiskit/transpiler/preset_passmanagers/builtin_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana
pass_manager_config.unitary_synthesis_plugin_config,
pass_manager_config.hls_config,
)
elif optimization_level in {1, 2}:
elif optimization_level == 1:
init = PassManager()
if (
pass_manager_config.initial_layout
Expand Down Expand Up @@ -123,10 +123,8 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana
]
)
)
if optimization_level == 2:
init.append(CommutativeCancellation())

elif optimization_level == 3:
elif optimization_level in {2, 3}:
init = common.generate_unroll_3q(
pass_manager_config.target,
pass_manager_config.basis_gates,
Expand Down Expand Up @@ -543,18 +541,7 @@ def _opt_control(property_set):
]
),
]
elif optimization_level == 2:
# Steps for optimization level 2
_opt = [
Optimize1qGatesDecomposition(
basis=pass_manager_config.basis_gates, target=pass_manager_config.target
),
CommutativeCancellation(
basis_gates=pass_manager_config.basis_gates,
target=pass_manager_config.target,
),
]
elif optimization_level == 3:
elif optimization_level in {2, 3}:
# Steps for optimization level 3
_opt = [
Collect2qBlocks(),
Expand Down Expand Up @@ -596,13 +583,13 @@ def _unroll_condition(property_set):
ConditionalController(unroll, condition=_unroll_condition),
]

if optimization_level == 3:
if optimization_level in {2, 3}:
optimization.append(_minimum_point_check)
else:
optimization.append(_depth_check + _size_check)
opt_loop = (
_opt + _unroll_if_out_of_basis + _minimum_point_check
if optimization_level == 3
if optimization_level in {2, 3}
else _opt + _unroll_if_out_of_basis + _depth_check + _size_check
)
optimization.append(DoWhileController(opt_loop, do_while=_opt_control))
Expand Down Expand Up @@ -746,10 +733,10 @@ def _swap_mapped(property_set):
choose_layout_0 = VF2Layout(
coupling_map=pass_manager_config.coupling_map,
seed=pass_manager_config.seed_transpiler,
call_limit=int(5e6), # Set call limit to ~10s with rustworkx 0.10.2
call_limit=int(5e4), # Set call limit to ~10s with rustworkx 0.10.2
properties=pass_manager_config.backend_properties,
target=pass_manager_config.target,
max_trials=25000, # Limits layout scoring to < 10s on ~400 qubit devices
max_trials=2500, # Limits layout scoring to < 10s on ~400 qubit devices
)
layout.append(
ConditionalController(choose_layout_0, condition=_choose_layout_condition)
Expand All @@ -758,8 +745,8 @@ def _swap_mapped(property_set):
coupling_map,
max_iterations=2,
seed=pass_manager_config.seed_transpiler,
swap_trials=10,
layout_trials=10,
swap_trials=20,
layout_trials=20,
skip_routing=pass_manager_config.routing_method is not None
and pass_manager_config.routing_method != "sabre",
)
Expand Down Expand Up @@ -911,8 +898,8 @@ def _swap_mapped(property_set):
coupling_map,
max_iterations=2,
seed=pass_manager_config.seed_transpiler,
swap_trials=10,
layout_trials=10,
swap_trials=20,
layout_trials=20,
skip_routing=pass_manager_config.routing_method is not None
and pass_manager_config.routing_method != "sabre",
)
Expand Down
7 changes: 1 addition & 6 deletions qiskit/transpiler/preset_passmanagers/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,16 +627,11 @@ def get_vf2_limits(
"""
limits = VF2Limits(None, None)
if layout_method is None and initial_layout is None:
if optimization_level == 1:
if optimization_level in {1, 2}:
limits = VF2Limits(
int(5e4), # Set call limit to ~100ms with rustworkx 0.10.2
2500, # Limits layout scoring to < 600ms on ~400 qubit devices
)
elif optimization_level == 2:
limits = VF2Limits(
int(5e6), # Set call limit to ~10 sec with rustworkx 0.10.2
25000, # Limits layout scoring to < 6 sec on ~400 qubit devices
)
elif optimization_level == 3:
limits = VF2Limits(
int(3e7), # Set call limit to ~60 sec with rustworkx 0.10.2
Expand Down

0 comments on commit 11b290e

Please sign in to comment.