Skip to content

Commit

Permalink
Add support for noise model and level 1 data to local sampler
Browse files Browse the repository at this point in the history
This change passes through the `simulator.noise_model` option to the
`BackendSamplerV2` or `BackendEstimatorV2` as a `noise_model` option if
the primitive supports the `noise_model` option (the primitives in the
current release of Qiskit, 1.2.4, do not but there is an open pull
request to add support).

Additionally, this change translates the `execution.meas_type` option
into `meas_level` and `meas_return` options if the `BackendSamplerV2`
supports them. This change allows support for level 1 data in local
testing mode, where otherwise the default is only to return classified
data.
  • Loading branch information
wshanks committed Oct 22, 2024
1 parent f67531e commit f30dea8
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion qiskit_ibm_runtime/fake_provider/local_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from __future__ import annotations

import dataclasses
import math
import copy
import logging
Expand Down Expand Up @@ -215,12 +216,46 @@ def _run_backend_primitive_v2(
"""
options_copy = copy.deepcopy(options)

# Create a dummy primitive to check which options it supports
if primitive == "sampler":
dummy_prim = BackendSamplerV2(backend=backend)
else:
dummy_prim = BackendEstimatorV2(backend=backend)
supported_options = {f.name for f in dataclasses.fields(dummy_prim)}



prim_options = {}
if seed_simulator := options_copy.pop("simulator", {}).pop("seed_simulator", None):
sim_options = options_copy.get("simulator", {})
if seed_simulator := sim_options.pop("seed_simulator", None):
prim_options["seed_simulator"] = seed_simulator
if "noise_model" in supported_options and (
noise_model := sim_options.pop("noise_model", None)
):
prim_options["noise_model"] = noise_model
if not sim_options:
options_copy.pop("simulator", None)
if primitive == "sampler":
if default_shots := options_copy.pop("default_shots", None):
prim_options["default_shots"] = default_shots
if {"meas_type", "meas_return"} <= supported_options and (
meas_type := options_copy.get("execution", {}).pop("meas_type", None)
):
if meas_type == "classified":
prim_options["meas_level"] = 2
elif meas_type == "kerneled":
prim_options["meas_level"] = 1
prim_options["meas_return"] = "single"
elif meas_type == "avg_kerneled":
prim_options["meas_level"] = 1
prim_options["meas_return"] = "avg"
else:
# Put unexepcted meas_type back so it is in the warning below
options_copy["execution"]["meas_type"] = meas_type

if not options_copy["execution"]:
del options_copy["execution"]

primitive_inst = BackendSamplerV2(backend=backend, options=prim_options)
else:
if default_shots := options_copy.pop("default_shots", None):
Expand Down

0 comments on commit f30dea8

Please sign in to comment.