diff --git a/qiskit/assembler/assemble_schedules.py b/qiskit/assembler/assemble_schedules.py index f5e72e297c9a..4581235746ae 100644 --- a/qiskit/assembler/assemble_schedules.py +++ b/qiskit/assembler/assemble_schedules.py @@ -20,7 +20,7 @@ from qiskit import qobj, pulse from qiskit.assembler.run_config import RunConfig from qiskit.exceptions import QiskitError -from qiskit.pulse import instructions, transforms, library, commands +from qiskit.pulse import instructions, transforms, library from qiskit.qobj import utils as qobj_utils, converters from qiskit.qobj.converters.pulse_instruction import ParametricPulseShapes @@ -144,7 +144,7 @@ def _assemble_instructions( schedule: pulse.Schedule, instruction_converter: converters.InstructionToQobjConverter, run_config: RunConfig, - user_pulselib: Dict[str, commands.Command] + user_pulselib: Dict[str, List[complex]] ) -> Tuple[List[qobj.PulseQobjInstruction], int]: """Assembles the instructions in a schedule into a list of PulseQobjInstructions and returns related metadata that will be assembled into the Qobj configuration. Lookup table for @@ -161,7 +161,7 @@ def _assemble_instructions( Returns: A list of converted instructions, the user pulse library dictionary (from pulse name to - pulse command), and the maximum number of readout memory slots used by this Schedule. + pulse samples), and the maximum number of readout memory slots used by this Schedule. """ max_memory_slot = 0 qobj_instructions = [] @@ -169,11 +169,6 @@ def _assemble_instructions( acquire_instruction_map = defaultdict(list) for time, instruction in schedule.instructions: - if isinstance(instruction, commands.ParametricInstruction): # deprecated - instruction = instructions.Play(instruction.command, - instruction.channels[0], - name=instruction.name) - if (isinstance(instruction, instructions.Play) and isinstance(instruction.pulse, library.ParametricPulse)): pulse_shape = ParametricPulseShapes(type(instruction.pulse)).name @@ -182,12 +177,6 @@ def _assemble_instructions( instruction.channel, name=instruction.name) - if isinstance(instruction, commands.PulseInstruction): # deprecated - name = instruction.command.name - instruction = instructions.Play( - library.Waveform(name=name, samples=instruction.command.samples), - instruction.channels[0], name=name) - if (isinstance(instruction, instructions.Play) and isinstance(instruction.pulse, library.Waveform)): name = hashlib.sha256(instruction.pulse.samples).hexdigest() @@ -197,17 +186,15 @@ def _assemble_instructions( name=name) user_pulselib[name] = instruction.pulse.samples - if isinstance(instruction, (commands.AcquireInstruction, instructions.Acquire)): + if isinstance(instruction, instructions.Acquire): if instruction.mem_slot: max_memory_slot = max(max_memory_slot, instruction.mem_slot.index) # Acquires have a single AcquireChannel per inst, but we have to bundle them # together into the Qobj as one instruction with many channels - acquire_instruction_map[(time, instruction.command)].append(instruction) + acquire_instruction_map[(time, instruction.duration)].append(instruction) continue - if isinstance(instruction, (commands.DelayInstruction, - instructions.Delay, - instructions.Directive)): + if isinstance(instruction, (instructions.Delay, instructions.Directive)): # delay instructions are ignored as timing is explicit within qobj continue @@ -227,13 +214,13 @@ def _assemble_instructions( def _validate_meas_map(instruction_map: Dict[Tuple[int, instructions.Acquire], - List[commands.AcquireInstruction]], + List[instructions.Acquire]], meas_map: List[List[int]]) -> None: """Validate all qubits tied in ``meas_map`` are to be acquired. Args: - instruction_map: A dictionary grouping AcquireInstructions according to their start time - and the command features (notably, their duration). + instruction_map: A dictionary grouping Acquire instructions according to their start time + and duration. meas_map: List of groups of qubits that must be acquired together. Raises: @@ -255,13 +242,13 @@ def _validate_meas_map(instruction_map: Dict[Tuple[int, instructions.Acquire], def _bundle_channel_indices( - instrs: List[commands.AcquireInstruction] + instrs: List[instructions.Acquire] ) -> Tuple[List[int], List[int], List[int]]: """From the list of AcquireInstructions, bundle the indices of the acquire channels, memory slots, and register slots into a 3-tuple of lists. Args: - instrs: A list of AcquireInstructions to be bundled. + instrs: A list of Acquire instructions to be bundled. Returns: The qubit indices, the memory slot indices, and register slot indices from instructions. diff --git a/qiskit/pulse/__init__.py b/qiskit/pulse/__init__.py index 06f8463ce94c..deae76dee6bb 100644 --- a/qiskit/pulse/__init__.py +++ b/qiskit/pulse/__init__.py @@ -442,11 +442,6 @@ MemorySlot, RegisterSlot, ) -from qiskit.pulse.commands import ( - AcquireInstruction, - FrameChange, - PersistentValue, -) from qiskit.pulse.configuration import ( Discriminator, Kernel, diff --git a/qiskit/pulse/channels.py b/qiskit/pulse/channels.py index da417b5735e9..d7e91ad2ccac 100644 --- a/qiskit/pulse/channels.py +++ b/qiskit/pulse/channels.py @@ -114,7 +114,7 @@ class AcquireChannel(Channel): class SnapshotChannel(Channel): - """Snapshot channels are used to specify commands for simulators.""" + """Snapshot channels are used to specify instructions for simulators.""" prefix = 's' def __init__(self): diff --git a/qiskit/pulse/commands/__init__.py b/qiskit/pulse/commands/__init__.py deleted file mode 100644 index 1b69d7c8ec4b..000000000000 --- a/qiskit/pulse/commands/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -# pylint: disable=cyclic-import - -"""Supported command types in Pulse. This directory is deprecated. - -AcquireInstruction, FrameChange, FrameChangeInstruction, PersistentValue, -PersistentValueInstruction, PulseInstruction, DelayInstruction and ParametricInstruction are all -deprecated. When they are removed, this ``pulse.commands`` import path for the remaining objects -can also be deprecated. -""" -from .acquire import Acquire, AcquireInstruction -from .frame_change import FrameChange, FrameChangeInstruction -from .meas_opts import Discriminator, Kernel -from .persistent_value import PersistentValue, PersistentValueInstruction -from .command import Command -from .pulse_decorators import functional_pulse -from .sample_pulse import SamplePulse, PulseInstruction -from .snapshot import Snapshot -from .delay import Delay, DelayInstruction -from .parametric_pulses import (ParametricPulse, ParametricInstruction, Gaussian, GaussianSquare, - Drag, Constant) diff --git a/qiskit/pulse/commands/acquire.py b/qiskit/pulse/commands/acquire.py deleted file mode 100644 index 9a9d5a3db979..000000000000 --- a/qiskit/pulse/commands/acquire.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Acquire. Deprecated path.""" -import warnings - -from typing import Optional - -from ..channels import MemorySlot, RegisterSlot, AcquireChannel -from ..exceptions import PulseError - -# pylint: disable=unused-import - -from ..instructions import Acquire -from ..instructions import Instruction - - -class AcquireInstruction(Instruction): - """Deprecated.""" - - def __init__(self, - command: Acquire, - acquire: AcquireChannel, - mem_slot: Optional[MemorySlot] = None, - reg_slot: Optional[RegisterSlot] = None, - name: Optional[str] = None): - - warnings.warn("The ``AcquireInstruction`` has been deprecated. Please use Acquire with " - "channels instead. For example, AcquireInstruction(Acquire(duration), " - "AcquireChannel(0), MemorySlot(0)) becomes Acquire(duration, " - "AcquireChannel(0), MemorySlot(0)).", - DeprecationWarning) - - if isinstance(acquire, list) or isinstance(mem_slot, list) or isinstance(reg_slot, list): - raise PulseError("The Acquire instruction takes only one AcquireChannel and one " - "classical memory destination for the measurement result.") - - if not (mem_slot or reg_slot): - raise PulseError('Neither memoryslots or registers were supplied') - - all_channels = [chan for chan in [acquire, mem_slot, reg_slot] if chan is not None] - super().__init__((), command, all_channels, name=name) - - self._acquire = acquire - self._mem_slot = mem_slot - self._reg_slot = reg_slot - - @property - def acquire(self): - """Acquire channel to be acquired on.""" - return self._acquire - - @property - def channel(self): - """Acquire channel to be acquired on.""" - return self._acquire - - @property - def mem_slot(self): - """MemorySlot.""" - return self._mem_slot - - @property - def reg_slot(self): - """RegisterSlot.""" - return self._reg_slot - - @property - def acquires(self): - """Acquire channels to be acquired on.""" - warnings.warn("Acquire.acquires is deprecated. Use the channel attribute instead.", - DeprecationWarning) - return [self._acquire] - - @property - def mem_slots(self): - """MemorySlots.""" - warnings.warn("Acquire.mem_slots is deprecated. Use the mem_slot attribute instead.", - DeprecationWarning) - return [self._mem_slot] - - @property - def reg_slots(self): - """RegisterSlots.""" - warnings.warn("Acquire.reg_slots is deprecated. Use the reg_slot attribute instead.", - DeprecationWarning) - return [self._reg_slot] diff --git a/qiskit/pulse/commands/command.py b/qiskit/pulse/commands/command.py deleted file mode 100644 index 581e242497be..000000000000 --- a/qiskit/pulse/commands/command.py +++ /dev/null @@ -1,122 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Base command. -""" -import re - -from abc import ABCMeta, abstractmethod -from typing import List, Optional, Union -import numpy as np - -from qiskit.pulse.exceptions import PulseError -from qiskit.pulse.channels import Channel - - -class MetaCount(ABCMeta): - """Meta class to count class instances.""" - def __new__(mcs, name, bases, namespace, **_): - new_cls = super(MetaCount, mcs).__new__(mcs, name, bases, namespace) - new_cls.instances_counter = 0 - return new_cls - - -class Command(metaclass=MetaCount): - """Abstract command class.""" - - # Counter for the number of instances in this class - prefix = 'c' - - @abstractmethod - def __init__(self, duration: Union[int, np.integer] = None): - """Create a new command. - - Args: - duration: Duration of this command. - Raises: - PulseError: when duration is not number of points - """ - if isinstance(duration, (int, np.integer)): - self._duration = int(duration) - else: - raise PulseError('Pulse duration should be integer.') - - self._name = Command.create_name() - - @classmethod - def create_name(cls, name: str = None) -> str: - """Autogenerate names for pulse commands.""" - if name is None: - try: - name = '%s%i' % (cls.prefix, cls.instances_counter) # pylint: disable=E1101 - except TypeError: - raise PulseError("prefix and counter must be non-None when name is None.") - else: - try: - name = str(name) - except Exception: - raise PulseError("The pulse command name should be castable to a string " - "(or None for autogenerate a name).") - name_format = re.compile('[a-zA-Z][a-zA-Z0-9_]*') - if name_format.match(name) is None: - raise PulseError("%s is an invalid OpenPulse command name." % name) - - cls.instances_counter += 1 # pylint: disable=E1101 - - return name - - @property - def duration(self) -> int: - """Duration of this command.""" - return self._duration - - @property - def name(self) -> str: - """Name of this command.""" - return self._name - - @abstractmethod - def to_instruction(self, command, *channels: List[Channel], - name: Optional[str] = None): - """Create an instruction from command. - - Returns: - Instruction - """ - pass - - def __call__(self, *args, **kwargs): - """Creates an Instruction obtained from call to `to_instruction` wrapped in a Schedule.""" - return self.to_instruction(*args, **kwargs) - - def __eq__(self, other: 'Command'): - """Two Commands are the same if they are of the same type - and have the same duration and name. - - Args: - other: other Command - - Returns: - bool: are self and other equal - """ - return (type(self) is type(other)) and (self.duration == other.duration) - - def __hash__(self): - return hash((type(self), self.duration, self.name)) - - def __repr__(self): - return '%s(duration=%d, name="%s")' % (self.__class__.__name__, - self.duration, - self.name) diff --git a/qiskit/pulse/commands/delay.py b/qiskit/pulse/commands/delay.py deleted file mode 100644 index d3837b3dc5e9..000000000000 --- a/qiskit/pulse/commands/delay.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Delay instruction. Deprecated path.""" -import warnings - -from ..channels import Channel -from ..instructions import Delay -from ..instructions import Instruction - - -class DelayInstruction(Instruction): - """Deprecated.""" - - def __init__(self, command: Delay, channel: Channel, name: str = None): - """Create a delay instruction from a delay command. - - Args: - command: Delay command to create instruction from. - channel: Channel for delay instruction to be created. - name: Name of delay instruction for display purposes. - """ - warnings.warn("The DelayInstruction is deprecated. Use Delay, instead, with channels. " - "For example: DelayInstruction(Delay(5), DriveChannel(0)) -> " - "Delay(5, DriveChannel(0)).", - DeprecationWarning) - super().__init__((), command, (channel,), name=name) diff --git a/qiskit/pulse/commands/frame_change.py b/qiskit/pulse/commands/frame_change.py deleted file mode 100644 index b8625bc2f065..000000000000 --- a/qiskit/pulse/commands/frame_change.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Frame change pulse. Deprecated.""" -import warnings - -from typing import Optional - -from qiskit.pulse.channels import PulseChannel -from ..instructions import Instruction -from .command import Command - - -class FrameChange(Command): - """Deprecated.""" - - prefix = 'fc' - - def __init__(self, phase: float, name: Optional[str] = None): - """Create new frame change pulse. - - Args: - phase: Frame change phase in radians. The allowable precision is device specific - name: Name of this framechange command. - """ - warnings.warn("FrameChange is deprecated. Use ShiftPhase, instead, with channels " - "specified. For example: FrameChange(3.14)(DriveChannel(0)) -> " - "ShiftPhase(3.14, DriveChannel(0)). This can be called to add a channel: " - "ShiftPhase(3.14)(DriveChannel(0)).", - DeprecationWarning) - super().__init__(duration=0) - self._phase = float(phase) - self._name = FrameChange.create_name(name) - - @property - def phase(self): - """Framechange phase.""" - return self._phase - - def __eq__(self, other: 'FrameChange'): - """Two FrameChanges are the same if they are of the same type and phase. - - Args: - other: other FrameChange - - Returns: - bool: are self and other equal - """ - return super().__eq__(other) and (self.phase == other.phase) - - def __hash__(self): - return hash((super().__hash__(), self.phase)) - - def __repr__(self): - return '%s(phase=%.3f, name="%s")' % (self.__class__.__name__, - self.phase, - self.name) - - # pylint: disable=arguments-differ - def to_instruction(self, channel: PulseChannel, name=None) -> 'FrameChangeInstruction': - return FrameChangeInstruction(self, channel, name=name) - # pylint: enable=arguments-differ - - -class FrameChangeInstruction(Instruction): - """Deprecated.""" - - def __init__(self, command: FrameChange, channel: PulseChannel, name=None): - warnings.warn("The FrameChangeInstruction is deprecated. Use ShiftPhase, instead, with " - "channels specified. For example: " - "FrameChangeInstruction(FrameChange(3.14), DriveChannel(0)) -> " - "ShiftPhase(3.14, DriveChannel(0)).", - DeprecationWarning) - super().__init__((), command, (channel,), name=name) diff --git a/qiskit/pulse/commands/instruction.py b/qiskit/pulse/commands/instruction.py deleted file mode 100644 index a2e3837394ef..000000000000 --- a/qiskit/pulse/commands/instruction.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Instruction = Leaf node of schedule. Deprecated path.""" -# pylint: disable=unused-import - -from qiskit.pulse.instructions import Instruction diff --git a/qiskit/pulse/commands/meas_opts.py b/qiskit/pulse/commands/meas_opts.py deleted file mode 100644 index d684a38648b3..000000000000 --- a/qiskit/pulse/commands/meas_opts.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Measurement options. Deprecated path.""" - -# pylint: disable=unused-import - - -from qiskit.pulse.configuration import Kernel, Discriminator diff --git a/qiskit/pulse/commands/parametric_pulses.py b/qiskit/pulse/commands/parametric_pulses.py deleted file mode 100644 index eeb30bf1e60d..000000000000 --- a/qiskit/pulse/commands/parametric_pulses.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2020. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Deprecated path to parametric pulses.""" -import warnings - -# pylint: disable=unused-import -from qiskit.pulse.library import (ParametricPulse, Gaussian, GaussianSquare, - Drag, Constant, ConstantPulse) -from qiskit.pulse.channels import Channel - - -class ParametricInstruction: - """Instruction to drive a parametric pulse to an `PulseChannel`.""" - - def __init__(self, command: ParametricPulse, channel: Channel, name: str = None): - warnings.warn("ParametricInstruction is deprecated. Use Play, instead, with a pulse and a " - "channel. For example: ParametricInstruction(Gaussian(amp=amp, sigma=sigma, " - "duration=duration), DriveChannel(0)) -> Play(Gaussian(amp=amp, sigma=sigma," - " duration=duration), DriveChannel(0)).", - DeprecationWarning) - super().__init__((), command, (channel,), name=name) diff --git a/qiskit/pulse/commands/persistent_value.py b/qiskit/pulse/commands/persistent_value.py deleted file mode 100644 index 6dd2bad5fba8..000000000000 --- a/qiskit/pulse/commands/persistent_value.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Persistent value. -""" -import warnings - -from typing import Optional - -from qiskit.pulse.channels import PulseChannel -from qiskit.pulse.exceptions import PulseError -from ..instructions import Instruction -from .command import Command - - -class PersistentValue(Command): - """Persistent value.""" - - prefix = 'pv' - - def __init__(self, value: complex, name: Optional[str] = None): - """create new persistent value command. - - Args: - value: Complex value to apply, bounded by an absolute value of 1 - The allowable precision is device specific - name: Name of this command. - Raises: - PulseError: when input value exceed 1 - """ - super().__init__(duration=0) - - if abs(value) > 1: - raise PulseError("Absolute value of PV amplitude exceeds 1.") - - warnings.warn("The PersistentValue command is deprecated. Use qiskit.pulse.Constant " - "instead.", DeprecationWarning) - - self._value = complex(value) - self._name = PersistentValue.create_name(name) - - @property - def value(self): - """Persistent value amplitude.""" - return self._value - - def __eq__(self, other: 'PersistentValue') -> bool: - """Two PersistentValues are the same if they are of the same type - and have the same value. - - Args: - other: other PersistentValue - - Returns: - bool: are self and other equal - """ - return super().__eq__(other) and self.value == other.value - - def __hash__(self): - return hash((super().__hash__(), self.value)) - - def __repr__(self): - return '%s(value=%s, name="%s")' % (self.__class__.__name__, - self.value, - self.name) - - # pylint: disable=arguments-differ - def to_instruction(self, channel: PulseChannel, name=None) -> 'PersistentValueInstruction': - return PersistentValueInstruction(self, channel, name=name) - # pylint: enable=arguments-differ - - -class PersistentValueInstruction(Instruction): - """Instruction to keep persistent value.""" - - def __init__(self, command: PersistentValue, channel: PulseChannel, name=None): - super().__init__((), command, (channel,), name=name) diff --git a/qiskit/pulse/commands/pulse_decorators.py b/qiskit/pulse/commands/pulse_decorators.py deleted file mode 100644 index cf2f5c42cdd3..000000000000 --- a/qiskit/pulse/commands/pulse_decorators.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -# pylint: disable=missing-return-doc, missing-return-type-doc,unused-import - -""" -Pulse decorators. -""" - -from qiskit.pulse.library.samplers.decorators import functional_pulse diff --git a/qiskit/pulse/commands/sample_pulse.py b/qiskit/pulse/commands/sample_pulse.py deleted file mode 100644 index f423e113c37e..000000000000 --- a/qiskit/pulse/commands/sample_pulse.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Sample pulse. Deprecated path.""" -import warnings - -from typing import Optional - -from ..channels import PulseChannel -# pylint: disable=unused-import -from ..library import Waveform, SamplePulse -from ..instructions import Instruction - - -class PulseInstruction(Instruction): - """Instruction to drive a pulse to an `PulseChannel`.""" - - def __init__(self, command: Waveform, channel: PulseChannel, name: Optional[str] = None): - warnings.warn("PulseInstruction is deprecated. Use Play, instead, with a pulse and a " - "channel. For example: PulseInstruction(Waveform([...]), DriveChannel(0))" - " -> Play(Waveform[...], DriveChannel(0)).", - DeprecationWarning) - super().__init__((), command, (channel,), name=name) diff --git a/qiskit/pulse/commands/snapshot.py b/qiskit/pulse/commands/snapshot.py deleted file mode 100644 index 947bca2e8f50..000000000000 --- a/qiskit/pulse/commands/snapshot.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Snapshot. Deprecated path.""" -# pylint: disable=unused-import - -from qiskit.pulse.instructions import Snapshot diff --git a/qiskit/pulse/instructions/acquire.py b/qiskit/pulse/instructions/acquire.py index 478f1c7f9499..851907981824 100644 --- a/qiskit/pulse/instructions/acquire.py +++ b/qiskit/pulse/instructions/acquire.py @@ -44,7 +44,7 @@ class Acquire(Instruction): def __init__(self, duration: int, - channel: Optional[AcquireChannel] = None, + channel: AcquireChannel, mem_slot: Optional[MemorySlot] = None, reg_slot: Optional[RegisterSlot] = None, kernel: Optional[Kernel] = None, @@ -71,7 +71,7 @@ def __init__(self, raise PulseError("The Acquire instruction takes only one AcquireChannel and one " "classical memory destination for the measurement result.") - if channel and not (mem_slot or reg_slot): + if not (mem_slot or reg_slot): raise PulseError('Neither MemorySlots nor RegisterSlots were supplied.') self._channel = channel @@ -80,10 +80,6 @@ def __init__(self, self._kernel = kernel self._discriminator = discriminator - if channel is None: - warnings.warn("Usage of Acquire without specifying a channel is deprecated. For " - "example, Acquire(1200)(AcquireChannel(0)) should be replaced by " - "Acquire(1200, AcquireChannel(0)).", DeprecationWarning) all_channels = [chan for chan in [channel, mem_slot, reg_slot] if chan is not None] super().__init__((duration, self.channel, self.mem_slot, self.reg_slot), duration, all_channels, name=name) @@ -149,45 +145,8 @@ def __repr__(self) -> str: return "{}({}{}{}{}{}{})".format( self.__class__.__name__, self.duration, - ', ' + str(self.channel) if self.channel else '', + ', ' + str(self.channel), ', ' + str(self.mem_slot) if self.mem_slot else '', ', ' + str(self.reg_slot) if self.reg_slot else '', ', ' + str(self.kernel) if self.kernel else '', ', ' + str(self.discriminator) if self.discriminator else '') - - def __call__(self, - channel: AcquireChannel, - mem_slot: Optional[MemorySlot] = None, - reg_slot: Optional[RegisterSlot] = None, - kernel: Optional[Kernel] = None, - discriminator: Optional[Discriminator] = None, - name: Optional[str] = None) -> 'Acquire': - """Return new ``Acquire`` that is fully instantiated with its channels. - - Args: - channel: The channel that will acquire data. - mem_slot: The classical memory slot in which to store the classified readout result. - reg_slot: The fast-access register slot in which to store the classified readout - result for fast feedback. - kernel: A ``Kernel`` for integrating raw data. - discriminator: A ``Discriminator`` for discriminating kerneled IQ data into 0/1 - results. - name: Name of the instruction for display purposes. - - Return: - Complete and ready to schedule ``Acquire``. - - Raises: - PulseError: If ``channel`` has already been set. - """ - warnings.warn("Calling Acquire with a channel is deprecated. Instantiate the acquire with " - "a channel instead.", DeprecationWarning) - if self._channel is not None: - raise PulseError("The channel has already been assigned as {}.".format(self.channel)) - return Acquire(self.duration, - channel=channel, - mem_slot=mem_slot, - reg_slot=reg_slot, - kernel=kernel, - discriminator=discriminator, - name=name if name is not None else self.name) diff --git a/qiskit/pulse/instructions/delay.py b/qiskit/pulse/instructions/delay.py index 6ab680674a3f..c14def9c64e9 100644 --- a/qiskit/pulse/instructions/delay.py +++ b/qiskit/pulse/instructions/delay.py @@ -13,12 +13,9 @@ # that they have been altered from the originals. """An instruction for blocking time on a channel; useful for scheduling alignment.""" -import warnings - from typing import Optional from ..channels import Channel -from ..exceptions import PulseError from .instruction import Instruction @@ -39,7 +36,7 @@ class Delay(Instruction): """ def __init__(self, duration: int, - channel: Optional[Channel] = None, + channel: Channel, name: Optional[str] = None): """Create a new delay instruction. @@ -51,13 +48,7 @@ def __init__(self, duration: int, name: Name of the delay for display purposes. """ self._channel = channel - if channel is None: - warnings.warn("Usage of Delay without specifying a channel is deprecated. For " - "example, Delay(5)(DriveChannel(0)) should be replaced by " - "Delay(5, DriveChannel(0)).", DeprecationWarning) - super().__init__((duration, channel), duration, tuple(), name=name) - else: - super().__init__((duration, channel), duration, (channel,), name=name) + super().__init__((duration, channel), duration, (channel,), name=name) @property def channel(self) -> Channel: @@ -65,21 +56,3 @@ def channel(self) -> Channel: scheduled on. """ return self._channel - - def __call__(self, channel: Channel) -> 'Delay': - """Return new ``Delay`` that is fully instantiated with both ``duration`` and a ``channel``. - - Args: - channel: The channel that will have the delay. - - Return: - Complete and ready to schedule ``Delay``. - - Raises: - PulseError: If ``channel`` has already been set. - """ - warnings.warn("Calling Delay with a channel is deprecated. Instantiate the delay with " - "a channel instead.", DeprecationWarning) - if self._channel is not None: - raise PulseError("The channel has already been assigned as {}.".format(self.channel)) - return Delay(self.duration, channel) diff --git a/qiskit/pulse/instructions/frequency.py b/qiskit/pulse/instructions/frequency.py index e5a90ec77cad..d8c415be8ad4 100644 --- a/qiskit/pulse/instructions/frequency.py +++ b/qiskit/pulse/instructions/frequency.py @@ -22,13 +22,13 @@ class SetFrequency(Instruction): - r"""Set the channel frequency. This command operates on ``PulseChannel`` s. + r"""Set the channel frequency. This instruction operates on ``PulseChannel`` s. A ``PulseChannel`` creates pulses of the form .. math:: Re[\exp(i 2\pi f jdt + \phi) d_j]. - Here, :math:`f` is the frequency of the channel. The command ``SetFrequency`` allows + Here, :math:`f` is the frequency of the channel. The instruction ``SetFrequency`` allows the user to set the value of :math:`f`. All pulses that are played on a channel after SetFrequency has been called will have the corresponding frequency. @@ -36,14 +36,14 @@ class SetFrequency(Instruction): """ def __init__(self, frequency: float, - channel: Optional[PulseChannel], + channel: PulseChannel, name: Optional[str] = None): """Creates a new set channel frequency instruction. Args: frequency: New frequency of the channel in Hz. channel: The channel this instruction operates on. - name: Name of this set channel frequency command. + name: Name of this set channel frequency instruction. """ self._frequency = float(frequency) self._channel = channel @@ -74,7 +74,7 @@ def __init__(self, Args: frequency: Frequency shift of the channel in Hz. channel: The channel this instruction operates on. - name: Name of this set channel frequency command. + name: Name of this set channel frequency instruction. """ self._frequency = float(frequency) self._channel = channel diff --git a/qiskit/pulse/instructions/instruction.py b/qiskit/pulse/instructions/instruction.py index b54f08da9c6b..a034886086ee 100644 --- a/qiskit/pulse/instructions/instruction.py +++ b/qiskit/pulse/instructions/instruction.py @@ -45,15 +45,14 @@ class Instruction(ScheduleComponent, ABC): def __init__(self, operands: Tuple, - duration, + duration: int, channels: Tuple[Channel], name: Optional[str] = None): """Instruction initializer. Args: operands: The argument list. - duration (Union['commands.Command', int]): Length of time taken by the instruction in - terms of dt. **Deprecated: the first argument used to be the Command.** + duration: Length of time taken by the instruction in terms of dt. channels: Tuple of pulse channels that this instruction operates on. name: Optional display name for this instruction. @@ -62,18 +61,9 @@ def __init__(self, PulseError: If the input ``channels`` are not all of type :class:`Channel`. """ - self._command = None - if isinstance(duration, (float, np.float)): - raise PulseError("Instruction duration was passed as a float. " - "Please replace with an integer.") if not isinstance(duration, (int, np.integer)): - warnings.warn("Commands have been deprecated. Use `qiskit.pulse.instructions` instead.", - DeprecationWarning) - self._command = duration - if name is None: - name = self.command.name - duration = self.command.duration - + raise PulseError("Instruction duration must be an integer, " + "got {} instead.".format(duration)) if duration < 0: raise PulseError("{} duration of {} is invalid: must be nonnegative." "".format(self.__class__.__name__, duration)) @@ -81,8 +71,7 @@ def __init__(self, for channel in channels: if not isinstance(channel, Channel): - raise PulseError( - "Expected a channel, got {} instead.".format(channel)) + raise PulseError("Expected a channel, got {} instead.".format(channel)) self._channels = channels self._timeslots = {channel: [(0, self.duration)] for channel in channels} @@ -96,14 +85,15 @@ def name(self) -> str: return self._name @property - def command(self): + def command(self) -> None: """The associated command. Commands are deprecated, so this method will be deprecated shortly. Returns: Command: The deprecated command if available. """ - return self._command + warnings.warn("The `command` method is deprecated. Commands have been removed and this " + "method returns None.", DeprecationWarning) @property def id(self) -> int: # pylint: disable=invalid-name @@ -113,9 +103,6 @@ def id(self) -> int: # pylint: disable=invalid-name @property def operands(self) -> Tuple: """Return instruction operands.""" - if self.command is not None: - warnings.warn("This is a deprecated instruction with a ``Command``, and it does " - "not populate its `operands`.") return self._operands @property @@ -297,16 +284,10 @@ def __eq__(self, other: 'Instruction') -> bool: Equality is determined by the instruction sharing the same operands and channels. """ - if self.command: - # Backwards compatibility for Instructions with Commands - return (self.command == other.command) and (set(self.channels) == set(other.channels)) return isinstance(other, type(self)) and self.operands == other.operands def __hash__(self) -> int: if self._hash is None: - if self.command: - # Backwards compatibility for Instructions with Commands - return hash(((tuple(self.command)), self.channels.__hash__())) self._hash = hash((type(self), self.operands, self.name)) return self._hash @@ -323,9 +304,6 @@ def __lshift__(self, time: int) -> Schedule: return self.shift(time) def __repr__(self) -> str: - if self.operands: - operands = ', '.join(str(op) for op in self.operands) - else: - operands = "{}, {}".format(self.command, ', '.join(str(ch) for ch in self.channels)) + operands = ', '.join(str(op) for op in self.operands) return "{}({}{})".format(self.__class__.__name__, operands, ", name='{}'".format(self.name) if self.name else "") diff --git a/qiskit/pulse/instructions/phase.py b/qiskit/pulse/instructions/phase.py index a0d9b48df8a7..c6bdbaa48fe9 100644 --- a/qiskit/pulse/instructions/phase.py +++ b/qiskit/pulse/instructions/phase.py @@ -17,13 +17,9 @@ at that moment, and ``ShiftPhase`` instructions which increase the existing phase by a relative amount. """ - -import warnings - from typing import Optional from ..channels import PulseChannel -from ..exceptions import PulseError from .instruction import Instruction @@ -45,7 +41,7 @@ class ShiftPhase(Instruction): """ def __init__(self, phase: complex, - channel: Optional[PulseChannel] = None, + channel: PulseChannel, name: Optional[str] = None): """Instantiate a shift phase instruction, increasing the output signal phase on ``channel`` by ``phase`` [radians]. @@ -55,10 +51,6 @@ def __init__(self, phase: complex, channel: The channel this instruction operates on. name: Display name for this instruction. """ - if channel is None: - warnings.warn("Usage of ShiftPhase without specifying a channel is deprecated. For " - "example, ShiftPhase(3.14)(DriveChannel(0)) should be replaced by " - "ShiftPhase(3.14, DriveChannel(0)).", DeprecationWarning) self._phase = phase self._channel = channel super().__init__((phase, channel), 0, (channel,), name=name) @@ -75,25 +67,6 @@ def channel(self) -> PulseChannel: """ return self._channel - def __call__(self, channel: PulseChannel) -> 'ShiftPhase': - """Return a new ShiftPhase instruction supporting the deprecated syntax of FrameChange. - - Args: - channel: The channel this instruction operates on. - - Raises: - PulseError: If channel was already added. - - Returns: - New ShiftPhase with both phase (from ``self`) and the ``channel`` provided. - """ - if self._channel is not None: - raise PulseError("The channel has already been assigned as {}.".format(self.channel)) - warnings.warn("Usage of ShiftPhase without specifying a channel is deprecated. For " - "example, ShiftPhase(3.14)(DriveChannel(0)) should be replaced by " - "ShiftPhase(3.14, DriveChannel(0)).", DeprecationWarning) - return ShiftPhase(self.phase, channel) - class SetPhase(Instruction): r"""The set phase instruction sets the phase of the proceeding pulses on that channel diff --git a/qiskit/pulse/instructions/snapshot.py b/qiskit/pulse/instructions/snapshot.py index ce2e5745aa48..9f002df17359 100644 --- a/qiskit/pulse/instructions/snapshot.py +++ b/qiskit/pulse/instructions/snapshot.py @@ -15,8 +15,6 @@ """A simulator instruction to capture output within a simulation. The types of snapshot instructions available are determined by the simulator being used. """ -import warnings - from typing import Optional from ..channels import SnapshotChannel @@ -59,8 +57,3 @@ def channel(self) -> SnapshotChannel: scheduled on; trivially, a ``SnapshotChannel``. """ return self._channel - - def __call__(self): - """Deprecated.""" - warnings.warn("Snapshot call method is deprecated.", DeprecationWarning) - return self diff --git a/qiskit/pulse/library/parametric_pulses.py b/qiskit/pulse/library/parametric_pulses.py index 8dd3c2c5c78a..3d536a259249 100644 --- a/qiskit/pulse/library/parametric_pulses.py +++ b/qiskit/pulse/library/parametric_pulses.py @@ -31,10 +31,11 @@ The new pulse must then be registered by the assembler in `qiskit/qobj/converters/pulse_instruction.py:ParametricPulseShapes` by following the existing pattern: + class ParametricPulseShapes(Enum): - gaussian = commands.Gaussian + gaussian = pulse_lib.Gaussian ... - new_supported_pulse_name = commands.YourPulseCommandClass + new_supported_pulse_name = pulse_lib.YourPulseWaveformClass """ import warnings from abc import abstractmethod diff --git a/qiskit/pulse/library/sample_pulse.py b/qiskit/pulse/library/sample_pulse.py index f7f163a414b1..f641558754e4 100644 --- a/qiskit/pulse/library/sample_pulse.py +++ b/qiskit/pulse/library/sample_pulse.py @@ -29,7 +29,7 @@ class SamplePulse(Waveform): def __init__(self, samples: Union[np.ndarray, List[complex]], name: Optional[str] = None, epsilon: float = 1e-7): - """Create new sample pulse command. + """Create new sample pulse envelope. Args: samples: Complex array of the samples in the pulse envelope. diff --git a/qiskit/pulse/library/samplers/decorators.py b/qiskit/pulse/library/samplers/decorators.py index fd3f4eec26c3..edc6915cffc4 100644 --- a/qiskit/pulse/library/samplers/decorators.py +++ b/qiskit/pulse/library/samplers/decorators.py @@ -30,7 +30,7 @@ def f(times: np.ndarray, *args, **kwargs) -> np.ndarray: def f(duration: int, *args, **kwargs) -> Waveform: ... -Samplers are used to build up pulse commands from continuous pulse functions. +Samplers are used to build up pulse waveforms from continuous pulse functions. In Python the creation of a dynamic function that wraps another function will cause the underlying signature and documentation of the underlying function to be overwritten. @@ -85,7 +85,7 @@ def linear(times: np.ndarray, m: float, b: float) -> np.ndarray: Which after decoration may be called with a duration rather than an array of times ```python duration = 10 - pulse_command = linear(10, 0.1, 0.1) + pulse_envelope = linear(10, 0.1, 0.1) ``` If one calls help on `linear` they will find ``` diff --git a/qiskit/pulse/macros.py b/qiskit/pulse/macros.py index c08a47813902..5686cfd5f223 100644 --- a/qiskit/pulse/macros.py +++ b/qiskit/pulse/macros.py @@ -16,7 +16,7 @@ from typing import Dict, List, Optional, Union -from qiskit.pulse import channels, commands, exceptions, instructions, utils +from qiskit.pulse import channels, exceptions, instructions, utils from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap from qiskit.pulse.schedule import Schedule @@ -76,16 +76,14 @@ def measure(qubits: List[int], "argument. For assistance, the instructions which are defined are: " "{}".format(measure_name, inst_map.instructions)) for time, inst in default_sched.instructions: - if qubit_mem_slots and isinstance( - inst, (instructions.Acquire, commands.AcquireInstruction)): + if qubit_mem_slots and isinstance(inst, instructions.Acquire): if inst.channel.index in qubit_mem_slots: mem_slot = channels.MemorySlot(qubit_mem_slots[inst.channel.index]) else: mem_slot = channels.MemorySlot(unused_mem_slots.pop()) schedule = schedule.insert(time, instructions.Acquire( inst.duration, inst.channel, mem_slot=mem_slot)) - elif qubit_mem_slots is None and isinstance( - inst, (instructions.Acquire, commands.AcquireInstruction)): + elif qubit_mem_slots is None and isinstance(inst, instructions.Acquire): schedule = schedule.insert(time, inst) # Measurement pulses should only be added if its qubit was measured by the user elif inst.channels[0].index in qubits: diff --git a/qiskit/pulse/transforms.py b/qiskit/pulse/transforms.py index bc19a03b0f47..3699eecc1097 100644 --- a/qiskit/pulse/transforms.py +++ b/qiskit/pulse/transforms.py @@ -21,7 +21,7 @@ import numpy as np -from qiskit.pulse import channels as chans, commands, exceptions, instructions, interfaces +from qiskit.pulse import channels as chans, exceptions, instructions, interfaces from qiskit.pulse.instructions import directives from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap from qiskit.pulse.schedule import Schedule @@ -65,8 +65,7 @@ def calculate_align_time(): for schedule in schedules: last_acquire = 0 acquire_times = [time for time, inst in schedule.instructions - if isinstance(inst, (instructions.Acquire, - commands.AcquireInstruction))] + if isinstance(inst, instructions.Acquire)] if acquire_times: last_acquire = max(acquire_times) align_time = max(align_time, last_acquire) @@ -107,7 +106,7 @@ def get_max_calibration_duration(): "{0} after acquire on " "same channel.".format(chan.index)) - if isinstance(inst, (instructions.Acquire, commands.AcquireInstruction)): + if isinstance(inst, instructions.Acquire): if time > align_time: warnings.warn("You provided an align_time which is scheduling an acquire " "sooner than it was scheduled for in the original Schedule.") @@ -138,13 +137,13 @@ def add_implicit_acquires(schedule: interfaces.ScheduleComponent, meas_map: List of lists of qubits that are measured together. Returns: - A ``Schedule`` with the additional acquisition commands. + A ``Schedule`` with the additional acquisition instructions. """ new_schedule = Schedule(name=schedule.name) acquire_map = dict() for time, inst in schedule.instructions: - if isinstance(inst, (instructions.Acquire, commands.AcquireInstruction)): + if isinstance(inst, instructions.Acquire): if inst.mem_slot and inst.mem_slot.index != inst.channel.index: warnings.warn("One of your acquires was mapped to a memory slot which didn't match" " the qubit index. I'm relabeling them to match.") diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index 47fde6b462be..e8ef98b9440d 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -19,7 +19,7 @@ from enum import Enum -from qiskit.pulse import commands, channels, instructions, library +from qiskit.pulse import channels, instructions, library from qiskit.pulse.exceptions import PulseError from qiskit.pulse.configuration import Kernel, Discriminator from qiskit.pulse.parser import parse_string_expr @@ -29,15 +29,15 @@ class ParametricPulseShapes(Enum): - """Map the assembled pulse names to the pulse module commands. + """Map the assembled pulse names to the pulse module waveforms. The enum name is the transport layer name for pulse shapes, the value is its mapping to the OpenPulse Command in Qiskit. """ - gaussian = commands.Gaussian - gaussian_square = commands.GaussianSquare - drag = commands.Drag - constant = commands.Constant + gaussian = library.Gaussian + gaussian_square = library.GaussianSquare + drag = library.Drag + constant = library.Constant class ConversionMethodBinder: @@ -119,55 +119,6 @@ def __call__(self, shift, instruction): method = self.bind_instruction.get_bound_method(type(instruction)) return method(self, shift, instruction) - @bind_instruction(commands.AcquireInstruction) - def convert_acquire_deprecated(self, shift, instruction): - """Return converted `AcquireInstruction`. - - Args: - shift(int): Offset time. - instruction (AcquireInstruction): acquire instruction. - Returns: - dict: Dictionary of required parameters. - """ - meas_level = self._run_config.get('meas_level', 2) - mem_slot = [] - if instruction.mem_slot: - mem_slot = [instruction.mem_slot.index] - - command_dict = { - 'name': 'acquire', - 't0': shift + instruction.start_time, - 'duration': instruction.duration, - 'qubits': [instruction.acquire.index], - 'memory_slot': mem_slot - } - if meas_level == MeasLevel.CLASSIFIED: - # setup discriminators - if instruction.command.discriminator: - command_dict.update({ - 'discriminators': [ - QobjMeasurementOption( - name=instruction.command.discriminator.name, - params=instruction.command.discriminator.params) - ] - }) - # setup register_slots - if instruction.reg_slot: - command_dict.update({ - 'register_slot': [instruction.reg_slot.index] - }) - if meas_level in [MeasLevel.KERNELED, MeasLevel.CLASSIFIED]: - # setup kernels - if instruction.command.kernel: - command_dict.update({ - 'kernels': [ - QobjMeasurementOption( - name=instruction.command.kernel.name, - params=instruction.command.kernel.params) - ] - }) - return self._qobj_model(**command_dict) - @bind_instruction(instructions.Acquire) def convert_acquire(self, shift, instruction): """Return converted `Acquire`. @@ -242,24 +193,6 @@ def convert_single_acquires(self, shift, instruction, res.register_slot = register_slot return res - @bind_instruction(commands.FrameChangeInstruction) - def convert_frame_change(self, shift, instruction): - """Return converted `FrameChangeInstruction`. - - Args: - shift(int): Offset time. - instruction (FrameChangeInstruction): frame change instruction. - Returns: - dict: Dictionary of required parameters. - """ - command_dict = { - 'name': 'fc', - 't0': shift + instruction.start_time, - 'ch': instruction.channels[0].name, - 'phase': instruction.command.phase - } - return self._qobj_model(**command_dict) - @bind_instruction(instructions.SetFrequency) def convert_set_frequency(self, shift, instruction): """ Return converted `SetFrequencyInstruction`. @@ -334,62 +267,6 @@ def convert_shift_phase(self, shift, instruction): } return self._qobj_model(**command_dict) - @bind_instruction(commands.PersistentValueInstruction) - def convert_persistent_value(self, shift, instruction): - """Return converted `PersistentValueInstruction`. - - Args: - shift(int): Offset time. - instruction (PersistentValueInstruction): persistent value instruction. - Returns: - dict: Dictionary of required parameters. - """ - warnings.warn("The PersistentValue command is deprecated. Use qiskit.pulse.Constant " - "instead.", DeprecationWarning) - command_dict = { - 'name': 'pv', - 't0': shift + instruction.start_time, - 'ch': instruction.channels[0].name, - 'val': instruction.command.value - } - return self._qobj_model(**command_dict) - - @bind_instruction(commands.PulseInstruction) - def convert_drive(self, shift, instruction): - """Return converted `PulseInstruction`. - - Args: - shift(int): Offset time. - instruction (PulseInstruction): drive instruction. - Returns: - dict: Dictionary of required parameters. - """ - command_dict = { - 'name': instruction.command.name, - 't0': shift + instruction.start_time, - 'ch': instruction.channels[0].name - } - return self._qobj_model(**command_dict) - - @bind_instruction(commands.ParametricInstruction) - def convert_parametric(self, shift, instruction): - """Return the converted `ParametricInstruction`. - - Args: - shift (int): Offset time. - instruction (ParametricInstruction): An instance of a ParametricInstruction subclass. - Returns: - dict: Dictionary of required parameters. - """ - command_dict = { - 'name': 'parametric_pulse', - 'pulse_shape': ParametricPulseShapes(type(instruction.command)).name, - 't0': shift + instruction.start_time, - 'ch': instruction.channels[0].name, - 'parameters': instruction.command.parameters - } - return self._qobj_model(**command_dict) - @bind_instruction(instructions.Play) def convert_play(self, shift, instruction): """Return the converted `Play`. @@ -654,31 +531,6 @@ def convert_delay(self, instruction): duration = instruction.duration return instructions.Delay(duration, channel) << t0 - @bind_name('pv') - def convert_persistent_value(self, instruction): - """Return converted `PersistentValueInstruction`. - - Args: - instruction (PulseQobjInstruction): persistent value qobj - Returns: - Schedule: Converted and scheduled Instruction - """ - t0 = instruction.t0 - channel = self.get_channel(instruction.ch) - val = instruction.val - - # This is parameterized - if isinstance(val, str): - val_expr = parse_string_expr(val, partial_binding=False) - - def gen_pv_sched(*args, **kwargs): - val = complex(val_expr(*args, **kwargs)) - return commands.PersistentValue(val)(channel) << t0 - - return ParameterizedSchedule(gen_pv_sched, parameters=val_expr.params) - - return commands.PersistentValue(val)(channel) << t0 - def bind_pulse(self, pulse): """Bind the supplied pulse to a converter method by pulse name. diff --git a/qiskit/test/mock/fake_openpulse_2q.py b/qiskit/test/mock/fake_openpulse_2q.py index f921f8addea6..15b046ca292a 100644 --- a/qiskit/test/mock/fake_openpulse_2q.py +++ b/qiskit/test/mock/fake_openpulse_2q.py @@ -219,8 +219,6 @@ def __init__(self): t0=0).to_dict(), PulseQobjInstruction(name='test_pulse_2', ch='u0', t0=10).to_dict(), - PulseQobjInstruction(name='pv', ch='d1', - t0=2, val='cos(P2)').to_dict(), PulseQobjInstruction(name='test_pulse_1', ch='d1', t0=20).to_dict(), PulseQobjInstruction(name='fc', ch='d1', diff --git a/qiskit/test/mock/fake_openpulse_3q.py b/qiskit/test/mock/fake_openpulse_3q.py index 5c4c7b3de66e..63890d4e8a06 100644 --- a/qiskit/test/mock/fake_openpulse_3q.py +++ b/qiskit/test/mock/fake_openpulse_3q.py @@ -279,10 +279,6 @@ def __init__(self): PulseQobjInstruction(name='test_pulse_2', ch='u0', t0=10).to_dict(), - PulseQobjInstruction(name='pv', - ch='d1', - t0=2, - val='cos(P2)').to_dict(), PulseQobjInstruction(name='test_pulse_1', ch='d1', t0=20).to_dict(), diff --git a/qiskit/visualization/pulse/matplotlib.py b/qiskit/visualization/pulse/matplotlib.py index f7305b4091d9..94cd2d237da0 100644 --- a/qiskit/visualization/pulse/matplotlib.py +++ b/qiskit/visualization/pulse/matplotlib.py @@ -33,8 +33,7 @@ from qiskit.pulse.channels import (DriveChannel, ControlChannel, MeasureChannel, AcquireChannel, SnapshotChannel, Channel) -from qiskit.pulse.commands import FrameChangeInstruction -from qiskit.pulse import (Waveform, SamplePulse, FrameChange, PersistentValue, Snapshot, Play, +from qiskit.pulse import (Waveform, SamplePulse, Snapshot, Play, Acquire, PulseError, ParametricPulse, SetFrequency, ShiftPhase, Instruction, ScheduleComponent, ShiftFrequency, SetPhase) @@ -71,9 +70,7 @@ def add_instruction(self, start_time: int, instruction: Instruction): start_time: Starting time of instruction instruction: Instruction object to be added """ - if instruction.command is not None: - pulse = instruction.command - elif isinstance(instruction, Play): + if isinstance(instruction, Play): pulse = instruction.pulse else: pulse = instruction @@ -91,7 +88,7 @@ def waveform(self) -> np.ndarray: return self._waveform[self.t0:self.tf] @property - def framechanges(self) -> Dict[int, FrameChangeInstruction]: + def framechanges(self) -> Dict[int, ShiftPhase]: """Get frame changes.""" if self._framechanges is None: self._build_waveform() @@ -205,7 +202,6 @@ def _build_waveform(self): fc = 0 pv = np.zeros(self.tf + 1, dtype=np.complex128) wf = np.zeros(self.tf + 1, dtype=np.complex128) - last_pv = None for time, commands in sorted(self.pulses.items()): if time > self.tf: break @@ -213,7 +209,7 @@ def _build_waveform(self): tmp_set_phase = 0 tmp_sf = None for command in commands: - if isinstance(command, (FrameChange, ShiftPhase)): + if isinstance(command, ShiftPhase): tmp_fc += command.phase pv[time:] = 0 elif isinstance(command, SetPhase): @@ -233,11 +229,6 @@ def _build_waveform(self): fc = tmp_set_phase if tmp_sf is not None: self._frequencychanges[time] = tmp_sf - for command in commands: - if isinstance(command, PersistentValue): - pv[time:] = np.exp(1j*fc) * command.value - last_pv = (time, command) - break for command in commands: duration = command.duration @@ -248,10 +239,6 @@ def _build_waveform(self): wf[time:tf] = np.exp(1j*fc) * command.samples[:tf-time] pv[time:] = 0 self._labels[time] = (tf, command) - if last_pv is not None: - pv_cmd = last_pv[1] - self._labels[last_pv[0]] = (time, pv_cmd) - last_pv = None elif isinstance(command, Acquire): wf[time:tf] = np.ones(tf - time) @@ -377,7 +364,7 @@ def _build_channels(self, schedule: ScheduleComponent, channels: Channels to plot. t0: Start time of plot. tf: End time of plot. - show_framechange_channels: Plot channels only with FrameChanges. + show_framechange_channels: Plot channels only with FrameChanges (ShiftPhase). Returns: channels: All channels. @@ -396,7 +383,7 @@ def _build_channels(self, schedule: ScheduleComponent, # take channels that do not only contain framechanges else: for start_time, instruction in schedule.instructions: - if not isinstance(instruction, (FrameChangeInstruction, ShiftPhase, SetPhase)): + if not isinstance(instruction, (ShiftPhase, SetPhase)): _channels.update(instruction.channels) _channels.update(channels) @@ -581,7 +568,7 @@ def _draw_snapshots(ax, arrowprops={'arrowstyle': 'wedge'}, ha='center') def _draw_framechanges(self, ax, - fcs: Dict[int, FrameChangeInstruction], + fcs: Dict[int, ShiftPhase], y0: float) -> bool: """Draw frame change of given channel to given mpl axis. @@ -663,9 +650,7 @@ def _draw_labels(self, ax, y0: vertical position to draw the labels. """ for t0, (tf, cmd) in labels.items(): - if isinstance(cmd, PersistentValue): - name = cmd.name if cmd.name else 'pv' - elif isinstance(cmd, Acquire): + if isinstance(cmd, Acquire): name = cmd.name if cmd.name else 'acquire' else: name = cmd.name diff --git a/releasenotes/notes/0.12/better-pulse-repr-9e5ba50649322b6b.yaml b/releasenotes/notes/0.12/better-pulse-repr-9e5ba50649322b6b.yaml index 9ea290f20305..9608a454f4da 100644 --- a/releasenotes/notes/0.12/better-pulse-repr-9e5ba50649322b6b.yaml +++ b/releasenotes/notes/0.12/better-pulse-repr-9e5ba50649322b6b.yaml @@ -4,22 +4,3 @@ features: Pulse :class:`qiskit.pulse.Schedule` objects now have better representations that for simple schedules should be valid Python expressions. - - for example: - - .. jupyter-execute:: - :hide-code: - :hide-output: - - import warnings - warnings.simplefilter("ignore") - - .. jupyter-execute:: - - from qiskit import pulse - - sched = pulse.Schedule(name='test') - sched += pulse.SamplePulse( - [0., 0,], name='test_pulse')(pulse.DriveChannel(0)) - sched += pulse.FrameChange(1.0)(pulse.DriveChannel(0)) - print(sched) diff --git a/releasenotes/notes/remove-deprecated-pulse-commands-18381c59264090dd.yaml b/releasenotes/notes/remove-deprecated-pulse-commands-18381c59264090dd.yaml new file mode 100644 index 000000000000..6817f0f101be --- /dev/null +++ b/releasenotes/notes/remove-deprecated-pulse-commands-18381c59264090dd.yaml @@ -0,0 +1,23 @@ +--- +upgrade: + - | + The `qiskit.pulse.commands` module containing `Commands` was deprecated in + Terra release 0.13.0 and have now been removed. You will have to upgrade + your Pulse code if you were still using commands. For example:: + + # old + Command(args)(channel) + + # new + Instruction(args, channel) + + :: + + Acquire(duration)(AcquireChannel(0)) -> Acquire(duration, AcquireChannel(0)) + Delay(duration)(channel) -> Delay(duration, channel) + + # FrameChange was also renamed + FrameChange(angle)(DriveChannel(0)) -> ShiftPhase(angle, DriveChannel(0)) + + # Pulses need to be `Play`d + Gaussian(...)(DriveChannel(0)) -> Play(Gaussian(...), DriveChannel(0)) diff --git a/test/python/compiler/test_assembler.py b/test/python/compiler/test_assembler.py index 7fd9ce56c0ed..21990e933b75 100644 --- a/test/python/compiler/test_assembler.py +++ b/test/python/compiler/test_assembler.py @@ -629,8 +629,7 @@ def test_pulse_name_conflicts_in_other_schedule(self): def test_assemble_with_delay(self): """Test that delay instruction is ignored in assembly.""" orig_schedule = self.schedule - with self.assertWarns(DeprecationWarning): - delay_schedule = orig_schedule + pulse.Delay(10)(self.backend_config.drive(0)) + delay_schedule = orig_schedule + pulse.Delay(10, self.backend_config.drive(0)) orig_qobj = assemble(orig_schedule, self.backend) validate_qobj_against_schema(orig_qobj) @@ -776,8 +775,6 @@ class TestPulseAssemblerMissingKwargs(QiskitTestCase): def setUp(self): self.schedule = pulse.Schedule(name='fake_experiment') - with self.assertWarns(DeprecationWarning): - self.schedule += pulse.FrameChange(0.)(pulse.DriveChannel(0)) self.backend = FakeOpenPulse2Q() self.config = self.backend.configuration() @@ -925,9 +922,8 @@ def test_single_and_deprecated_acquire_styles(self): new_style_schedule += Acquire(acq_dur, AcquireChannel(i), MemorySlot(i)) deprecated_style_schedule = Schedule() - with self.assertWarns(DeprecationWarning): - for i in range(5): - deprecated_style_schedule += Acquire(1200)(AcquireChannel(i), MemorySlot(i)) + for i in range(5): + deprecated_style_schedule += Acquire(1200, AcquireChannel(i), MemorySlot(i)) # The Qobj IDs will be different n_qobj = assemble(new_style_schedule, backend) diff --git a/test/python/pulse/test_commands.py b/test/python/pulse/test_commands.py deleted file mode 100644 index b55a62b2a19f..000000000000 --- a/test/python/pulse/test_commands.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Test cases for the pulse command group.""" - -import unittest - -from qiskit.pulse import (Acquire, FrameChange, PersistentValue, Snapshot, Kernel, Discriminator, - Delay) -from qiskit.test import QiskitTestCase - - -class TestAcquire(QiskitTestCase): - """Acquisition tests.""" - - def test_can_construct_valid_acquire_command(self): - """Test if valid acquire command can be constructed.""" - kernel_opts = { - 'start_window': 0, - 'stop_window': 10 - } - kernel = Kernel(name='boxcar', **kernel_opts) - - discriminator_opts = { - 'neighborhoods': [{'qubits': 1, 'channels': 1}], - 'cal': 'coloring', - 'resample': False - } - discriminator = Discriminator(name='linear_discriminator', **discriminator_opts) - - with self.assertWarns(DeprecationWarning): - acq = Acquire(duration=10, kernel=kernel, discriminator=discriminator) - - self.assertEqual(acq.duration, 10) - self.assertEqual(acq.discriminator.name, 'linear_discriminator') - self.assertEqual(acq.discriminator.params, discriminator_opts) - self.assertEqual(acq.kernel.name, 'boxcar') - self.assertEqual(acq.kernel.params, kernel_opts) - - def test_can_construct_acquire_command_with_default_values(self): - """Test if an acquire command can be constructed with default discriminator and kernel. - """ - with self.assertWarns(DeprecationWarning): - acq_a = Acquire(duration=10) - - self.assertEqual(acq_a.duration, 10) - self.assertEqual(acq_a.discriminator, None) - self.assertEqual(acq_a.kernel, None) - self.assertEqual(acq_a.name, None) - - -class TestFrameChangeCommand(QiskitTestCase): - """FrameChange tests. Deprecated.""" - - def test_default(self): - """Test default frame change. - """ - with self.assertWarns(DeprecationWarning): - fc_command = FrameChange(phase=1.57) - - self.assertEqual(fc_command.phase, 1.57) - self.assertEqual(fc_command.duration, 0) - self.assertTrue(fc_command.name.startswith('fc')) - - -class TestPersistentValueCommand(QiskitTestCase): - """PersistentValue tests.""" - - def test_default(self): - """Test default persistent value. - """ - with self.assertWarns(DeprecationWarning): - pv_command = PersistentValue(value=0.5 - 0.5j) - - self.assertEqual(pv_command.value, 0.5-0.5j) - self.assertEqual(pv_command.duration, 0) - self.assertTrue(pv_command.name.startswith('pv')) - - -class TestSnapshotCommand(QiskitTestCase): - """Snapshot tests.""" - - def test_default(self): - """Test default snapshot. - """ - snap_command = Snapshot(label='test_name', snapshot_type='state') - - self.assertEqual(snap_command.name, "test_name") - self.assertEqual(snap_command.type, "state") - self.assertEqual(snap_command.duration, 0) - - -class TestDelayCommand(QiskitTestCase): - """Delay tests.""" - - def test_delay(self): - """Test delay.""" - with self.assertWarns(DeprecationWarning): - delay_command = Delay(10, name='test_name') - - self.assertEqual(delay_command.name, "test_name") - self.assertEqual(delay_command.duration, 10) - - -class TestKernel(QiskitTestCase): - """Kernel tests.""" - - def test_can_construct_kernel_with_default_values(self): - """Test if Kernel can be constructed with default name and params.""" - kernel = Kernel() - - self.assertEqual(kernel.name, None) - self.assertEqual(kernel.params, {}) - - -class TestDiscriminator(QiskitTestCase): - """Discriminator tests.""" - - def test_can_construct_discriminator_with_default_values(self): - """Test if Discriminator can be constructed with default name and params.""" - discriminator = Discriminator() - - self.assertEqual(discriminator.name, None) - self.assertEqual(discriminator.params, {}) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/python/pulse/test_instruction_schedule_map.py b/test/python/pulse/test_instruction_schedule_map.py index 92bcb0b512ef..782b9fa81b41 100644 --- a/test/python/pulse/test_instruction_schedule_map.py +++ b/test/python/pulse/test_instruction_schedule_map.py @@ -151,25 +151,6 @@ def test_pop(self): with self.assertRaises(PulseError): inst_map.pop('not_there', (0,)) - def test_parameterized_schedule(self): - """Test adding parameterized schedule.""" - converter = QobjToInstructionConverter([], buffer=0) - qobj = PulseQobjInstruction(name='pv', ch='u1', t0=10, val='P2*cos(np.pi*P1)') - converted_instruction = converter(qobj) - - inst_map = InstructionScheduleMap() - - inst_map.add('pv_test', 0, converted_instruction) - self.assertEqual(inst_map.get_parameters('pv_test', 0), ('P1', 'P2')) - - with self.assertWarns(DeprecationWarning): - sched = inst_map.get('pv_test', 0, P1=0, P2=-1) - self.assertEqual(sched.instructions[0][-1].command.value, -1) - with self.assertRaises(PulseError): - inst_map.get('pv_test', 0, 0, P1=-1) - with self.assertRaises(PulseError): - inst_map.get('pv_test', 0, P1=1, P2=2, P3=3) - def test_sequenced_parameterized_schedule(self): """Test parametrized schedule consists of multiple instruction. """ converter = QobjToInstructionConverter([], buffer=0) diff --git a/test/python/pulse/test_pulse_lib.py b/test/python/pulse/test_pulse_lib.py index 6b4c9a81c193..859c865a7c3f 100644 --- a/test/python/pulse/test_pulse_lib.py +++ b/test/python/pulse/test_pulse_lib.py @@ -118,9 +118,9 @@ def test_gauss_samples(self): times = np.array(range(25), dtype=np.complex_) times = times - (duration / 2) + 0.5 gauss = amp * np.exp(-(times / sigma)**2 / 2) - # command - command = Gaussian(duration=duration, sigma=sigma, amp=amp) - samples = command.get_sample_pulse().samples + # wf + wf = Gaussian(duration=duration, sigma=sigma, amp=amp) + samples = wf.get_sample_pulse().samples np.testing.assert_almost_equal(samples, gauss) def test_gauss_square_samples(self): @@ -132,9 +132,9 @@ def test_gauss_square_samples(self): times = np.array(range(25), dtype=np.complex_) times = times - (25 / 2) + 0.5 gauss = amp * np.exp(-(times / sigma)**2 / 2) - # command - command = GaussianSquare(duration=duration, sigma=sigma, amp=amp, width=100) - samples = command.get_sample_pulse().samples + # wf + wf = GaussianSquare(duration=duration, sigma=sigma, amp=amp, width=100) + samples = wf.get_sample_pulse().samples np.testing.assert_almost_equal(samples[50], amp) np.testing.assert_almost_equal(samples[100], amp) np.testing.assert_almost_equal(samples[:10], gauss[:10]) @@ -165,9 +165,9 @@ def test_drag_samples(self): gauss = amp * np.exp(-(times / sigma)**2 / 2) gauss_deriv = -(times / sigma**2) * gauss drag = gauss + 1j * beta * gauss_deriv - # command - command = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) - samples = command.get_sample_pulse().samples + # wf + wf = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) + samples = wf.get_sample_pulse().samples np.testing.assert_almost_equal(samples, drag) def test_drag_validation(self): @@ -176,21 +176,21 @@ def test_drag_validation(self): sigma = 4 amp = 0.5j beta = 1 - command = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) - samples = command.get_sample_pulse().samples + wf = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) + samples = wf.get_sample_pulse().samples self.assertTrue(max(np.abs(samples)) <= 1) beta = sigma ** 2 with self.assertRaises(PulseError): - command = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) + wf = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) # If sigma is high enough, side peaks fall out of range and norm restriction is met sigma = 100 - command = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) + wf = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) def test_drag_beta_validation(self): """Test drag beta parameter validation.""" def check_drag(duration, sigma, amp, beta): - command = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) - samples = command.get_sample_pulse().samples + wf = Drag(duration=duration, sigma=sigma, amp=amp, beta=beta) + samples = wf.get_sample_pulse().samples self.assertTrue(max(np.abs(samples)) <= 1) check_drag(duration=50, sigma=16, amp=1, beta=2) check_drag(duration=50, sigma=16, amp=1, beta=4) @@ -271,16 +271,16 @@ def local_gaussian(duration, amp, t0, sig): x = np.linspace(0, duration - 1, duration) return amp * np.exp(-(x - t0) ** 2 / sig ** 2) - pulse_command = local_gaussian(duration=10, amp=1, t0=5, sig=1, name='test_pulse') + pulse_wf_inst = local_gaussian(duration=10, amp=1, t0=5, sig=1, name='test_pulse') _y = 1 * np.exp(-(np.linspace(0, 9, 10) - 5)**2 / 1**2) - self.assertListEqual(list(pulse_command.samples), list(_y)) + self.assertListEqual(list(pulse_wf_inst.samples), list(_y)) # check name - self.assertEqual(pulse_command.name, 'test_pulse') + self.assertEqual(pulse_wf_inst.name, 'test_pulse') # check duration - self.assertEqual(pulse_command.duration, 10) + self.assertEqual(pulse_wf_inst.duration, 10) def test_variable_duration(self): """Test generation of sample pulse with variable duration. @@ -294,8 +294,8 @@ def local_gaussian(duration, amp, t0, sig): _durations = np.arange(10, 15, 1) for _duration in _durations: - pulse_command = local_gaussian(duration=_duration, amp=1, t0=5, sig=1) - self.assertEqual(len(pulse_command.samples), _duration) + pulse_wf_inst = local_gaussian(duration=_duration, amp=1, t0=5, sig=1) + self.assertEqual(len(pulse_wf_inst.samples), _duration) if __name__ == '__main__': diff --git a/test/python/pulse/test_schedule.py b/test/python/pulse/test_schedule.py index a5b33c34a9f2..71582ff96ac4 100644 --- a/test/python/pulse/test_schedule.py +++ b/test/python/pulse/test_schedule.py @@ -44,7 +44,6 @@ SnapshotChannel, MeasureChannel, ) -from qiskit.pulse.commands import PersistentValue, PulseInstruction from qiskit.pulse.exceptions import PulseError from qiskit.pulse.schedule import Schedule, ParameterizedSchedule, _overlaps, _insertion_index from qiskit.test import QiskitTestCase @@ -131,9 +130,6 @@ def test_can_create_valid_schedule(self): sched = Schedule() sched = sched.append(Play(gp0, self.config.drive(0))) - with self.assertWarns(DeprecationWarning): - sched = sched.insert(0, PersistentValue(value=0.2 + 0.4j)(self.config.control( - [0, 1])[0])) sched = sched.insert(60, ShiftPhase(-1.57, self.config.drive(0))) sched = sched.insert(30, Play(gp1, self.config.drive(0))) sched = sched.insert(60, Play(gp0, self.config.control([0, 1])[0])) @@ -165,8 +161,6 @@ def test_can_create_valid_schedule_with_syntax_sugar(self): sched = Schedule() sched += Play(gp0, self.config.drive(0)) - with self.assertWarns(DeprecationWarning): - sched |= PersistentValue(value=0.2 + 0.4j)(self.config.control([0, 1])[0]) sched |= ShiftPhase(-1.57, self.config.drive(0)) << 60 sched |= Play(gp1, self.config.drive(0)) << 30 sched |= Play(gp0, self.config.control(qubits=[0, 1])[0]) << 60 @@ -320,8 +314,6 @@ def test_auto_naming(self, is_main_process_mock): def test_name_inherited(self): """Test that schedule keeps name if an instruction is added.""" gp0 = library.gaussian(duration=100, amp=0.7, sigma=3, name='pulse_name') - with self.assertWarns(DeprecationWarning): - pv0 = PersistentValue(0.1) snapshot = Snapshot('snapshot_label', 'state') sched1 = Schedule(name='test_name') @@ -337,10 +329,6 @@ def test_name_inherited(self): sched_pulse = Play(gp0, self.config.drive(0)) | sched1 self.assertEqual(sched_pulse.name, 'pulse_name') - with self.assertWarns(DeprecationWarning): - sched_pv = pv0(self.config.drive(0), name='pv_name') | sched1 - self.assertEqual(sched_pv.name, 'pv_name') - sched_fc = ShiftPhase(0.1, self.config.drive(0), name='fc_name') | sched1 self.assertEqual(sched_fc.name, 'fc_name') @@ -352,19 +340,17 @@ def test_multiple_parameters_not_returned(self): arguments should not produce repeated parameters in resulting ParameterizedSchedule object.""" def my_test_par_sched_one(x, y, z): - with self.assertWarns(DeprecationWarning): - result = PulseInstruction( - Waveform(np.array([x, y, z]), name='sample'), - self.config.drive(0) - ) + result = Play( + Waveform(np.array([x, y, z]), name='sample'), + self.config.drive(0) + ) return 0, result def my_test_par_sched_two(x, y, z): - with self.assertWarns(DeprecationWarning): - result = PulseInstruction( - Waveform(np.array([x, y, z]), name='sample'), - self.config.drive(0) - ) + result = Play( + Waveform(np.array([x, y, z]), name='sample'), + self.config.drive(0) + ) return 5, result par_sched_in_0 = ParameterizedSchedule( @@ -766,7 +752,7 @@ def test_filter_multiple(self): sched = sched.insert(90, Play(lp0, self.config.drive(0))) - # split instructions with filters on channel 0, of type PulseInstruction, + # split instructions with filters on channel 0, of type Play # occurring in the time interval (25, 100) filtered, excluded = self._filter_and_test_consistency(sched, channels={self.config.drive(0)}, @@ -788,7 +774,7 @@ def test_filter_multiple(self): for time, inst in filtered.instructions: self.assertIsInstance(inst, (ShiftPhase, Play)) self.assertTrue(len(filtered.instructions), 4) - # make sure the PulseInstruction not in the intervals is maintained + # make sure the Play instruction is not in the intervals self.assertIsInstance(excluded.instructions[0][1], Play) # split based on Acquire in the specified intervals @@ -864,7 +850,7 @@ def test_empty_filters(self): # empty channels with other non-empty filters filtered, excluded = self._filter_and_test_consistency(sched, channels=[], - instruction_types=[PulseInstruction]) + instruction_types=[Play]) self.assertTrue(len(filtered.instructions) == 0) self.assertTrue(len(excluded.instructions) == 6) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index 868a6cc5aaeb..a577868307db 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -21,13 +21,11 @@ QobjMeasurementOption) from qiskit.qobj.converters import (InstructionToQobjConverter, QobjToInstructionConverter, LoConfigConverter) -from qiskit.pulse.commands import (SamplePulse, FrameChange, PersistentValue, Snapshot, Acquire, - Gaussian, GaussianSquare, Constant, Drag) from qiskit.pulse.instructions import (SetPhase, ShiftPhase, SetFrequency, ShiftFrequency, Play, - Delay) + Delay, Acquire, Snapshot) from qiskit.pulse.channels import (DriveChannel, ControlChannel, MeasureChannel, AcquireChannel, MemorySlot, RegisterSlot) -from qiskit.pulse.pulse_lib import Waveform +from qiskit.pulse.library import Waveform, Gaussian, GaussianSquare, Constant, Drag from qiskit.pulse.schedule import ParameterizedSchedule, Schedule from qiskit.pulse import LoConfig, Kernel, Discriminator @@ -35,22 +33,6 @@ class TestInstructionToQobjConverter(QiskitTestCase): """Pulse converter tests.""" - def test_deprecated_drive_instruction(self): - """Test converted qobj from PulseInstruction.""" - converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - with self.assertWarns(DeprecationWarning): - command = SamplePulse(np.arange(0, 0.01), name='linear') - with self.assertWarns(DeprecationWarning): - instruction = command(DriveChannel(0)) - - valid_qobj = PulseQobjInstruction( - name='linear', - ch='d0', - t0=0 - ) - - self.assertEqual(converter(0, instruction), valid_qobj) - def test_drive_instruction(self): """Test converted qobj from Play.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) @@ -73,20 +55,6 @@ def test_gaussian_pulse_instruction(self): parameters={'duration': 25, 'sigma': 15, 'amp': -0.5 + 0.2j}) self.assertEqual(converter(0, instruction), valid_qobj) - def test_deprecated_gaussian_pulse_instruction(self): - """Test that parametric pulses are correctly converted to PulseQobjInstructions.""" - converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - with self.assertWarns(DeprecationWarning): - instruction = Gaussian(duration=25, sigma=15, amp=-0.5 + 0.2j)(DriveChannel(0)) - - valid_qobj = PulseQobjInstruction( - name='parametric_pulse', - pulse_shape='gaussian', - ch='d0', - t0=0, - parameters={'duration': 25, 'sigma': 15, 'amp': -0.5 + 0.2j}) - self.assertEqual(converter(0, instruction), valid_qobj) - def test_gaussian_square_pulse_instruction(self): """Test that parametric pulses are correctly converted to PulseQobjInstructions.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) @@ -128,26 +96,19 @@ def test_drag_pulse_instruction(self): self.assertEqual(converter(30, instruction), valid_qobj) def test_frame_change(self): - """Test converted qobj from FrameChangeInstruction.""" + """Test converted qobj from ShiftPhase.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - with self.assertWarns(DeprecationWarning): - command = FrameChange(phase=0.1) - with self.assertWarns(DeprecationWarning): - instruction = command(DriveChannel(0)) - valid_qobj = PulseQobjInstruction( name='fc', ch='d0', t0=0, phase=0.1 ) - - self.assertEqual(converter(0, instruction), valid_qobj) instruction = ShiftPhase(0.1, DriveChannel(0)) self.assertEqual(converter(0, instruction), valid_qobj) def test_set_phase(self): - """Test converted qobj from FrameChangeInstruction.""" + """Test converted qobj from ShiftPhase.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) instruction = SetPhase(3.14, DriveChannel(0)) @@ -188,59 +149,6 @@ def test_shift_frequency(self): self.assertEqual(converter(0, instruction), valid_qobj) - def test_persistent_value(self): - """Test converted qobj from PersistentValueInstruction.""" - converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - with self.assertWarns(DeprecationWarning): - command = PersistentValue(value=0.1j) - with self.assertWarns(DeprecationWarning): - instruction = command(DriveChannel(0)) - - valid_qobj = PulseQobjInstruction( - name='pv', - ch='d0', - t0=0, - val=0.1j - ) - - with self.assertWarns(DeprecationWarning): - self.assertEqual(converter(0, instruction), valid_qobj) - - def test_deprecated_acquire(self): - """Test converted qobj from AcquireInstruction.""" - converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - with self.assertWarns(DeprecationWarning): - command = Acquire(duration=10) - with self.assertWarns(DeprecationWarning): - instruction = command(AcquireChannel(0), - MemorySlot(0), - RegisterSlot(0)) - - valid_qobj = PulseQobjInstruction( - name='acquire', - t0=0, - duration=10, - qubits=[0], - memory_slot=[0], - register_slot=[0] - ) - - self.assertEqual(converter(0, instruction), valid_qobj) - - # test without register - with self.assertWarns(DeprecationWarning): - instruction = command(AcquireChannel(0), MemorySlot(0)) - - valid_qobj = PulseQobjInstruction( - name='acquire', - t0=0, - duration=10, - qubits=[0], - memory_slot=[0] - ) - - self.assertEqual(converter(0, instruction), valid_qobj) - def test_acquire(self): """Test converted qobj from AcquireInstruction.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) @@ -297,16 +205,6 @@ def test_drive_instruction(self): converted_instruction = self.converter(qobj) self.assertEqual(converted_instruction.instructions[0][-1], instruction) - def test_deprecated_drive_instruction(self): - """Test converted qobj from PulseInstruction.""" - with self.assertWarns(DeprecationWarning): - instruction = self.linear(DriveChannel(0)) - - qobj = PulseQobjInstruction(name='linear', ch='d0', t0=10) - converted_instruction = self.converter(qobj) - - self.assertEqual(converted_instruction.instructions[0][-1], instruction) - def test_parametric_pulses(self): """Test converted qobj from ParametricInstruction.""" instruction = Play(Gaussian(duration=25, sigma=15, amp=-0.5 + 0.2j), DriveChannel(0)) @@ -322,7 +220,7 @@ def test_parametric_pulses(self): self.assertEqual(converted_instruction.instructions[0][-1], instruction) def test_frame_change(self): - """Test converted qobj from FrameChangeInstruction.""" + """Test converted qobj from ShiftPhase.""" qobj = PulseQobjInstruction(name='fc', ch='m0', t0=0, phase=0.1) converted_instruction = self.converter(qobj) @@ -376,21 +274,6 @@ def test_delay(self): self.assertEqual(converted_instruction.duration, instruction.duration) self.assertEqual(converted_instruction.instructions[0][-1], instruction) - def test_persistent_value(self): - """Test converted qobj from PersistentValueInstruction.""" - with self.assertWarns(DeprecationWarning): - cmd = PersistentValue(value=0.1j) - with self.assertWarns(DeprecationWarning): - instruction = cmd(ControlChannel(1)) - - qobj = PulseQobjInstruction(name='pv', ch='u1', t0=0, val=0.1j) - with self.assertWarns(DeprecationWarning): - converted_instruction = self.converter(qobj) - - self.assertEqual(converted_instruction.start_time, 0) - self.assertEqual(converted_instruction.duration, 0) - self.assertEqual(converted_instruction.instructions[0][-1], instruction) - def test_acquire(self): """Test converted qobj from Acquire.""" schedule = Schedule() @@ -428,7 +311,7 @@ def test_snapshot(self): self.assertEqual(converted_instruction.instructions[0][-1], instruction) def test_parameterized_frame_change(self): - """Test converted qobj from FrameChangeInstruction.""" + """Test converted qobj from ShiftPhase.""" instruction = ShiftPhase(4., MeasureChannel(0)) shifted = instruction << 10 @@ -443,25 +326,6 @@ def test_parameterized_frame_change(self): self.assertEqual(evaluated_instruction.duration, shifted.duration) self.assertEqual(evaluated_instruction.instructions[0][-1], instruction) - def test_parameterized_persistent_value(self): - """Test converted qobj from PersistentValueInstruction.""" - with self.assertWarns(DeprecationWarning): - cmd = PersistentValue(value=0.5+0.j) - with self.assertWarns(DeprecationWarning): - instruction = cmd(ControlChannel(1)) << 10 - - qobj = PulseQobjInstruction(name='pv', ch='u1', t0=10, val='P1*cos(np.pi*P2)') - converted_instruction = self.converter(qobj) - - self.assertIsInstance(converted_instruction, ParameterizedSchedule) - - with self.assertWarns(DeprecationWarning): - evaluated_instruction = converted_instruction.bind_parameters(P1=0.5, P2=0.) - - self.assertEqual(evaluated_instruction.start_time, instruction.start_time) - self.assertEqual(evaluated_instruction.duration, instruction.duration) - self.assertEqual(evaluated_instruction.instructions[0][-1].command, cmd) - class TestLoConverter(QiskitTestCase): """LO converter tests.""" diff --git a/test/python/scheduler/test_basic_scheduler.py b/test/python/scheduler/test_basic_scheduler.py index 4afe0eb8e08c..2c02a43dbad7 100644 --- a/test/python/scheduler/test_basic_scheduler.py +++ b/test/python/scheduler/test_basic_scheduler.py @@ -52,8 +52,7 @@ def test_alap_pass(self): (78, self.inst_map.get('measure', [0, 1]))) for actual, expected in zip(sched.instructions, expected.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_alap_with_barriers(self): """Test that ALAP respects barriers on new qubits.""" @@ -69,8 +68,7 @@ def test_alap_with_barriers(self): (28, self.inst_map.get('u2', [1], 0, 0))) for actual, expected in zip(sched.instructions, expected.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_empty_circuit_schedule(self): """Test empty circuit being scheduled.""" @@ -94,8 +92,7 @@ def test_alap_aligns_end(self): (26, self.inst_map.get('u3', [0], 0, 0, 0))) for actual, expected in zip(sched.instructions, expected_sched.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) self.assertEqual(sched.ch_duration(DriveChannel(0)), expected_sched.ch_duration(DriveChannel(1))) @@ -121,8 +118,7 @@ def test_asap_pass(self): (78, self.inst_map.get('measure', [0, 1]))) for actual, expected in zip(sched.instructions, expected.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_alap_resource_respecting(self): """Test that the ALAP pass properly respects busy resources when backwards scheduling. @@ -155,8 +151,7 @@ def test_inst_map_schedules_unaltered(self): sched2 = schedule(qc, self.backend, method="as_late_as_possible") for asap, alap in zip(sched1.instructions, sched2.instructions): self.assertEqual(asap[0], alap[0]) - self.assertEqual(asap[1].command, alap[1].command) - self.assertEqual(asap[1].channels, alap[1].channels) + self.assertEqual(asap[1], alap[1]) insts = sched1.instructions self.assertEqual(insts[0][0], 0) self.assertEqual(insts[1][0], 10) @@ -211,8 +206,7 @@ def test_3q_schedule(self): (74, inst_map.get('u3', [0], 3.14, 1.57))) for actual, expected in zip(sched.instructions, expected.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_schedule_multi(self): """Test scheduling multiple circuits at once.""" @@ -226,8 +220,7 @@ def test_schedule_multi(self): expected_insts = schedule(qc0, self.backend).instructions for actual, expected in zip(schedules[0].instructions, expected_insts): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_circuit_name_kept(self): """Test that the new schedule gets its name from the circuit.""" @@ -267,8 +260,7 @@ def test_can_add_gates_into_free_space(self): (28, self.inst_map.get('u2', [1], 0, 0))) for actual, expected in zip(sched.instructions, expected.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_barriers_in_middle(self): """As a follow on to `test_can_add_gates_into_free_space`, similar issues @@ -292,8 +284,7 @@ def test_barriers_in_middle(self): (28, self.inst_map.get('u2', [1], 0, 0))) for actual, expected in zip(sched.instructions, expected.instructions): self.assertEqual(actual[0], expected[0]) - self.assertEqual(actual[1].command, expected[1].command) - self.assertEqual(actual[1].channels, expected[1].channels) + self.assertEqual(actual[1], expected[1]) def test_parametric_input(self): """Test that scheduling works with parametric pulses as input.""" diff --git a/test/python/visualization/test_pulse_visualization_output.py b/test/python/visualization/test_pulse_visualization_output.py index 37c34ddae8c6..fe9c109ffc59 100644 --- a/test/python/visualization/test_pulse_visualization_output.py +++ b/test/python/visualization/test_pulse_visualization_output.py @@ -22,7 +22,6 @@ from qiskit.pulse import library from qiskit.pulse.channels import (DriveChannel, MeasureChannel, ControlChannel, AcquireChannel, MemorySlot, RegisterSlot) -from qiskit.pulse.commands import FrameChange from qiskit.pulse.instructions import (SetFrequency, Play, Acquire, Delay, Snapshot, ShiftFrequency, SetPhase, ShiftPhase) from qiskit.pulse.schedule import Schedule @@ -60,24 +59,23 @@ def sample_schedule(self): gp1 = library.gaussian(duration=20, amp=-1.0, sigma=2.0) gs0 = library.gaussian_square(duration=20, amp=-1.0, sigma=2.0, risefall=3) - acquire = Acquire(10) - delay = Delay(100) sched = Schedule(name='test_schedule') sched = sched.append(gp0(DriveChannel(0))) sched = sched.insert(0, library.Constant(duration=60, amp=0.2 + 0.4j)( ControlChannel(0))) - sched = sched.insert(60, FrameChange(phase=-1.57)(DriveChannel(0))) + sched = sched.insert(60, ShiftPhase(-1.57, DriveChannel(0))) sched = sched.insert(60, SetFrequency(8.0, DriveChannel(0))) sched = sched.insert(60, SetPhase(3.14, DriveChannel(0))) sched = sched.insert(70, ShiftFrequency(4.0e6, DriveChannel(0))) - sched = sched.insert(30, gp1(DriveChannel(1))) - sched = sched.insert(60, gp0(ControlChannel(0))) - sched = sched.insert(60, gs0(MeasureChannel(0))) + sched = sched.insert(30, Play(gp1, DriveChannel(1))) + sched = sched.insert(60, Play(gp0, ControlChannel(0))) + sched = sched.insert(60, Play(gs0, MeasureChannel(0))) sched = sched.insert(90, ShiftPhase(1.57, DriveChannel(0))) - sched = sched.insert(90, acquire(AcquireChannel(1), + sched = sched.insert(90, Acquire(10, + AcquireChannel(1), MemorySlot(1), RegisterSlot(1))) - sched = sched.append(delay(DriveChannel(0))) + sched = sched.append(Delay(100, DriveChannel(0))) sched = sched + sched sched |= Snapshot("snapshot_1", "snap_type") << 60 sched |= Snapshot("snapshot_2", "snap_type") << 120 @@ -157,8 +155,7 @@ def test_truncated_schedule_matplotlib_drawer(self): @unittest.skip('Useful for refactoring purposes, skipping by default.') def test_truncate_acquisition(self): sched = Schedule(name='test_schedule') - acquire = Acquire(30) - sched = sched.insert(0, acquire(AcquireChannel(1), + sched = sched.insert(0, Acquire(30, AcquireChannel(1), MemorySlot(1), RegisterSlot(1))) # Check ValueError is not thrown @@ -172,10 +169,10 @@ def test_schedule_drawer_show_framechange(self): filename = self._get_resource_path('current_show_framechange_ref.png') gp0 = library.gaussian(duration=20, amp=1.0, sigma=1.0) sched = Schedule(name='test_schedule') - sched = sched.append(gp0(DriveChannel(0))) - sched = sched.insert(60, FrameChange(phase=-1.57)(DriveChannel(0))) - sched = sched.insert(30, FrameChange(phase=-1.50)(DriveChannel(1))) - sched = sched.insert(70, FrameChange(phase=1.50)(DriveChannel(1))) + sched = sched.append(Play(gp0, DriveChannel(0))) + sched = sched.insert(60, ShiftPhase(-1.57, DriveChannel(0))) + sched = sched.insert(30, ShiftPhase(-1.50, DriveChannel(1))) + sched = sched.insert(70, ShiftPhase(1.50, DriveChannel(1))) pulse_drawer(sched, filename=filename, show_framechange_channels=False) self.assertImagesAreEqual(filename, self.schedule_show_framechange_ref) os.remove(filename)