Estimator-Eingaben und -Ausgaben
Paketversionen
Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen, diese Versionen oder neuere zu verwenden.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Diese Seite gibt einen Überblick über die Eingaben und Ausgaben des Qiskit Runtime Estimator-Primitives, das Workloads auf IBM Quantum® Rechenressourcen ausführt. Der Estimator ermöglicht es dir, vektorisierte Workloads effizient zu definieren, indem du eine Datenstruktur namens Primitive Unified Bloc (PUB) verwendest. Diese werden als Eingaben für die run()-Methode des Estimator-Primitives verwendet, die den definierten Workload als Job ausführt. Nachdem der Job abgeschlossen ist, werden die Ergebnisse in einem Format zurückgegeben, das sowohl von den verwendeten PUBs als auch von den vom Primitive angegebenen Laufzeitoptionen abhängt.
Eingaben
Jeder PUB hat dieses Format:
(<einzelner Circuit>, <ein oder mehrere Observablen>, <optionale ein oder mehrere Parameterwerte>, <optionale Präzision>),
Die optionalen Parameterwerte können eine Liste oder ein einzelner Parameter sein. Elemente aus Observablen und Parameterwerten werden nach den NumPy-Broadcasting-Regeln kombiniert, wie im Thema Primitive-Eingaben und -Ausgaben beschrieben, und für jedes Element der gesendeten Form wird ein Schätzwert für den Erwartungswert zurückgegeben.
Wenn die Eingabe Messungen enthält, werden diese ignoriert.
Für das Estimator-Primitive kann ein PUB höchstens vier Werte enthalten:
- Einen einzelnen
QuantumCircuit, der ein oder mehrereParameter-Objekte enthalten kann - Eine Liste von einer oder mehreren Observablen, die die zu schätzenden Erwartungswerte angeben, in ein Array angeordnet (zum Beispiel eine einzelne Observable als 0-dimensionales Array, eine Liste von Observablen als 1-dimensionales Array usw.). Die Daten können in einem der
ObservablesArrayLike-Formate wiePauli,SparsePauliOp,PauliListoderstrvorliegen.Kommutierende Observablen- Kommutierende Observablen im selben PUB werden mit dieser Methode gruppiert.
- Kommutierende Observablen in verschiedenen PUBs, auch wenn sie denselben Circuit haben, werden nicht mit derselben Messung geschätzt. Jeder PUB stellt eine andere Messbasis dar, daher sind für jeden PUB separate Messungen erforderlich.
- Um sicherzustellen, dass kommutierende Observablen mit derselben Messung geschätzt werden, gruppiere sie innerhalb desselben PUBs.
- Eine Sammlung von Parameterwerten, gegen die der Circuit gebunden wird. Dies kann als einzelnes array-ähnliches Objekt angegeben werden, bei dem der letzte Index über Circuit-
Parameter-Objekte geht, oder weggelassen (oder äquivalent aufNonegesetzt) werden, wenn der Circuit keineParameter-Objekte hat. - (Optional) Eine Zielpräzision für die zu schätzenden Erwartungswerte
Der folgende Code zeigt ein Beispiel für einen Satz vektorisierter Eingaben für das Estimator-Primitive und führt diese auf einem IBM® Backend als einzelnes RuntimeJobV2-Objekt aus.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit.circuit import (
Parameter,
QuantumCircuit,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import (
QiskitRuntimeService,
EstimatorV2 as Estimator,
)
import numpy as np
# Instantiate runtime service and get
# the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Define a circuit with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.rz(Parameter("b"), 0)
circuit.cx(0, 1)
circuit.h(0)
# Transpile the circuit
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
layout = transpiled_circuit.layout
# Now define a sweep over parameter values, the last axis of dimension 2 is
# for the two parameters "a" and "b"
params = np.vstack(
[
np.linspace(-np.pi, np.pi, 100),
np.linspace(-4 * np.pi, 4 * np.pi, 100),
]
).T
# Define three observables. The inner length-1 lists cause this array of
# observables to have shape (3, 1), rather than shape (3,) if they were
# omitted.
observables = [
[SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
[SparsePauliOp("XX")],
[SparsePauliOp("IY")],
]
# Apply the same layout as the transpiled circuit.
observables = [
[observable.apply_layout(layout) for observable in observable_set]
for observable_set in observables
]
# Estimate the expectation value for all 300 combinations of observables
# and parameter values, where the pub result will have shape (3, 100).
#
# This shape is due to our array of parameter bindings having shape
# (100, 2), combined with our array of observables having shape (3, 1).
estimator_pub = (transpiled_circuit, observables, params)
# Instantiate the new Estimator object, then run the transpiled circuit
# using the set of parameters and observables.
estimator = Estimator(mode=backend)
job = estimator.run([estimator_pub])
result = job.result()
Ausgaben
Nachdem ein oder mehrere PUBs zur Ausführung an eine QPU gesendet wurden und ein Job erfolgreich abgeschlossen wurde, werden die Daten als PrimitiveResult-Container-Objekt zurückgegeben, auf das durch Aufrufen der RuntimeJobV2.result()-Methode zugegriffen wird.
Das PrimitiveResult enthält eine iterierbare Liste von PubResult-Objekten, die die Ausführungsergebnisse für jeden PUB enthalten.
Jedes Element dieser Liste entspricht jedem PUB, der an die run()-Methode des Primitives übergeben wurde (zum Beispiel gibt ein Job, der mit 20 PUBs übermittelt wurde, ein PrimitiveResult-Objekt zurück, das eine Liste von 20 PubResult-Objekten enthält, eines für jeden PUB).
Jedes PubResult für das Estimator-Primitive enthält mindestens ein Array von Erwartungswerten (PubResult.data.evs) und zugehörige Standardabweichungen (entweder PubResult.data.stds oder PubResult.data.ensemble_standard_error, je nach verwendetem resilience_level), kann aber je nach den angegebenen Fehlerminderungsoptionen mehr Daten enthalten.
Jedes PubResult-Objekt besitzt sowohl ein data- als auch ein metadata-Attribut.
- Das
data-Attribut ist ein angepassterDataBin, der die tatsächlichen Messwerte, Standardabweichungen usw. enthält. - Der
DataBinhat verschiedene Attribute je nach Form oder Struktur des zugehörigen PUBs sowie den Fehlerminderungsoptionen, die durch das Primitive angegeben wurden, das zum Übermitteln des Jobs verwendet wurde (zum Beispiel ZNE oder PEC). - Das
metadata-Attribut enthält Informationen über die verwendeten Laufzeit- und Fehlerminderungsoptionen (später im Abschnitt Ergebnis-Metadaten dieser Seite erklärt).
Das Folgende ist ein visueller Überblick über die PrimitiveResult-Datenstruktur für die Estimator-Ausgabe:
└── PrimitiveResult
├── PubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── evs
│ │ └── List of estimated expectation values in the shape
| | specified by the first pub
│ └── stds
│ └── List of calculated standard deviations in the
| same shape as above
├── PubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| ├── evs
| │ └── List of estimated expectation values in the shape
| | specified by the second pub
| └── stds
| └── List of calculated standard deviations in the
| same shape as above
├── ...
├── ...
└── ...
Kurz gesagt gibt ein einzelner Job ein PrimitiveResult-Objekt zurück und enthält eine Liste von einem oder mehreren PubResult-Objekten. Diese PubResult-Objekte speichern dann die Messdaten für jeden PUB, der dem Job übergeben wurde.
Der folgende Code-Ausschnitt beschreibt das PrimitiveResult- (und zugehörige PubResult-)Format für den oben erstellten Job.
print(
f"The result of the submitted job had {len(result)} "
f"PUBs and has a value:\n {result}\n"
)
print(
"The associated PubResult of this job has the following data bins:\n "
"{result[0].data}\n"
)
print(f"And this DataBin has attributes: {result[0].data.keys()}")
print(
"Recall that this shape is due to our array of parameter binding sets"
"having shape (100, 2), where 2 is the number of parameters in the "
"circuit, combined with our array of observables having shape (3, 1). \n"
)
with np.printoptions(threshold=200):
print(
"The expectation values measured from this PUB are: \n"
"{result[0].data.evs}\n"
)
The result of the submitted job had 1 PUB and has a value:
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
The associated PubResult of this job has the following data bins:
DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100))
And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])
Recall that this shape is due to our array of parameter binding sets having shape (100, 2) -- where 2 is the
number of parameters in the circuit -- combined with our array of observables having shape (3, 1).
The expectation values measured from this PUB are:
[[-0.00369065 0.15107692 0.30110431 ... -0.30159536 -0.15431523
0.00576586]
[ 0.00601655 0.04412133 0.1253447 ... -0.12434194 -0.04662823
0.01153171]
[-0.01339784 0.2580325 0.47686391 ... -0.47884878 -0.26200223
0. ]]
Wie das Estimator-Primitive den Fehler berechnet
Zusätzlich zur Schätzung des Mittelwerts der in den Eingabe-PUBs übergebenen Observablen (das Feld evs des DataBin) versucht der Estimator auch, eine Schätzung des mit diesen Erwartungswerten verbundenen Fehlers zu liefern. Alle Estimator-Abfragen füllen das Feld stds mit einer Größe wie dem Standardfehler des Mittelwerts für jeden Erwartungswert, aber einige Fehlerminderungsoptionen erzeugen zusätzliche Informationen, wie ensemble_standard_error.
Betrachte eine einzelne Observable . Ohne ZNE kann jeder Shot der Estimator-Ausführung als Punktschätzung des Erwartungswerts betrachtet werden. Wenn die punktweisen Schätzungen in einem Vektor Os sind, dann ist der in ensemble_standard_error zurückgegebene Wert äquivalent zum folgenden (wobei die Standardabweichung der Erwartungswertschätzung und die Anzahl der Shots ist):
was alle Shots als Teil eines einzigen Ensembles behandelt. Wenn du Gate-Twirling angefordert hast (twirling.enable_gates = True), kannst du die punktweisen Schätzungen von in Mengen sortieren, die ein gemeinsames Twirl teilen. Nenn diese Mengen von Schätzungen O_twirls, und es gibt num_randomizations (Anzahl der Twirls) davon. Dann ist stds der Standardfehler des Mittelwerts von O_twirls, wie in
wobei die Standardabweichung von O_twirls und die Anzahl der Twirls ist. Wenn du Twirling nicht aktivierst, sind stds und ensemble_standard_error gleich.
Wenn du ZNE aktivierst, werden die oben beschriebenen stds zu Gewichtungen in einer nicht-linearen Regression an ein Extrapolationsmodell. Was schließlich in stds zurückgegeben wird, ist in diesem Fall die Unsicherheit des Fit-Modells, ausgewertet bei einem Rauschfaktor von null. Bei einem schlechten Fit oder großer Unsicherheit im Fit können die gemeldeten stds sehr groß werden. Wenn ZNE aktiviert ist, werden auch pub_result.data.evs_noise_factors und pub_result.data.stds_noise_factors befüllt, sodass du deine eigene Extrapolation durchführen kannst.
Ergebnis-Metadaten
Zusätzlich zu den Ausführungsergebnissen enthalten sowohl die PrimitiveResult- als auch die PubResult-Objekte ein Metadaten-Attribut über den übermittelten Job. Die Metadaten mit Informationen für alle übermittelten PUBs (wie die verschiedenen verfügbaren Laufzeitoptionen) befinden sich in PrimitiveResult.metatada, während die für jeden PUB spezifischen Metadaten in PubResult.metadata zu finden sind.
Im Metadatenfeld können Primitive-Implementierungen beliebige Informationen über die für sie relevante Ausführung zurückgeben, und es gibt keine Schlüssel-Wert-Paare, die durch das Basis-Primitive garantiert werden. Daher können die zurückgegebenen Metadaten in verschiedenen Primitive-Implementierungen unterschiedlich sein.
# Print out the results metadata
print("The metadata of the PrimitiveResult is:")
for key, val in result.metadata.items():
print(f"'{key}' : {val},")
print("\nThe metadata of the PubResult result is:")
for key, val in result[0].metadata.items():
print(f"'{key}' : {val},")
The metadata of the PrimitiveResult is:
'dynamical_decoupling' : {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'},
'twirling' : {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'},
'resilience' : {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False},
'version' : 2,
The metadata of the PubResult result is:
'shots' : 4096,
'target_precision' : 0.015625,
'circuit_metadata' : {},
'resilience' : {},
'num_randomizations' : 32,