From 4f4e87df928a297a795c0c5c08be5bfa63dab705 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 4 Dec 2023 20:04:35 +0200 Subject: [PATCH 01/15] Added restless configuration to finalize. --- .../framework/restless_mixin.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/qiskit_experiments/framework/restless_mixin.py b/qiskit_experiments/framework/restless_mixin.py index 19d65c238f..c2f8b94506 100644 --- a/qiskit_experiments/framework/restless_mixin.py +++ b/qiskit_experiments/framework/restless_mixin.py @@ -61,16 +61,56 @@ class makes it easy to determine if restless measurements are supported for a gi analysis: BaseAnalysis _default_run_options: Options() + run_options: Options() set_run_options: Callable _backend: Backend _physical_qubits: Sequence[int] _num_qubits: int + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # self._enable_restless = False + self.rep_delay = None + self.override_processor_by_restless = None + self.suppress_t1_error = None + def enable_restless( self, rep_delay: Optional[float] = None, override_processor_by_restless: bool = True, suppress_t1_error: bool = False, + ): + """ + Set a flag to enable restless configuration when running the experiment. + + Args: + rep_delay: The repetition delay. This is the delay between a measurement + and the subsequent quantum circuit. Since the backends have + dynamic repetition rates, the repetition delay can be set to a small + value which is required for restless experiments. Typical values are + 1 us or less. + override_processor_by_restless: If False, a data processor that is specified in the + analysis options of the experiment is not overridden by the restless data + processor. The default is True. + suppress_t1_error: If True, the default is False, then no error will be raised when + ``rep_delay`` is larger than the T1 times of the qubits. Instead, a warning will + be logged as restless measurements may have a large amount of noise. + + """ + + self.set_run_options(restless=True) + if rep_delay: + self.rep_delay = rep_delay + if override_processor_by_restless: + self.override_processor_by_restless = override_processor_by_restless + if suppress_t1_error: + self.suppress_t1_error = suppress_t1_error + + def _enable_restless( + self, + rep_delay: Optional[float] = None, + override_processor_by_restless: bool = True, + suppress_t1_error: bool = False, ): """Enables a restless experiment by setting the restless run options and the restless data processor. @@ -98,6 +138,7 @@ def enable_restless( T1 time of one of the physical qubits in the experiment and the flag ``ignore_t1_check`` is False. """ + LOG.debug("Enabling restless configuration. This will override current configuration. ") try: if not rep_delay: # BackendV1 only; BackendV2 does not support this @@ -218,3 +259,12 @@ def _t1_check(self, rep_delay: float) -> bool: ) from error return False + + def _finalize(self): + if self.run_options.get("restless", None): + self._enable_restless( + rep_delay=self.rep_delay, + override_processor_by_restless=self.override_processor_by_restless, + suppress_t1_error=self.suppress_t1_error, + ) + super()._finalize() From 562133d203d381a518b985f1757694e84ad7f35e Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 4 Dec 2023 20:04:54 +0200 Subject: [PATCH 02/15] Changed inheritance order --- qiskit_experiments/library/characterization/rabi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_experiments/library/characterization/rabi.py b/qiskit_experiments/library/characterization/rabi.py index 9193b22dd5..26bf83ea6f 100644 --- a/qiskit_experiments/library/characterization/rabi.py +++ b/qiskit_experiments/library/characterization/rabi.py @@ -27,7 +27,7 @@ from qiskit_experiments.curve_analysis import ParameterRepr, OscillationAnalysis -class Rabi(BaseExperiment, RestlessMixin): +class Rabi(RestlessMixin, BaseExperiment): r"""An experiment that scans a pulse amplitude to calibrate rotations on the :math:`|0\rangle` <-> :math:`|1\rangle` transition. From b65da5e46c3778dbb17da3a3bced119de08b2dcc Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 4 Dec 2023 20:05:15 +0200 Subject: [PATCH 03/15] added restless option to base experiment. --- qiskit_experiments/framework/base_experiment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_experiments/framework/base_experiment.py b/qiskit_experiments/framework/base_experiment.py index 41240df41c..3768797646 100644 --- a/qiskit_experiments/framework/base_experiment.py +++ b/qiskit_experiments/framework/base_experiment.py @@ -451,7 +451,7 @@ def set_transpile_options(self, **fields): @classmethod def _default_run_options(cls) -> Options: """Default options values for the experiment :meth:`run` method.""" - return Options(meas_level=MeasLevel.CLASSIFIED) + return Options(meas_level=MeasLevel.CLASSIFIED, restless=False) @property def run_options(self) -> Options: From 1fb45ce6fdbd6c05988b7f05ea3fc7b963cd7c5d Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 4 Dec 2023 20:29:25 +0200 Subject: [PATCH 04/15] Changed inheritance order in restless experiments --- qiskit_experiments/library/characterization/drag.py | 2 +- qiskit_experiments/library/characterization/fine_amplitude.py | 2 +- qiskit_experiments/library/characterization/fine_drag.py | 2 +- qiskit_experiments/library/characterization/ramsey_xy.py | 2 +- .../library/randomized_benchmarking/standard_rb.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qiskit_experiments/library/characterization/drag.py b/qiskit_experiments/library/characterization/drag.py index fb48add906..cfede2197d 100644 --- a/qiskit_experiments/library/characterization/drag.py +++ b/qiskit_experiments/library/characterization/drag.py @@ -26,7 +26,7 @@ from qiskit_experiments.library.characterization.analysis import DragCalAnalysis -class RoughDrag(BaseExperiment, RestlessMixin): +class RoughDrag(RestlessMixin, BaseExperiment): r"""An experiment that scans the DRAG parameter to find the optimal value. # section: overview diff --git a/qiskit_experiments/library/characterization/fine_amplitude.py b/qiskit_experiments/library/characterization/fine_amplitude.py index 7cf32a6138..8be9c79834 100644 --- a/qiskit_experiments/library/characterization/fine_amplitude.py +++ b/qiskit_experiments/library/characterization/fine_amplitude.py @@ -25,7 +25,7 @@ from qiskit_experiments.library.characterization.analysis import FineAmplitudeAnalysis -class FineAmplitude(BaseExperiment, RestlessMixin): +class FineAmplitude(RestlessMixin, BaseExperiment): r"""An experiment to determine the optimal pulse amplitude by amplifying gate errors. # section: overview diff --git a/qiskit_experiments/library/characterization/fine_drag.py b/qiskit_experiments/library/characterization/fine_drag.py index 668fdec8d1..64b5ad56a0 100644 --- a/qiskit_experiments/library/characterization/fine_drag.py +++ b/qiskit_experiments/library/characterization/fine_drag.py @@ -24,7 +24,7 @@ from qiskit_experiments.curve_analysis.standard_analysis import ErrorAmplificationAnalysis -class FineDrag(BaseExperiment, RestlessMixin): +class FineDrag(RestlessMixin, BaseExperiment): r"""An experiment that performs fine characterizations of DRAG pulse coefficients. # section: overview diff --git a/qiskit_experiments/library/characterization/ramsey_xy.py b/qiskit_experiments/library/characterization/ramsey_xy.py index 3a4046253e..f8c0760e62 100644 --- a/qiskit_experiments/library/characterization/ramsey_xy.py +++ b/qiskit_experiments/library/characterization/ramsey_xy.py @@ -34,7 +34,7 @@ import sympy as sym -class RamseyXY(BaseExperiment, RestlessMixin): +class RamseyXY(RestlessMixin, BaseExperiment): r"""A sign-sensitive experiment to measure the frequency of a qubit. # section: overview diff --git a/qiskit_experiments/library/randomized_benchmarking/standard_rb.py b/qiskit_experiments/library/randomized_benchmarking/standard_rb.py index e87091fd3f..668bdd5260 100644 --- a/qiskit_experiments/library/randomized_benchmarking/standard_rb.py +++ b/qiskit_experiments/library/randomized_benchmarking/standard_rb.py @@ -52,7 +52,7 @@ SequenceElementType = Union[Clifford, Integral, QuantumCircuit] -class StandardRB(BaseExperiment, RestlessMixin): +class StandardRB(RestlessMixin, BaseExperiment): """An experiment to characterize the error rate of a gate set on a device. # section: overview From 53ddcd4ff86080860d31668ee299331936468d3a Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 4 Dec 2023 20:29:43 +0200 Subject: [PATCH 05/15] deleted a space from log message. --- qiskit_experiments/framework/restless_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_experiments/framework/restless_mixin.py b/qiskit_experiments/framework/restless_mixin.py index c2f8b94506..d23d3e9a24 100644 --- a/qiskit_experiments/framework/restless_mixin.py +++ b/qiskit_experiments/framework/restless_mixin.py @@ -138,7 +138,7 @@ def _enable_restless( T1 time of one of the physical qubits in the experiment and the flag ``ignore_t1_check`` is False. """ - LOG.debug("Enabling restless configuration. This will override current configuration. ") + LOG.debug("Enabling restless configuration. This will override current configuration.") try: if not rep_delay: # BackendV1 only; BackendV2 does not support this From d5c159a7a0309f5056cd1a821cecfc142050c610 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 4 Dec 2023 20:49:36 +0200 Subject: [PATCH 06/15] fixed previous tests --- test/data_processing/test_restless_experiment.py | 4 +++- test/framework/test_composite.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/data_processing/test_restless_experiment.py b/test/data_processing/test_restless_experiment.py index 7eb1844c45..a98ddd5c94 100644 --- a/test/data_processing/test_restless_experiment.py +++ b/test/data_processing/test_restless_experiment.py @@ -37,9 +37,11 @@ def test_enable_restless(self): error = -np.pi * 0.01 backend = MockRestlessFineAmp(error, np.pi, "x") + amp_exp = FineXAmplitude([0], backend) with self.assertRaises(DataProcessorError): - FineXAmplitude([0], backend).enable_restless(rep_delay=2.0) + amp_exp.enable_restless(rep_delay=2.0) + amp_exp.run() amp_exp = FineXAmplitude([0], backend) amp_exp.enable_restless(rep_delay=2.0, suppress_t1_error=True) diff --git a/test/framework/test_composite.py b/test/framework/test_composite.py index b006d9f7c0..5f974dd904 100644 --- a/test/framework/test_composite.py +++ b/test/framework/test_composite.py @@ -65,7 +65,7 @@ def test_parallel_options(self): par_exp = ParallelExperiment([exp0, exp2], flatten_results=False) self.assertEqual(par_exp.experiment_options, par_exp._default_experiment_options()) - self.assertEqual(par_exp.run_options, Options(meas_level=2)) + self.assertEqual(par_exp.run_options, Options(meas_level=2, restless=False)) self.assertEqual(par_exp.transpile_options, Options(optimization_level=0)) self.assertEqual(par_exp.analysis.options, par_exp.analysis._default_options()) From 1b40d458b87d8c23901e5e1258c58805c42e9783 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 11 Dec 2023 10:31:35 +0200 Subject: [PATCH 07/15] Fake experiment analysis attribute can be assign Fake experiment analysis attribute can be assign. `FakeAnalysis` would be assigned by deafult. --- test/fake_experiment.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/fake_experiment.py b/test/fake_experiment.py index f904a7f4c4..ab0b957246 100644 --- a/test/fake_experiment.py +++ b/test/fake_experiment.py @@ -48,13 +48,15 @@ def _default_experiment_options(cls) -> Options: options.dummyoption = None return options - def __init__(self, physical_qubits=None, backend=None, experiment_type=None): + def __init__(self, physical_qubits=None, backend=None, analysis=None, experiment_type=None): """Initialise the fake experiment.""" if physical_qubits is None: physical_qubits = [0] + if analysis is None: + analysis = FakeAnalysis() super().__init__( physical_qubits, - analysis=FakeAnalysis(), + analysis=analysis, backend=backend, experiment_type=experiment_type, ) From 4929ab487389ab54c09a3c25bbb0459f4249d832 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 11 Dec 2023 10:44:38 +0200 Subject: [PATCH 08/15] Added test for restless experiment --- test/framework/test_framework.py | 81 ++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/test/framework/test_framework.py b/test/framework/test_framework.py index 16488a38f7..b944834aae 100644 --- a/test/framework/test_framework.py +++ b/test/framework/test_framework.py @@ -21,7 +21,11 @@ from qiskit.providers.fake_provider import FakeVigoV2, FakeJob from qiskit.providers.jobstatus import JobStatus from qiskit.exceptions import QiskitError +from qiskit.qobj.utils import MeasLevel +from qiskit.result import Result + +import qiskit_experiments.data_processing as dp from qiskit_experiments.exceptions import AnalysisError from qiskit_experiments.framework import ( ExperimentData, @@ -29,6 +33,8 @@ BaseAnalysis, AnalysisResultData, AnalysisStatus, + RestlessMixin, + Options, ) from qiskit_experiments.test.fake_backend import FakeBackend from qiskit_experiments.database_service import Qubit @@ -359,3 +365,78 @@ def circuits(self): self.assertEqual(exp2.experiment_type, "MyExp") exp2.experiment_type = "suieee" self.assertEqual(exp2.experiment_type, "suieee") + + def test_restless_experiment_options(self): + """Test override of experiment option in restless experiment.""" + # pylint: disable-next=redefined-outer-name, reimported + from qiskit_experiments.test.utils import FakeJob + import uuid + + class FakeRestlessBackend(FakeVigoV2): + """Fake backend for restless experiment""" + + def run(self, run_input, **options): + result = { + "backend_name": "fake_backend", + "backend_version": "0", + "qobj_id": uuid.uuid4().hex, + "job_id": uuid.uuid4().hex, + "success": True, + "results": [], + } + return FakeJob(backend=self, result=Result.from_dict(result)) + + class FakeRestlessAnalysis(FakeAnalysis): + """Fake analysis class for fake restless experiment. We need this for the data processor.""" + + @classmethod + def _default_options(cls) -> Options: + """Default analysis options.""" + options = super()._default_options() + + options.update_options( + data_processor=dp.DataProcessor("counts", [dp.Probability("1")]), + stark_coefficients="latest", + x_key="xval", + ) + return options + + class FakeRestlessExperiment(RestlessMixin, FakeExperiment): + """Fake restless experiment for testing.""" + + def __init__( + self, physical_qubits=None, backend=None, experiment_type="FakeRestlessExperiment" + ): + """Initialise the fake experiment.""" + if physical_qubits is None: + physical_qubits = [0] + super().__init__( + physical_qubits, + analysis=FakeRestlessAnalysis(), + backend=backend, + experiment_type=experiment_type, + ) + + @classmethod + def _default_run_options(cls) -> Options: + """Default option values for the experiment :meth:`run` method.""" + options = super()._default_run_options() + + options.meas_level = MeasLevel.KERNELED + options.meas_return = "single" + + return options + + backend = FakeRestlessBackend() + exp = FakeRestlessExperiment(backend=backend) + + exp.run_options.meas_level = MeasLevel.CLASSIFIED + exp.enable_restless( + override_processor_by_restless=False, rep_delay=250, suppress_t1_error=True + ) + self.assertNotEqual(exp.run_options.get("meas_level"), MeasLevel.KERNELED) + # `run()` method makes a copy of the experiment if run option is passed through it, and we cannot + # access it for testing. + # pylint: disable-next=unused-variable + expdata = exp.run() + self.assertEqual(exp.run_options.get("meas_level"), MeasLevel.KERNELED) From b4069dac872053aeba92e6d110a0a1ca97a9c501 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 11 Dec 2023 12:26:20 +0200 Subject: [PATCH 09/15] Changed the class method to work with its' attributes --- .../framework/restless_mixin.py | 55 ++++++------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/qiskit_experiments/framework/restless_mixin.py b/qiskit_experiments/framework/restless_mixin.py index d23d3e9a24..080611bd05 100644 --- a/qiskit_experiments/framework/restless_mixin.py +++ b/qiskit_experiments/framework/restless_mixin.py @@ -34,8 +34,10 @@ class RestlessMixin: This class defines the following methods: - :meth:`~.RestlessMixin.enable_restless` + - :meth:`~.RestlessMixin._enable_restless` - :meth:`~.RestlessMixin._get_restless_processor` - :meth:`~.RestlessMixin._t1_check` + - :meth:`~.RestlessMixin._finalize` A restless enabled experiment is an experiment that can be run in a restless measurement setting. In restless measurements, the qubit is not reset after @@ -81,7 +83,8 @@ def enable_restless( suppress_t1_error: bool = False, ): """ - Set a flag to enable restless configuration when running the experiment. + Set a flag to enable restless configuration when running the experiment. If the flag is set to + `True`, the program will run `_enable_restless` method in the `_finilized` step. Args: rep_delay: The repetition delay. This is the delay between a measurement @@ -106,28 +109,10 @@ def enable_restless( if suppress_t1_error: self.suppress_t1_error = suppress_t1_error - def _enable_restless( - self, - rep_delay: Optional[float] = None, - override_processor_by_restless: bool = True, - suppress_t1_error: bool = False, - ): + def _enable_restless(self): """Enables a restless experiment by setting the restless run options and the restless data processor. - Args: - rep_delay: The repetition delay. This is the delay between a measurement - and the subsequent quantum circuit. Since the backends have - dynamic repetition rates, the repetition delay can be set to a small - value which is required for restless experiments. Typical values are - 1 us or less. - override_processor_by_restless: If False, a data processor that is specified in the - analysis options of the experiment is not overridden by the restless data - processor. The default is True. - suppress_t1_error: If True, the default is False, then no error will be raised when - ``rep_delay`` is larger than the T1 times of the qubits. Instead, a warning will - be logged as restless measurements may have a large amount of noise. - Raises: DataProcessorError: If the attribute rep_delay_range is not defined for the backend. DataProcessorError: If a data processor has already been set but @@ -140,9 +125,9 @@ def _enable_restless( """ LOG.debug("Enabling restless configuration. This will override current configuration.") try: - if not rep_delay: + if not self.rep_delay: # BackendV1 only; BackendV2 does not support this - rep_delay = self._backend.configuration().rep_delay_range[0] + self.rep_delay = self._backend.configuration().rep_delay_range[0] except AttributeError as error: raise DataProcessorError( "The restless experiment can not be enabled because " @@ -151,15 +136,15 @@ def _enable_restless( ) from error # Check the rep_delay compared to the T1 time. - if not self._t1_check(rep_delay): + if not self._t1_check(): msg = ( - f"The specified repetition delay {rep_delay} is equal to or greater " + f"The specified repetition delay {self.rep_delay} is equal to or greater " f"than the T1 time of one of the physical qubits" f"{self._physical_qubits} in the experiment. Consider choosing " f"a smaller repetition delay for the restless experiment." ) - if suppress_t1_error: + if self.suppress_t1_error: LOG.warning(msg) else: raise DataProcessorError(msg) @@ -170,7 +155,7 @@ def _enable_restless( meas_return = self._default_run_options().get("meas_return", MeasReturnType.SINGLE) if not self.analysis.options.get("data_processor", None): self.set_run_options( - rep_delay=rep_delay, + rep_delay=self.rep_delay, init_qubits=False, memory=True, meas_level=meas_level, @@ -187,9 +172,9 @@ def _enable_restless( "does not have the data_processor option." ) else: - if not override_processor_by_restless: + if not self.override_processor_by_restless: self.set_run_options( - rep_delay=rep_delay, + rep_delay=self.rep_delay, init_qubits=False, memory=True, meas_level=meas_level, @@ -229,13 +214,9 @@ def _get_restless_processor(self, meas_level: int = MeasLevel.CLASSIFIED) -> Dat ], ) - def _t1_check(self, rep_delay: float) -> bool: + def _t1_check(self) -> bool: """Check that repetition delay < T1 of the physical qubits in the experiment. - Args: - rep_delay: The repetition delay. This is the delay between a measurement - and the subsequent quantum circuit. - Returns: True if the repetition delay is smaller than the qubit T1 times. @@ -250,7 +231,7 @@ def _t1_check(self, rep_delay: float) -> bool: for physical_qubit in self._physical_qubits ] - if all(rep_delay / t1_value < 1.0 for t1_value in t1_values): + if all(self.rep_delay / t1_value < 1.0 for t1_value in t1_values): return True except AttributeError as error: raise DataProcessorError( @@ -262,9 +243,5 @@ def _t1_check(self, rep_delay: float) -> bool: def _finalize(self): if self.run_options.get("restless", None): - self._enable_restless( - rep_delay=self.rep_delay, - override_processor_by_restless=self.override_processor_by_restless, - suppress_t1_error=self.suppress_t1_error, - ) + self._enable_restless() super()._finalize() From 78ad574393622751028879dc6d8791051530f065 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 11 Dec 2023 14:53:47 +0200 Subject: [PATCH 10/15] Made a call to `self._enable_restless()` so the experiment new option will be available to the user --- qiskit_experiments/framework/restless_mixin.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qiskit_experiments/framework/restless_mixin.py b/qiskit_experiments/framework/restless_mixin.py index 080611bd05..bfe0ef6bd5 100644 --- a/qiskit_experiments/framework/restless_mixin.py +++ b/qiskit_experiments/framework/restless_mixin.py @@ -109,6 +109,11 @@ def enable_restless( if suppress_t1_error: self.suppress_t1_error = suppress_t1_error + # Calling `_enable_restless()` so the run option will be visible to the user. + self._enable_restless() + # Setting override_processor_by_restless to false as the data processor was already configured. + self.override_processor_by_restless = False + def _enable_restless(self): """Enables a restless experiment by setting the restless run options and the restless data processor. @@ -242,6 +247,7 @@ def _t1_check(self) -> bool: return False def _finalize(self): + # Calling again to self._enable_restless() to override experiment option for restless experiment. if self.run_options.get("restless", None): self._enable_restless() super()._finalize() From bc83d6b8a29b16cc704c32671f7158b797967e71 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Mon, 11 Dec 2023 14:54:04 +0200 Subject: [PATCH 11/15] updated test --- test/framework/test_framework.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/framework/test_framework.py b/test/framework/test_framework.py index b944834aae..078e85e1b4 100644 --- a/test/framework/test_framework.py +++ b/test/framework/test_framework.py @@ -430,11 +430,12 @@ def _default_run_options(cls) -> Options: backend = FakeRestlessBackend() exp = FakeRestlessExperiment(backend=backend) - exp.run_options.meas_level = MeasLevel.CLASSIFIED exp.enable_restless( override_processor_by_restless=False, rep_delay=250, suppress_t1_error=True ) + exp.run_options.meas_level = MeasLevel.CLASSIFIED self.assertNotEqual(exp.run_options.get("meas_level"), MeasLevel.KERNELED) + # `run()` method makes a copy of the experiment if run option is passed through it, and we cannot # access it for testing. # pylint: disable-next=unused-variable From ae71544ea55a349caf532d4052081244a21eeb08 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Thu, 14 Dec 2023 09:33:17 +0200 Subject: [PATCH 12/15] updated comment in `restless_mixin` --- qiskit_experiments/framework/restless_mixin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiskit_experiments/framework/restless_mixin.py b/qiskit_experiments/framework/restless_mixin.py index bfe0ef6bd5..3e24f15127 100644 --- a/qiskit_experiments/framework/restless_mixin.py +++ b/qiskit_experiments/framework/restless_mixin.py @@ -111,7 +111,8 @@ def enable_restless( # Calling `_enable_restless()` so the run option will be visible to the user. self._enable_restless() - # Setting override_processor_by_restless to false as the data processor was already configured. + # Setting override_processor_by_restless to false because + # the data processor was already configured. self.override_processor_by_restless = False def _enable_restless(self): From 0e509d8586a61b1562f321974257962c46b0453d Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Thu, 14 Dec 2023 09:33:33 +0200 Subject: [PATCH 13/15] update doc file --- docs/manuals/measurement/restless_measurements.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/manuals/measurement/restless_measurements.rst b/docs/manuals/measurement/restless_measurements.rst index c62fe75d27..949f6a4bc0 100644 --- a/docs/manuals/measurement/restless_measurements.rst +++ b/docs/manuals/measurement/restless_measurements.rst @@ -52,7 +52,8 @@ In Qiskit Experiments, the experiments that support restless measurements have a special method :meth:`~.RestlessMixin.enable_restless` to set the restless run options and define the data processor that will process the measured data. If you are an experiment developer, you can add the :class:`.RestlessMixin` -to your experiment class to add support for restless measurements. +to your experiment class to add support for restless measurements. For correct method resolution order, +:class:`.RestlessMixin` should be the first base class your class will inherit from. Here, we will show how to activate restless measurements using a fake backend and a rough DRAG experiment. Note however, that you will not observe any meaningful outcomes with fake backends since the circuit simulator @@ -84,9 +85,11 @@ they use always starts with the qubits in the ground state. As you can see, a restless data processor is automatically chosen for the experiment. This data processor post-processes the restless measured shots according to the order in which -they were acquired. Furthermore, the appropriate run options are also set. Note that -these run options might be unique to IBM Quantum providers. Therefore, execute may fail -on non-IBM Quantum providers if the required options are not supported. +they were acquired. Furthermore, the appropriate run options are also set. Those run options would also +override new run options that will be set afterward. To disable this override, one should set the +option `restless` to `False`. Note that these run options might be unique to IBM Quantum providers. +Therefore, execute may fail on non-IBM Quantum providers if the required options are not supported. + After calling :meth:`~.RestlessMixin.enable_restless` the experiment is ready to be run in a restless mode. With a hardware backend, this would be done by calling the From a3eb645b45d947fd36cad877993dd89725a2ec84 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Thu, 14 Dec 2023 11:32:52 +0200 Subject: [PATCH 14/15] added release notes --- .../notes/inforcing-restless-options-9a659248108c2533.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 releasenotes/notes/inforcing-restless-options-9a659248108c2533.yaml diff --git a/releasenotes/notes/inforcing-restless-options-9a659248108c2533.yaml b/releasenotes/notes/inforcing-restless-options-9a659248108c2533.yaml new file mode 100644 index 0000000000..5218f8dcd2 --- /dev/null +++ b/releasenotes/notes/inforcing-restless-options-9a659248108c2533.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + `RestlessMixin` class will now override the experiment run option at `_finilize()` method. + `RestlessMixin` class should be the first base class that an experiment inherits from for correct + MRO (Method Resolution Order). To cancel this override, set `restless` to False in the experiment + options. From f525d21bf527abeff1ca04e856587ac241eb67c5 Mon Sep 17 00:00:00 2001 From: ItamarGoldman Date: Wed, 1 May 2024 13:26:22 +0300 Subject: [PATCH 15/15] lint --- test/framework/test_framework.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framework/test_framework.py b/test/framework/test_framework.py index f74e554505..904b6db793 100644 --- a/test/framework/test_framework.py +++ b/test/framework/test_framework.py @@ -26,8 +26,8 @@ from qiskit.result import Result -import qiskit_experiments.data_processing as dp from qiskit_ibm_runtime.fake_provider import FakeVigoV2 +import qiskit_experiments.data_processing as dp from qiskit_experiments.database_service import Qubit from qiskit_experiments.exceptions import AnalysisError