Входи та виходи Estimator
Версії пакетів
Код на цій сторінці було розроблено з використанням таких вимог. Рекомендуємо використовувати ці або новіші версії.
qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
Ця сторінка містить огляд вхідних і вихідних даних примітива IBM Quantum Estimator, який виконує навантаження на обчислювальних ресурсах IBM Quantum®. Estimator дозволяє ефективно визначати векторизовані навантаження, використовуючи структуру даних, що називається Primitive Unified Bloc (PUB). Вони використовуються як вхідні дані для методу run() примітива Estimator, який виконує визначене навантаження як завдання. Потім, після завершення завдання, результати повертаються у форматі, який залежить як від використаних PUB, так і від опцій середовища виконання, заданих для примітива.
Входи
Кожен PUB має такий формат:
(<single circuit>, <one or more observables>, <optional one or more parameter values>, <optional precision>),
Необов'язкові parameter values можуть бути списком або одним параметром. Елементи зі спостережуваних та значень параметрів комбінуються відповідно до правил трансляції NumPy, як описано в темі Входи та виходи примітивів, і одна оцінка очікуваного значення повертається для кожного елемента транслюваної форми.
Якщо вхідні дані містять вимірювання, вони ігноруються.
Для примітива Estimator PUB може містити не більше чотирьох значень:
- Одна
QuantumCircuit, яка може містити один або кілька об'єктівParameter - Список одного або кількох спостережуваних, що вказують очікувані значення для оцінки, впорядковані в масив (наприклад, одне спостережуване, представлене як 0-d масив, список спостережуваних як 1-d масив тощо). Дані можуть бути в будь-якому з форматів
ObservablesArrayLike, таких якPauli,SparsePauliOp,PauliListабоstr.Комутуючі спостережувані- Комутуючі спостережувані в одному і тому ж PUB групуються разом за допомогою цього методу.
- Комутуючі спостережувані в різних PUB, навіть якщо вони мають однакову схему, не оцінюються за допомогою одного вимірювання. Кожен PUB представляє різний базис для вимірювання, і тому для кожного PUB потрібні окремі вимірювання.
- Щоб гарантувати, що комутуючі спостережувані оцінюються за допомогою одного вимірювання, групуй їх у тому ж PUB.
- Колекція значень параметрів для прив'язки схеми. Це може бути вказано як єдиний об'єкт, схожий на масив, де останній індекс — над об'єктами
Parameterсхеми, або пропущено (або еквівалентно, встановлено наNone), якщо схема не має об'єктівParameter. - (Необов'язково) Цільова точність для оцінки очікуваних значень
Наступний код демонструє приклад набору векторизованих вхідних даних для примітива Estimator та виконує їх на бекенді IBM® як єдиний об'єкт RuntimeJobV2 .
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Estimator
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_estimator import 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()
Виходи
Після надсилання одного або кількох PUB до QPU для виконання та успішного завершення завдання дані повертаються як об'єкт-контейнер PrimitiveResult, доступний шляхом виклику методу RuntimeJobV2.result().
PrimitiveResult містить ітерований список об'єктів PubResult, що містять результати виконання для кожного PUB.
Кожен елемент цього списку відповідає кожному PUB, надісланому до методу run() примітива (наприклад, завдання, надіслане з 20 PUB, поверне об'єкт PrimitiveResult, що містить список з 20 об'єктів PubResult, кожен відповідний своєму PUB).
Кожен PubResult для примітива Estimator містить щонайменше масив очікуваних значень (PubResult.data.evs) та пов'язані стандартні відхилення (або PubResult.data.stds, або PubResult.data.ensemble_standard_error залежно від використовуваного resilience_level), але може містити більше даних залежно від вказаних опцій пом'якшення помилок.
Кожен об'єкт PubResult має як атрибут data, так і атрибут metadata.
- Атрибут
data— це налаштованийDataBin, що містить фактичні значення вимірювань, стандартні відхилення тощо. DataBinмає різні атрибути залежно від форми або структури пов'язаного PUB, а також від опцій пом'якшення помилок, вказаних примітивом, використовуваним для надсилання завдання (наприклад, ZNE або PEC).- Атрибут
metadataмістить інформацію про опції середовища виконання та пом'якшення помилок, використовувані (пояснено пізніше в розділі Метадані результату цієї сторінки).
Нижче наведено наочну схему структури даних PrimitiveResult для виходу Estimator:
└── 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
├── ...
├── ...
└── ...
Простіше кажучи, одне завдання повертає об'єкт PrimitiveResult та містить список з одного або кількох об'єктів PubResult. Ці об'єкти PubResult потім зберігають дані вимірювань для кожного PUB, надісланого до завдання.
Наступний фрагмент коду описує формат PrimitiveResult (та пов'язаного PubResult) для завдання, створеного вище.
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 PUBs 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:
{result[0].data}
And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])
Recall that this shape is due to our array of parameter binding setshaving 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:
{result[0].data.evs}
Як примітив Estimator обчислює помилку
На додаток до оцінки середнього значення спостережуваних, переданих у вхідних PUB (поле evs DataBin), Estimator також намагається надати оцінку помилки, пов'язаної з цими очікуваними значеннями. Всі запити до Estimator заповнюватимуть поле stds величиною, схожою на стандартну помилку середнього для кожного очікуваного значення, але деякі опції пом'якшення помилок надають додаткову інформацію, наприклад ensemble_standard_error.
Розглянемо одне спостережуване . За відсутності ZNE кожен постріл виконання Estimator можна розглядати як точкову оцінку очікуваного значення . Якщо точкові оцінки знаходяться у векторі Os, то значення, що повертається в ensemble_standard_error, еквівалентне такому (де — стандартне відхилення оцінки очікуваного значення, а — кількість пострілів):
що розглядає всі постріли як частину єдиного ансамблю. Якщо запитано gate twirling (twirling.enable_gates = True), можна відсортувати точкові оцінки у набори, що мають спільний twirl. Назвемо ці набори оцінок O_twirls, їх є num_randomizations (кількість twirl). Тоді stds є стандартною помилкою середнього O_twirls, як у
де — стандартне відхилення O_twirls, а — кількість twirl. Коли twirling не увімкнено, stds та ensemble_standard_error рівні.
Якщо увімкнено ZNE, то stds, описані вище, стають вагами в нелінійній регресії до моделі екстраполятора. У цьому випадку в stds зрештою повертається невизначеність моделі підгонки, оцінена при нульовому факторі шуму. При поганій підгонці або великій невизначеності в підгонці повідомлені stds можуть ставати дуже великими. Коли ZNE увімкнено, також заповнюються pub_result.data.evs_noise_factors та pub_result.data.stds_noise_factors, щоб можна було виконати власну екстраполяцію.
Метадані результату
На додаток до результатів виконання, обидва об'єкти PrimitiveResult та PubResult містять атрибут метаданих про надіслане завдання. Метадані, що містять інформацію для всіх надісланих PUB (наприклад, різні опції середовища виконання), можна знайти в PrimitiveResult.metatada, тоді як метадані, специфічні для кожного PUB, знаходяться в PubResult.metadata.
Клієнтський Estimator надсилає своє робоче навантаження як завдання Executor. Метадані базового результату Executor, які містять інформацію про час виконання, що називається проміжками виконання, доступні за ключем "executor" в PrimitiveResult.metadata.
У полі метаданих реалізації примітивів можуть повертати будь-яку інформацію про виконання, що є для них релевантною, і немає пар ключ-значення, що гарантовані базовим примітивом. Таким чином, повернені метадані можуть відрізнятися в різних реалізаціях примітивів.
# 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,
Переглянь проміжки виконання
Клієнтський Estimator працює як завдання Executor, яке виконує свою роботу на QPU порціями. Час кожної порції міститься в result.metadata["executor"].chunk_timing, списку об'єктів ChunkSpan. Кожен ChunkSpan має часові мітки start і stop та список parts, де кожна частина вказує індекс елемента (idx_item) і кількість конфігурацій з цього елемента (size), що виконалися в цій порції.
idx_item — це індекс елемента в програмі Executor, яку Estimator будує з твоїх PUB. Він не обов'язково збігається з індексом PUB, оскільки Estimator може додавати елементи програми залежно від опцій пом'якшення помилок. Наприклад, він додає кола калібрування помилок вимірювання, коли ввімкнено TREX.
Щоб візуалізувати час, передай список у draw_chunk_timings, як показано в наведеному нижче прикладі.
Щоб дізнатися, що означають часові мітки порцій, як читати графік і чому між порціями можуть з'являтися проміжки, див. Перегляд проміжків виконання у посібнику про вхідні та вихідні дані Executor.
from qiskit_ibm_runtime.visualization import draw_chunk_timings
# Note the "executor" key: the timing comes from the underlying Executor job
chunk_timing = result.metadata["executor"].chunk_timing
for idx, span in enumerate(chunk_timing):
duration = (span.stop - span.start).total_seconds()
print(f"Chunk {idx}: {span.start} to {span.stop} ({duration:.3f} s)")
for part in span.parts:
print(f" Item {part.idx_item}: {part.size} configurations")
fig = draw_chunk_timings(chunk_timing, names="Estimator job")
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("chunk_timings.html")
Chunk 0: 2026-11-06 01:39:01.509471+00:00 to 2026-11-06 01:39:35.171288+00:00 (33.662 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 1: 2026-11-06 01:39:48.299074+00:00 to 2026-11-06 01:40:21.826190+00:00 (33.527 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 2: 2026-11-06 01:40:22.855454+00:00 to 2026-11-06 01:40:53.781896+00:00 (30.926 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 3: 2026-11-06 01:40:54.993867+00:00 to 2026-11-06 01:41:26.068319+00:00 (31.074 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 4: 2026-11-06 01:41:41.019968+00:00 to 2026-11-06 01:42:15.956573+00:00 (34.937 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 5: 2026-11-06 01:42:47.834717+00:00 to 2026-11-06 01:43:21.436255+00:00 (33.602 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 6: 2026-11-06 01:43:22.698235+00:00 to 2026-11-06 01:43:53.647547+00:00 (30.949 s)
Item 0: 800 configurations
Item 1: 4 configurations
Chunk 7: 2026-11-06 01:43:54.710995+00:00 to 2026-11-06 01:44:25.762574+00:00 (31.052 s)
Item 0: 800 configurations
Item 1: 4 configurations