From 7c9979e22e833a5af195fe75e08a25d678ff4aa3 Mon Sep 17 00:00:00 2001 From: ptristan3 <44805021+ptristan3@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:23:06 -0300 Subject: [PATCH] Add twirling options to SamplerV2 (#1583) * add twirling options to SamplerV2 * linter fixes * style fixes * add release note * Update release-notes/unreleased/1557.feat.rst Co-authored-by: Kevin Tian * update docstrings * updated tests, included twirling option * updated docstring from PR comment * updated test_program_inputs * Update qiskit_ibm_runtime/options/twirling_options.py Co-authored-by: Ian Hincks * Update release-notes/unreleased/1557.feat.rst Co-authored-by: Ian Hincks --------- Co-authored-by: Kevin Tian Co-authored-by: Ian Hincks Co-authored-by: Jessie Yu --- qiskit_ibm_runtime/options/sampler_options.py | 4 ++++ qiskit_ibm_runtime/options/twirling_options.py | 4 ++-- release-notes/unreleased/1557.feat.rst | 2 ++ test/unit/test_sampler_options.py | 9 +++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 release-notes/unreleased/1557.feat.rst diff --git a/qiskit_ibm_runtime/options/sampler_options.py b/qiskit_ibm_runtime/options/sampler_options.py index 6b1006dce..8079c6ded 100644 --- a/qiskit_ibm_runtime/options/sampler_options.py +++ b/qiskit_ibm_runtime/options/sampler_options.py @@ -21,6 +21,7 @@ from .options import OptionsV2 from .utils import primitive_dataclass from .dynamical_decoupling_options import DynamicalDecouplingOptions +from .twirling_options import TwirlingOptions @primitive_dataclass @@ -36,6 +37,8 @@ class SamplerOptions(OptionsV2): execution: Execution time options. See :class:`ExecutionOptionsV2` for all available options. + twirling: Pauli twirling options. See :class:`TwirlingOptions` for all available options. + experimental: Experimental options. """ @@ -47,4 +50,5 @@ class SamplerOptions(OptionsV2): execution: Union[SamplerExecutionOptionsV2, Dict] = Field( default_factory=SamplerExecutionOptionsV2 ) + twirling: Union[TwirlingOptions, Dict] = Field(default_factory=TwirlingOptions) experimental: Union[UnsetType, dict] = Unset diff --git a/qiskit_ibm_runtime/options/twirling_options.py b/qiskit_ibm_runtime/options/twirling_options.py index 62d4f579b..d6523a63c 100644 --- a/qiskit_ibm_runtime/options/twirling_options.py +++ b/qiskit_ibm_runtime/options/twirling_options.py @@ -32,8 +32,8 @@ class TwirlingOptions: Args: enable_gates: Whether to apply 2-qubit gate twirling. Default: False. - enable_measure: Whether to enable twirling of expectation value measurements - in Estimator. Default: True. + enable_measure: Whether to enable twirling of measurements. Twirling will only be applied to + those measurement registers not involved within a conditional logic. Default: True. num_randomizations: The number of random samples to use when twirling or peforming sampled mitigation. If "auto", the value will be chosen automatically diff --git a/release-notes/unreleased/1557.feat.rst b/release-notes/unreleased/1557.feat.rst new file mode 100644 index 000000000..f70273d9e --- /dev/null +++ b/release-notes/unreleased/1557.feat.rst @@ -0,0 +1,2 @@ +`SamplerV2` now supports twirling. +Twirling will only be applied to those measurement registers not involved within a conditional logic. \ No newline at end of file diff --git a/test/unit/test_sampler_options.py b/test/unit/test_sampler_options.py index b9225d1a5..2777a074b 100644 --- a/test/unit/test_sampler_options.py +++ b/test/unit/test_sampler_options.py @@ -62,6 +62,7 @@ def test_program_inputs(self): environment = {"log_level": "INFO"} dynamical_decoupling = {"enable": True, "sequence_type": "XX"} execution = {"init_qubits": True, "rep_delay": 0.01} + twirling = {"enable_gates": True, "enable_measure": True, "strategy": "active-circuit"} opt = SamplerOptions( max_execution_time=100, @@ -69,6 +70,7 @@ def test_program_inputs(self): simulator=simulator, default_shots=1000, dynamical_decoupling=dynamical_decoupling, + twirling=twirling, execution=execution, experimental={"foo": "bar", "execution": {"secret": 88}}, ) @@ -80,6 +82,11 @@ def test_program_inputs(self): options = { "default_shots": 1000, "dynamical_decoupling": dynamical_decoupling, + "twirling": { + "enable_gates": True, + "enable_measure": True, + "strategy": "active-circuit", + }, "execution": execution, "experimental": {"foo": "bar"}, "simulator": simulator, @@ -97,6 +104,7 @@ def test_program_inputs(self): {"execution": {"init_qubits": True, "meas_type": "avg_kerneled"}}, {"dynamical_decoupling": {"enable": True, "sequence_type": "XX"}}, {"environment": {"log_level": "ERROR"}}, + {"twirling": {"enable_gates": True, "strategy": "active"}}, ) def test_init_options_with_dictionary(self, opts_dict): """Test initializing options with dictionaries.""" @@ -117,6 +125,7 @@ def test_init_options_with_dictionary(self, opts_dict): "sequence_type": "XX", "log_level": "INFO", }, + {"twirling": {"enable_gates": True, "strategy": "active"}}, ) def test_update_options(self, new_opts): """Test update method."""