diff --git a/qiskit/__init__.py b/qiskit/__init__.py index 20f2e3c80851..456205d82d89 100644 --- a/qiskit/__init__.py +++ b/qiskit/__init__.py @@ -102,34 +102,32 @@ def __init__(self): def __bool__(self): if self.aer is None: + warnings.warn( + "The 'qiskit.Aer' entry point is deprecated and will be removed in Qiskit 1.0." + " You should use 'qiskit_aer.Aer' directly instead.", + DeprecationWarning, + stacklevel=2, + ) try: - from qiskit.providers import aer - - self.aer = aer.Aer - warnings.warn( - "The qiskit.Aer entry point will be deprecated in a future release and " - "subsequently removed. Instead you should use this " - "directly from the root of the qiskit-aer package.", - PendingDeprecationWarning, - stacklevel=2, - ) + import qiskit_aer + + self.aer = qiskit_aer.Aer except ImportError: return False return True def __getattr__(self, attr): if not self.aer: + warnings.warn( + "The 'qiskit.Aer' entry point is deprecated and will be removed in Qiskit 1.0." + " You should use 'qiskit_aer.Aer' directly instead.", + DeprecationWarning, + stacklevel=2, + ) try: - from qiskit.providers import aer - - self.aer = aer.Aer - warnings.warn( - "The qiskit.Aer entry point will be deprecated in a future release and " - "subsequently removed. Instead you should use this " - "directly from the root of the qiskit-aer package.", - PendingDeprecationWarning, - stacklevel=2, - ) + import qiskit_aer + + self.aer = qiskit_aer.Aer except ImportError as ex: raise MissingOptionalLibraryError( "qiskit-aer", "Aer provider", "pip install qiskit-aer" @@ -145,40 +143,39 @@ def __init__(self): def __bool__(self): if self.ibmq is None: + warnings.warn( + "The qiskit.IBMQ entrypoint and the qiskit-ibmq-provider package (" + "accessible from 'qiskit.providers.ibmq`) are deprecated and will be removed " + "in a future release. Instead you should use the qiskit-ibm-provider package " + "which is accessible from 'qiskit_ibm_provider'. You can install it with " + "'pip install qiskit_ibm_provider'", + DeprecationWarning, + stacklevel=2, + ) try: from qiskit.providers import ibmq self.ibmq = ibmq.IBMQ - warnings.warn( - "The qiskit.IBMQ entrypoint and the qiskit-ibmq-provider package (" - "accessible from 'qiskit.providers.ibmq`) are deprecated and will be removed " - "in a future release. Instead you should use the qiskit-ibm-provider package " - "which is accessible from 'qiskit_ibm_provider'. You can install it with " - "'pip install qiskit_ibm_provider'", - DeprecationWarning, - stacklevel=2, - ) - except ImportError: return False return True def __getattr__(self, attr): if not self.ibmq: + warnings.warn( + "The qiskit.IBMQ entrypoint and the qiskit-ibmq-provider package (" + "accessible from 'qiskit.providers.ibmq`) are deprecated and will be removed " + "in a future release. Instead you should use the qiskit-ibm-provider package " + "which is accessible from 'qiskit_ibm_provider'. You can install it with " + "'pip install qiskit_ibm_provider'. Just replace 'qiskit.IBMQ' with " + "'qiskit_ibm_provider.IBMProvider'", + DeprecationWarning, + stacklevel=2, + ) try: from qiskit.providers import ibmq self.ibmq = ibmq.IBMQ - warnings.warn( - "The qiskit.IBMQ entrypoint and the qiskit-ibmq-provider package (" - "accessible from 'qiskit.providers.ibmq`) are deprecated and will be removed " - "in a future release. Instead you should use the qiskit-ibm-provider package " - "which is accessible from 'qiskit_ibm_provider'. You can install it with " - "'pip install qiskit_ibm_provider'. Just replace 'qiskit.IBMQ' with " - "'qiskit_ibm_provider.IBMProvider'", - DeprecationWarning, - stacklevel=2, - ) except ImportError as ex: raise MissingOptionalLibraryError( "qiskit-ibmq-provider", "IBMQ provider", "pip install qiskit-ibmq-provider" diff --git a/qiskit/algorithms/optimizers/umda.py b/qiskit/algorithms/optimizers/umda.py index edea27939ade..30df031c8288 100644 --- a/qiskit/algorithms/optimizers/umda.py +++ b/qiskit/algorithms/optimizers/umda.py @@ -73,7 +73,7 @@ class UMDA(Optimizer): .. code-block:: python from qiskit.opflow import X, Z, I - from qiskit import Aer + from qiskit_aer import Aer from qiskit.algorithms.optimizers import UMDA from qiskit.algorithms import QAOA from qiskit.utils import QuantumInstance diff --git a/qiskit/namespace.py b/qiskit/namespace.py index c33d637258bc..dfa62fa93013 100644 --- a/qiskit/namespace.py +++ b/qiskit/namespace.py @@ -17,6 +17,7 @@ import sys from importlib.abc import MetaPathFinder, Loader import importlib +import warnings def _new_namespace(fullname, old_namespace, new_package): @@ -34,6 +35,12 @@ def __init__(self, new_package, old_namespace): super().__init__() self.new_package = new_package self.old_namespace = old_namespace + warnings.warn( + f"Importing from '{self.old_namespace}' is deprecated." + f" Import from '{self.new_package}' instead, which should work identically.", + category=DeprecationWarning, + stacklevel=3, + ) def module_repr(self, module): return repr(module) diff --git a/qiskit/opflow/expectations/aer_pauli_expectation.py b/qiskit/opflow/expectations/aer_pauli_expectation.py index 6eaa77d3d644..bb4e3f015315 100644 --- a/qiskit/opflow/expectations/aer_pauli_expectation.py +++ b/qiskit/opflow/expectations/aer_pauli_expectation.py @@ -90,7 +90,7 @@ def convert(self, operator: OperatorBase) -> OperatorBase: @classmethod def _replace_pauli_sums(cls, operator): try: - from qiskit.providers.aer.library import SaveExpectationValue + from qiskit_aer.library import SaveExpectationValue except ImportError as ex: raise MissingOptionalLibraryError( libname="qiskit-aer", diff --git a/qiskit/providers/fake_provider/__init__.py b/qiskit/providers/fake_provider/__init__.py index 943869114f85..35e768a7debc 100644 --- a/qiskit/providers/fake_provider/__init__.py +++ b/qiskit/providers/fake_provider/__init__.py @@ -71,7 +71,7 @@ .. code-block:: python from qiskit.providers.ibmq import IBMQ - from qiskit.providers.aer import AerSimulator + from qiskit_aer import AerSimulator # get a real backend from a real provider provider = IBMQ.load_account() diff --git a/qiskit/providers/fake_provider/fake_backend.py b/qiskit/providers/fake_provider/fake_backend.py index e1740368884c..2963639a86a1 100644 --- a/qiskit/providers/fake_provider/fake_backend.py +++ b/qiskit/providers/fake_provider/fake_backend.py @@ -118,9 +118,9 @@ def _parse_channels(self, channels): def _setup_sim(self): if _optionals.HAS_AER: - from qiskit.providers import aer + import qiskit_aer - self.sim = aer.AerSimulator() + self.sim = qiskit_aer.AerSimulator() if self.target and self._props_dict: noise_model = self._get_noise_model_from_backend_v2() self.sim.set_options(noise_model=noise_model) @@ -200,9 +200,9 @@ def _default_options(cls): default values set """ if _optionals.HAS_AER: - from qiskit.providers import aer + import qiskit_aer - return aer.AerSimulator._default_options() + return qiskit_aer.AerSimulator._default_options() else: return basicaer.QasmSimulatorPy._default_options() @@ -376,13 +376,13 @@ def _get_noise_model_from_backend_v2( from qiskit.circuit import Delay from qiskit.providers.exceptions import BackendPropertyError - from qiskit.providers.aer.noise import NoiseModel - from qiskit.providers.aer.noise.device.models import ( + from qiskit_aer.noise import NoiseModel + from qiskit_aer.noise.device.models import ( _excited_population, basic_device_gate_errors, basic_device_readout_errors, ) - from qiskit.providers.aer.noise.passes import RelaxationNoisePass + from qiskit_aer.noise.passes import RelaxationNoisePass if self._props_dict is None: self._set_props_dict_from_json() @@ -403,7 +403,7 @@ def _get_noise_model_from_backend_v2( with warnings.catch_warnings(): warnings.filterwarnings( "ignore", - module="qiskit.providers.aer.noise.device.models", + module="qiskit_aer.noise.device.models", ) gate_errors = basic_device_gate_errors( properties, @@ -459,10 +459,10 @@ def __init__(self, configuration, time_alive=10): def _setup_sim(self): if _optionals.HAS_AER: - from qiskit.providers import aer - from qiskit.providers.aer.noise import NoiseModel + import qiskit_aer + from qiskit_aer.noise import NoiseModel - self.sim = aer.AerSimulator() + self.sim = qiskit_aer.AerSimulator() if self.properties(): noise_model = NoiseModel.from_backend(self) self.sim.set_options(noise_model=noise_model) @@ -527,9 +527,9 @@ def properties(self): @classmethod def _default_options(cls): if _optionals.HAS_AER: - from qiskit.providers import aer + from qiskit_aer import QasmSimulator - return aer.QasmSimulator._default_options() + return QasmSimulator._default_options() else: return basicaer.QasmSimulatorPy._default_options() @@ -553,12 +553,20 @@ def run(self, run_input, **kwargs): "QuantumCircuit, Schedule, or a list of either" % circuits ) if pulse_job: + warnings.warn( + "Simulating pulse jobs on fake backends is deprecated as of Qiskit 0.46," + " and the functionality will be removed in Qiskit 1.0, due to Qiskit Aer removing" + " its pulse-simulation capabilities in its most recent versions." + " You can try using Qiskit Dynamics instead.", + DeprecationWarning, + stacklevel=2, + ) if _optionals.HAS_AER: - from qiskit.providers import aer - from qiskit.providers.aer.pulse import PulseSystemModel + import qiskit_aer + from qiskit_aer.pulse import PulseSystemModel system_model = PulseSystemModel.from_backend(self) - sim = aer.Aer.get_backend("pulse_simulator") + sim = qiskit_aer.Aer.get_backend("pulse_simulator") job = sim.run(circuits, system_model=system_model, **kwargs) else: raise QiskitError("Unable to run pulse schedules without qiskit-aer installed") diff --git a/qiskit/test/decorators.py b/qiskit/test/decorators.py index a15ab9ccc361..2f1ed064f201 100644 --- a/qiskit/test/decorators.py +++ b/qiskit/test/decorators.py @@ -17,11 +17,10 @@ import functools import os import socket -import sys from typing import Union, Callable, Type, Iterable import unittest -from qiskit.utils import wrap_method +from qiskit.utils import wrap_method, optionals from .testing_options import get_test_options HAS_NET_CONNECTION = None @@ -55,14 +54,7 @@ def is_aer_provider_available(): Returns: bool: True if simulator executable is available """ - # TODO: HACK FROM THE DEPTHS OF DESPAIR AS AER DOES NOT WORK ON MAC - if sys.platform == "darwin": - return False - try: - import qiskit.providers.aer # pylint: disable=unused-import - except ImportError: - return False - return True + return bool(optionals.HAS_AER) def requires_aer_provider(test_item): diff --git a/qiskit/utils/backend_utils.py b/qiskit/utils/backend_utils.py index cdce30da8dc6..13706084696b 100644 --- a/qiskit/utils/backend_utils.py +++ b/qiskit/utils/backend_utils.py @@ -14,6 +14,7 @@ import logging from qiskit.utils.deprecation import deprecate_func +from qiskit.utils import optionals logger = logging.getLogger(__name__) @@ -79,18 +80,7 @@ def has_ibmq(): ) def has_aer(): """Check if Aer is installed.""" - if not _PROVIDER_CHECK.checked_aer: - try: - from qiskit.providers.aer import AerProvider - - _PROVIDER_CHECK.has_aer = True - except Exception as ex: # pylint: disable=broad-except - _PROVIDER_CHECK.has_aer = False - logger.debug("AerProvider not loaded: '%s'", str(ex)) - - _PROVIDER_CHECK.checked_aer = True - - return _PROVIDER_CHECK.has_aer + return bool(optionals.HAS_AER) @deprecate_func( @@ -107,11 +97,11 @@ def is_aer_provider(backend): bool: True is AerProvider """ if has_aer(): - from qiskit.providers.aer import AerProvider + from qiskit_aer import AerProvider if isinstance(_get_backend_provider(backend), AerProvider): return True - from qiskit.providers.aer.backends.aerbackend import AerBackend + from qiskit_aer.backends.aerbackend import AerBackend return isinstance(backend, AerBackend) @@ -192,7 +182,7 @@ def is_statevector_backend(backend): return False backend_interface_version = _get_backend_interface_version(backend) if has_aer(): - from qiskit.providers.aer.backends import AerSimulator, StatevectorSimulator + from qiskit_aer.backends import AerSimulator, StatevectorSimulator if isinstance(backend, StatevectorSimulator): return True diff --git a/qiskit/utils/optionals.py b/qiskit/utils/optionals.py index 07dc6e4376e5..ba0b8d8fc1f2 100644 --- a/qiskit/utils/optionals.py +++ b/qiskit/utils/optionals.py @@ -29,16 +29,16 @@ :widths: 25 75 * - .. py:data:: HAS_AER - - :mod:`Qiskit Aer ` provides high-performance simulators for the - quantum circuits constructed within Qiskit. + - `Qiskit Aer `__ provides high-performance simulators for + the quantum circuits constructed within Qiskit. * - .. py:data:: HAS_IBMQ - - The :mod:`Qiskit IBMQ Provider ` is used for accessing IBM Quantum - hardware in the IBM cloud. + - The Qiskit IBMQ Provider was historically used for accessing IBM Quantum hardware in the IBM + cloud, but is now deprecated. * - .. py:data:: HAS_IGNIS - - :mod:`Qiskit Ignis ` provides tools for quantum hardware verification, noise - characterization, and error correction. + - Qiskit Ignis provided tools for quantum hardware verification, noise characterization, and + error correction, but is now deprecated. * - .. py:data:: HAS_TOQM - `Qiskit TOQM `__ provides transpiler passes @@ -224,7 +224,7 @@ _logger = _logging.getLogger(__name__) HAS_AER = _LazyImportTester( - "qiskit.providers.aer", + "qiskit_aer", name="Qiskit Aer", install="pip install qiskit-aer", ) diff --git a/qiskit/utils/quantum_instance.py b/qiskit/utils/quantum_instance.py index f27050782fa5..1a4c50d8701d 100644 --- a/qiskit/utils/quantum_instance.py +++ b/qiskit/utils/quantum_instance.py @@ -502,7 +502,7 @@ def execute(self, circuits, had_transpiled: bool = False): if self.is_statevector and "aer_simulator_statevector" in self.backend_name: try: - from qiskit.providers.aer.library import SaveStatevector + from qiskit_aer.library import SaveStatevector def _find_save_state(data): for instruction in reversed(data): diff --git a/qiskit/version.py b/qiskit/version.py index 79cadf189742..bd112de545ea 100644 --- a/qiskit/version.py +++ b/qiskit/version.py @@ -109,11 +109,9 @@ def _load_versions(self): stacklevel=3, ) try: - # TODO: Update to use qiskit_aer instead when we remove the - # namespace redirect - from qiskit.providers import aer + import qiskit_aer - self._version_dict["qiskit-aer"] = aer.__version__ + self._version_dict["qiskit-aer"] = qiskit_aer.__version__ except Exception: self._version_dict["qiskit-aer"] = None try: diff --git a/releasenotes/notes/deprecate-aer-hooks-1bc00a96ebb269f6.yaml b/releasenotes/notes/deprecate-aer-hooks-1bc00a96ebb269f6.yaml new file mode 100644 index 000000000000..1b5227d6b459 --- /dev/null +++ b/releasenotes/notes/deprecate-aer-hooks-1bc00a96ebb269f6.yaml @@ -0,0 +1,14 @@ +--- +deprecations: + - | + Use of the :attr:`qiskit.Aer` object is deprecated and will be removed in Qiskit 1.0. You + should instead use the same object from the ``qiskit_aer`` namespace, which is a drop-in + replacement. + - | + Importing from ``qiskit.providers.aer`` is deprecated and will stop working in Qiskit 1.0. You + should instead import from ``qiskit_aer``, which is a drop-in replacement. + - | + Running pulse jobs on backends from :mod:`qiskit.providers.fake_provider` is deprecated, and + all support will be removed in Qiskit 1.0. This is due to Qiskit Aer removing its simulation + functionality for such jobs. For low-level Hamiltonain-simulation workloads, consider using + a specialised library such as `Qiskit Dynamics `__. diff --git a/test/python/algorithms/test_backendv1.py b/test/python/algorithms/test_backendv1.py index d0a544834c72..d050399ad728 100644 --- a/test/python/algorithms/test_backendv1.py +++ b/test/python/algorithms/test_backendv1.py @@ -100,7 +100,7 @@ def test_run_circuit_oracle_single_experiment_backend(self): def test_measurement_error_mitigation_with_vqe(self): """measurement error mitigation test with vqe""" try: - from qiskit.providers.aer import noise + from qiskit_aer import noise except ImportError as ex: self.skipTest(f"Package doesn't appear to be installed. Error: '{str(ex)}'") return diff --git a/test/python/algorithms/test_measure_error_mitigation.py b/test/python/algorithms/test_measure_error_mitigation.py index ed9e972c524e..772f06007e13 100644 --- a/test/python/algorithms/test_measure_error_mitigation.py +++ b/test/python/algorithms/test_measure_error_mitigation.py @@ -31,16 +31,16 @@ from qiskit.utils.measurement_error_mitigation import build_measurement_error_mitigation_circuits from qiskit.utils import optionals -if optionals.HAS_AER: - # pylint: disable=no-name-in-module - from qiskit import Aer - from qiskit.providers.aer import noise if optionals.HAS_IGNIS: # pylint: disable=no-name-in-module from qiskit.ignis.mitigation.measurement import ( CompleteMeasFitter as CompleteMeasFitter_IG, TensoredMeasFitter as TensoredMeasFitter_IG, ) +if optionals.HAS_AER: + # pylint: disable=no-name-in-module + from qiskit_aer import Aer + from qiskit_aer import noise @ddt diff --git a/test/python/algorithms/test_skip_qobj_validation.py b/test/python/algorithms/test_skip_qobj_validation.py index 4ebf8a0fb7b0..10ae37e8a2a6 100644 --- a/test/python/algorithms/test_skip_qobj_validation.py +++ b/test/python/algorithms/test_skip_qobj_validation.py @@ -106,7 +106,7 @@ def test_w_noise(self): # build noise model # Asymmetric readout error on qubit-0 only try: - from qiskit.providers.aer.noise import NoiseModel + from qiskit_aer.noise import NoiseModel from qiskit_aer import Aer self.backend = Aer.get_backend("qasm_simulator") diff --git a/test/python/algorithms/test_vqd.py b/test/python/algorithms/test_vqd.py index e153ba50ddb7..f33dac82b6b5 100644 --- a/test/python/algorithms/test_vqd.py +++ b/test/python/algorithms/test_vqd.py @@ -46,7 +46,7 @@ if has_aer(): - from qiskit import Aer + from qiskit_aer import Aer @ddt diff --git a/test/python/opflow/test_state_op_meas_evals.py b/test/python/opflow/test_state_op_meas_evals.py index e6d23390ea78..e4a59fefa7ec 100644 --- a/test/python/opflow/test_state_op_meas_evals.py +++ b/test/python/opflow/test_state_op_meas_evals.py @@ -67,7 +67,7 @@ def test_wf_evals_x(self): def test_coefficients_correctly_propagated(self): """Test that the coefficients in SummedOp and states are correctly used.""" try: - from qiskit.providers.aer import Aer + from qiskit_aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return @@ -95,7 +95,7 @@ def test_coefficients_correctly_propagated(self): def test_is_measurement_correctly_propagated(self): """Test if is_measurement property of StateFn is propagated to converted StateFn.""" try: - from qiskit.providers.aer import Aer + from qiskit_aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return @@ -110,7 +110,7 @@ def test_is_measurement_correctly_propagated(self): def test_parameter_binding_on_listop(self): """Test passing a ListOp with differing parameters works with the circuit sampler.""" try: - from qiskit.providers.aer import Aer + from qiskit_aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return @@ -146,7 +146,7 @@ def test_list_op_eval_coeff_with_nonlinear_combofn(self): def test_single_parameter_binds(self): """Test passing parameter binds as a dictionary to the circuit sampler.""" try: - from qiskit.providers.aer import Aer + from qiskit_aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return @@ -166,7 +166,7 @@ def test_single_parameter_binds(self): def test_circuit_sampler_caching(self, caching): """Test caching all operators works.""" try: - from qiskit.providers.aer import Aer + from qiskit_aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return @@ -219,7 +219,7 @@ def test_evaluating_nonunitary_circuit_state(self): def test_quantum_instance_with_backend_shots(self): """Test sampling a circuit where the backend has shots attached.""" try: - from qiskit.providers.aer import AerSimulator + from qiskit_aer import AerSimulator except Exception as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") diff --git a/test/python/transpiler/test_sabre_swap.py b/test/python/transpiler/test_sabre_swap.py index aaa84257d490..ca2a4ab24333 100644 --- a/test/python/transpiler/test_sabre_swap.py +++ b/test/python/transpiler/test_sabre_swap.py @@ -251,7 +251,7 @@ def test_no_infinite_loop(self, method): if not optionals.HAS_AER: return - from qiskit import Aer + from qiskit_aer import Aer sim = Aer.get_backend("aer_simulator") in_results = sim.run(qc, shots=4096).result().get_counts() diff --git a/tools/find_optional_imports.py b/tools/find_optional_imports.py index 5ee23c882d2d..7ddb2b6602f8 100755 --- a/tools/find_optional_imports.py +++ b/tools/find_optional_imports.py @@ -29,6 +29,7 @@ def _main(): "ipywidgets", "scipy.stats", "matplotlib", + "qiskit_aer", "qiskit.providers.aer", "qiskit.providers.ibmq", "qiskit.ignis",