Skip to main contentIBM Quantum Documentation


class qiskit.pulse.ScheduleBlock(name=None, metadata=None, alignment_context=None)

GitHub(opens in a new tab)

Bases: object(opens in a new tab)

Time-ordered sequence of instructions with alignment context.

ScheduleBlock supports lazy scheduling of context instructions, i.e. their timeslots is always generated at runtime. This indicates we can parametrize instruction durations as well as other parameters. In contrast to Schedule being somewhat static, ScheduleBlock is a dynamic representation of a pulse program.

Pulse Builder

The Qiskit pulse builder is a domain specific language that is developed on top of the schedule block. Use of the builder syntax will improve the workflow of pulse programming. See Pulse Builder for a user guide.

Alignment contexts

A schedule block is always relatively scheduled. Instead of taking individual instructions with absolute execution time t0, the schedule block defines a context of scheduling and instructions under the same context are scheduled in the same manner (alignment). Several contexts are available in Alignments. A schedule block is instantiated with one of these alignment contexts. The default context is AlignLeft, for which all instructions are left-justified, in other words, meaning they use as-soon-as-possible scheduling.

If you need an absolute-time interval in between instructions, you can explicitly insert Delay instructions.

Nested blocks

A schedule block can contain other nested blocks with different alignment contexts. This enables advanced scheduling, where a subset of instructions is locally scheduled in a different manner. Note that a Schedule instance cannot be directly added to a schedule block. To add a Schedule instance, wrap it in a Call instruction. This is implicitly performed when a schedule is added through the Pulse Builder.

Unsupported operations

Because the schedule block representation lacks timeslots, it cannot perform particular Schedule operations such as insert() or shift() that require instruction start time t0. In addition, exclude() and filter() methods are not supported because these operations may identify the target instruction with t0. Except for these operations, ScheduleBlock provides full compatibility with Schedule.


The timeslots-free representation offers much greater flexibility for writing pulse programs. Because ScheduleBlock only cares about the ordering of the child blocks we can add an undefined pulse sequence as a subroutine of the main program. If your program contains the same sequence multiple times, this representation may reduce the memory footprint required by the program construction. Such a subroutine is realized by the special compiler directive Reference that is defined by a unique set of reference key strings to the subroutine. The (executable) subroutine is separately stored in the main program. Appended reference directives are resolved when the main program is executed. Subroutines must be assigned through assign_references() before execution.

One way to reference a subroutine in a schedule is to use the pulse builder’s reference() function to declare an unassigned reference. In this example, the program is called with the reference key “grand_child”. You can call a subroutine without specifying a substantial program.

from qiskit import pulse
from qiskit.circuit.parameter import Parameter
amp1 = Parameter("amp1")
amp2 = Parameter("amp2")
with as sched_inner:, amp1), pulse.DriveChannel(0))
with as sched_outer:
    with pulse.align_right():
        pulse.reference("grand_child"), amp2), pulse.DriveChannel(0))

Now you assign the inner pulse program to this reference.

sched_outer.assign_references({("grand_child", ): sched_inner})
{Parameter(amp1), Parameter(amp2)}

