From c5d4bd280fdecac13ed2c937a4862abb1c98e010 Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Thu, 1 Feb 2024 00:34:59 -0500 Subject: [PATCH 1/7] Replace qiskit.providers.basicaer test usage with qiskit-aer qiskit.providers.basicaer was removed in Qiskit 1.0. See https://github.com/Qiskit/qiskit/pull/11422 --- test/curve_analysis/test_curve_fitting.py | 4 ++-- test/library/calibration/test_rabi.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/curve_analysis/test_curve_fitting.py b/test/curve_analysis/test_curve_fitting.py index e64b5b5d65..937cd65b95 100644 --- a/test/curve_analysis/test_curve_fitting.py +++ b/test/curve_analysis/test_curve_fitting.py @@ -15,7 +15,7 @@ import numpy as np from qiskit import QuantumCircuit, transpile -from qiskit.providers.basicaer import QasmSimulatorPy +from qiskit_aer import AerSimulator from qiskit_experiments.curve_analysis import process_curve_data from qiskit_experiments.curve_analysis.utils import ( level2_probability, @@ -36,7 +36,7 @@ def simulate_experiment_data(self, thetas, shots=1024): qc.measure_all() circuits.append(qc) - sim = QasmSimulatorPy() + sim = AerSimulator() circuits = transpile(circuits, sim) job = sim.run(circuits, shots=shots, seed_simulator=10) result = job.result() diff --git a/test/library/calibration/test_rabi.py b/test/library/calibration/test_rabi.py index 962b3abd92..36df7fce9b 100644 --- a/test/library/calibration/test_rabi.py +++ b/test/library/calibration/test_rabi.py @@ -18,8 +18,8 @@ from qiskit import QuantumCircuit, pulse, transpile from qiskit.exceptions import QiskitError from qiskit.circuit import Parameter -from qiskit.providers.basicaer import QasmSimulatorPy from qiskit.qobj.utils import MeasLevel +from qiskit_aer import AerSimulator from qiskit_experiments.framework import ExperimentData, ParallelExperiment from qiskit_experiments.library import Rabi, EFRabi @@ -223,7 +223,7 @@ def simulate_experiment_data(self, thetas, amplitudes, shots=1024): qc.measure_all() circuits.append(qc) - sim = QasmSimulatorPy() + sim = AerSimulator() circuits = transpile(circuits, sim) job = sim.run(circuits, shots=shots, seed_simulator=10) result = job.result() @@ -272,7 +272,10 @@ def test_bad_analysis(self): """Test the Rabi analysis.""" experiment_data = ExperimentData() - thetas = np.linspace(0.0, np.pi / 4, 31) + # Change rotation angle with square root of amplitude so that + # population versus amplitude will not be sinusoidal and the fit will + # be bad. + thetas = np.sqrt(np.linspace(0.0, 4 * np.pi**2, 31)) amplitudes = np.linspace(0.0, 0.95, 31) experiment_data.add_data(self.simulate_experiment_data(thetas, amplitudes, shots=200)) From e2c6ec10479098abc04efc4baa7df71abd87c55c Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Thu, 1 Feb 2024 22:36:05 -0500 Subject: [PATCH 2/7] Unpin qiskit --- requirements-dev.txt | 1 - requirements.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 3594ba0434..df05d947e5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,3 @@ -qiskit==0.45.3 # Linters black~=22.0 pylint~=3.0.2 diff --git a/requirements.txt b/requirements.txt index 23690b345a..2bda6ad888 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ numpy>=1.17 scipy>=1.4 -qiskit==0.45.3 # Temporary +qiskit>=0.45 qiskit-ibm-experiment>=0.3.4 matplotlib>=3.4 uncertainties From db6f49f293ffcb5c458cb310fade2d005c833345 Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Thu, 1 Feb 2024 23:19:06 -0500 Subject: [PATCH 3/7] Use FakeJob from qiskit_experiments.test instead of Qiskit --- test/framework/test_framework.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/framework/test_framework.py b/test/framework/test_framework.py index 0d52da1d84..6d45fe2f67 100644 --- a/test/framework/test_framework.py +++ b/test/framework/test_framework.py @@ -13,17 +13,18 @@ """Tests for base experiment framework.""" import pickle +from itertools import product from test.fake_experiment import FakeExperiment, FakeAnalysis from test.base import QiskitExperimentsTestCase -from itertools import product + import ddt from qiskit import QuantumCircuit -from qiskit.providers.fake_provider import FakeJob from qiskit.providers.jobstatus import JobStatus from qiskit.exceptions import QiskitError from qiskit_ibm_runtime.fake_provider import FakeVigoV2 +from qiskit_experiments.database_service import Qubit from qiskit_experiments.exceptions import AnalysisError from qiskit_experiments.framework import ( ExperimentData, @@ -33,7 +34,7 @@ AnalysisStatus, ) from qiskit_experiments.test.fake_backend import FakeBackend -from qiskit_experiments.database_service import Qubit +from qiskit_experiments.test.utils import FakeJob @ddt.ddt @@ -287,7 +288,7 @@ class MyBackend(FakeVigoV2): """A backend that works with `MyJob`""" def run(self, run_input, **options): - return MyJob(self, "jobid", None) + return MyJob(self) class MyJob(FakeJob): """A job with status ERROR, that errors when the result is queried""" From 08ea54c4c41dd477619845961e4d1f04ffe12c89 Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Fri, 2 Feb 2024 00:33:51 -0500 Subject: [PATCH 4/7] Switch from plot_histogram to plot_distribution in experiment manual --- docs/manuals/measurement/readout_mitigation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/manuals/measurement/readout_mitigation.rst b/docs/manuals/measurement/readout_mitigation.rst index 8fa861a4ff..418e7c7be4 100644 --- a/docs/manuals/measurement/readout_mitigation.rst +++ b/docs/manuals/measurement/readout_mitigation.rst @@ -40,7 +40,7 @@ experiments to generate the corresponding mitigators. import numpy as np import matplotlib.pyplot as plt from qiskit import QuantumCircuit - from qiskit.visualization import plot_histogram + from qiskit.visualization import plot_distribution from qiskit_experiments.library import LocalReadoutError, CorrelatedReadoutError from qiskit_aer import AerSimulator @@ -128,7 +128,7 @@ Probabilities .. jupyter-execute:: legend = ['Mitigated Probabilities', 'Unmitigated Probabilities'] - plot_histogram([mitigated_probs, unmitigated_probs], legend=legend, sort="value_desc", bar_labels=False) + plot_distribution([mitigated_probs, unmitigated_probs], legend=legend, sort="value_desc", bar_labels=False) Expectation value From 1c110e7997b47137515fb0a8eb925793a141858b Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Sat, 3 Feb 2024 00:05:45 -0500 Subject: [PATCH 5/7] Handle deprecation of FakeBackendV2 in Qiskit 1.0 --- qiskit_experiments/framework/backend_data.py | 37 ++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/qiskit_experiments/framework/backend_data.py b/qiskit_experiments/framework/backend_data.py index 93ed671d6d..90e8910100 100644 --- a/qiskit_experiments/framework/backend_data.py +++ b/qiskit_experiments/framework/backend_data.py @@ -17,7 +17,38 @@ class unifies data access for various data fields. """ from qiskit.providers.models import PulseBackendConfiguration from qiskit.providers import BackendV1, BackendV2 -from qiskit.providers.fake_provider import fake_backend, FakeBackendV2, FakeBackend +from qiskit.providers.fake_provider import FakeBackendV2, FakeBackend + +# One of the FakeBackendV2's was moved from qiskit to qiskit-ibm-runtime. Check +# both packages until dropping support for qiskit<1 +try: + from qiskit.providers.fake_provider.fake_backend import FakeBackendV2 as QiskitFakeBackendV2 +except ImportError: + + class QiskitFakeBackendV2: + """Dummy class for when FakeBackendV2 import fails + + This class is only used in isinstance checks. If the import fails, then + there won't be an instance of the class either so any dummy class is + fine. + """ + + pass + + +try: + from qiskit_ibm_runtime.fake_provider.fake_backend import FakeBackendV2 as RuntimeFakeBackendV2 +except ImportError: + + class RuntimeFakeBackendV2: + """Dummy class for when FakeBackendV2 import fails + + This class is only used in isinstance checks. If the import fails, then + there won't be an instance of the class either so any dummy class is + fine. + """ + + pass class BackendData: @@ -255,7 +286,9 @@ def is_simulator(self): if self._backend.configuration().simulator or isinstance(self._backend, FakeBackend): return True if self._v2: - if isinstance(self._backend, (FakeBackendV2, fake_backend.FakeBackendV2)): + if isinstance( + self._backend, (FakeBackendV2, QiskitFakeBackendV2, RuntimeFakeBackendV2) + ): return True return False From f958426616cf68151bd81f70e83bc9c2d0ea383f Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Sat, 3 Feb 2024 00:44:45 -0500 Subject: [PATCH 6/7] Guard the right FakeBackendV2 import --- qiskit_experiments/framework/backend_data.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/qiskit_experiments/framework/backend_data.py b/qiskit_experiments/framework/backend_data.py index 90e8910100..c5d420d24c 100644 --- a/qiskit_experiments/framework/backend_data.py +++ b/qiskit_experiments/framework/backend_data.py @@ -17,12 +17,12 @@ class unifies data access for various data fields. """ from qiskit.providers.models import PulseBackendConfiguration from qiskit.providers import BackendV1, BackendV2 -from qiskit.providers.fake_provider import FakeBackendV2, FakeBackend +from qiskit.providers.fake_provider import FakeBackend +from qiskit.providers.fake_provider.fake_backend import FakeBackendV2 -# One of the FakeBackendV2's was moved from qiskit to qiskit-ibm-runtime. Check -# both packages until dropping support for qiskit<1 try: - from qiskit.providers.fake_provider.fake_backend import FakeBackendV2 as QiskitFakeBackendV2 + # Removed in Qiskit 1.0. Different from the other FakeBackendV2's + from qiskit.providers.fake_provider import FakeBackendV2 except ImportError: class QiskitFakeBackendV2: @@ -37,6 +37,8 @@ class QiskitFakeBackendV2: try: + # A copy of qiskit.providers.fake_provider.fake_backend.FakeBackendV2, at + # least as of qiskit-ibm-runtime 0.18.0 and Qiskit 1.0 from qiskit_ibm_runtime.fake_provider.fake_backend import FakeBackendV2 as RuntimeFakeBackendV2 except ImportError: From 45480bc52181f608c5f997c507ec161ce01d5a4b Mon Sep 17 00:00:00 2001 From: Will Shanks Date: Sat, 3 Feb 2024 01:35:36 -0500 Subject: [PATCH 7/7] Use internal FakeProvider in place of one removed in Qiskit 1.0 --- qiskit_experiments/framework/backend_data.py | 2 +- qiskit_experiments/test/fake_backend.py | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/qiskit_experiments/framework/backend_data.py b/qiskit_experiments/framework/backend_data.py index c5d420d24c..3d4e91eb92 100644 --- a/qiskit_experiments/framework/backend_data.py +++ b/qiskit_experiments/framework/backend_data.py @@ -22,7 +22,7 @@ class unifies data access for various data fields. try: # Removed in Qiskit 1.0. Different from the other FakeBackendV2's - from qiskit.providers.fake_provider import FakeBackendV2 + from qiskit.providers.fake_provider import QiskitFakeBackendV2 except ImportError: class QiskitFakeBackendV2: diff --git a/qiskit_experiments/test/fake_backend.py b/qiskit_experiments/test/fake_backend.py index 3918cca70b..0fcf06f626 100644 --- a/qiskit_experiments/test/fake_backend.py +++ b/qiskit_experiments/test/fake_backend.py @@ -13,8 +13,8 @@ """Fake backend class for tests.""" import uuid from qiskit.circuit.library import Measure +from qiskit.providers import ProviderV1 from qiskit.providers.backend import BackendV2 -from qiskit.providers.fake_provider import FakeProvider from qiskit.providers.options import Options from qiskit.transpiler import Target @@ -23,6 +23,14 @@ from qiskit_experiments.test.utils import FakeJob +class FakeProvider(ProviderV1): + """Fake provider with no backends for testing""" + + def backends(self, name=None, **kwargs): + """List of available backends. Empty in this case""" + return [] + + class FakeBackend(BackendV2): """ Fake backend for test purposes only.