Skip to content

Commit

Permalink
Remove schedule component (#5245)
Browse files Browse the repository at this point in the history
* Deprecate ScheduleComponent class

Deprecate the ScheduleComponent class and remove it as the base class
of Schedule and Instruction. Anywhere that currently accepts a
ScheduleComponent should instead accept a Union[Schedule, Instruction].
Propagate the docstrings for the removed properties to Instruction and
the Schedule classes themselves. Use Schedule and Instruction type
forwardRef of the classes in the typed arguments

* deprecate channels argument in ch_start_time method of Instruction

Fixes #5076

* Add ScheduleComponent deprecation release note

* Fix forward references.

* Linting.

* Remove warning causing docs to fail.

* remove trailing whitespace.

* Remove schedule type annotations in instruction.

* Update Instruction type hint.

* Linting

Co-authored-by: Thomas Alexander <thomas.a.alexander@ibm.com>
Co-authored-by: Thomas Alexander <thomasalexander2718@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Oct 30, 2020
1 parent 8c40b02 commit f0b47e2
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 59 deletions.
4 changes: 2 additions & 2 deletions qiskit/compiler/assemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from typing import Union, List, Dict, Optional
from qiskit.circuit import QuantumCircuit, Qubit, Parameter
from qiskit.exceptions import QiskitError
from qiskit.pulse import ScheduleComponent, LoConfig
from qiskit.pulse import LoConfig, Instruction
from qiskit.assembler.run_config import RunConfig
from qiskit.assembler import assemble_circuits, assemble_schedules
from qiskit.qobj import QobjHeader, Qobj
Expand Down Expand Up @@ -153,7 +153,7 @@ def assemble(experiments: Union[QuantumCircuit, List[QuantumCircuit], Schedule,
return assemble_circuits(circuits=bound_experiments, qobj_id=qobj_id,
qobj_header=qobj_header, run_config=run_config)

elif all(isinstance(exp, ScheduleComponent) for exp in experiments):
elif all(isinstance(exp, (Schedule, Instruction)) for exp in experiments):
run_config = _parse_pulse_args(backend, qubit_lo_freq, meas_lo_freq,
qubit_lo_range, meas_lo_range,
schedule_los, meas_level, meas_return,
Expand Down
74 changes: 54 additions & 20 deletions qiskit/pulse/instructions/instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@
from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType
from qiskit.pulse.channels import Channel
from qiskit.pulse.exceptions import PulseError
from qiskit.pulse.interfaces import ScheduleComponent
from qiskit.pulse.schedule import Schedule
# pylint: disable=missing-return-doc


class Instruction(ScheduleComponent, ABC):
class Instruction(ABC):
"""The smallest schedulable unit: a single instruction. It has a fixed duration and specified
channels.
"""
Expand Down Expand Up @@ -130,7 +128,7 @@ def duration(self) -> int:
return self._duration

@property
def _children(self) -> Tuple[ScheduleComponent]:
def _children(self) -> Tuple['Instruction']:
"""Instruction has no child nodes."""
return ()

Expand All @@ -147,7 +145,11 @@ def ch_duration(self, *channels: List[Channel]) -> int:
"""
return self.ch_stop_time(*channels)

def ch_start_time(self, *channels: List[Channel]) -> int:
def ch_start_time(
self,
*channels: List[Channel]
) -> int:
# pylint: disable=unused-argument
"""Return minimum start time for supplied channels.
Args:
Expand All @@ -172,48 +174,62 @@ def _instructions(self, time: int = 0) -> Iterable[Tuple[int, 'Instruction']]:
time: Shifted time of this node due to parent
Yields:
Tuple[int, ScheduleComponent]: Tuple containing time `ScheduleComponent` starts
at and the flattened `ScheduleComponent`
Tuple[int, Union['Schedule, 'Instruction']]: Tuple of the form
(start_time, instruction).
"""
yield (time, self)

def flatten(self) -> 'Instruction':
"""Return itself as already single instruction."""
return self

def shift(self: ScheduleComponent, time: int, name: Optional[str] = None) -> Schedule:
def shift(self,
time: int, name: Optional[str] = None):
"""Return a new schedule shifted forward by `time`.
Args:
time: Time to shift by
name: Name of the new schedule. Defaults to name of self
Returns:
Schedule: The shifted schedule.
"""
from qiskit.pulse.schedule import Schedule

if name is None:
name = self.name
return Schedule((time, self), name=name)

def insert(self, start_time: int, schedule: ScheduleComponent,
name: Optional[str] = None) -> Schedule:
def insert(self, start_time: int, schedule,
name: Optional[str] = None):
"""Return a new :class:`~qiskit.pulse.Schedule` with ``schedule`` inserted within
``self`` at ``start_time``.
Args:
start_time: Time to insert the schedule schedule
schedule: Schedule to insert
schedule (Union['Schedule', 'Instruction']): Schedule or instruction to insert
name: Name of the new schedule. Defaults to name of self
Returns:
Schedule: A new schedule with ``schedule`` inserted with this instruction at t=0.
"""
from qiskit.pulse.schedule import Schedule

if name is None:
name = self.name
return Schedule(self, (start_time, schedule), name=name)

def append(self, schedule: ScheduleComponent,
name: Optional[str] = None) -> Schedule:
def append(self, schedule,
name: Optional[str] = None):
"""Return a new :class:`~qiskit.pulse.Schedule` with ``schedule`` inserted at the
maximum time over all channels shared between ``self`` and ``schedule``.
Args:
schedule: schedule to be appended
schedule (Union['Schedule', 'Instruction']): Schedule or instruction to be appended
name: Name of the new schedule. Defaults to name of self
Returns:
Schedule: A new schedule with ``schedule`` a this instruction at t=0.
"""
common_channels = set(self.channels) & set(schedule.channels)
time = self.ch_stop_time(*common_channels)
Expand Down Expand Up @@ -301,16 +317,34 @@ def __hash__(self) -> int:
self._hash = hash((type(self), self.operands, self.name))
return self._hash

def __add__(self, other: ScheduleComponent) -> Schedule:
"""Return a new schedule with `other` inserted within `self` at `start_time`."""
def __add__(self, other):
"""Return a new schedule with `other` inserted within `self` at `start_time`.
Args:
other (Union['Schedule', 'Instruction']): Schedule or instruction to be appended
Returns:
Schedule: A new schedule with ``schedule`` appended after this instruction at t=0.
"""
return self.append(other)

def __or__(self, other: ScheduleComponent) -> Schedule:
"""Return a new schedule which is the union of `self` and `other`."""
def __or__(self, other):
"""Return a new schedule which is the union of `self` and `other`.
Args:
other (Union['Schedule', 'Instruction']): Schedule or instruction to union with
Returns:
Schedule: A new schedule with ``schedule`` inserted with this instruction at t=0
"""
return self.insert(0, other)

def __lshift__(self, time: int) -> Schedule:
"""Return a new schedule which is shifted forward by `time`."""
def __lshift__(self, time: int):
"""Return a new schedule which is shifted forward by `time`.
Returns:
Schedule: The shifted schedule
"""
return self.shift(time)

def __repr__(self) -> str:
Expand Down
64 changes: 62 additions & 2 deletions qiskit/pulse/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
# that they have been altered from the originals.

"""
ScheduleComponent, a common interface for components of schedule (Instruction and Schedule).
ScheduleComponent has been deprecated.
It is a common interface for components of schedule (Instruction and Schedule).
"""
import warnings
from abc import ABCMeta, abstractmethod
from typing import Tuple, List, Union, Optional

Expand All @@ -22,68 +24,108 @@


class ScheduleComponent(metaclass=ABCMeta):
"""Common interface for components of schedule. """
"""ScheduleComponent has been deprecated.
It has been replaced by `qiskit.pulse.values.Value` and `qiskit.pulse.values.NamedValue``.
Anywhere that currently accepts a ``ScheduleComponent`` should instead accept a
``Union[Schedule, Instruction]``.
"""

@property
@abstractmethod
def name(self) -> str:
"""Name of ScheduleComponent."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@property
@abstractmethod
def channels(self) -> List[Channel]:
"""Return channels used by schedule."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)

pass

@property
@abstractmethod
def duration(self) -> int:
"""Duration of this schedule component."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)

pass

@property
@abstractmethod
def start_time(self) -> int:
"""Starting time of this schedule component."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)

pass

@property
@abstractmethod
def stop_time(self) -> int:
"""Stopping time of this schedule component."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def ch_duration(self, *channels: List[Channel]) -> int:
"""Duration of the `channels` in schedule component."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def ch_start_time(self, *channels: List[Channel]) -> int:
"""Starting time of the `channels` in schedule component. """
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def ch_stop_time(self, *channels: List[Channel]) -> int:
"""Stopping of the `channels` in schedule component."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@property
@abstractmethod
def _children(self) -> Tuple[Union[int, 'ScheduleComponent']]:
"""Child nodes of this schedule component. """
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@property
@abstractmethod
def instructions(self) -> Tuple[Tuple[int, 'Instructions']]:
"""Return iterable for all `Instruction`s in `Schedule` tree."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def flatten(self) -> 'ScheduleComponent':
"""Return a new schedule which is the flattened schedule contained all `instructions`."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
Expand All @@ -95,6 +137,9 @@ def shift(self: 'ScheduleComponent', time: int,
time: Time to shift by
name: Name of the new schedule. Defaults to name of parent
"""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
Expand All @@ -107,6 +152,9 @@ def insert(self, start_time: int, schedule: 'ScheduleComponent',
schedule: schedule to be inserted
name: Name of the new schedule. Defaults to name of parent
"""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
Expand All @@ -119,19 +167,31 @@ def append(self, schedule: 'ScheduleComponent',
schedule: schedule to be appended
name: Name of the new schedule. Defaults to name of parent
"""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def __add__(self, schedule: 'ScheduleComponent') -> 'ScheduleComponent':
"""Return a new schedule with `schedule` inserted within `self` at `start_time`."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def __or__(self, schedule: 'ScheduleComponent') -> 'ScheduleComponent':
"""Return a new schedule which is the union of `self` and `schedule`."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass

@abstractmethod
def __lshift__(self, time: int) -> 'ScheduleComponent':
"""Return a new schedule which is shifted forward by `time`."""
warnings.warn("ScheduleComponent is deprecated and will be removed in a future release. "
"Anywhere that currently accepts a ``ScheduleComponent`` should instead "
"accept a ``Union[Schedule, Instruction]`` ", DeprecationWarning)
pass
Loading

0 comments on commit f0b47e2

Please sign in to comment.