Zum Hauptinhalt springen

Optionen festlegen

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

Du kannst Optionen verwenden, um die Primitives Estimator und Sampler anzupassen. Dieser Abschnitt erklärt, wie du Optionen für Qiskit Runtime Primitives festlegst. Obwohl die Schnittstelle der run()-Methode der Primitives bei allen Implementierungen gleich ist, sind ihre Optionen es nicht. Weitere Informationen zu den Optionen von qiskit.primitives und qiskit_aer.primitives findest du in den entsprechenden API-Referenzen.

Hinweise zum Festlegen von Optionen in den Primitives:

  • SamplerV2 und EstimatorV2 haben separate Optionsklassen. Du kannst die verfügbaren Optionen einsehen und Optionswerte während oder nach der Initialisierung des Primitives ändern.
  • Verwende die Methode update(), um Änderungen am Attribut options vorzunehmen.
  • Wenn du keinen Wert für eine Option angibst, erhält sie den speziellen Wert Unset und es werden die Standardwerte des Servers verwendet.
  • Das Attribut options hat den Python-Typ dataclass. Du kannst die eingebaute Methode asdict verwenden, um es in ein Dictionary umzuwandeln.

Optionen für Primitives festlegen

Du kannst Optionen bei der Initialisierung des Primitives, nach der Initialisierung oder in der run()-Methode festlegen. Lies den Abschnitt zu den Vorrangregeln, um zu verstehen, was passiert, wenn dieselbe Option an mehreren Stellen angegeben wird.

Initialisierung des Primitives

Du kannst bei der Initialisierung eines Primitives eine Instanz der Optionsklasse oder ein Dictionary übergeben, woraufhin eine Kopie dieser Optionen erstellt wird. Änderungen am ursprünglichen Dictionary oder an der ursprünglichen Optionsinstanz wirken sich daher nicht auf die Optionen aus, die dem Primitive gehören.

Optionsklasse

Beim Erstellen einer Instanz der Klasse EstimatorV2 oder SamplerV2 kannst du eine Instanz der Optionsklasse übergeben. Diese Optionen werden dann angewendet, wenn du run() zur Durchführung der Berechnung verwendest. Gib die Optionen in diesem Format an: options.option.sub-option.sub-sub-option = choice. Zum Beispiel: options.dynamical_decoupling.enable = True

Beispiel:

SamplerV2 und EstimatorV2 haben separate Optionsklassen (EstimatorOptions und SamplerOptions).

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime.options import EstimatorOptions

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

options = EstimatorOptions(
resilience_level=2,
resilience={"zne_mitigation": True, "zne": {"noise_factors": [1, 3, 5]}},
)

# or...
options = EstimatorOptions()
options.resilience_level = 2
options.resilience.zne_mitigation = True
options.resilience.zne.noise_factors = [1, 3, 5]

estimator = Estimator(mode=backend, options=options)

Dictionary

Du kannst Optionen bei der Initialisierung des Primitives als Dictionary angeben.

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Setting options during primitive initialization
estimator = Estimator(
backend,
options={
"resilience_level": 2,
"resilience": {
"zne_mitigation": True,
"zne": {"noise_factors": [1, 3, 5]},
},
},
)

Optionen nach der Initialisierung aktualisieren

Du kannst Optionen in diesem Format angeben: primitive.options.option.sub-option.sub-sub-option = choice, um die Autovervollständigung zu nutzen, oder die Methode update() für Massenaktualisierungen verwenden.

Die Optionsklassen SamplerV2 und EstimatorV2 (EstimatorOptions und SamplerOptions) müssen nicht instanziiert werden, wenn du Optionen nach der Initialisierung des Primitives festlegst.

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

estimator = Estimator(mode=backend)

# Setting options after primitive initialization
# This uses auto-complete.
estimator.options.default_shots = 4000
# This does bulk update.
estimator.options.update(
default_shots=4000, resilience={"zne_mitigation": True}
)

Methode Run()

