Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate provider-specific fake backends,FakeProvider class and related tools in 0.46 #11381

Merged
merged 10 commits into from
Jan 31, 2024
Merged
14 changes: 12 additions & 2 deletions qiskit/providers/fake_provider/fake_backend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2023.
# (C) Copyright IBM 2019, 2024.
#
# 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
Expand Down Expand Up @@ -33,6 +33,7 @@
from qiskit.providers import basic_provider
from qiskit.transpiler import Target
from qiskit.providers.backend_compat import convert_to_target
from qiskit.utils.deprecation import deprecate_func

from .utils.json_decoder import (
decode_backend_configuration,
Expand All @@ -56,7 +57,7 @@ class FakeBackendV2(BackendV2):

The class inherits :class:`~qiskit.providers.BackendV2` class. This version
differs from earlier :class:`~qiskit.providers.fake_provider.FakeBackend` (V1) class in a
few aspects. Firstly, configuration attribute no longer exsists. Instead,
few aspects. Firstly, configuration attribute no longer exists. Instead,
attributes exposing equivalent required immutable properties of the backend
device are added. For example ``fake_backend.configuration().n_qubits`` is
accessible from ``fake_backend.num_qubits`` now. Secondly, this version
Expand All @@ -71,6 +72,15 @@ class FakeBackendV2(BackendV2):
defs_filename = None
backend_name = None

@deprecate_func(
additional_msg="This class has been migrated to the `qiskit_ibm_runtime` package. "
"To migrate your code, run `pip install qiskit-ibm-runtime` and use "
"`from qiskit_ibm_runtime.fake_provider import FakeExample` "
"instead of `from qiskit.providers.fake_provider import FakeExample`. ",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
"""FakeBackendV2 initializer."""
self._conf_dict = self._get_conf_dict_from_json()
Expand Down
22 changes: 22 additions & 0 deletions qiskit/providers/fake_provider/fake_backend_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,19 @@
from qiskit.providers.options import Options
from qiskit.transpiler import Target, InstructionProperties
from qiskit.providers.basic_provider.basic_simulator import BasicSimulator
from qiskit.utils.deprecation import deprecate_func


class FakeBackendV2(BackendV2):
"""A mock backend that doesn't implement run() to test compatibility with Terra internals."""

@deprecate_func(
additional_msg="Use the `qiskit.providers.basic_provider.GenericBackendV2` "
"class instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
super().__init__(
None,
Expand Down Expand Up @@ -111,6 +119,13 @@ def qubit_properties(self, qubit):
class FakeBackend5QV2(BackendV2):
"""A mock backend that doesn't implement run() to test compatibility with Terra internals."""

@deprecate_func(
additional_msg="Use the `qiskit.providers.basic_provider.GenericBackendV2` "
"class instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self, bidirectional=True):
super().__init__(
None,
Expand Down Expand Up @@ -183,6 +198,13 @@ def run(self, run_input, **options):
class FakeBackendSimple(BackendV2):
"""A fake simple backend that wraps BasicSimulator to implement run()."""

@deprecate_func(
additional_msg="Use the `qiskit.providers.basic_provider.GenericBackendV2` "
"class instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
super().__init__(
None,
Expand Down
9 changes: 8 additions & 1 deletion qiskit/providers/fake_provider/fake_job.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019.
# (C) Copyright IBM 2019, 2024.
#
# 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
Expand All @@ -19,13 +19,20 @@

from qiskit.providers import JobV1
from qiskit.providers.jobstatus import JobStatus
from qiskit.utils.deprecation import deprecate_func


class FakeJob(JobV1):
"""Fake simulator job"""

_executor = futures.ThreadPoolExecutor()

@deprecate_func(
additional_msg="Use the `qiskit.providers.JobV1` class directly instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self, backend, job_id, fn):
super().__init__(backend, job_id)
self._backend = backend
Expand Down
8 changes: 8 additions & 0 deletions qiskit/providers/fake_provider/fake_mumbai_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@
from qiskit.providers.backend import BackendV2, QubitProperties
from qiskit.providers.options import Options
from qiskit.transpiler import Target, InstructionProperties
from qiskit.utils.deprecation import deprecate_func


class FakeMumbaiFractionalCX(BackendV2):
"""A fake mumbai backend."""

@deprecate_func(
additional_msg="Use the `qiskit.providers.basic_provider.GenericBackendV2` "
"class instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
super().__init__(
name="FakeMumbaiFractionalCX",
Expand Down
30 changes: 29 additions & 1 deletion qiskit/providers/fake_provider/fake_provider.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019.
# (C) Copyright IBM 2019, 2024.
#
# 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
Expand All @@ -18,6 +18,7 @@

from qiskit.providers.provider import ProviderV1
from qiskit.providers.exceptions import QiskitBackendNotFoundError
from qiskit.utils.deprecation import deprecate_func

from .backends import *
from .fake_qasm_simulator import FakeQasmSimulator
Expand All @@ -28,6 +29,15 @@
class FakeProviderFactory:
"""Fake provider factory class."""

@deprecate_func(
additional_msg="This class has been migrated to the `qiskit_ibm_runtime` package. "
"To migrate your code, run `pip install qiskit-ibm-runtime` and "
"use `from qiskit_ibm_runtime.fake_provider import FakeProviderExample` "
"instead of `from qiskit.providers.fake_provider import FakeProviderExample`.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
self.fake_provider = FakeProvider()

Expand Down Expand Up @@ -86,6 +96,15 @@ def get_backend(self, name=None, **kwargs):
def backends(self, name=None, **kwargs):
return self._backends

@deprecate_func(
additional_msg="This class has been migrated to the `qiskit_ibm_runtime` package. "
"To migrate your code, run `pip install qiskit-ibm-runtime` and "
"use `from qiskit_ibm_runtime.fake_provider import FakeProviderExample` "
"instead of `from qiskit.providers.fake_provider import FakeProviderExample`.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
self._backends = [
FakeAlmadenV2(),
Expand Down Expand Up @@ -160,6 +179,15 @@ def get_backend(self, name=None, **kwargs):
def backends(self, name=None, **kwargs):
return self._backends

@deprecate_func(
additional_msg="This class has been migrated to the `qiskit_ibm_runtime` package. "
"To migrate your code, run `pip install qiskit-ibm-runtime` and "
"use `from qiskit_ibm_runtime.fake_provider import FakeProviderExample` "
"instead of `from qiskit.providers.fake_provider import FakeProviderExample`.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
self._backends = [
FakeAlmaden(),
Expand Down
20 changes: 19 additions & 1 deletion qiskit/providers/fake_provider/fake_pulse_backend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
# (C) Copyright IBM 2020, 2024.
#
# 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
Expand All @@ -14,6 +14,8 @@
Fake backend abstract class for mock backends supporting OpenPulse.
"""

import warnings

from qiskit.exceptions import QiskitError
from qiskit.providers.models import PulseBackendConfiguration, PulseDefaults

Expand All @@ -26,6 +28,22 @@ class FakePulseBackend(FakeQasmBackend):

defs_filename = None

def __init__(self):
super().__init__()
# This is a deprecation warning for the subclasses.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this class still used by anything in Qiskit? And, how about FakeBackendV1 which this ultimately uses as a base class? Can all of this be deprecated?

Copy link
Contributor

@kevinhartman kevinhartman Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, you're doing this in a separate PR it looks like 😄.

Or wait, are you? I'm a bit confused since I would think this file wouldn't have changes at all here since it's part of the V1 hierarchy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is confusing, but the V1 base classes (FakeBackendV1, FakePulseBackend, FakeQasmBackend) cannot be deprecated yet because they are used in the "generic" backend version too. The "fake backend alternatives" in #10952 are effectively snapshot-based fake backends with "more generic" names. This was agreed to be the best temporary alternative while BackendV1 is around, the plan is to eventually fully transition to BackendV2 but this will not happen for 1.0.

So now we have the challenge to deprecate ~45 subclasses without deprecating the base classes. This warning is only for the subclasses, and this is why I don't use the decorator here, so that the message doesn't say "FakeBackendV1 is deprecated" but "All fake backend instances based on real device snapshots...". And about the V1 hierarchy, I am taking advantage of the fact that these "V1 alternatives" to fake backends live on the main branch and the deprecations live on 0.46, so the warning would never appear on the non-deprecated alternatives.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay, thank you! I was missing that subtly 😄.

# FakePulseBackend is not deprecated.
warnings.warn(
message="All fake backend instances based on real device snapshots (`FakeVigo`,"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to have this message in the deprecation for FakeBackendV2 as well, since as it is I believe it won't tell users that the classes which inherit from FakeBackendV2 are deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the warnings locally and they show up in my environment (I also checked when running the unit tests):
Screenshot 2024-01-30 at 21 44 43

Copy link
Contributor

@kevinhartman kevinhartman Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I specifically meant the bit "All fake backend instances based on real device snapshots" might be helpful, since the user might think it's a bug otherwise to get a warning about a base class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aah sure, that makes sense

Copy link
Contributor Author

@ElePT ElePT Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually realized thanks to that screenshot that the message said "it will be removed Qiskit 1.0", so I updated the removal timeline of all the classes that were missing the "in" in 706de09.
Screenshot 2024-01-30 at 22 26 40

"`FakeSherbrooke`,...) have been migrated to the `qiskit_ibm_runtime` package. "
"These classes are deprecated as of qiskit 0.46.0 and will be removed in qiskit 1.0.0. "
"To migrate your code, run `pip install qiskit-ibm-runtime` and use "
"`from qiskit_ibm_runtime.fake_provider import FakeExample` "
"instead of `from qiskit.providers.fake_provider import FakeExample`. "
"If you are using a custom fake backend implementation, you don't need to take any action.",
category=DeprecationWarning,
stacklevel=2,
)

def defaults(self):
"""Returns a snapshot of device defaults"""
if not self._defaults:
Expand Down
16 changes: 15 additions & 1 deletion qiskit/providers/fake_provider/fake_qasm_backend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
# (C) Copyright IBM 2020, 2024.
#
# 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
Expand All @@ -16,6 +16,7 @@

import json
import os
import warnings

from qiskit.exceptions import QiskitError
from qiskit.providers.models import BackendProperties, QasmBackendConfiguration
Expand All @@ -40,6 +41,19 @@ def __init__(self):
self._defaults = None
self._properties = None
super().__init__(configuration)
# This is a deprecation warning for the subclasses.
# FakeQasmBackend is not deprecated.
warnings.warn(
message="All fake backend instances based on real device snapshots (`FakeVigo`,"
"`FakeSherbrooke`,...) have been migrated to the `qiskit_ibm_runtime` package. "
"These classes are deprecated as of qiskit 0.46.0 and will be removed in qiskit 1.0.0. "
"To migrate your code, run `pip install qiskit-ibm-runtime` and use "
"`from qiskit_ibm_runtime.fake_provider import FakeExample` "
"instead of `from qiskit.providers.fake_provider import FakeExample`. "
"If you are using a custom fake backend implementation, you don't need to take any action.",
category=DeprecationWarning,
stacklevel=2,
)

def properties(self):
"""Returns a snapshot of device properties"""
Expand Down
7 changes: 7 additions & 0 deletions qiskit/providers/fake_provider/fake_qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@
"""

from qiskit.providers.models import GateConfig, QasmBackendConfiguration
from qiskit.utils.deprecation import deprecate_func

from .fake_backend import FakeBackend


class FakeQasmSimulator(FakeBackend):
"""A fake simulator backend."""

@deprecate_func(
additional_msg="Use the `qiskit.providers.basic_provider.BasicSimulator` class instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
configuration = QasmBackendConfiguration(
backend_name="fake_qasm_simulator",
Expand Down
9 changes: 8 additions & 1 deletion qiskit/providers/fake_provider/fake_qobj.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019.
# (C) Copyright IBM 2019, 2024.
#
# 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
Expand All @@ -23,13 +23,20 @@
QasmQobjExperiment,
QasmQobjConfig,
)
from qiskit.utils.deprecation import deprecate_func

from .fake_qasm_simulator import FakeQasmSimulator


class FakeQobj(QasmQobj):
"""A fake `Qobj` instance."""

@deprecate_func(
additional_msg="Use the `qiskit.qobj.QasmQobj` class directly instead.",
since="0.46.0",
removal_timeline="Qiskit 1.0",
package_name="qiskit",
)
def __init__(self):
qobj_id = "test_id"
config = QasmQobjConfig(shots=1024, memory_slots=1)
Expand Down
7 changes: 5 additions & 2 deletions qiskit/test/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ def setUpClass(cls):
]
for msg in allow_DeprecationWarning_message:
warnings.filterwarnings("default", category=DeprecationWarning, message=msg)

allow_aer_DeprecationWarning_message = [
# This warning should be fixed once Qiskit/qiskit-aer#1761 is in a release version of Aer.
"Setting metadata to None.*",
Expand All @@ -257,11 +256,15 @@ def setUpClass(cls):
"The qiskit.extensions module is deprecated since Qiskit 0.46.0. It will be removed "
"in the Qiskit 1.0 release.",
]

for msg in allow_aer_DeprecationWarning_message:
warnings.filterwarnings(
"default", category=DeprecationWarning, module="qiskit_aer.*", message=msg
)
# Ignore fake backend deprecation warnings to avoid over-crowding the test log
ignore_fake_backend_message = r".*been migrated to the `qiskit_ibm_runtime` package.*"
warnings.filterwarnings(
"ignore", category=DeprecationWarning, message=ignore_fake_backend_message
)


class FullQiskitTestCase(QiskitTestCase):
Expand Down
Loading
Loading