Skip to content

Commit

Permalink
Use VF2Layout in all preset passmanagers (#7213)
Browse files Browse the repository at this point in the history
* Use VF2Layout in all preset passmanagers

With the introduction of the VF2Layout pass we now have a very fast
method of searching for a perfect layout. Previously we only had the
CSPLayout method for doing this which could be quite slow and we only
used in level 2 and level 3. Since VF2Layout operates quickly adding the
pass to each preset pass manager makes sense so we always use a perfect
layout if available (or unless a user explicitly specifies an initial
layout or layout method). This commit makes this change and adds
VF2Layout to each optimization level and uses a perfect layout if found
by default.

Fixes #7156

* Revert changes to level 0

For optimization level 0 we don't actually want to use VF2Layout because
while it can find a perfect layout it would be potentially surprising to
users that the level which is supposed to have no optimizations picks a
non-trivial layout.

* Set seed on perfect layout test

* Fix test failures and unexpected change in behavior

This commit makes several changes to fix both unexpected changes in
behavior and also update the default behavior of the vf2 layout pass.
The first issues is that the vf2 pass was raising an exception if it was
run with >2 qubit gates. This caused issues if we run with calibrations
(or backends that support >2q gates) as vf2 layout is used as an
opportunistic thing and if there is for example a 5q gate being used
we shouldn't fail the entire transpile just because vf2 can't deal with
it. It's only an issue if the later passes can't either, it just means
vf2 won't be able to find a perfect layout. The second change is around
the default seeding. For the preset pass managers to have a consistent
output this removed the randomization if no seed is specified and just
use an in order comparison. This is necessary to have a consistent
layout for testing and reproducability, while we can set a seed
everywhere, the previous behavior was more stable as it would default to
trivial layout most of the time (assuming that was perfect). When we add
multiple vf2 trials and are picking the best choice among those for a
given time budget we can add back in the default seed randomization. The
last change made here is that several tests implicitly expected a
trivial layout (mainly around device aware transpilation or
calibrations). In those cases the transpile wasn't valid for an
arbitrary layout, for example if a calibrated gate is only defined on a
single qubit. Using vf2 layout in those cases doesn't work because the
gate is only defined on a single qubit so picking a non-trivial layout
correctly errors. To fix these cases the tests are updated to explicitly
state they require a trivial layout instead of assuming the transpiler
will implicitly give them that if it's a perfect layout.

* Add missing release note

* Apply suggestions from code review in release note

Co-authored-by: Jake Lishman <jake@binhbar.com>

* Make vf2 layout stop reason an Enum

* Update releasenotes/notes/vf2layout-preset-passmanager-db46513a24e79aa9.yaml

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>

* Add back initial layout to level1

Since there seems to be a pretty baked in asumption for level 1 that it
will use the trivial layout by default if it's a perfect mapping. This
was causing the majority of the test failures and might be an unexpected
breakage for people. However, in a future release we should remove this
(likely when vf2layout is made noise aware). To anticipate this a
FutureWarning is emitted when a trivial layout is used to indicate that
this behavior will change in the future for level 1 and if you're
relying on it you should explicitly set the layout_method='trivial'.

* Tweak seeds to reduce effect of noise on fake_yorktown with aer

* Update release note

* Use id_order=True on vf2_mapping() for VF2Layout pass

Using id_order=False orders the nodes by degree which biases the
mapping found by vf2 towards nodes with higher connectivity which
typically have higher error rates. Until the pass is made noise aware
to counter this bias we should just use id_order=True which uses the
node id for the order (which roughly matches insertion order) which
won't have this bias in the results.

* Revert "Use id_order=True on vf2_mapping() for VF2Layout pass"

VF2 without the Vf2++ heuristic is too slow for some common use cases
that we probably don't want to use it by default. Instead we should use
some techniques to improve the quality of the results. The first
approach will be applying a score heuristic to a found mapping. A
potential follow on after that could be to do some pre-filtering of
noisy nodes.

This reverts commit 53d54c3.

* Set real limits on calling vf2 and add quality heuristic

This commit adds options to set limits on the vf2 pass, both the
internal call limit for the vf2 execution in retworkx, a total time
spent in the pass trying multiple layouts, and the number of trials to
attempt. These are then set in the preset pass manager to ensure we
don't sit spinning on vf2 forever in the real world. While the pass is
generally fast there are edge cases where it can get stuck. At the same
time this adds a rough quality heuristic (based on readout error falling
back to connectivity) to select between multiple mappings found by
retworkx. This addresses the poor quality results we were getting with
vf2++ in earlier revisions as we can find the best from multiple
mappings.

* Remove initial layout default from level 1

Now that vf2 layout has limited noise awareness and multiple trials it
no longer will be defaulting to the worst qubits like it was with only a
single sample when vf2++ is used. This commit removes the implicit
trivial layout attempt as it's no longer needed.

* Remove unused imports

* Use vigo instead of yorktown for oracle tests

* Revert "Remove initial layout default from level 1"

This is breaking the pulse tutorials, as fixing that is a more
involved change and probably indicates we should continue to
assume trivial layout by default if perfect for level 1 and raise a
warning to users that it's going away to give everyone who needs a
default trivial layout time to adjust their code. This commit reverts
only using vf2 for level 1 and adds back in a trivial layout stage.

This reverts commit df47835.
This reverts commit 65ae6ee.

* Fix warning and update docs to not emit one

This commit fixes the warning so it's only emitted if the trivial layout
is used, previously it would also be emitted if an initial layout was
set. The the docs are updated to not emit the warning, in some cases
code examples are updated to explicitly use a trivial layout if that's
what's needed. In others there were needless jupyter-execute directives
being used when there was no visualization and a code-block is just as
effective (which avoids the execution during doc builds).

* Add debug logging and fix heurstic usage

* Add better test coverage of new pass features

* Only run a single trial if the graphs are the same size

If the interaction graph and the coupling graph are the same size
currently the score heuristic will produce the same results since they
just look at the sum of qubit noise (or degree). We don't need to run
multiple trials or bother scoring things since we'll just pick the first
mapping anyway.

* Fix rebase error

* Use enum type for stop reason condition

* Add comment about call_limit value

* Undo unecessary seed change

* Add back default seed randomization

After all the improvements to the VF2Layout pass in #7276 this was no
longer needed. It was added back prior to #7276 where the vf2 layout
pass was not behaving well for simple cases.

* Permute operator bits based on layout

The backendv2 transpilation tests were failing with vf2 layout enabled
by default because we were no longer guaranteed to get an initial layout
by default. The tests were checking for an equivalent operator between
the output circuit and the input one. However, the use of vf2layout was
potentially changing the bit order (especially at higher optimization
levels) in the operator because a non trivial layout was selected. This
caused the tests to fail. This commit fixes the test failures by adding
a helper function to permute the qubits back based on the layout
property in the transpiled circuit.

* Fix docs build

* Remove warning on use of TrivialLayout in opt level 1

The warning which was being emitted by an optimization level 1 transpile()
if a trivial layout was used was decided to be too potentially noisy for
users, especially because it wasn't directly actionable. For the first
step of using vf2 layout everywhere we decided to leave level1 as trying
a trivial layout first and then falling back to vf2 layout if the
trivial layout isn't a perfect match. We'll investigate whether it makes
sense in the future to change this behavior and come up with a migration
plan when that happens.

* Apply suggestions from code review

Co-authored-by: Jake Lishman <jake@binhbar.com>

* Cleanup inline comment numbering in preset pass manager modules

* Fix lint

* Remove operator_permuted_layout() from backendv2 tests

This commit removes the custom operator_permuted_layout() function from
the backendv2 tests. This function was written to permute the qubits
based on the output layout from transpile() so it can be compared to the
input circuit for equivalence. However, since this PR was first opened a
new constructor method Operator.from_circuit() was added in #7616 to
handle this directly in the Operator construction instead of doing it
out of band. THis commit just leverages the new constructor instead of
having a duplicate local test function.

* Remove unused import

Co-authored-by: Jake Lishman <jake@binhbar.com>
Co-authored-by: Kevin Krsulich <kevin@krsulich.net>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Feb 24, 2022
1 parent 9ec0c4e commit 7cab49f
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 168 deletions.
68 changes: 53 additions & 15 deletions qiskit/transpiler/preset_passmanagers/level1.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
from qiskit.transpiler.passes import CheckMap
from qiskit.transpiler.passes import GateDirection
from qiskit.transpiler.passes import SetLayout
from qiskit.transpiler.passes import VF2Layout
from qiskit.transpiler.passes import TrivialLayout
from qiskit.transpiler.passes import DenseLayout
from qiskit.transpiler.passes import NoiseAdaptiveLayout
from qiskit.transpiler.passes import SabreLayout
from qiskit.transpiler.passes import BarrierBeforeFinalMeasurements
from qiskit.transpiler.passes import Layout2qDistance
from qiskit.transpiler.passes import BasicSwap
from qiskit.transpiler.passes import LookaheadSwap
from qiskit.transpiler.passes import StochasticSwap
Expand All @@ -44,7 +46,6 @@
from qiskit.transpiler.passes import Optimize1qGatesDecomposition
from qiskit.transpiler.passes import ApplyLayout
from qiskit.transpiler.passes import CheckGateDirection
from qiskit.transpiler.passes import Layout2qDistance
from qiskit.transpiler.passes import Collect2qBlocks
from qiskit.transpiler.passes import ConsolidateBlocks
from qiskit.transpiler.passes import UnitarySynthesis
Expand All @@ -56,6 +57,7 @@
from qiskit.transpiler.passes import PulseGates
from qiskit.transpiler.passes import Error
from qiskit.transpiler.passes import ContainsInstruction
from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason

from qiskit.transpiler import TranspilerError

Expand Down Expand Up @@ -102,17 +104,58 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager:
timing_constraints = pass_manager_config.timing_constraints or TimingConstraints()
target = pass_manager_config.target

# 1. Use trivial layout if no layout given
# 1. Use trivial layout if no layout given if that isn't perfect use vf2 layout
_given_layout = SetLayout(initial_layout)

_choose_layout_and_score = [
TrivialLayout(coupling_map),
Layout2qDistance(coupling_map, property_name="trivial_layout_score"),
]

def _choose_layout_condition(property_set):
return not property_set["layout"]

def _trivial_not_perfect(property_set):
# Verify that a trivial layout is perfect. If trivial_layout_score > 0
# the layout is not perfect. The layout is unconditionally set by trivial
# layout so we need to clear it before contuing.
if (
property_set["trivial_layout_score"] is not None
and property_set["trivial_layout_score"] != 0
):
return True
return False

def _vf2_match_not_found(property_set):
# If a layout hasn't been set by the time we run vf2 layout we need to
# run layout
if property_set["layout"] is None:
return True
# if VF2 layout stopped for any reason other than solution found we need
# to run layout since VF2 didn't converge.
if (
property_set["VF2Layout_stop_reason"] is not None
and property_set["VF2Layout_stop_reason"] is not VF2LayoutStopReason.SOLUTION_FOUND
):
return True
return False

_choose_layout_0 = (
[]
if pass_manager_config.layout_method
else [
TrivialLayout(coupling_map),
Layout2qDistance(coupling_map, property_name="trivial_layout_score"),
]
)

_choose_layout_1 = (
[]
if pass_manager_config.layout_method
else VF2Layout(
coupling_map,
seed=seed_transpiler,
call_limit=int(5e4), # Set call limit to ~100ms with retworkx 0.10.2
time_limit=0.1,
properties=backend_properties,
)
)

# 2. Decompose so only 1-qubit and 2-qubit gates remain
_unroll3q = [
# Use unitary synthesis for basis aware decomposition of UnitaryGates
Expand All @@ -138,12 +181,6 @@ def _choose_layout_condition(property_set):
else:
raise TranspilerError("Invalid layout method %s." % layout_method)

def _not_perfect_yet(property_set):
return (
property_set["trivial_layout_score"] is not None
and property_set["trivial_layout_score"] != 0
)

# 4. Extend dag/layout with ancillas using the full coupling map
_embed = [FullAncillaAllocation(coupling_map), EnlargeWithAncilla(), ApplyLayout()]

Expand Down Expand Up @@ -279,8 +316,9 @@ def _contains_delay(property_set):
if coupling_map or initial_layout:
pm1.append(_given_layout)
pm1.append(_unroll3q)
pm1.append(_choose_layout_and_score, condition=_choose_layout_condition)
pm1.append(_improve_layout, condition=_not_perfect_yet)
pm1.append(_choose_layout_0, condition=_choose_layout_condition)
pm1.append(_choose_layout_1, condition=_trivial_not_perfect)
pm1.append(_improve_layout, condition=_vf2_match_not_found)
pm1.append(_embed)
pm1.append(_swap_check)
pm1.append(_swap, condition=_swap_condition)
Expand Down
69 changes: 28 additions & 41 deletions qiskit/transpiler/preset_passmanagers/level2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from qiskit.transpiler.passes import CheckMap
from qiskit.transpiler.passes import GateDirection
from qiskit.transpiler.passes import SetLayout
from qiskit.transpiler.passes import CSPLayout
from qiskit.transpiler.passes import VF2Layout
from qiskit.transpiler.passes import TrivialLayout
from qiskit.transpiler.passes import DenseLayout
from qiskit.transpiler.passes import NoiseAdaptiveLayout
Expand All @@ -45,7 +45,6 @@
from qiskit.transpiler.passes import Optimize1qGatesDecomposition
from qiskit.transpiler.passes import CommutativeCancellation
from qiskit.transpiler.passes import ApplyLayout
from qiskit.transpiler.passes import Layout2qDistance
from qiskit.transpiler.passes import CheckGateDirection
from qiskit.transpiler.passes import Collect2qBlocks
from qiskit.transpiler.passes import ConsolidateBlocks
Expand All @@ -58,6 +57,7 @@
from qiskit.transpiler.passes import PulseGates
from qiskit.transpiler.passes import Error
from qiskit.transpiler.passes import ContainsInstruction
from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason

from qiskit.transpiler import TranspilerError

Expand Down Expand Up @@ -126,54 +126,42 @@ def _choose_layout_condition(property_set):
# layout hasn't been set yet
return not property_set["layout"]

# 1a. If layout_method is not set, first try a trivial layout
_choose_layout_0 = (
[]
if pass_manager_config.layout_method
else [
TrivialLayout(coupling_map),
Layout2qDistance(coupling_map, property_name="trivial_layout_score"),
]
)
# 2b. If a trivial layout wasn't perfect (ie no swaps are needed) then try using
# CSP layout to find a perfect layout
_choose_layout_1 = (
[]
if pass_manager_config.layout_method
else CSPLayout(coupling_map, call_limit=1000, time_limit=10, seed=seed_transpiler)
)

def _trivial_not_perfect(property_set):
# Verify that a trivial layout is perfect. If trivial_layout_score > 0
# the layout is not perfect. The layout is unconditionally set by trivial
# layout so we need to clear it before continuing.
if property_set["trivial_layout_score"] is not None:
if property_set["trivial_layout_score"] != 0:
return True
return False

def _csp_not_found_match(property_set):
# If a layout hasn't been set by the time we run csp we need to run layout
def _vf2_match_not_found(property_set):
# If a layout hasn't been set by the time we run vf2 layout we need to
# run layout
if property_set["layout"] is None:
return True
# if CSP layout stopped for any reason other than solution found we need
# to run layout since CSP didn't converge.
# if VF2 layout stopped for any reason other than solution found we need
# to run layout since VF2 didn't converge.
if (
property_set["CSPLayout_stop_reason"] is not None
and property_set["CSPLayout_stop_reason"] != "solution found"
property_set["VF2Layout_stop_reason"] is not None
and property_set["VF2Layout_stop_reason"] is not VF2LayoutStopReason.SOLUTION_FOUND
):
return True
return False

# 2c. if CSP layout doesn't converge on a solution use layout_method (dense) to get a layout
# 2a. Try using VF2 layout to find a perfect layout
_choose_layout_0 = (
[]
if pass_manager_config.layout_method
else VF2Layout(
coupling_map,
seed=seed_transpiler,
call_limit=int(5e6), # Set call limit to ~10 sec with retworkx 0.10.2
time_limit=10.0,
properties=backend_properties,
)
)

# 2b. if VF2 layout doesn't converge on a solution use layout_method (dense) to get a layout
if layout_method == "trivial":
_choose_layout_2 = TrivialLayout(coupling_map)
_choose_layout_1 = TrivialLayout(coupling_map)
elif layout_method == "dense":
_choose_layout_2 = DenseLayout(coupling_map, backend_properties)
_choose_layout_1 = DenseLayout(coupling_map, backend_properties)
elif layout_method == "noise_adaptive":
_choose_layout_2 = NoiseAdaptiveLayout(backend_properties)
_choose_layout_1 = NoiseAdaptiveLayout(backend_properties)
elif layout_method == "sabre":
_choose_layout_2 = SabreLayout(coupling_map, max_iterations=2, seed=seed_transpiler)
_choose_layout_1 = SabreLayout(coupling_map, max_iterations=2, seed=seed_transpiler)
else:
raise TranspilerError("Invalid layout method %s." % layout_method)

Expand Down Expand Up @@ -317,8 +305,7 @@ def _contains_delay(property_set):
pm2.append(_given_layout)
pm2.append(_unroll3q)
pm2.append(_choose_layout_0, condition=_choose_layout_condition)
pm2.append(_choose_layout_1, condition=_trivial_not_perfect)
pm2.append(_choose_layout_2, condition=_csp_not_found_match)
pm2.append(_choose_layout_1, condition=_vf2_match_not_found)
pm2.append(_embed)
pm2.append(_swap_check)
pm2.append(_swap, condition=_swap_condition)
Expand Down
60 changes: 23 additions & 37 deletions qiskit/transpiler/preset_passmanagers/level3.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from qiskit.transpiler.passes import CheckMap
from qiskit.transpiler.passes import GateDirection
from qiskit.transpiler.passes import SetLayout
from qiskit.transpiler.passes import CSPLayout
from qiskit.transpiler.passes import VF2Layout
from qiskit.transpiler.passes import TrivialLayout
from qiskit.transpiler.passes import DenseLayout
from qiskit.transpiler.passes import NoiseAdaptiveLayout
Expand All @@ -51,7 +51,6 @@
from qiskit.transpiler.passes import ConsolidateBlocks
from qiskit.transpiler.passes import UnitarySynthesis
from qiskit.transpiler.passes import ApplyLayout
from qiskit.transpiler.passes import Layout2qDistance
from qiskit.transpiler.passes import CheckGateDirection
from qiskit.transpiler.passes import TimeUnitConversion
from qiskit.transpiler.passes import ALAPSchedule
Expand All @@ -61,6 +60,7 @@
from qiskit.transpiler.passes import PulseGates
from qiskit.transpiler.passes import Error
from qiskit.transpiler.passes import ContainsInstruction
from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason

from qiskit.transpiler import TranspilerError

Expand Down Expand Up @@ -129,54 +129,41 @@ def _choose_layout_condition(property_set):
# layout hasn't been set yet
return not property_set["layout"]

def _csp_not_found_match(property_set):
# If a layout hasn't been set by the time we run csp we need to run layout
def _vf2_match_not_found(property_set):
# If a layout hasn't been set by the time we run vf2 layout we need to
# run layout
if property_set["layout"] is None:
return True
# if CSP layout stopped for any reason other than solution found we need
# to run layout since CSP didn't converge.
# if VF2 layout stopped for any reason other than solution found we need
# to run layout since VF2 didn't converge.
if (
property_set["CSPLayout_stop_reason"] is not None
and property_set["CSPLayout_stop_reason"] != "solution found"
property_set["VF2Layout_stop_reason"] is not None
and property_set["VF2Layout_stop_reason"] is not VF2LayoutStopReason.SOLUTION_FOUND
):
return True
return False

# 2a. If layout method is not set, first try a trivial layout
# 2a. If layout method is not set, first try VF2Layout
_choose_layout_0 = (
[]
if pass_manager_config.layout_method
else [
TrivialLayout(coupling_map),
Layout2qDistance(coupling_map, property_name="trivial_layout_score"),
]
)
# 2b. If trivial layout wasn't perfect (ie no swaps are needed) then try
# using CSP layout to find a perfect layout
_choose_layout_1 = (
[]
if pass_manager_config.layout_method
else CSPLayout(coupling_map, call_limit=10000, time_limit=60, seed=seed_transpiler)
else VF2Layout(
coupling_map,
seed=seed_transpiler,
call_limit=int(3e7), # Set call limit to ~60 sec with retworkx 0.10.2
time_limit=60,
properties=backend_properties,
)
)

def _trivial_not_perfect(property_set):
# Verify that a trivial layout is perfect. If trivial_layout_score > 0
# the layout is not perfect. The layout property set is unconditionally
# set by trivial layout so we clear that before running CSP
if property_set["trivial_layout_score"] is not None:
if property_set["trivial_layout_score"] != 0:
return True
return False

# 2c. if CSP didn't converge on a solution use layout_method (dense).
# 2b. if VF2 didn't converge on a solution use layout_method (dense).
if layout_method == "trivial":
_choose_layout_2 = TrivialLayout(coupling_map)
_choose_layout_1 = TrivialLayout(coupling_map)
elif layout_method == "dense":
_choose_layout_2 = DenseLayout(coupling_map, backend_properties)
_choose_layout_1 = DenseLayout(coupling_map, backend_properties)
elif layout_method == "noise_adaptive":
_choose_layout_2 = NoiseAdaptiveLayout(backend_properties)
_choose_layout_1 = NoiseAdaptiveLayout(backend_properties)
elif layout_method == "sabre":
_choose_layout_2 = SabreLayout(coupling_map, max_iterations=4, seed=seed_transpiler)
_choose_layout_1 = SabreLayout(coupling_map, max_iterations=4, seed=seed_transpiler)
else:
raise TranspilerError("Invalid layout method %s." % layout_method)

Expand Down Expand Up @@ -329,8 +316,7 @@ def _contains_delay(property_set):
if coupling_map or initial_layout:
pm3.append(_given_layout)
pm3.append(_choose_layout_0, condition=_choose_layout_condition)
pm3.append(_choose_layout_1, condition=_trivial_not_perfect)
pm3.append(_choose_layout_2, condition=_csp_not_found_match)
pm3.append(_choose_layout_1, condition=_vf2_match_not_found)
pm3.append(_embed)
pm3.append(_swap_check)
pm3.append(_swap, condition=_swap_condition)
Expand Down
6 changes: 3 additions & 3 deletions qiskit/visualization/pulse_v2/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def draw(
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
qc = transpile(qc, FakeAlmaden())
qc = transpile(qc, FakeAlmaden(), layout_method='trivial')
sched = schedule(qc, FakeAlmaden())
draw(sched, backend=FakeAlmaden())
Expand All @@ -331,7 +331,7 @@ def draw(
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
qc = transpile(qc, FakeAlmaden())
qc = transpile(qc, FakeAlmaden(), layout_method='trivial')
sched = schedule(qc, FakeAlmaden())
draw(sched, style=IQXSimple(), backend=FakeAlmaden())
Expand All @@ -348,7 +348,7 @@ def draw(
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
qc = transpile(qc, FakeAlmaden())
qc = transpile(qc, FakeAlmaden(), layout_method='trivial')
sched = schedule(qc, FakeAlmaden())
draw(sched, style=IQXDebugging(), backend=FakeAlmaden())
Expand Down
6 changes: 3 additions & 3 deletions qiskit/visualization/timeline/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def draw(
qc.h(0)
qc.cx(0,1)
qc = transpile(qc, FakeAlmaden(), scheduling_method='alap')
qc = transpile(qc, FakeAlmaden(), scheduling_method='alap', layout_method='trivial')
draw(qc)
Drawing with the simple stylesheet.
Expand All @@ -312,7 +312,7 @@ def draw(
qc.h(0)
qc.cx(0,1)
qc = transpile(qc, FakeAlmaden(), scheduling_method='alap')
qc = transpile(qc, FakeAlmaden(), scheduling_method='alap', layout_method='trivial')
draw(qc, style=IQXSimple())
Drawing with the stylesheet suited for program debugging.
Expand All @@ -327,7 +327,7 @@ def draw(
qc.h(0)
qc.cx(0,1)
qc = transpile(qc, FakeAlmaden(), scheduling_method='alap')
qc = transpile(qc, FakeAlmaden(), scheduling_method='alap', layout_method='trivial')
draw(qc, style=IQXDebugging())
You can partially customize a preset stylesheet when call it::
Expand Down
Loading

0 comments on commit 7cab49f

Please sign in to comment.