Die einzigen Werte, die du an run() übergeben kannst, sind die in der Schnittstelle definierten: shots für Sampler und precision für Estimator. Diese überschreiben alle für default_shots oder default_precision für den aktuellen Lauf festgelegten Werte.

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()

pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)

transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)

sampler = Sampler(mode=backend)
# Default shots to use if not specified in run()
sampler.options.default_shots = 500
# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)

# Sample two circuits with different numbers of shots.
# 100 shots is used for transpiled1 and 200 for transpiled.
sampler.run([(transpiled1, None, 100), (transpiled2, None, 200)])
<RuntimeJobV2('d5k96cn853es738djikg', 'sampler')>

Sonderfälle

Resilienz-Level (nur Estimator)

Der Resilienz-Level ist keine Option, die die Primitive-Abfrage direkt beeinflusst, sondern gibt einen kuratierten Basissatz von Optionen vor. Im Allgemeinen deaktiviert Level 0 alle Fehlerminderungsmaßnahmen, Level 1 aktiviert Optionen zur Messfehlerminderung und Level 2 aktiviert Optionen zur Gate- und Messfehlerminderung.

Alle Optionen, die du zusätzlich zum Resilienz-Level manuell angibst, werden auf den durch den Resilienz-Level definierten Basissatz aufgesetzt. Theoretisch könntest du den Resilienz-Level auf 1 setzen, aber dann die Messfehlerminderung deaktivieren – auch wenn das nicht empfohlen wird.

Im folgenden Beispiel deaktiviert das Setzen des Resilienz-Levels auf 0 zunächst zne_mitigation, aber estimator.options.resilience.zne_mitigation = True überschreibt die entsprechende Einstellung von estimator.options.resilience_level = 0.

from qiskit_ibm_runtime import EstimatorV2, QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

estimator = EstimatorV2(backend)

estimator.options.default_shots = 100
estimator.options.resilience_level = 0
estimator.options.resilience.zne_mitigation = True

Shots (nur Sampler)

Die Methode SamplerV2.run akzeptiert zwei Argumente: eine Liste von PUBs, von denen jeder einen PUB-spezifischen Wert für shots angeben kann, sowie ein Schlüsselwortargument shots. Diese Shot-Werte sind Teil der Sampler-Ausführungsschnittstelle und unabhängig von den Optionen des Runtime Samplers. Sie haben Vorrang vor allen als Optionen angegebenen Werten, um der Sampler-Abstraktion zu entsprechen.

Wenn shots jedoch weder von einem PUB noch im run-Schlüsselwortargument angegeben wird (oder wenn alle None sind), wird der Shot-Wert aus den Optionen verwendet, insbesondere default_shots.

Zusammenfassend gilt für jeden PUB folgende Vorrangreihenfolge bei der Angabe von shots im Sampler:

  1. Wenn der PUB shots angibt, wird dieser Wert verwendet.
  2. Wenn das Schlüsselwortargument shots in run angegeben wird, wird dieser Wert verwendet.
  3. Wenn num_randomizations und shots_per_randomization als twirling-Optionen angegeben werden, entspricht die Shot-Anzahl dem Produkt dieser Werte.
  4. Wenn sampler.options.default_shots angegeben wird, wird dieser Wert verwendet.

Wenn shots an allen möglichen Stellen angegeben werden, wird derjenige mit dem höchsten Vorrang (shots im PUB) verwendet.

Präzision (nur Estimator)

Präzision ist analog zu shots, wie im vorherigen Abschnitt beschrieben, mit dem Unterschied, dass die Estimator-Optionen sowohl default_shots als auch default_precision enthalten. Da Gate-Twirling standardmäßig aktiviert ist, hat das Produkt aus num_randomizations und shots_per_randomization Vorrang vor diesen beiden Optionen.

