Skip to content

Commit

Permalink
Deprecate PulseSimulator backend (#1728)
Browse files Browse the repository at this point in the history
* Deprecate PulseSimulator backend

This commit deprecates the PulseSimulator backend for qiskit aer. For
the past several releases development on the pulse simulator has mostly
been frozen as the combined efforts for improving pulse level simulation
have been working on Qiskit Dynamics instead. This commit marks the
legacy PulseSimulator as deprecated and points existing users to Qiskit
Dynamics instead.

Closes #1722

* handle deprecation of pulse simulation in tests

---------

Co-authored-by: Hiroshi Horii <horii@jp.ibm.com>
Co-authored-by: Hiroshi Horii <hhorii@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 24, 2023
1 parent c48b0a8 commit 82eb26c
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 51 deletions.
10 changes: 10 additions & 0 deletions qiskit_aer/aerprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# pylint: disable=invalid-name
"""Provider for Qiskit Aer backends."""

import warnings

from qiskit.providers import ProviderV1 as Provider
from qiskit.providers.providerutils import filter_backends

Expand Down Expand Up @@ -59,6 +61,14 @@ def __init__(self):
AerProvider._BACKENDS = backends

def get_backend(self, name=None, **kwargs):
if name == "pulse_simulator":
warnings.warn(
"The Pulse simulator backend in Qiskit Aer is deprecated and will "
"be removed in a future release. Instead the qiskit-dynamics "
"library should be used instead for simulating at the pulse level.",
DeprecationWarning,
stacklevel=2,
)
return super().get_backend(name=name, **kwargs)

def backends(self, name=None, filters=None, **kwargs):
Expand Down
16 changes: 15 additions & 1 deletion qiskit_aer/backends/pulse_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@


class PulseSimulator(AerBackend):
r"""Pulse schedule simulator backend.
r"""Deprecated: Pulse schedule simulator backend.
.. warning::
This simulator is deprecated having been superseded by the
`Qiskit Dynamics <https://qiskit.org/documentation/dynamics/>`__ library.
If you need to perform pulse level simulation you should use the
Qiskit Dynamics library instead.
The ``PulseSimulator`` simulates continuous time Hamiltonian dynamics of a quantum system,
with controls specified by pulse :class:`~qiskit.Schedule` objects, and the model of the
Expand Down Expand Up @@ -154,6 +161,13 @@ def __init__(self,
defaults=None,
provider=None,
**backend_options):
warn(
"The Pulse simulator backend in Qiskit Aer is deprecated and will "
"be removed in a future release. Instead the qiskit-dynamics "
"library should be used instead for simulating at the pulse level.",
DeprecationWarning,
stacklevel=2,
)

if configuration is None:
configuration = BackendConfiguration.from_dict(
Expand Down
10 changes: 10 additions & 0 deletions releasenotes/notes/deprecate-pulse-simulator-27cde3ece112c346.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
deprecations:
- |
The :class:`~.PulseSimulator` backend has been deprecated and will be
removed in a future release. If you're using the :class:`~.PulseSimulator`
backend to perform pulse level simulation, instead you should use the
`Qiskit Dynamics <https://qiskit.org/documentation/dynamics/>`__ library
instead to perform the simulation. Qiskit Dynamics provides a more
flexible and robust pulse level simulation framework than the
:class:`~.PulseSimulator` backend.
36 changes: 24 additions & 12 deletions test/terra/backends/test_config_pulse_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def test_from_backend(self):
"""Test that configuration, defaults, and properties are correclty imported."""

athens_backend = FakeAthens()
athens_sim = PulseSimulator.from_backend(athens_backend)
with self.assertWarns(DeprecationWarning):
athens_sim = PulseSimulator.from_backend(athens_backend)

self.assertEqual(athens_backend.properties(), athens_sim.properties())
# check that configuration is correctly imported
Expand Down Expand Up @@ -79,7 +80,8 @@ def test_from_backend_system_model(self):
"""Test that the system model is correctly imported from the backend."""

athens_backend = FakeAthens()
athens_sim = PulseSimulator.from_backend(athens_backend)
with self.assertWarns(DeprecationWarning):
athens_sim = PulseSimulator.from_backend(athens_backend)

# u channel lo
athens_attr = athens_backend.configuration().u_channel_lo
Expand All @@ -97,7 +99,8 @@ def test_set_system_model_options(self):
"""Test setting of options that need to be changed in multiple places."""

athens_backend = FakeAthens()
athens_sim = PulseSimulator.from_backend(athens_backend)
with self.assertWarns(DeprecationWarning):
athens_sim = PulseSimulator.from_backend(athens_backend)

# u channel lo
set_attr = [[UchannelLO(0, 1.0 + 0.0j)]]
Expand All @@ -118,7 +121,8 @@ def test_from_backend_parametric_pulses(self):
Results don't matter, just need to check that it runs.
"""

backend = PulseSimulator.from_backend(FakeAthens())
with self.assertWarns(DeprecationWarning):
backend = PulseSimulator.from_backend(FakeAthens())

qc = QuantumCircuit(2)
qc.x(0)
Expand All @@ -132,7 +136,8 @@ def test_parametric_pulses_error(self):
"""Verify error is raised if a parametric pulse makes it into the digest."""

fake_backend = FakeAthens()
backend = PulseSimulator.from_backend(fake_backend)
with self.assertWarns(DeprecationWarning):
backend = PulseSimulator.from_backend(fake_backend)

# reset parametric_pulses option
backend.set_option('parametric_pulses', fake_backend.configuration().parametric_pulses)
Expand All @@ -150,7 +155,8 @@ def test_set_meas_levels(self):
"""Test setting of meas_levels."""

athens_backend = FakeAthens()
athens_sim = PulseSimulator.from_backend(athens_backend)
with self.assertWarns(DeprecationWarning):
athens_sim = PulseSimulator.from_backend(athens_backend)

# test that a warning is thrown when meas_level 0 is attempted to be set
with warnings.catch_warnings(record=True) as w:
Expand Down Expand Up @@ -187,7 +193,8 @@ def test_set_system_model_from_backend(self):
armonk_sim = PulseSimulator.from_backend(backend=armonk_backend,
system_model=system_model)

self.assertEqual(len(w), 1)
self.assertEqual(len(w), 2)
self.assertTrue('will be removed in a future release' in str(w[0].message))
self.assertTrue('inconsistencies' in str(w[-1].message))

# check that system model properties have been imported
Expand All @@ -211,7 +218,8 @@ def test_set_system_model_in_constructor(self):

test_sim = PulseSimulator(system_model=system_model)

self.assertEqual(len(w), 0)
self.assertEqual(len(w), 1)
self.assertTrue('will be removed in a future release' in str(w[0].message))

# check that system model properties have been imported
self.assertEqual(test_sim.configuration().dt, system_model.dt)
Expand All @@ -226,7 +234,8 @@ def test_set_system_model_after_construction(self):
system_model.u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)]]

# first test setting after construction with no hamiltonian
test_sim = PulseSimulator()
with self.assertWarns(DeprecationWarning):
test_sim = PulseSimulator()

with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.
Expand All @@ -243,7 +252,8 @@ def test_set_system_model_after_construction(self):
# next, construct a pulse simulator with a config containing a Hamiltonian and observe
# warnings
armonk_backend = FakeArmonk()
test_sim = PulseSimulator(configuration=armonk_backend.configuration())
with self.assertWarns(DeprecationWarning):
test_sim = PulseSimulator(configuration=armonk_backend.configuration())

# add system model and verify warning is raised
with warnings.catch_warnings(record=True) as w:
Expand All @@ -261,7 +271,8 @@ def test_set_system_model_after_construction(self):
def test_validation_num_acquires(self):
"""Test that validation fails if 0 or >1 acquire is given in a schedule."""

test_sim = PulseSimulator.from_backend(FakeArmonk())
with self.assertWarns(DeprecationWarning):
test_sim = PulseSimulator.from_backend(FakeArmonk())
test_sim.set_options(
meas_level=2,
qubit_lo_freq=test_sim.defaults().qubit_freq_est,
Expand Down Expand Up @@ -298,7 +309,8 @@ def test_run_simulation_from_backend(self):
dt = 2.2222222222222221e-10
armonk_backend.configuration().dt = dt

armonk_sim = PulseSimulator.from_backend(armonk_backend)
with self.assertWarns(DeprecationWarning):
armonk_sim = PulseSimulator.from_backend(armonk_backend)
armonk_sim.set_options(
meas_level=2,
meas_return='single',
Expand Down
Loading

0 comments on commit 82eb26c

Please sign in to comment.