The outer program now has the parameter amp2 from the inner program, indicating that the inner program’s data has been made available to the outer program. The program calling the “grand_child” has a reference program description which is accessed through ScheduleBlock.references.

  - ('grand_child',): ScheduleBlock(Play(Constant(duration=100, amp=amp1,...

Finally, you may want to call this program from another program. Here we try a different approach to define subroutine. Namely, we call a subroutine from the root program with the actual program sched2.

amp3 = Parameter("amp3")
with as main:, amp3), pulse.DriveChannel(0)), name="child")
{Parameter(amp1), Parameter(amp2), Parameter(amp3}

This implicitly creates a reference named “child” within the root program and assigns sched_outer to it.

Note that the root program is only aware of its direct references.

  - ('child',): ScheduleBlock(ScheduleBlock(ScheduleBlock(Play(Con...

As you can see the main program cannot directly assign a subroutine to the “grand_child” because this subroutine is not called within the root program, i.e. it is indirectly called by “child”. However, the returned ReferenceManager is a dict-like object, and you can still reach to “grand_child” via the “child” program with the following chained dict access.

main.references[("child", )].references[("grand_child", )]

Note that ScheduleBlock.parameters still collects all parameters also from the subroutine once it’s assigned.

Create an empty schedule block.


  • name (str(opens in a new tab) | None) – Name of this schedule. Defaults to an autogenerated string if not provided.
  • metadata (dict(opens in a new tab) | None) – Arbitrary key value metadata to associate with the schedule. This gets stored as free-form data in a dict in the metadata attribute. It will not be directly used in the schedule.
  • alignment_context (AlignmentKind) – AlignmentKind instance that manages scheduling of instructions in this block.


TypeError(opens in a new tab) – if metadata is not a dict.



Return alignment instance that allocates block component to generate schedule.


Get the block elements added to self.


The sequence of elements is returned in order of addition. Because the first element is schedule first, e.g. FIFO, the returned sequence is roughly time-ordered. However, in the parallel alignment context, especially in the as-late-as-possible scheduling, or AlignRight context, the actual timing of when the instructions are issued is unknown until the ScheduleBlock is scheduled and converted into a Schedule.


Returns channels that this schedule block uses.


Duration of this schedule block.


Default value: count(0)


Get the time-ordered instructions from self.


The user provided metadata associated with the schedule.

User provided dict of metadata for the schedule. The metadata contents do not affect the semantics of the program but are used to influence the execution of the schedule. It is expected to be passed between all transforms of the schedule and that providers will associate any schedule metadata with the results it returns from the execution of that schedule.


Return name of this schedule


Return unassigned parameters with raw names.


Default value: 'block'


Return a reference manager of the current scope.



append(block, name=None, inplace=True)

GitHub(opens in a new tab)

Return a new schedule block with block appended to the context block. The execution time is automatically assigned when the block is converted into schedule.


  • block (BlockComponent) – ScheduleBlock to be appended.
  • name (str(opens in a new tab) | None) – Name of the new Schedule. Defaults to name of self.
  • inplace (bool(opens in a new tab)) – Perform operation inplace on this schedule. Otherwise, return a new Schedule.


Schedule block with appended schedule.


PulseError – When invalid schedule type is specified.

Return type



assign_parameters(value_dict, inplace=True)

GitHub(opens in a new tab)

Assign the parameters in this schedule according to the input.



Schedule with updated parameters.


PulseError – When the block is nested into another block.

Return type



assign_references(subroutine_dict, inplace=True)

GitHub(opens in a new tab)

Assign schedules to references.

It is only capable of assigning a schedule block to immediate references which are directly referred within the current scope. Let’s see following example:

from qiskit import pulse
with as subroutine:
    pulse.delay(10, pulse.DriveChannel(0))
with as sub_prog:
with as main_prog:

In above example, the main_prog can refer to the subroutine “root::B” and the reference of “B” to program “A”, i.e., “B::A”, is not defined in the root namespace. This prevents breaking the reference “root::B::A” by the assignment of “root::B”. For example, if a user could indirectly assign “root::B::A” from the root program, one can later assign another program to “root::B” that doesn’t contain “A” within it. In this situation, a reference “root::B::A” would still live in the reference manager of the root. However, the subroutine “root::B::A” would no longer be used in the actual pulse program. To assign subroutine “A” to nested_prog as a nested subprogram of main_prog, you must first assign “A” of the sub_prog, and then assign the sub_prog to the main_prog.

sub_prog.assign_references({("A", ): nested_prog}, inplace=True)
main_prog.assign_references({("B", ): sub_prog}, inplace=True)

Alternatively, you can also write

main_prog.assign_references({("B", ): sub_prog}, inplace=True)
main_prog.references[("B", )].assign_references({"A": nested_prog}, inplace=True)

Here references returns a dict-like object, and you can mutably update the nested reference of the particular subroutine.


Assigned programs are deep-copied to prevent an unexpected update.



Schedule block with assigned subroutine.


PulseError – When reference key is not defined in the current scope.

Return type




GitHub(opens in a new tab)

Return the time of the end of the last instruction over the supplied channels.


*channels (Channel) – Channels within self to include.

Return type

int(opens in a new tab)


draw(style=None, backend=None, time_range=None, time_unit='dt', disable_channels=None, show_snapshot=True, show_framechange=True, show_waveform_info=True, plot_barrier=True, plotter='mpl2d', axis=None, show_barrier=True)

GitHub(opens in a new tab)

Plot the schedule.


  • style (dict(opens in a new tab)[str(opens in a new tab), Any] | None) – Stylesheet options. This can be dictionary or preset stylesheet classes. See IQXStandard, IQXSimple, and IQXDebugging for details of preset stylesheets.

  • backend (Optional[BaseBackend]) – Backend object to play the input pulse program. If provided, the plotter may use to make the visualization hardware aware.

  • time_range (tuple(opens in a new tab)[int(opens in a new tab), int(opens in a new tab)] | None) – Set horizontal axis limit. Tuple (tmin, tmax).

  • time_unit (str(opens in a new tab)) – The unit of specified time range either dt or ns. The unit of ns is available only when backend object is provided.

  • disable_channels (list(opens in a new tab)[Channel] | None) – A control property to show specific pulse channel. Pulse channel instances provided as a list are not shown in the output image.

  • show_snapshot (bool(opens in a new tab)) – Show snapshot instructions.

  • show_framechange (bool(opens in a new tab)) – Show frame change instructions. The frame change represents instructions that modulate phase or frequency of pulse channels.

  • show_waveform_info (bool(opens in a new tab)) – Show additional information about waveforms such as their name.

  • plot_barrier (bool(opens in a new tab)) – Show barrier lines.

  • plotter (str(opens in a new tab)) –

    Name of plotter API to generate an output image. One of following APIs should be specified:

    mpl2d: Matplotlib API for 2D image generation.
        Matplotlib API to generate 2D image. Charts are placed along y axis with
        vertical offset. This API takes matplotlib.axes.Axes as ``axis`` input.

    axis and style kwargs may depend on the plotter.

  • axis (Any | None) – Arbitrary object passed to the plotter. If this object is provided, the plotters use a given axis instead of internally initializing a figure object. This object format depends on the plotter. See plotter argument for details.

  • show_barrier (bool(opens in a new tab)) – DEPRECATED. Show barrier lines.


Visualization output data. The returned data type depends on the plotter. If matplotlib family is specified, this will be a matplotlib.pyplot.Figure data.


exclude(*filter_funcs, channels=None, instruction_types=None, check_subroutine=True)

GitHub(opens in a new tab)

Return a new ScheduleBlock with only the instructions from this ScheduleBlock failing at least one of the provided filters. This method is the complement of py:meth:~self.filter, so that:

self.filter(args) + self.exclude(args) == self in terms of instructions included.

Because ScheduleBlock is not aware of the execution time of the context instructions, excluding some instructions may change the execution time of the remaining instructions.



ScheduleBlock consisting of instructions that do not match with at least one of filtering conditions.


filter(*filter_funcs, channels=None, instruction_types=None, check_subroutine=True)

GitHub(opens in a new tab)

Return a new ScheduleBlock with only the instructions from this ScheduleBlock which pass though the provided filters; i.e. an instruction will be retained if every function in filter_funcs returns True, the instruction occurs on a channel type contained in channels, and the instruction type is contained in instruction_types.


Because ScheduleBlock is not aware of the execution time of the context instructions, filtering out some instructions may change the execution time of the remaining instructions.

If no arguments are provided, self is returned.



ScheduleBlock consisting of instructions that matches with filtering condition.



GitHub(opens in a new tab)

Get parameter object bound to this schedule by string name.

Note that we can define different parameter objects with the same name, because these different objects are identified by their unique uuid. For example,

from qiskit import pulse, circuit
amp1 = circuit.Parameter("amp")
amp2 = circuit.Parameter("amp")
with as sub_prog:, amp1), pulse.DriveChannel(0))
with as main_prog:, name="sub"), amp2), pulse.DriveChannel(0))

This returns a list of two parameters amp1 and amp2.


parameter_name (str(opens in a new tab)) – Name of parameter.


Parameter objects that have corresponding name.

Return type

list(opens in a new tab)[qiskit.circuit.parameter.Parameter]


classmethod initialize_from(other_program, name=None)

GitHub(opens in a new tab)

Create new schedule object with metadata of another schedule object.


  • other_program (Any) – Qiskit program that provides metadata to new object.
  • name (str(opens in a new tab) | None) – Name of new schedule. Name of block is used by default.


New block object with name and metadata.


PulseError – When other_program does not provide necessary information.

Return type




GitHub(opens in a new tab)

Return True iff the instruction is parameterized.

Return type

bool(opens in a new tab)



GitHub(opens in a new tab)

Return True iff the current schedule block contains reference to subroutine.

Return type

bool(opens in a new tab)



GitHub(opens in a new tab)

Return True if all durations are assigned.

Return type

bool(opens in a new tab)


replace(old, new, inplace=True)

GitHub(opens in a new tab)

Return a ScheduleBlock with the old component replaced with a new component.



The modified schedule block with old replaced by new.

Return type


Was this page helpful?
Report a bug or request content on GitHub.