From d42511b9e0774c7504d73837fec75bc23b31972f Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 4 Apr 2022 12:20:36 -0400 Subject: [PATCH 1/6] Update docstrings for renamed scheduling passes In #7835 we renamed the passes used in the new scheduler pass workflow to differentiate them from the existing legacy scheduling pass workflow (which we restored pending a future deprecation in that PR). However, while we updated the docstring for the legacy path to update them to point to the new passes, we neglected to update the docstrings for the renamed classes to reflect the new names. The examples in the docstrings still worked because of the old passes, but it wasn't showing an example of how to use the new workflow anymore. This commit corrects this oversight so that they actually explain how to use them. --- .../passes/scheduling/alignments/reschedule.py | 2 +- .../passes/scheduling/padding/dynamical_decoupling.py | 10 +++++----- qiskit/transpiler/passes/scheduling/scheduling/alap.py | 4 ++-- qiskit/transpiler/passes/scheduling/scheduling/asap.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/qiskit/transpiler/passes/scheduling/alignments/reschedule.py b/qiskit/transpiler/passes/scheduling/alignments/reschedule.py index ab22b0080a9d..af28fed1adb6 100644 --- a/qiskit/transpiler/passes/scheduling/alignments/reschedule.py +++ b/qiskit/transpiler/passes/scheduling/alignments/reschedule.py @@ -25,7 +25,7 @@ class ConstrainedReschedule(AnalysisPass): """Rescheduler pass that updates node start times to conform to the hardware alignments. This pass shifts DAG node start times previously scheduled with one of - the scheduling passes, e.g. :class:`ASAPSchedule` or :class:`ALAPSchedule`, + the scheduling passes, e.g. :class:`ASAPScheduleAnalysis` or :class:`ALAPScheduleAnalysis`, so that every instruction start time satisfies alignment constraints. Examples: diff --git a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py index 828fb49f5bcf..d19727d469a1 100644 --- a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +++ b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py @@ -53,7 +53,7 @@ class PadDynamicalDecoupling(BasePadding): from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import XGate from qiskit.transpiler import PassManager, InstructionDurations - from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling + from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDynamicalDecoupling from qiskit.visualization import timeline_drawer circ = QuantumCircuit(4) circ.h(0) @@ -71,8 +71,8 @@ class PadDynamicalDecoupling(BasePadding): # balanced X-X sequence on all qubits dd_sequence = [XGate(), XGate()] - pm = PassManager([ALAPSchedule(durations), - DynamicalDecoupling(durations, dd_sequence)]) + pm = PassManager([ALAPScheduleAnalysis(durations), + PadDynamicalDecoupling(durations, dd_sequence)]) circ_dd = pm.run(circ) timeline_drawer(circ_dd) @@ -89,8 +89,8 @@ def uhrig_pulse_location(k): spacing.append(1 - sum(spacing)) pm = PassManager( [ - ALAPSchedule(durations), - DynamicalDecoupling(durations, dd_sequence, qubits=[0], spacing=spacing), + ALAPScheduleAnalysis(durations), + PadDynamicalDecoupling(durations, dd_sequence, qubits=[0], spacing=spacing), ] ) circ_dd = pm.run(circ) diff --git a/qiskit/transpiler/passes/scheduling/scheduling/alap.py b/qiskit/transpiler/passes/scheduling/scheduling/alap.py index e9a26b19e49e..09b859e5855f 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/alap.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/alap.py @@ -20,8 +20,8 @@ class ALAPScheduleAnalysis(BaseScheduler): """ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible. - See :class:`~qiskit.transpiler.passes.scheduling.base_scheduler.BaseScheduler` for the - detailed behavior of the control flow operation, i.e. ``c_if``. + See :class:`~qiskit.transpiler.passes.scheduling.scheduling.base_scheduler.BaseScheduler` for + the detailed behavior of the control flow operation, i.e. ``c_if``. """ def run(self, dag): diff --git a/qiskit/transpiler/passes/scheduling/scheduling/asap.py b/qiskit/transpiler/passes/scheduling/scheduling/asap.py index e4ed656655a2..0d7e12347b15 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/asap.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/asap.py @@ -20,8 +20,8 @@ class ASAPScheduleAnalysis(BaseScheduler): """ASAP Scheduling pass, which schedules the start time of instructions as early as possible.. - See :class:`~qiskit.transpiler.passes.scheduling.base_scheduler.BaseScheduler` for the - detailed behavior of the control flow operation, i.e. ``c_if``. + See :class:`~qiskit.transpiler.passes.scheduling.scheduling.base_scheduler.BaseScheduler` for + the detailed behavior of the control flow operation, i.e. ``c_if``. """ def run(self, dag): From 3ae60d20bec3f5e41156468248dc4a6068f525b5 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 11 Apr 2022 15:21:44 -0400 Subject: [PATCH 2/6] Add scheduling section to top level transpiler doc --- qiskit/transpiler/__init__.py | 240 ++++++++++++++++++ .../passes/scheduling/scheduling/alap.py | 2 +- .../passes/scheduling/scheduling/asap.py | 2 +- .../scheduling/scheduling/base_scheduler.py | 180 +------------ 4 files changed, 243 insertions(+), 181 deletions(-) diff --git a/qiskit/transpiler/__init__.py b/qiskit/transpiler/__init__.py index 19aafb51a1bc..87c072783b49 100644 --- a/qiskit/transpiler/__init__.py +++ b/qiskit/transpiler/__init__.py @@ -354,6 +354,246 @@
+.. dropdown:: Scheduling + :animate: fade-in-slide-down + + After the circuit has been translated to the target basis, mapped to the device, and optimized + another optional phase to the compiler is scheduling. The scheduling phase is used to optionally + account for all the idle time in the circuit. At a high level the scheduling + can be thought of as inserting delays into the circuit to account for idle + time on the qubits between the execution of instructions. For example, if we start with a + circuit such as: + + .. jupyter-execute:: + + from qiskit import QuantumCircuit, transpile + from qiskit.test.mock import FakeBoeblingen + backend = FakeBoeblingen() + + ghz = QuantumCircuit(5) + ghz.h(0) + ghz.cx(0,range(1,5)) + ghz.draw(output='mpl') + + we can then call :func:`~.transpile` on it with ``scheduling_method`` set: + + .. jupyter-execute:: + + circ = transpile(ghz, backend, scheduling_method="asap") + circ.draw(output='mpl') + + You can see here that the transpiler inserted :class:`~qiskit.circuit.Delay` instructions to + account for idle time on each qubit. To get a better idea of the timing of the circuit we can + also look at it with the :func:`.timeline.draw` function: + + .. jupyter-execute:: + + from qiskit.visualization.timeline import draw as timeline_draw + + timeline_draw(circ) + + The scheduling of a circuit involves two parts, analysis and constraint mapping followed by a + padding pass. The first part requires running a scheduling analysis pass such as + :class:`~.ALAPSchedulingAnalysis` or :class:`~.ASAPSchedulingAnalysis` which analyzes the circuit + and maps the start time of each instruction in the circuit using a scheduling algorithm ("as late + as possible" for :class:`~.ALAPSchedulingAnalysis` and "as soon as possible" for + :class:~.ASAPSchedulingAnalysis) to the property set. Once the circuit has an initial scheduling + additional passes can be run to account for any timing constraints on the target backend, such + as alignment constraints. This is typically done with the + :class:`~.ConstrainedReschedule` pass which will adjust the scheduling + set in the property set to the contraints of the target backend. Once all + the scheduling and adjustments/rescheduling are finished a padding pass, + such as :class:`~.PadDelay` or :class:`~.PadDynamicalDecoupling` are run + to insert the instructions to the circuit to complete the scheduling. + + .. _scheduling_passes_control_flow: + + Scheduling Anaylsis with control flow instructions: + + When scheduling analysis passes run there are additional constraints on classical conditions and control + flow instructions in a circuit. This section covers the details of these additional constraints that any + scheduling pass will need to account for. + + Policy of topological node ordering in scheduling: + + The DAG representation of ``QuantumCircuit`` respects the node ordering also in the + classical register wires, though theoretically two conditional instructions + conditioned on the same register are commute, i.e. read-access to the + classical register doesn't change its state. + + .. parsed-literal:: + + qc = QuantumCircuit(2, 1) + qc.delay(100, 0) + qc.x(0).c_if(0, True) + qc.x(1).c_if(0, True) + + The scheduler SHOULD comply with above topological ordering policy of the DAG circuit. + Accordingly, the `asap`-scheduled circuit will become + + .. parsed-literal:: + + ┌────────────────┐ ┌───┐ + q_0: ┤ Delay(100[dt]) ├───┤ X ├────────────── + ├────────────────┤ └─╥─┘ ┌───┐ + q_1: ┤ Delay(100[dt]) ├─────╫────────┤ X ├─── + └────────────────┘ ║ └─╥─┘ + ┌────╨────┐┌────╨────┐ + c: 1/══════════════════╡ c_0=0x1 ╞╡ c_0=0x1 ╞ + └─────────┘└─────────┘ + + Note that this scheduling might be inefficient in some cases, + because the second conditional operation can start without waiting the delay of 100 dt. + However, such optimization should be done by another pass, + otherwise scheduling may break topological ordering of the original circuit. + + Realistic control flow scheduling respecting for microarcitecture: + + In the dispersive QND readout scheme, qubit is measured with microwave stimulus to qubit (Q) + followed by resonator ring-down (depopulation). This microwave signal is recorded + in the buffer memory (B) with hardware kernel, then a discriminated (D) binary value + is moved to the classical register (C). + The sequence from t0 to t1 of the measure instruction interval might be modeled as follows: + + .. parsed-literal:: + + Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + B ░░▒▒▒▒▒▒▒▒░░░░░░░░░ + D ░░░░░░░░░░▒▒▒▒▒▒░░░ + C ░░░░░░░░░░░░░░░░▒▒░ + + However, ``QuantumCircuit`` representation is not enough accurate to represent + this model. In the circuit representation, thus ``Qubit`` is occupied by the + stimulus microwave signal during the first half of the interval, + and ``Clbit`` is only occupied at the very end of the interval. + + This precise model may induce weird edge case. + + .. parsed-literal:: + + ┌───┐ + q_0: ───┤ X ├────── + └─╥─┘ ┌─┐ + q_1: ─────╫─────┤M├ + ┌────╨────┐└╥┘ + c: 1/╡ c_0=0x1 ╞═╩═ + └─────────┘ 0 + + In this example, user may intend to measure the state of ``q_1``, after ``XGate`` is + applied to the ``q_0``. This is correct interpretation from viewpoint of + the topological node ordering, i.e. x gate node come in front of the measure node. + However, according to the measurement model above, the data in the register + is unchanged during the stimulus, thus two nodes are simultaneously operated. + If one `alap`-schedule this circuit, it may return following circuit. + + .. parsed-literal:: + + ┌────────────────┐ ┌───┐ + q_0: ┤ Delay(500[dt]) ├───┤ X ├────── + └────────────────┘ └─╥─┘ ┌─┐ + q_1: ───────────────────────╫─────┤M├ + ┌────╨────┐└╥┘ + c: 1/══════════════════╡ c_0=0x1 ╞═╩═ + └─────────┘ 0 + + Note that there is no delay on ``q_1`` wire, and the measure instruction immediately + start after t=0, while the conditional gate starts after the delay. + It looks like the topological ordering between the nodes are flipped in the scheduled view. + This behavior can be understood by considering the control flow model described above, + + .. parsed-literal:: + + : Quantum Circuit, first-measure + 0 ░░░░░░░░░░░░▒▒▒▒▒▒░ + 1 ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + + : In wire q0 + Q ░░░░░░░░░░░░░░░▒▒▒░ + C ░░░░░░░░░░░░▒▒░░░░░ + + : In wire q1 + Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + B ░░▒▒▒▒▒▒▒▒░░░░░░░░░ + D ░░░░░░░░░░▒▒▒▒▒▒░░░ + C ░░░░░░░░░░░░░░░░▒▒░ + + Since there is no qubit register (Q0, Q1) overlap, the node ordering is determined by the + shared classical register C. As you can see, the execution order is still + preserved on C, i.e. read C then apply ``XGate``, finally store the measured outcome in C. + Because ``DAGOpNode`` cannot define different durations for associated registers, + the time ordering of two nodes is inverted anyways. + + This behavior can be controlled by ``clbit_write_latency`` and ``conditional_latency``. + The former parameter determines the delay of the register write-access from + the beginning of the measure instruction t0, and another parameter determines + the delay of conditional gate operation from t0 which comes from the register read-access. + These information might be found in the backend configuration and then should + be copied to the pass manager property set before the pass is called. + + By default latencies, the `alap`-scheduled circuit of above example may become + + .. parsed-literal:: + + ┌───┐ + q_0: ───┤ X ├────── + └─╥─┘ ┌─┐ + q_1: ─────╫─────┤M├ + ┌────╨────┐└╥┘ + c: 1/╡ c_0=0x1 ╞═╩═ + └─────────┘ 0 + + If the backend microarchitecture supports smart scheduling of the control flow, i.e. + it may separately schedule qubit and classical register, + insertion of the delay yields unnecessary longer total execution time. + + .. parsed-literal:: + : Quantum Circuit, first-xgate + 0 ░▒▒▒░░░░░░░░░░░░░░░ + 1 ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + + : In wire q0 + Q ░▒▒▒░░░░░░░░░░░░░░░ + C ░░░░░░░░░░░░░░░░░░░ (zero latency) + + : In wire q1 + Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + C ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ (zero latency, scheduled after C0 read-access) + + However this result is much more intuitive in the topological ordering view. + If finite conditional latency is provided, for example, 30 dt, the circuit + is scheduled as follows. + + .. parsed-literal:: + + ┌───────────────┐ ┌───┐ + q_0: ┤ Delay(30[dt]) ├───┤ X ├────── + ├───────────────┤ └─╥─┘ ┌─┐ + q_1: ┤ Delay(30[dt]) ├─────╫─────┤M├ + └───────────────┘┌────╨────┐└╥┘ + c: 1/═════════════════╡ c_0=0x1 ╞═╩═ + └─────────┘ 0 + + with the timing model: + + .. parsed-literal:: + : Quantum Circuit, first-xgate + 0 ░░▒▒▒░░░░░░░░░░░░░░░ + 1 ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + + : In wire q0 + Q ░░▒▒▒░░░░░░░░░░░░░░░ + C ░▒░░░░░░░░░░░░░░░░░░ (30dt latency) + + : In wire q1 + Q ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + C ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ + + See https://arxiv.org/abs/2102.01682 for more details. + + .. raw:: html + +
+ Transpiler API ============== diff --git a/qiskit/transpiler/passes/scheduling/scheduling/alap.py b/qiskit/transpiler/passes/scheduling/scheduling/alap.py index 09b859e5855f..bba1b95e7ba7 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/alap.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/alap.py @@ -20,7 +20,7 @@ class ALAPScheduleAnalysis(BaseScheduler): """ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible. - See :class:`~qiskit.transpiler.passes.scheduling.scheduling.base_scheduler.BaseScheduler` for + See :ref:`scheduling_passes_control_flow` for the detailed behavior of the control flow operation, i.e. ``c_if``. """ diff --git a/qiskit/transpiler/passes/scheduling/scheduling/asap.py b/qiskit/transpiler/passes/scheduling/scheduling/asap.py index 0d7e12347b15..393d52b2964d 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/asap.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/asap.py @@ -20,7 +20,7 @@ class ASAPScheduleAnalysis(BaseScheduler): """ASAP Scheduling pass, which schedules the start time of instructions as early as possible.. - See :class:`~qiskit.transpiler.passes.scheduling.scheduling.base_scheduler.BaseScheduler` for + See :ref:`scheduling_passes_control_flow` for the detailed behavior of the control flow operation, i.e. ``c_if``. """ diff --git a/qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py b/qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py index 5cedbd0e1ae5..8dacf45f1e83 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py @@ -25,185 +25,7 @@ class BaseScheduler(AnalysisPass): - """Base scheduler pass. - - Policy of topological node ordering in scheduling - - The DAG representation of ``QuantumCircuit`` respects the node ordering also in the - classical register wires, though theoretically two conditional instructions - conditioned on the same register are commute, i.e. read-access to the - classical register doesn't change its state. - - .. parsed-literal:: - - qc = QuantumCircuit(2, 1) - qc.delay(100, 0) - qc.x(0).c_if(0, True) - qc.x(1).c_if(0, True) - - The scheduler SHOULD comply with above topological ordering policy of the DAG circuit. - Accordingly, the `asap`-scheduled circuit will become - - .. parsed-literal:: - - ┌────────────────┐ ┌───┐ - q_0: ┤ Delay(100[dt]) ├───┤ X ├────────────── - ├────────────────┤ └─╥─┘ ┌───┐ - q_1: ┤ Delay(100[dt]) ├─────╫────────┤ X ├─── - └────────────────┘ ║ └─╥─┘ - ┌────╨────┐┌────╨────┐ - c: 1/══════════════════╡ c_0=0x1 ╞╡ c_0=0x1 ╞ - └─────────┘└─────────┘ - - Note that this scheduling might be inefficient in some cases, - because the second conditional operation can start without waiting the delay of 100 dt. - However, such optimization should be done by another pass, - otherwise scheduling may break topological ordering of the original circuit. - - Realistic control flow scheduling respecting for microarcitecture - - In the dispersive QND readout scheme, qubit is measured with microwave stimulus to qubit (Q) - followed by resonator ring-down (depopulation). This microwave signal is recorded - in the buffer memory (B) with hardware kernel, then a discriminated (D) binary value - is moved to the classical register (C). - The sequence from t0 to t1 of the measure instruction interval might be modeled as follows: - - .. parsed-literal:: - - Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - B ░░▒▒▒▒▒▒▒▒░░░░░░░░░ - D ░░░░░░░░░░▒▒▒▒▒▒░░░ - C ░░░░░░░░░░░░░░░░▒▒░ - - However, ``QuantumCircuit`` representation is not enough accurate to represent - this model. In the circuit representation, thus ``Qubit`` is occupied by the - stimulus microwave signal during the first half of the interval, - and ``Clbit`` is only occupied at the very end of the interval. - - This precise model may induce weird edge case. - - .. parsed-literal:: - - ┌───┐ - q_0: ───┤ X ├────── - └─╥─┘ ┌─┐ - q_1: ─────╫─────┤M├ - ┌────╨────┐└╥┘ - c: 1/╡ c_0=0x1 ╞═╩═ - └─────────┘ 0 - - In this example, user may intend to measure the state of ``q_1``, after ``XGate`` is - applied to the ``q_0``. This is correct interpretation from viewpoint of - the topological node ordering, i.e. x gate node come in front of the measure node. - However, according to the measurement model above, the data in the register - is unchanged during the stimulus, thus two nodes are simultaneously operated. - If one `alap`-schedule this circuit, it may return following circuit. - - .. parsed-literal:: - - ┌────────────────┐ ┌───┐ - q_0: ┤ Delay(500[dt]) ├───┤ X ├────── - └────────────────┘ └─╥─┘ ┌─┐ - q_1: ───────────────────────╫─────┤M├ - ┌────╨────┐└╥┘ - c: 1/══════════════════╡ c_0=0x1 ╞═╩═ - └─────────┘ 0 - - Note that there is no delay on ``q_1`` wire, and the measure instruction immediately - start after t=0, while the conditional gate starts after the delay. - It looks like the topological ordering between the nodes are flipped in the scheduled view. - This behavior can be understood by considering the control flow model described above, - - .. parsed-literal:: - - : Quantum Circuit, first-measure - 0 ░░░░░░░░░░░░▒▒▒▒▒▒░ - 1 ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - - : In wire q0 - Q ░░░░░░░░░░░░░░░▒▒▒░ - C ░░░░░░░░░░░░▒▒░░░░░ - - : In wire q1 - Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - B ░░▒▒▒▒▒▒▒▒░░░░░░░░░ - D ░░░░░░░░░░▒▒▒▒▒▒░░░ - C ░░░░░░░░░░░░░░░░▒▒░ - - Since there is no qubit register (Q0, Q1) overlap, the node ordering is determined by the - shared classical register C. As you can see, the execution order is still - preserved on C, i.e. read C then apply ``XGate``, finally store the measured outcome in C. - Because ``DAGOpNode`` cannot define different durations for associated registers, - the time ordering of two nodes is inverted anyways. - - This behavior can be controlled by ``clbit_write_latency`` and ``conditional_latency``. - The former parameter determines the delay of the register write-access from - the beginning of the measure instruction t0, and another parameter determines - the delay of conditional gate operation from t0 which comes from the register read-access. - These information might be found in the backend configuration and then should - be copied to the pass manager property set before the pass is called. - - By default latencies, the `alap`-scheduled circuit of above example may become - - .. parsed-literal:: - - ┌───┐ - q_0: ───┤ X ├────── - └─╥─┘ ┌─┐ - q_1: ─────╫─────┤M├ - ┌────╨────┐└╥┘ - c: 1/╡ c_0=0x1 ╞═╩═ - └─────────┘ 0 - - If the backend microarchitecture supports smart scheduling of the control flow, i.e. - it may separately schedule qubit and classical register, - insertion of the delay yields unnecessary longer total execution time. - - .. parsed-literal:: - : Quantum Circuit, first-xgate - 0 ░▒▒▒░░░░░░░░░░░░░░░ - 1 ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - - : In wire q0 - Q ░▒▒▒░░░░░░░░░░░░░░░ - C ░░░░░░░░░░░░░░░░░░░ (zero latency) - - : In wire q1 - Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - C ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ (zero latency, scheduled after C0 read-access) - - However this result is much more intuitive in the topological ordering view. - If finite conditional latency is provided, for example, 30 dt, the circuit - is scheduled as follows. - - .. parsed-literal:: - - ┌───────────────┐ ┌───┐ - q_0: ┤ Delay(30[dt]) ├───┤ X ├────── - ├───────────────┤ └─╥─┘ ┌─┐ - q_1: ┤ Delay(30[dt]) ├─────╫─────┤M├ - └───────────────┘┌────╨────┐└╥┘ - c: 1/═════════════════╡ c_0=0x1 ╞═╩═ - └─────────┘ 0 - - with the timing model: - - .. parsed-literal:: - : Quantum Circuit, first-xgate - 0 ░░▒▒▒░░░░░░░░░░░░░░░ - 1 ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - - : In wire q0 - Q ░░▒▒▒░░░░░░░░░░░░░░░ - C ░▒░░░░░░░░░░░░░░░░░░ (30dt latency) - - : In wire q1 - Q ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - C ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ - - See https://arxiv.org/abs/2102.01682 for more details. - - """ + """Base scheduler pass.""" CONDITIONAL_SUPPORTED = (Gate, Delay) From e6f49b4b08dafe0d5643d4bf799e9b6f2cf6d494 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 11 Apr 2022 16:15:30 -0400 Subject: [PATCH 3/6] Update reference --- qiskit/transpiler/__init__.py | 4 ++-- qiskit/transpiler/passes/scheduling/scheduling/alap.py | 2 +- qiskit/transpiler/passes/scheduling/scheduling/asap.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qiskit/transpiler/__init__.py b/qiskit/transpiler/__init__.py index 87c072783b49..24e6ddd41fa1 100644 --- a/qiskit/transpiler/__init__.py +++ b/qiskit/transpiler/__init__.py @@ -43,6 +43,8 @@ these ready-made routines. +.. _transpiler_supplemental: + Supplementary Information ========================= @@ -406,8 +408,6 @@ such as :class:`~.PadDelay` or :class:`~.PadDynamicalDecoupling` are run to insert the instructions to the circuit to complete the scheduling. - .. _scheduling_passes_control_flow: - Scheduling Anaylsis with control flow instructions: When scheduling analysis passes run there are additional constraints on classical conditions and control diff --git a/qiskit/transpiler/passes/scheduling/scheduling/alap.py b/qiskit/transpiler/passes/scheduling/scheduling/alap.py index bba1b95e7ba7..9de6b162ec0b 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/alap.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/alap.py @@ -20,7 +20,7 @@ class ALAPScheduleAnalysis(BaseScheduler): """ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible. - See :ref:`scheduling_passes_control_flow` for + See the Scheduling section in :ref:`transpiler_supplemental` for the detailed behavior of the control flow operation, i.e. ``c_if``. """ diff --git a/qiskit/transpiler/passes/scheduling/scheduling/asap.py b/qiskit/transpiler/passes/scheduling/scheduling/asap.py index 393d52b2964d..c37beb4f967e 100644 --- a/qiskit/transpiler/passes/scheduling/scheduling/asap.py +++ b/qiskit/transpiler/passes/scheduling/scheduling/asap.py @@ -20,7 +20,7 @@ class ASAPScheduleAnalysis(BaseScheduler): """ASAP Scheduling pass, which schedules the start time of instructions as early as possible.. - See :ref:`scheduling_passes_control_flow` for + See Scheduling section in :ref:`transpiler_supplemental` for the detailed behavior of the control flow operation, i.e. ``c_if``. """ From 551318a3899c98cc01f63d42e8d9981366e90fde Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 11 Apr 2022 17:02:13 -0400 Subject: [PATCH 4/6] Fix lint --- qiskit/transpiler/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiskit/transpiler/__init__.py b/qiskit/transpiler/__init__.py index 24e6ddd41fa1..818d2e455005 100644 --- a/qiskit/transpiler/__init__.py +++ b/qiskit/transpiler/__init__.py @@ -410,9 +410,9 @@ Scheduling Anaylsis with control flow instructions: - When scheduling analysis passes run there are additional constraints on classical conditions and control - flow instructions in a circuit. This section covers the details of these additional constraints that any - scheduling pass will need to account for. + When scheduling analysis passes run there are additional constraints on classical conditions + and control flow instructions in a circuit. This section covers the details of these additional + constraints that any scheduling pass will need to account for. Policy of topological node ordering in scheduling: From 11942c13d359bc0296e8069813e9dec04c55d794 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 11 Apr 2022 18:23:11 -0400 Subject: [PATCH 5/6] Fix typos Co-authored-by: Naoki Kanazawa --- qiskit/transpiler/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit/transpiler/__init__.py b/qiskit/transpiler/__init__.py index 818d2e455005..30f87bbce04e 100644 --- a/qiskit/transpiler/__init__.py +++ b/qiskit/transpiler/__init__.py @@ -398,8 +398,8 @@ padding pass. The first part requires running a scheduling analysis pass such as :class:`~.ALAPSchedulingAnalysis` or :class:`~.ASAPSchedulingAnalysis` which analyzes the circuit and maps the start time of each instruction in the circuit using a scheduling algorithm ("as late - as possible" for :class:`~.ALAPSchedulingAnalysis` and "as soon as possible" for - :class:~.ASAPSchedulingAnalysis) to the property set. Once the circuit has an initial scheduling + as possible" for :class:`~.ALAPSchedulingAnalysis` and "as soon as possible" for + :class:`~.ASAPSchedulingAnalysis`) to the property set. Once the circuit has an initial scheduling additional passes can be run to account for any timing constraints on the target backend, such as alignment constraints. This is typically done with the :class:`~.ConstrainedReschedule` pass which will adjust the scheduling From 402bdd729698d5167dffaa87c46e84df2483e417 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 18 Apr 2022 17:54:02 -0400 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Kevin Hartman --- qiskit/transpiler/__init__.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/qiskit/transpiler/__init__.py b/qiskit/transpiler/__init__.py index 30f87bbce04e..8a3b61f17bc3 100644 --- a/qiskit/transpiler/__init__.py +++ b/qiskit/transpiler/__init__.py @@ -359,11 +359,10 @@ .. dropdown:: Scheduling :animate: fade-in-slide-down - After the circuit has been translated to the target basis, mapped to the device, and optimized - another optional phase to the compiler is scheduling. The scheduling phase is used to optionally - account for all the idle time in the circuit. At a high level the scheduling - can be thought of as inserting delays into the circuit to account for idle - time on the qubits between the execution of instructions. For example, if we start with a + After the circuit has been translated to the target basis, mapped to the device, and optimized, + a scheduling phase can be applied to optionally account for all the idle time in the circuit. + At a high level the scheduling can be thought of as inserting delays into the circuit to account + for idle time on the qubits between the execution of instructions. For example, if we start with a circuit such as: .. jupyter-execute:: @@ -397,16 +396,16 @@ The scheduling of a circuit involves two parts, analysis and constraint mapping followed by a padding pass. The first part requires running a scheduling analysis pass such as :class:`~.ALAPSchedulingAnalysis` or :class:`~.ASAPSchedulingAnalysis` which analyzes the circuit - and maps the start time of each instruction in the circuit using a scheduling algorithm ("as late + and records the start time of each instruction in the circuit using a scheduling algorithm ("as late as possible" for :class:`~.ALAPSchedulingAnalysis` and "as soon as possible" for - :class:`~.ASAPSchedulingAnalysis`) to the property set. Once the circuit has an initial scheduling + :class:`~.ASAPSchedulingAnalysis`) in the property set. Once the circuit has an initial scheduling additional passes can be run to account for any timing constraints on the target backend, such as alignment constraints. This is typically done with the :class:`~.ConstrainedReschedule` pass which will adjust the scheduling set in the property set to the contraints of the target backend. Once all the scheduling and adjustments/rescheduling are finished a padding pass, - such as :class:`~.PadDelay` or :class:`~.PadDynamicalDecoupling` are run - to insert the instructions to the circuit to complete the scheduling. + such as :class:`~.PadDelay` or :class:`~.PadDynamicalDecoupling` is run + to insert the instructions into the circuit, which completes the scheduling. Scheduling Anaylsis with control flow instructions: