อินพุตและเอาต์พุตของ Sampler
เวอร์ชันแพ็คเกจ
โค้ดในหน้านี้ได้รับการพัฒนาโดยใช้ข้อกำหนดต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
หน้านี้ให้ภาพรวมของอินพุตและเอาต์พุตของ qiskit-ibm-runtime Sampler primitive ซึ่งรันเวิร์กโหลดบน IBM Quantum® Compute Service Sampler ช่วยให้คุณกำหนดเวิร์กโหลดแบบเวกเตอร์ได้อย่างมีประสิทธิภาพโดยใช้โครงสร้างข้อมูลที่เรียกว่า Primitive Unified Bloc (PUB) ซึ่งใช้เป็นอินพุตสำหรับเมธอด run() ของ Sampler primitive ที่รันเวิร์กโหลดที่กำหนดเป็นงาน จากนั้นหลังจากงานเสร็จสิ้น ผลลัพธ์จะถูกส่งคืนในรูปแบบที่ขึ้นอยู่กับทั้ง PUB และตัวเลือก runtime ที่ระบุจาก primitive
อินพุต
PUB แต่ละอันมีรูปแบบ:
(<single circuit>, <one or more optional parameter value>, <optional shots>),
สามารถมีรายการ parameter values หลายรายการ และแต่ละรายการสามารถเป็นอาร์เรย์หรือพารามิเตอร์เดียว ขึ้นอยู่กับ circuit ที่เลือก นอกจากนี้ อินพุตต้องมีการวัด
สำหรับ Sampler primitive PUB สามารถมีค่าได้สูงสุดสามค่า:
QuantumCircuitเดียวที่อาจมีออบเจ็กต์Parameterหนึ่งหรือมากกว่า หมายเหตุ: circuit เหล่านี้ควรมีคำสั่งการวัดสำหรับ qubit แต่ละตัวที่จะทำ sampling ด้วย- คอลเลกชันของค่าพารามิเตอร์สำหรับ bind กับ circuit (จำเป็นเฉพาะเมื่อมีออบเจ็กต์
Parameterที่ต้อง bind ที่ runtime) - (เสริม) จำนวน shots สำหรับวัด circuit
โค้ดต่อไปนี้แสดงตัวอย่างชุดอินพุตแบบเวกเตอร์ไปยัง primitive Sampler และรันบน backend ของ 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,
ClassicalRegister,
QuantumRegister,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives.containers import BitArray
from qiskit_ibm_runtime import QiskitRuntimeService
# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import Sampler
# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.executor_sampler import Sampler
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)
circuit.measure_all()
# 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
sampler_pub = (transpiled_circuit, params)
# Instantiate the new Sampler object, then run the transpiled circuit
# using the set of parameters and observables.
sampler = Sampler(mode=backend)
job = sampler.run([sampler_pub])
result = job.result()
เอาต์พุต
หลังจาก PUB หนึ่งตัวหรือมากกว่าถูกส่งไปยัง QPU เพื่อรันและงานเสร็จสิ้นอย่างสำเร็จ ข้อมูลจะถูกส่งคืนเป็นออบเจ็กต์คอนเทนเนอร์ PrimitiveResult ที่เข้าถึงได้โดยการเรียกเมธอด RuntimeJobV2.result() PrimitiveResult มีรายการแบบ iterable ของออบเจ็กต์ SamplerPubResult ที่มีผลลัพธ์การรันสำหรับ PUB แต่ละตัว ข้อมูลเหล่านี้คือตัวอย่างของเอาต์พุต circuit
แต่ละองค์ประกอบในรายการนี้สอดคล้องกับ PUB ที่ส่งไปยังเมธอด run() ของ primitive (เช่น งานที่ส่งพร้อม PUB 20 ตัวจะส่งคืนออบเจ็กต์ PrimitiveResult ที่มีรายการออบเจ็กต์ SamplerPubResult 20 ตัว ตัวหนึ่งสำหรับแต่ละ PUB)
แต่ละออบเจ็กต์ SamplerPubResult มีทั้งแอตทริบิวต์ data และ metadata
- แอตทริบิวต์
dataคือDataBinที่กำหนดเองซึ่งมีค่าการวัดจริง ส่วนเบี่ยงเบนมาตรฐาน และอื่นๆ data bins เป็นออบเจ็กต์คล้าย dict ที่มีBitArrayหนึ่งตัวต่อClassicalRegisterใน circuit - คลาส
BitArrayเป็นคอนเทนเนอร์สำหรับข้อมูล shot ที่มีลำดับ เก็บ bitstrings ที่ sampling ไว้เป็นไบต์ภายในอาร์เรย์สองมิติ แกนซ้ายสุดของอาร์เรย์นี้ไล่ตาม shots ตามลำดับ ส่วนแกนขวาสุดไล่ตามไบต์ - แอตทริบิวต์
metadataมีข้อมูลเกี่ยวกับตัวเลือก runtime ที่ใช้ (อธิบายในส่วน ข้อมูลเมตาของผลลัพธ์ ในหน้านี้)
ต่อไปนี้คือโครงร่างภาพของโครงสร้างข้อมูล PrimitiveResult:
└── PrimitiveResult
├── SamplerPubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── NAME_OF_CLASSICAL_REGISTER
│ │ └── BitArray of count data (default is 'meas')
| |
│ └── NAME_OF_ANOTHER_CLASSICAL_REGISTER
│ └── BitArray of count data (exists only if more than one
| ClassicalRegister was specified in the circuit)
├── SamplerPubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| └── NAME_OF_CLASSICAL_REGISTER
| └── BitArray of count data for second pub
├── ...
├── ...
└── ...
พูดง่ายๆ งานเดียวส่งคืนออบเจ็กต์ PrimitiveResult และมีรายการออบเจ็กต์ SamplerPubResult หนึ่งตัวหรือมากกว่า ออบเจ็กต์ SamplerPubResult เหล่านี้จะเก็บข้อมูลการวัดสำหรับ PUB แต่ละตัวที่ส่งไปยังงาน
สำหรับตัวอย่างแรก ลองดู circuit 10 qubit ต่อไปนี้:
# generate a ten-qubit GHZ circuit
circuit = QuantumCircuit(10)
circuit.h(0)
circuit.cx(range(0, 9), range(1, 10))
# append measurements with the `measure_all` method
circuit.measure_all()
# transpile the circuit
transpiled_circuit = pm.run(circuit)
# run the Sampler job and retrieve the results
sampler = Sampler(mode=backend)
job = sampler.run([transpiled_circuit])
result = job.result()
# the data bin contains one BitArray
data = result[0].data
print(f"Databin: {data}\n")
# to access the BitArray, use the key "meas", which is the default name of
# the classical register when this is added by the `measure_all` method
array = data.meas
print(f"BitArray: {array}\n")
print(f"The shape of register `meas` is {data.meas.array.shape}.\n")
print(f"The bytes in register `alpha`, shot by shot:\n{data.meas.array}\n")
Databin: DataBin(meas=BitArray(<shape=(), num_shots=4096, num_bits=10>))
BitArray: BitArray(<shape=(), num_shots=4096, num_bits=10>)
The shape of register `meas` is (4096, 2).
The bytes in register `alpha`, shot by shot:
[[ 3 247]
[ 0 0]
[ 3 223]
...
[ 0 255]
[ 0 0]
[ 0 0]]
บางครั้งอาจสะดวกที่จะแปลงจากรูปแบบไบต์ใน BitArray เป็น bitstrings เมธอด get_count ส่งคืน dictionary ที่ map bitstrings กับจำนวนครั้งที่เกิดขึ้น
# optionally, convert away from the native BitArray format to a dictionary format
counts = data.meas.get_counts()
print(f"Counts: {counts}")
Counts: {'1111110111': 28, '0000000000': 1680, '1111011111': 35, '1111111111': 1467, '1110000000': 28, '0000000010': 15, '1111111011': 15, '1110111111': 7, '1000000000': 52, '1111101111': 16, '1111110000': 22, '0000000101': 3, '0001111101': 1, '0000000111': 17, '0000000001': 66, '1111111110': 119, '0000001000': 15, '0011111111': 24, '1111111101': 38, '0000001111': 32, '1100000000': 39, '1101111111': 51, '0000011111': 34, '1110000010': 2, '0010000000': 25, '0111111111': 21, '0001111111': 34, '1011111111': 16, '1000011111': 3, '0000001101': 1, '1111100000': 22, '1111111100': 22, '1111111000': 8, '0010001011': 1, '0011000000': 1, '0000000011': 16, '0011111100': 2, '1011110001': 1, '1101111100': 1, '1101111101': 1, '0000000110': 2, '0000000100': 2, '0001111110': 6, '0000001110': 4, '0011110111': 2, '1101111110': 3, '0111111011': 1, '0110000000': 1, '0000001011': 2, '1111110110': 3, '0111111000': 1, '1010000000': 2, '0001110111': 1, '1111101000': 1, '0010011110': 1, '1111100111': 1, '0111110111': 1, '0100000000': 5, '1101110111': 1, '0000001001': 1, '0010000001': 1, '1111000001': 1, '0000010000': 3, '1111101110': 1, '1111000000': 8, '0001011111': 3, '1000000001': 1, '1111010111': 2, '0010011111': 1, '1011111110': 1, '1101101111': 1, '1111011110': 2, '1111111010': 1, '1111010000': 1, '1101000000': 1, '1100001111': 1, '1100011111': 1, '0000111111': 4, '0010111111': 1, '1000000110': 1, '1110111110': 1, '1101011111': 2, '0000011000': 1, '1101110000': 2, '1011111011': 1, '1000111111': 1, '1011000000': 1, '1110000001': 2, '0101111111': 2, '1111110101': 1, '0010000011': 1, '0000011110': 1, '0000011101': 1, '0111000000': 1, '0001110000': 1, '0001000000': 4, '1101111000': 1, '1011111000': 1, '0111110000': 1, '1101110110': 1, '0011011111': 1, '0000100000': 2, '1111101100': 1, '1100001000': 1, '1010000011': 1, '0011111110': 1, '1010001110': 1, '1000001000': 1, '1000000011': 1, '1111101011': 1}
เมื่อ circuit มี classical register มากกว่าหนึ่งตัว ผลลัพธ์จะถูกเก็บไว้ในออบเจ็กต์ BitArray ที่แตกต่างกัน ตัวอย่างต่อไปนี้แก้ไข snippet ก่อนหน้าโดยแบ่ง classical register เป็น register แยกกันสองตัว:
# generate a ten-qubit GHZ circuit with two classical registers
circuit = QuantumCircuit(
qreg := QuantumRegister(10),
alpha := ClassicalRegister(1, "alpha"),
beta := ClassicalRegister(9, "beta"),
)
circuit.h(0)
circuit.cx(range(0, 9), range(1, 10))
# append measurements with the `measure_all` method
circuit.measure([0], alpha)
circuit.measure(range(1, 10), beta)
# transpile the circuit
transpiled_circuit = pm.run(circuit)
# run the Sampler job and retrieve the results
sampler = Sampler(mode=backend)
job = sampler.run([transpiled_circuit])
result = job.result()
# the data bin contains two BitArrays, one per register, and can be accessed
# as attributes using the registers' names
data = result[0].data
print(f"BitArray for register 'alpha': {data.alpha}")
print(f"BitArray for register 'beta': {data.beta}")
BitArray for register 'alpha': BitArray(<shape=(), num_shots=4096, num_bits=1>)
BitArray for register 'beta': BitArray(<shape=(), num_shots=4096, num_bits=9>)
ใช้ออบเจ็กต์ BitArray สำหรับการประมวลผลหลังที่มีประสิทธิภาพ
เนื่องจากอาร์เรย์โดยทั่วไปมีประสิทธิภาพดีกว่า dictionary จึงแนะนำให้ทำการประมวลผลหลังบนออบเจ็กต์ BitArray โดยตรงแทน dictionary ของจำนวนนับ คลาส BitArray มีเมธอดหลายอย่างสำหรับทำการประมวลผลหลังทั่วไป:
print(f"The shape of register `alpha` is {data.alpha.array.shape}.")
print(f"The bytes in register `alpha`, shot by shot:\n{data.alpha.array}\n")
print(f"The shape of register `beta` is {data.beta.array.shape}.")
print(f"The bytes in register `beta`, shot by shot:\n{data.beta.array}\n")
# post-select the bitstrings of `beta` based on having sampled "1" in `alpha`
mask = data.alpha.array == 0b1
ps_beta = data.beta[mask[:, 0]]
print(f"The shape of `beta` after post-selection is {ps_beta.array.shape}.")
print(f"The bytes in `beta` after post-selection:\n{ps_beta.array}")
# get a slice of `beta` to retrieve the first three bits
beta_sl_bits = data.beta.slice_bits([0, 1, 2])
print(
f"The shape of `beta` after bit-wise slicing is {beta_sl_bits.array.shape}."
)
print(f"The bytes in `beta` after bit-wise slicing:\n{beta_sl_bits.array}\n")
# get a slice of `beta` to retrieve the bytes of the first five shots
beta_sl_shots = data.beta.slice_shots([0, 1, 2, 3, 4])
print(
f"The shape of `beta` after shot-wise slicing is {beta_sl_shots.array.shape}."
)
print(
f"The bytes in `beta` after shot-wise slicing:\n{beta_sl_shots.array}\n"
)
# calculate the expectation value of diagonal operators on `beta`
ops = [SparsePauliOp("ZZZZZZZZZ"), SparsePauliOp("IIIIIIIIZ")]
exp_vals = data.beta.expectation_values(ops)
for o, e in zip(ops, exp_vals):
print(f"Exp. val. for observable `{o}` is: {e}")
# concatenate the bitstrings in `alpha` and `beta` to "merge" the results of the two
# registers
merged_results = BitArray.concatenate_bits([data.alpha, data.beta])
print(f"\nThe shape of the merged results is {merged_results.array.shape}.")
print(f"The bytes of the merged results:\n{merged_results.array}\n")
The shape of register `alpha` is (4096, 1).
The bytes in register `alpha`, shot by shot:
[[1]
[0]
[1]
...
[0]
[1]
[0]]
The shape of register `beta` is (4096, 2).
The bytes in register `beta`, shot by shot:
[[ 1 255]
[ 0 0]
[ 1 255]
...
[ 0 0]
[ 1 255]
[ 0 0]]
The shape of `beta` after post-selection is (0, 2).
The bytes in `beta` after post-selection:
[]
The shape of `beta` after bit-wise slicing is (4096, 1).
The bytes in `beta` after bit-wise slicing:
[[7]
[0]
[7]
...
[0]
[7]
[0]]
The shape of `beta` after shot-wise slicing is (5, 2).
The bytes in `beta` after shot-wise slicing:
[[ 1 255]
[ 0 0]
[ 1 255]
[ 1 255]
[ 1 255]]
Exp. val. for observable `SparsePauliOp(['ZZZZZZZZZ'],
coeffs=[1.+0.j])` is: 0.0595703125
Exp. val. for observable `SparsePauliOp(['IIIIIIIIZ'],
coeffs=[1.+0.j])` is: 0.02783203125
The shape of the merged results is (4096, 2).
The bytes of the merged results:
[[ 3 255]
[ 0 0]
[ 3 255]
...
[ 0 0]
[ 3 255]
[ 0 0]]
ข้อมูลเมตาของผลลัพธ์
นอกเหนือจากผลลัพธ์การรันแล้ว ทั้งออบเจ็กต์ PrimitiveResult และ SamplerPubResult ยังมีแอตทริบิวต์ข้อมูลเมตาเกี่ยวกับงานที่ถูกส่ง ข้อมูลเมตาที่มีข้อมูลสำหรับ PUB ที่ส่งทั้งหมด (เช่น ตัวเลือก runtime ต่างๆ ที่มี) สามารถพบได้ใน PrimitiveResult.metatada ในขณะที่ข้อมูลเมตาเฉพาะของแต่ละ PUB สามารถพบได้ใน SamplerPubResult.metadata
Sampler ฝั่งไคลเอนต์ส่งเวิร์กโหลดของมันเป็นงาน Executor เมตาดาตาของผลลัพธ์ Executor ที่อยู่เบื้องหลัง ซึ่งรวมข้อมูลเวลาการรันที่เรียกว่า execution spans พบได้ภายใต้คีย์ "executor" ของ PrimitiveResult.metadata
ในช่อง metadata การใช้งาน primitive สามารถคืนข้อมูลใดก็ได้เกี่ยวกับการรันที่เกี่ยวข้อง และไม่มีคู่คีย์-ค่าใดที่รับประกันโดย primitive พื้นฐาน ดังนั้น metadata ที่คืนมาอาจแตกต่างกันในการใช้งาน primitive ที่แตกต่างกัน
# 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:
'execution' : {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-09-01 07:46:47', stop='2026-09-01 07:46:49', size=4096>)])},
'version' : 2,
The metadata of the PubResult result is:
'circuit_metadata' : {},
ดู execution spans
Sampler ฝั่งไคลเอนต์ใช้ Executor เพื่อรันงาน ซึ่งรันงานบน QPU เป็น chunks เวลาของแต่ละ chunk อยู่ใน result.metadata["executor"].chunk_timing ซึ่งเป็นลิสต์ของออบเจ็กต์ ChunkSpan แต่ละ ChunkSpan มี timestamp start และ stop และลิสต์ของ parts โดยแต่ละ part ระบุดัชนีของ item (idx_item) และจำนวน configuration จาก item นั้น (size) ที่รันใน chunk นั้น
Sampler สร้าง Executor program item หนึ่งรายการต่อ PUB หนึ่งรายการ ดังนั้น idx_item คือดัชนีของ PUB ตามลำดับที่ส่ง PUB ให้ run() หากเปิดใช้ twirling แต่ละ randomization ของชุดค่าพารามิเตอร์แต่ละชุดจะนับเป็น configuration แยกกัน
หากต้องการแสดงภาพเวลา ให้ส่งลิสต์ไปยัง draw_chunk_timings ดังตัวอย่างต่อไปนี้
หากต้องการทราบว่า timestamp ของ chunk หมายถึงอะไร วิธีอ่านกราฟ และเหตุใดจึงอาจมีช่องว่างระหว่าง chunk ดู ดู execution spans ในคู่มืออินพุตและเอาต์พุตของ Executor
# Define a circuit with one parameter.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.cx(0, 1)
circuit.h(0)
circuit.measure_all()
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
# Define two PUBs, each with a different set of parameter values
sampler_pubs = [
(transpiled_circuit, np.random.uniform(size=(10, 1))),
(transpiled_circuit, np.random.uniform(size=(20, 1))),
]
job = sampler.run(sampler_pubs, shots=1024)
result = job.result()
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" PUB {part.idx_item}: {part.size} configurations")
fig = draw_chunk_timings(chunk_timing, names="Sampler 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:36:36.203348+00:00 to 2026-11-06 01:36:45.420844+00:00 (9.217 s)
PUB 0: 10 configurations
PUB 1: 20 configurations
Execution spans ใน Sampler แบบเดิม
ตั้งแต่ qiskit-ibm-runtime v0.50.0 เป็นต้นไป Sampler ฝั่งเซิร์ฟเวอร์แบบเดิมถูกเลิกใช้ (deprecated) Sampler ฝั่งไคลเอนต์ไม่คืนออบเจ็กต์ ExecutionSpans ให้ใช้ chunk timing ที่อธิบายไว้ก่อนหน้านี้แทน ดูย้ายไปใช้ primitives ฝั่งไคลเอนต์ สำหรับขั้นตอนการย้าย
คลิกเพื่อเรียนรู้เพิ่มเติม
ผลลัพธ์ของงานจาก Sampler ฝั่งเซิร์ฟเวอร์แบบเดิมมีข้อมูลเวลาการรันใน result.metadata["execution"]["execution_spans"] ในรูปของออบเจ็กต์ ExecutionSpans ออบเจ็กต์นี้เป็นคอนเทนเนอร์คล้ายลิสต์ของออบเจ็กต์ ExecutionSpan ซึ่งแต่ละอันระบุเวลาเริ่มต้น เวลาสิ้นสุด และข้อกำหนดว่า shots ใดบ้างที่ถูกเก็บใน span นั้น
execution span ระบุว่าข้อมูลใดถูกรันภายในช่วงเวลาของ span นั้นโดยให้เมธอด ExecutionSpan.mask เมธอดนี้เมื่อให้ดัชนี PUB ใดก็ตาม จะคืน boolean mask ที่เป็น True สำหรับ shots ทั้งหมดที่รันภายในช่วงเวลานั้น ตัวอย่างเช่น ถ้า PUB มีรูปร่าง (2, 3) และรันด้วย 4 shots รูปร่างของ mask จะเป็น (2, 3, 4) ดูหน้า API execution_span สำหรับรายละเอียดเพิ่มเติม
from qiskit.primitives import BitArray
spans = result.metadata["execution"]["execution_spans"]
# ดึง mask ของ PUB ที่ 1 สำหรับ span ที่ 0
mask = spans[0].mask(0)
# สร้าง bit array ใหม่ที่มีเฉพาะข้อมูลของ PUB-0 ที่เก็บใน span นี้
bits = result[0].data.meas
filtered_data = BitArray(bits.array[mask], bits.num_bits)
# เลือกชุดย่อยของ spans ที่อ้างอิงข้อมูลใน PUB 0 หรือ 2
spans.filter_by_pub([0, 2])
# ดูข้อมูลโดยรวมของคอลเลกชัน execution spans
print("Number of execution spans:", len(spans))
print(" Start of the first span:", spans.start)
print(" End of the last span:", spans.stop)
print(" Total duration (s):", spans.duration)
หากต้องการแสดงภาพ execution spans แบบเดิม ให้ใช้ฟังก์ชัน draw_execution_spans
เป็นไปได้ที่หน้าต่างเวลาที่ระบุโดย execution spans ที่แตกต่างกันจะซ้อนทับกัน นี่ไม่ใช่เพราะ QPU กำลังทำการรันหลายรายการพร้อมกัน แต่เป็นผลจากการประมวลผล classical บางอย่างที่อาจเกิดขึ้นพร้อมกับการรัน quantum การรับประกันคือข้อมูลที่อ้างอิงเกิดขึ้นในช่วง execution span ที่รายงานแน่นอน แต่ไม่จำเป็นว่าขอบเขตของหน้าต่างเวลาจะแคบที่สุดเท่าที่เป็นไปได้