From 54982aceed0447b8fb22201882f9cc25aeb4617c Mon Sep 17 00:00:00 2001 From: Jessie Yu Date: Thu, 21 Mar 2024 12:44:06 -0400 Subject: [PATCH] Treat resilience_level=0 for EstimatorV2 properly (replace of 1541) (#1542) * treat resilience_level=0 properly * add tests --------- Co-authored-by: Takashi Imamichi --- qiskit_ibm_runtime/options/options.py | 2 +- release-notes/unreleased/1541.bug.rst | 2 ++ test/unit/test_estimator_options.py | 43 ++++++++++++++++++++++++++- test/unit/test_sampler_options.py | 21 ++++++++++++- 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 release-notes/unreleased/1541.bug.rst diff --git a/qiskit_ibm_runtime/options/options.py b/qiskit_ibm_runtime/options/options.py index 32857e88a..b4e86d163 100644 --- a/qiskit_ibm_runtime/options/options.py +++ b/qiskit_ibm_runtime/options/options.py @@ -163,7 +163,7 @@ def _set_if_exists(name: str, _inputs: dict, _options: dict) -> None: remove_empty_dict(output_options) inputs = {"options": output_options, "version": OptionsV2._VERSION, "support_qiskit": True} - if options_copy.get("resilience_level"): + if options_copy.get("resilience_level", Unset) != Unset: inputs["resilience_level"] = options_copy["resilience_level"] return inputs diff --git a/release-notes/unreleased/1541.bug.rst b/release-notes/unreleased/1541.bug.rst new file mode 100644 index 000000000..ce4c1258f --- /dev/null +++ b/release-notes/unreleased/1541.bug.rst @@ -0,0 +1,2 @@ +Fix a bug that caused setting of ``resilience_level=0`` in ``EstimatorV2`` +to be ignored (and the default value used instead). diff --git a/test/unit/test_estimator_options.py b/test/unit/test_estimator_options.py index e52e4b767..628c29c1a 100644 --- a/test/unit/test_estimator_options.py +++ b/test/unit/test_estimator_options.py @@ -18,11 +18,18 @@ from pydantic import ValidationError from qiskit_aer.noise import NoiseModel +from qiskit_ibm_runtime import EstimatorV2 as Estimator from qiskit_ibm_runtime.options import EstimatorOptions from qiskit_ibm_runtime.fake_provider import FakeManila from ..ibm_test_case import IBMTestCase -from ..utils import dict_keys_equal, dict_paritally_equal, flat_dict_partially_equal +from ..utils import ( + dict_keys_equal, + dict_paritally_equal, + flat_dict_partially_equal, + get_mocked_backend, + get_primitive_inputs, +) @ddt @@ -168,3 +175,37 @@ def test_update_options(self, new_opts): ) # Make sure the structure didn't change. self.assertTrue(dict_keys_equal(asdict(options), asdict(EstimatorOptions()))) + + @data( + {"default_shots": 0}, + {"seed_estimator": 0}, + {"resilience": {"layer_noise_learning": {"max_layers_to_learn": 0}}}, + {"resilience": {"layer_noise_learning": {"layer_pair_depths": [0]}}}, + {"execution": {"rep_delay": 0.0}}, + ) + def test_zero_values(self, opt_dict): + """Test options with values of 0.""" + backend = get_mocked_backend() + estimator = Estimator(backend=backend, options=opt_dict) + _ = estimator.run(**get_primitive_inputs(estimator)) + options = backend.service.run.call_args.kwargs["inputs"]["options"] + self.assertDictEqual(options, opt_dict) + + def test_zero_optimization_level(self): + """Test optimization_level=0.""" + opt_dict = {"optimization_level": 0} + backend = get_mocked_backend() + estimator = Estimator(backend=backend, options=opt_dict) + _ = estimator.run(**get_primitive_inputs(estimator)) + options = backend.service.run.call_args.kwargs["inputs"]["options"] + self.assertDictEqual(options, {"transpilation": {"optimization_level": 0}}) + + def test_zero_resilience_level(self): + """Test resilience_level=0""" + opt_dict = {"resilience_level": 0} + backend = get_mocked_backend() + estimator = Estimator(backend=backend, options=opt_dict) + _ = estimator.run(**get_primitive_inputs(estimator)) + options = backend.service.run.call_args.kwargs["inputs"] + self.assertIn("resilience_level", options) + self.assertEqual(options["resilience_level"], 0) diff --git a/test/unit/test_sampler_options.py b/test/unit/test_sampler_options.py index daec97978..9e5866351 100644 --- a/test/unit/test_sampler_options.py +++ b/test/unit/test_sampler_options.py @@ -18,11 +18,18 @@ from pydantic import ValidationError from qiskit_aer.noise import NoiseModel +from qiskit_ibm_runtime import SamplerV2 as Sampler from qiskit_ibm_runtime.options import SamplerOptions from qiskit_ibm_runtime.fake_provider import FakeManila from ..ibm_test_case import IBMTestCase -from ..utils import dict_keys_equal, dict_paritally_equal, flat_dict_partially_equal +from ..utils import ( + dict_keys_equal, + dict_paritally_equal, + flat_dict_partially_equal, + get_mocked_backend, + get_primitive_inputs, +) @ddt @@ -123,3 +130,15 @@ def test_update_options(self, new_opts): ) # Make sure the structure didn't change. self.assertTrue(dict_keys_equal(asdict(options), asdict(SamplerOptions()))) + + @data( + {"default_shots": 0}, + {"execution": {"rep_delay": 0.0}}, + ) + def test_zero_values(self, opt_dict): + """Test options with values of 0.""" + backend = get_mocked_backend() + sampler = Sampler(backend=backend, options=opt_dict) + _ = sampler.run(**get_primitive_inputs(sampler)) + options = backend.service.run.call_args.kwargs["inputs"]["options"] + self.assertDictEqual(options, opt_dict)