Skip to content

Commit

Permalink
SamplerV2 options (#1223)
Browse files Browse the repository at this point in the history
* Add experimental options (#1067)

* add options

* fix mypy

* rename meas err mit

* Add additional resilience options

* Add additional execution options for twirling

* A twirling strategy option and validation

* handle default resilience options

* add _experimental

* Update default resilience options (#1062)

* remove default resilience options

* add reno

* add logic to override default

* add test

* purge None values from options

(cherry picked from commit 76603f2)

* add finalize options

* add tests

* Update qiskit_ibm_runtime/options/resilience_options.py

* add validation

* lint

* lint again

* lint again

* Allow None values for specific options to be passed through

* Fix parameter validation, allow computational basis

* black

* Fix ZneExtrapolatorType validation

* lint

* lint again

* fix mypy

* Fix ZNE extrapolator default option

* fix level options

* black

* use _isreal

* Disable gate twirling for default lvl 1 opts

* Support for legacy options

---------

Co-authored-by: Christopher J. Wood <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>
Co-authored-by: mberna <[email protected]>
Co-authored-by: Mariana C Bernagozzi <[email protected]>

* fix merge issues

* add pydantic

* black

* lint

* Fast forward experimental to latest main (#1178)

* Remove min execution time check (#1065)

* Remove min execution time check

* update unit test

* remove integration test

* Update `max_execution_time` docstrings (#1059)

* Update max_execution_time docstrings

* add commas

* Update qiskit_ibm_runtime/options/options.py

Co-authored-by: Rebecca Dimock <[email protected]>

* Update qiskit_ibm_runtime/options/options.py

Co-authored-by: Rebecca Dimock <[email protected]>

* Update qiskit_ibm_runtime/runtime_options.py

Co-authored-by: Rebecca Dimock <[email protected]>

* Update releasenotes/notes/max-execution-time-definition-196cb6297693c0f2.yaml

Co-authored-by: Rebecca Dimock <[email protected]>

---------

Co-authored-by: Rebecca Dimock <[email protected]>

* Removed remaining code related to Schedules (#1068)

Co-authored-by: Kevin Tian <[email protected]>

* Enable datetime parameter for backend properties (#1070)

* enable datetime param for backend properties

* add test & reno

* improve test

* Update default resilience options (#1062)

* remove default resilience options

* add reno

* add logic to override default

* add test

* purge None values from options

* fix test (#1074)

* Prepare release 0.12.1 (#1075)

* Update main branch veresion 0.12.2 (#1076)

* use ibmq_qasm_simulator (#1078)

* Add reason code to error message (#1072)

* Add reason code to error message

* add reno

* Remove importing PauliSumOp, which is deprecated. (#1079)

---------

Co-authored-by: Jake Lishman <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>

* Adjusts default value for optimization_level (#1082)

* add instance info (#1083)

* add instance info

* Add cloud note

* Update README.md

Co-authored-by: Kevin Tian <[email protected]>

---------

Co-authored-by: Kevin Tian <[email protected]>

* Fix links to options in README.md (#1084)

* Remove auth parameter (#1077)

* Removed auth parameter

* Removed calls to migrate()

* black and lint

---------

Co-authored-by: Kevin Tian <[email protected]>

* Remove opflow and algorithms from serialization tests (#1085)

* Remove opflow from tests

* Re-add test for PauliSumOp

* Fix lint

* Fix black

---------

Co-authored-by: Kevin Tian <[email protected]>

* RuntimeJobTimeoutError should inherit from JobTimeoutError (#1090)

* RuntimeJobTimeoutError inherits from JobTimeoutError

* black

---------

Co-authored-by: Kevin Tian <[email protected]>

* Allow user to define a default account as an environment variable (#1018)

* Allow user to define a default account as an environment variable

* Fixed test

* Fixed mistaken paste

* Cleaned up test

* Moved test to TestAccountManager

* Added ability to define default channel in save_account

* Cleaned up code, fixed bugs

* Changed name of parameter

* Added test. Cleaned up code surrounding preferences of channel selection

* black and lint

* Fixed bug when json file was empty

* Code cleanup and documentation

* Documentation

* Removed channel from condition, because unnecessary

* changed default_channel to default_account

* Changed saving and getting default channel to default account

* black

* Documentation

* Release notes

* Reverted diff that was unnecessary

---------

Co-authored-by: Kevin Tian <[email protected]>

* Skip test_job_logs (#1094)

* Update session max_time docstring (#1089)

* Update session max_time docstring

* Update qiskit_ibm_runtime/session.py

Co-authored-by: Rebecca Dimock <[email protected]>

---------

Co-authored-by: Rebecca Dimock <[email protected]>

* Fix unit tests against qiskit/main (#1099)

* Add measurements to sampler

* Remove observables from sampler run

---------

Co-authored-by: Kevin Tian <[email protected]>

* fix iqp link (#1096)

Co-authored-by: Kevin Tian <[email protected]>

* Only return channel strategy supported backends  (#1095)

* Q-CTRL Backend filters

* add reno

* fix unit tests

* Attempt to fix terra unit tests (#1102)

* Attempt to fix terra unit tests

* test on my fork

* revert coder_qc change

* Making account code more generic  (#1060)

* Making account code more generic by defining subclasses for channel types

* Removed channel parameter from _assert_valid_instance

* mypy, lint and black

* Changed order of decorators

* Code cleanup

* Documentation fixes

* black

---------

Co-authored-by: Kevin Tian <[email protected]>

* Remove old deprecations (#1106)

* removing old deprecations

* update unit tests

* Open plan updates (#1105)

* Initial edits

* edit

* Update docs/faqs/max_execution_time.rst

* Update docs/faqs/max_execution_time.rst

* Update docs/faqs/max_execution_time.rst

* Update docs/faqs/max_execution_time.rst

* Update docs/faqs/max_execution_time.rst

* Update docs/faqs/max_execution_time.rst

Co-authored-by: Jessie Yu <[email protected]>

* Jessie comments

* Update docs/faqs/max_execution_time.rst

Co-authored-by: Jessie Yu <[email protected]>

* Update docs/faqs/max_execution_time.rst

Co-authored-by: Jessie Yu <[email protected]>

* Update docs/sessions.rst

* Update docs/faqs/max_execution_time.rst

---------

Co-authored-by: Jessie Yu <[email protected]>

* New method to create a new Session object with a given id (#1101)

* Added the Session.from_id method

* release notes

* Added integration test

---------

Co-authored-by: Kevin Tian <[email protected]>

* fix test_session_from_id (#1110)

* Warn users if job submitted will exceed quota (#1100)

* Warn users if job will exceed quota

* update reno

* update reno again

* Removed support for backend as session parameter (#1091)

Co-authored-by: Kevin Tian <[email protected]>

* Fix minor todos (#1112)

* Change qpu complex wording (#1109)

* Don't use QPU complex

* don't use the word 'limit'

* Update docs/faqs/max_execution_time.rst

* Update qiskit_ibm_runtime/options/options.py

* Update qiskit_ibm_runtime/runtime_job.py

* Update releasenotes/notes/0.11/job-cost-estimation-d0ba83dbc95c3f67.yaml

* Clarify usage

* reclarify reset time

* rogue comma

* fix whitespace & formatting

* job -> system execution time

---------

Co-authored-by: Kevin Tian <[email protected]>

* Add IBM Cloud channel (#1113)

* Changes for #1806

* Update docs/faqs/max_execution_time.rst

Co-authored-by: Jessie Yu <[email protected]>

---------

Co-authored-by: Kevin Tian <[email protected]>
Co-authored-by: Jessie Yu <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>

* Prepare release 0.12.2 (#1115)

* Update main branch 0.13.0 (#1116)

* remove error message test (#1125)

* Exceptions should inherit from Terra where suitable (#1120)

* Changed RuntimeJobFailureError to inherit from JobError

* Changed error type

---------

Co-authored-by: Kevin Tian <[email protected]>

* update docstring & remove max_time (#1137)

* Expose new session details  (#1119)

* add session details method

* add reno

* support iqp urls

* update details mehotd, add status()

* update status() to use enum

* revert previous change, wait for impl details

* update fields returned

* update status method

* update docstring & reno

* update docstrings for both methods

* fix docs build

* address comments

* fix docs build

* fix typo

* docs build again

* fix indent

* fix indent again

* fix indent 3rd time

* Support only LocalFoldingAmplifier as noise_amplifier option (#1093)

* Removed support for all noise_amplifier options other than LocalFoldingAmplifier. Removed deprecation warning.

* Removed tests that covered deprecation. Updated documentation

---------

Co-authored-by: Kevin Tian <[email protected]>

* Fix target_history date bug  (#1143)

* fix target_history datetime bug

* add reno

* add test

* Fixed bug when defining shots as int64 (#1151)

* Log instance on initialization and when running a job (#1150)

* log instances

* add _default_instance & fix lint

* add test

* change var name to current_instance

* Move methods into class pages for docs (#1144)

* Fix link to `Close a session` (#1152)

[1] links to [2] but doesn't go directly to the target section.

[1] https://qiskit.org/ecosystem/ibm-runtime/sessions.html#what-happens-when-a-session-ends
[2] https://qiskit.org/ecosystem/ibm-runtime/how_to/run_session.html#close-a-session

Co-authored-by: Kevin Tian <[email protected]>

* logging instance test is IQP channel only (#1154)

* Update deploy yml (#1148)

* Allow users to indicate they are done submitting jobs to a session (#1139)

* copy changes over

* clean up branch again

* address comments, update docstrings

* catch appropriate error code

* update status code to 404

* Update qiskit_ibm_runtime/session.py

Co-authored-by: Jessie Yu <[email protected]>

* set self._active & remove runtime_session

* Update releasenotes/notes/session-accepting-jobs-d7ef6b60c0f5527b.yaml

Co-authored-by: Jessie Yu <[email protected]>

---------

Co-authored-by: Jessie Yu <[email protected]>

* Prepare release 0.13 (#1157)

* Update main branch 0.13.1 (#1158)

* Update Sphinx theme (#1156)

Co-authored-by: Kevin Tian <[email protected]>

* Added IBM Quantum logo (#1164)

* sessions changes (#1169)

* sessions changes

* add more ticks

* fix link

* fix links

* Update docs/sessions.rst

Co-authored-by: abbycross <[email protected]>

* Update docs/sessions.rst

Co-authored-by: abbycross <[email protected]>

---------

Co-authored-by: abbycross <[email protected]>

* Disallow unsupported options (#1108)

* Disallow unsupported options

* Moved checking of unsupported options to 'flexible' decorator

* Modified the test to give TypeError where needed

* Removed empty newline

* Moved tests from test_ibm_primitives to test_options, because they don't require a primitive

* typo

* Release note

* black and lint

* black again

* Fixed test failing in CI

* Removed _flexible decorator. Moved _post_init into Options class

* lint

* lint

* Fixed bug

* lint

---------

Co-authored-by: Kevin Tian <[email protected]>

* fix merge issues

* black

* lint

---------

Co-authored-by: Kevin Tian <[email protected]>
Co-authored-by: Rebecca Dimock <[email protected]>
Co-authored-by: merav-aharoni <[email protected]>
Co-authored-by: Luciano Bello <[email protected]>
Co-authored-by: Jake Lishman <[email protected]>
Co-authored-by: Esteban Ginez <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>
Co-authored-by: mberna <[email protected]>
Co-authored-by: Elena Peña Tapia <[email protected]>
Co-authored-by: Arnau Casau <[email protected]>
Co-authored-by: Matt Riedemann <[email protected]>
Co-authored-by: abbycross <[email protected]>

* v2 options

* estimator options

* update test

* lint

* fix merge issues

* black

* fix noise model type

* lint again

* fix header

* fix mypy

* use v2 as default

* cleanup terra options

* black

* options need not be callable

* fix doc

* fix tests

* fix version

* add sampler option

* lint

* freeze constants

* freeze constants

* remove is_simulator

* make image work

* fix merge issues

* fix tests

* fix tests

* lint

* add seed_estimator

* resolve merge issues

---------

Co-authored-by: Christopher J. Wood <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>
Co-authored-by: mberna <[email protected]>
Co-authored-by: Mariana C Bernagozzi <[email protected]>
Co-authored-by: Rebecca Dimock <[email protected]>
Co-authored-by: merav-aharoni <[email protected]>
Co-authored-by: Luciano Bello <[email protected]>
Co-authored-by: Jake Lishman <[email protected]>
Co-authored-by: Esteban Ginez <[email protected]>
Co-authored-by: Kevin Tian <[email protected]>
Co-authored-by: Elena Peña Tapia <[email protected]>
Co-authored-by: Arnau Casau <[email protected]>
Co-authored-by: Matt Riedemann <[email protected]>
Co-authored-by: abbycross <[email protected]>
  • Loading branch information
15 people authored Nov 16, 2023
1 parent f807061 commit b73fdac
Show file tree
Hide file tree
Showing 13 changed files with 869 additions and 329 deletions.
4 changes: 2 additions & 2 deletions qiskit_ibm_runtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ def result_callback(job_id, result):
from .version import __version__

from .estimator import EstimatorV2, EstimatorV1 as Estimator
from .sampler import SamplerV1 as Sampler
from .options import Options, EstimatorOptions
from .sampler import SamplerV2, SamplerV1 as Sampler
from .options import Options, EstimatorOptions, SamplerOptions

# Setup the logger for the IBM Quantum Provider package.
logger = logging.getLogger(__name__)
Expand Down
1 change: 0 additions & 1 deletion qiskit_ibm_runtime/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
class Estimator:
"""Base class for Qiskit Runtime Estimator."""

_PROGRAM_ID = "estimator"
version = 0


Expand Down
2 changes: 2 additions & 0 deletions qiskit_ibm_runtime/options/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
SimulatorOptions
TwirlingOptions
EstimatorOptions
SamplerOptions
"""

Expand All @@ -62,3 +63,4 @@
from .resilience_options import ResilienceOptionsV1 as ResilienceOptions
from .twirling_options import TwirlingOptions
from .estimator_options import EstimatorOptions
from .sampler_options import SamplerOptions
118 changes: 3 additions & 115 deletions qiskit_ibm_runtime/options/estimator_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@
"""Primitive options."""

from typing import Union, Literal
import copy

from qiskit.transpiler import CouplingMap
from pydantic.dataclasses import dataclass as pydantic_dataclass
from pydantic import Field, ConfigDict, field_validator

from .utils import (
Dict,
Unset,
UnsetType,
_remove_dict_unset_values,
merge_options,
skip_unset_validation,
)
from .execution_options import ExecutionOptionsV2
Expand Down Expand Up @@ -74,6 +70,8 @@ class EstimatorOptions(OptionsV2):
Allowed values are ``"XX"``, ``"XpXm"``, ``"XY4"``.
Default: None
seed_estimator: Seed used to control sampling.
transpilation: Transpilation options. See :class:`TranspilationOptions` for all
available options.
Expand All @@ -90,14 +88,14 @@ class EstimatorOptions(OptionsV2):
"""

_VERSION: int = Field(2, frozen=True) # pylint: disable=invalid-name
_MAX_OPTIMIZATION_LEVEL: int = Field(3, frozen=True) # pylint: disable=invalid-name
_MAX_RESILIENCE_LEVEL: int = Field(3, frozen=True) # pylint: disable=invalid-name

# Sadly we cannot use pydantic's built in validation because it won't work on Unset.
optimization_level: Union[UnsetType, int] = Unset
resilience_level: Union[UnsetType, int] = Unset
dynamical_decoupling: Union[UnsetType, DDSequenceType] = Unset
seed_estimator: Union[UnsetType, int] = Unset
transpilation: Union[TranspilationOptions, Dict] = Field(default_factory=TranspilationOptions)
resilience: Union[ResilienceOptionsV2, Dict] = Field(default_factory=ResilienceOptionsV2)
execution: Union[ExecutionOptionsV2, Dict] = Field(default_factory=ExecutionOptionsV2)
Expand Down Expand Up @@ -127,113 +125,3 @@ def _validate_resilience_level(cls, resilience_level: int) -> int:
f"0-{EstimatorOptions._MAX_RESILIENCE_LEVEL}"
)
return resilience_level

@staticmethod
def _get_program_inputs(options: dict) -> dict:
"""Convert the input options to program compatible inputs.
Returns:
Inputs acceptable by primitives.
"""

sim_options = options.get("simulator", {})
inputs = {}
inputs["transpilation"] = copy.copy(options.get("transpilation", {}))
inputs["skip_transpilation"] = inputs["transpilation"].pop("skip_transpilation")
coupling_map = sim_options.get("coupling_map", None)
# TODO: We can just move this to json encoder
if isinstance(coupling_map, CouplingMap):
coupling_map = list(map(list, coupling_map.get_edges()))
inputs["transpilation"].update(
{
"optimization_level": options.get("optimization_level"),
"coupling_map": coupling_map,
"basis_gates": sim_options.get("basis_gates", None),
}
)

inputs["resilience_level"] = options.get("resilience_level")
inputs["resilience"] = options.get("resilience", {})

inputs["twirling"] = options.get("twirling", {})

inputs["execution"] = options.get("execution", {})
inputs["execution"].update(
{
"noise_model": sim_options.get("noise_model", Unset),
"seed_simulator": sim_options.get("seed_simulator", Unset),
}
)

# Add arbitrary experimental options
if isinstance(options.get("experimental", None), dict):
inputs = merge_options(inputs, options.get("experimental"))

# Remove image
inputs.pop("image", None)

inputs["_experimental"] = True
inputs["version"] = EstimatorOptions._VERSION
_remove_dict_unset_values(inputs)

return inputs


# @dataclass(frozen=True)
# class _ResilienceLevel0Options:
# resilience_level: int = 0
# resilience: ResilienceOptions = field(
# default_factory=lambda: ResilienceOptions(
# measure_noise_mitigation=False, zne_mitigation=False, pec_mitigation=False
# )
# )
# twirling: TwirlingOptions = field(
# default_factory=lambda: TwirlingOptions(gates=False, measure=False)
# )


# @dataclass(frozen=True)
# class _ResilienceLevel1Options:
# resilience_level: int = 1
# resilience: ResilienceOptions = field(
# default_factory=lambda: ResilienceOptions(
# measure_noise_mitigation=True, zne_mitigation=False, pec_mitigation=False
# )
# )
# twirling: TwirlingOptions = field(
# default_factory=lambda: TwirlingOptions(gates=False, measure=True, strategy="active-accum")
# )


# @dataclass(frozen=True)
# class _ResilienceLevel2Options:
# resilience_level: int = 2
# resilience: ResilienceOptions = field(
# default_factory=lambda: ResilienceOptions(
# measure_noise_mitigation=True, pec_mitigation=False, **asdict(_ZneOptions())
# )
# )
# twirling: TwirlingOptions = field(
# default_factory=lambda: TwirlingOptions(gates=True, measure=True, strategy="active-accum")
# )


# @dataclass(frozen=True)
# class _ResilienceLevel3Options:
# resilience_level: int = 3
# resilience: ResilienceOptions = field(
# default_factory=lambda: ResilienceOptions(
# measure_noise_mitigation=True, zne_mitigation=False, **asdict(_PecOptions())
# )
# )
# twirling: TwirlingOptions = field(
# default_factory=lambda: TwirlingOptions(gates=True, measure=True, strategy="active")
# )


# _DEFAULT_RESILIENCE_LEVEL_OPTIONS = {
# 0: _ResilienceLevel0Options(),
# 1: _ResilienceLevel1Options(),
# 2: _ResilienceLevel2Options(),
# 3: _ResilienceLevel3Options(),
# }
69 changes: 68 additions & 1 deletion qiskit_ibm_runtime/options/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from pydantic.dataclasses import dataclass as pydantic_dataclass
from pydantic import Field, ConfigDict

from .utils import Dict, _to_obj, UnsetType, Unset, _remove_dict_unset_values
from .utils import Dict, _to_obj, UnsetType, Unset, _remove_dict_unset_values, merge_options
from .environment_options import EnvironmentOptions
from .execution_options import ExecutionOptionsV1 as ExecutionOptions
from .simulator_options import SimulatorOptions
Expand Down Expand Up @@ -93,10 +93,77 @@ class OptionsV2(BaseOptions):
:class:`SimulatorOptions` for all available options.
"""

_VERSION: int = Field(2, frozen=True) # pylint: disable=invalid-name

# Options not really related to primitives.
max_execution_time: Union[UnsetType, int] = Unset
environment: Union[EnvironmentOptions, Dict] = Field(default_factory=EnvironmentOptions)
simulator: Union[SimulatorOptions, Dict] = Field(default_factory=SimulatorOptions)

@staticmethod
def _get_program_inputs(options: dict) -> dict:
"""Convert the input options to program compatible inputs.
Returns:
Inputs acceptable by primitives.
"""

def _set_if_exists(name: str, _inputs: dict, _options: dict) -> None:
if name in _options:
_inputs[name] = _options[name]

options_copy = copy.deepcopy(options)
sim_options = options_copy.get("simulator", {})
inputs = {}
inputs["transpilation"] = options_copy.get("transpilation", {})
inputs["skip_transpilation"] = inputs["transpilation"].pop("skip_transpilation")
coupling_map = sim_options.get("coupling_map", Unset)
# TODO: We can just move this to json encoder
if isinstance(coupling_map, CouplingMap):
coupling_map = list(map(list, coupling_map.get_edges()))
inputs["transpilation"].update(
{
"optimization_level": options_copy.get("optimization_level", Unset),
"coupling_map": coupling_map,
"basis_gates": sim_options.get("basis_gates", Unset),
}
)

for fld in [
"resilience_level",
"resilience",
"twirling",
"dynamical_decoupling",
"seed_estimator",
]:
_set_if_exists(fld, inputs, options_copy)

inputs["execution"] = options_copy.get("execution", {})
inputs["execution"].update(
{
"noise_model": sim_options.get("noise_model", Unset),
"seed_simulator": sim_options.get("seed_simulator", Unset),
}
)

# Add arbitrary experimental options
if isinstance(options_copy.get("experimental", None), dict):
inputs = merge_options(inputs, options_copy.get("experimental"))

# Remove image
inputs.pop("image", None)

inputs["_experimental"] = True
inputs["version"] = OptionsV2._VERSION
_remove_dict_unset_values(inputs)

# Remove empty dictionaries
for key, val in list(inputs.items()):
if isinstance(val, dict) and not val:
del inputs[key]

return inputs


@dataclass
class Options(BaseOptions):
Expand Down
91 changes: 91 additions & 0 deletions qiskit_ibm_runtime/options/sampler_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Sampler options."""

from typing import Union, Literal

from pydantic.dataclasses import dataclass as pydantic_dataclass
from pydantic import Field, ConfigDict, field_validator

from .utils import (
Dict,
Unset,
UnsetType,
skip_unset_validation,
)
from .execution_options import ExecutionOptionsV2
from .transpilation_options import TranspilationOptions
from .twirling_options import TwirlingOptions
from .options import OptionsV2

DDSequenceType = Literal["XX", "XpXm", "XY4"]


@pydantic_dataclass(
config=ConfigDict(validate_assignment=True, arbitrary_types_allowed=True, extra="forbid")
)
class SamplerOptions(OptionsV2):
"""Options for v2 Sampler.
Args:
optimization_level: How much optimization to perform on the circuits.
Higher levels generate more optimized circuits,
at the expense of longer transpilation times. This is based on the
``optimization_level`` parameter in qiskit-terra but may include
backend-specific optimization. Default: 1.
* 0: no optimization
* 1: light optimization
* 2: heavy optimization
* 3: even heavier optimization
dynamical_decoupling: Optional, specify a dynamical decoupling sequence to use.
Allowed values are ``"XX"``, ``"XpXm"``, ``"XY4"``.
Default: None
transpilation: Transpilation options. See :class:`TranspilationOptions` for all
available options.
execution: Execution time options. See :class:`ExecutionOptionsV2` for all available options.
twirling: Pauli-twirling related options. See :class:`TwirlingOptions` for all available options.
environment: Options related to the execution environment. See
:class:`EnvironmentOptions` for all available options.
simulator: Simulator options. See
:class:`SimulatorOptions` for all available options.
"""

_MAX_OPTIMIZATION_LEVEL: int = Field(3, frozen=True) # pylint: disable=invalid-name

# Sadly we cannot use pydantic's built in validation because it won't work on Unset.
optimization_level: Union[UnsetType, int] = Unset
dynamical_decoupling: Union[UnsetType, DDSequenceType] = Unset
transpilation: Union[TranspilationOptions, Dict] = Field(default_factory=TranspilationOptions)
execution: Union[ExecutionOptionsV2, Dict] = Field(default_factory=ExecutionOptionsV2)
twirling: Union[TwirlingOptions, Dict] = Field(default_factory=TwirlingOptions)
experimental: Union[UnsetType, dict] = Unset

@field_validator("optimization_level")
@classmethod
@skip_unset_validation
def _validate_optimization_level(cls, optimization_level: int) -> int:
"""Validate optimization_leve."""
if not 0 <= optimization_level <= SamplerOptions._MAX_OPTIMIZATION_LEVEL:
raise ValueError(
"Invalid optimization_level. Valid range is "
f"0-{SamplerOptions._MAX_OPTIMIZATION_LEVEL}"
)
return optimization_level
1 change: 1 addition & 0 deletions qiskit_ibm_runtime/qiskit/primitives/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@

from .base_estimator import BaseEstimatorV2 # type: ignore
from .base_primitive import BasePrimitiveOptions # type: ignore
from .base_sampler import BaseSamplerV2 # type: ignore
Loading

0 comments on commit b73fdac

Please sign in to comment.