Für jeden Estimator-PUB gilt im Einzelnen:

  1. Wenn der PUB eine Präzision angibt, wird dieser Wert verwendet.
  2. Wenn das Schlüsselwortargument precision in run angegeben wird, wird dieser Wert verwendet.
  3. Wenn num_randomizations und shots_per_randomization als twirling-Optionen angegeben werden (standardmäßig aktiviert), wird ihr Produkt zur Steuerung der Datenmenge verwendet.
  4. Wenn estimator.options.default_shots angegeben wird, wird dieser Wert zur Steuerung der Datenmenge verwendet.
  5. Wenn estimator.options.default_precision angegeben wird, wird dieser Wert verwendet.

Wenn beispielsweise die Präzision an allen vier Stellen angegeben wird, wird derjenige mit dem höchsten Vorrang (Präzision im PUB) verwendet.

hinweis

Die Präzision skaliert umgekehrt proportional zur Nutzung. Das heißt: Je niedriger die Präzision, desto mehr QPU-Zeit wird für die Ausführung benötigt.

Häufig verwendete Optionen

Es gibt viele verfügbare Optionen, aber die folgenden werden am häufigsten verwendet:

Shots

Für einige Algorithmen ist das Festlegen einer bestimmten Anzahl von shots ein wesentlicher Bestandteil ihrer Routinen. Shots (oder Präzision) können an mehreren Stellen angegeben werden. Sie werden in folgender Reihenfolge priorisiert:

Für jeden Sampler-PUB:

  1. Ganzzahliger shots-Wert im PUB
  2. Der Wert run(...,shots=val)
  3. Der Wert options.default_shots

Für jeden Estimator-PUB:

  1. Gleitkomma-Präzisionswert im PUB
  2. Der Wert run(...,precision=val)
  3. Der Wert options.default_shots
  4. Der Wert options.default_precision

Beispiel:

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()

pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)

transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)

# Setting shots during primitive initialization
sampler = Sampler(mode=backend, options={"default_shots": 4096})

# Setting options after primitive initialization
# This uses auto-complete.
sampler.options.default_shots = 2000

# This does bulk update. The value for default_shots is overridden if you specify shots with run() or in the PUB.
sampler.options.update(
default_shots=1024, dynamical_decoupling={"sequence_type": "XpXm"}
)

# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)
<RuntimeJobV2('d5k96icjt3vs73ds5t0g', 'sampler')>

Maximale Ausführungszeit

Die maximale Ausführungszeit (max_execution_time) begrenzt, wie lange ein Job laufen kann. Wird diese Zeitgrenze überschritten, wird der Job zwangsweise abgebrochen. Dieser Wert gilt für einzelne Jobs, unabhängig davon, ob sie im Job-, Session- oder Batch-Modus ausgeführt werden.

Der Wert wird in Sekunden angegeben und basiert auf der Quantenzeit (nicht der Echtzeit), also der Zeit, die der QPU für die Verarbeitung deines Jobs gewidmet ist. Er wird beim lokalen Testmodus ignoriert, da dieser Modus keine Quantenzeit verwendet.

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

estimator = Estimator(mode=backend)

estimator.options.max_execution_time = 2500

Alle Fehlerminderung und Fehlerunterdrückung deaktivieren

Du kannst alle Fehlerminderung und Fehlerunterdrückung deaktivieren, wenn du beispielsweise eigene Minderungstechniken erforschst. Setze dazu bei EstimatorV2 den resilience_level = 0. Für SamplerV2 sind keine Änderungen erforderlich, da standardmäßig keine Fehlerminderung oder Fehlerunterdrückung aktiviert ist.

Beispiel:

Alle Fehlerminderung und Fehlerunterdrückung im Estimator deaktivieren.

from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService

# Define the service. This allows you to access IBM QPU.
service = QiskitRuntimeService()

# Get a backend
backend = service.least_busy(operational=True, simulator=False)

# Define Estimator
estimator = Estimator(backend)

options = estimator.options

# Turn off all error mitigation and suppression
options.resilience_level = 0

Nächste Schritte

Empfehlungen