Input dan output Executor
Versi paket
Kode di halaman ini dikembangkan menggunakan persyaratan berikut. Kami menyarankan menggunakan versi ini atau yang lebih baru.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
samplomatic~=0.18.0
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime samplomatic
Primitif Executor adalah bagian dari model eksekusi terarah, yang memberikan fleksibilitas lebih saat menyesuaikan alur kerja mitigasi error.
Input dan output primitif Executor sangat berbeda dari primitif Sampler dan Estimator. Misalnya, alih-alih mengambil daftar PUB sebagai input, Executor mengambil QuantumProgram, yang berisi daftar objek QuantumProgramItem. Kelas kontainer ini memberikan lebih banyak fleksibilitas daripada PUB, yang merupakan struktur data tuple sederhana.
Output Executor adalah QuantumProgramResult, yang merupakan iterable dan berisi satu elemen untuk setiap QuantumProgramItem input.
Input: Program quantum
Seperti yang disebutkan sebelumnya, input ke primitif Executor adalah QuantumProgram, yang merupakan iterable dari objek QuantumProgramItem. Objek-objek ini bisa berupa dua tipe:
CircuitItem, yang biasanya menyimpan circuit dan nilai parameternya (jika ada).SamplexItem, yang biasanya menyimpan hal-hal berikut:- Template circuit
- Objek samplex, yang digunakan untuk menghasilkan sekumpulan parameter teracak saat runtime (misalnya untuk melakukan twirling atau menyuntikkan noise)
- Argumen untuk samplex, yang mungkin mencakup nilai parameter untuk circuit asli
Setiap item ini merepresentasikan tugas berbeda yang harus dilakukan Executor.
Sebelum kamu mulai
Beberapa contoh kode di halaman ini menggunakan samplex, yang merupakan bagian dari paket Samplomatic. Karena itu, sebelum menjalankan blok kode tersebut, kamu harus menginstal Samplomatic, seperti yang ditunjukkan di blok kode berikut. Untuk informasi lebih lanjut, lihat dokumentasi Samplomatic.
pip install samplomatic
# For visualization support, include the visualization dependencies.
# pip install samplomatic[vis]
Contoh: Buat QuantumProgram dengan dua tugas berbeda
Pertama inisialisasi program quantum-mu, lalu tambahkan item program ke dalamnya menggunakan append_circuit_item atau append_samplex_item (jika ada samplex), seperti yang ditunjukkan dalam contoh berikut.
Sel berikut menginisialisasi QuantumProgram dan menentukan bahwa ia harus menjalankan 1024 shot untuk setiap konfigurasi dari setiap item dalam program.
Tidak seperti Sampler, QuantumProgram hanya mengambil satu nilai shot. Jika kamu ingin nilai shot yang berbeda, kamu perlu QuantumProgram terpisah, yang akan menjadi job terpisah.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from qiskit_ibm_runtime import Executor, QiskitRuntimeService
from qiskit.circuit import Parameter, QuantumCircuit
import numpy as np
from samplomatic import build
from samplomatic.transpiler import generate_boxing_pass_manager
# Initialize an empty program
program = QuantumProgram(shots=1024)
# Initialize and transpile a 3-qubit quantum circuit with 2 parameters.
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.rz(Parameter("theta"), 0)
circuit.rz(Parameter("phi"), 1)
# `measure_all` adds a 3-bit classical register named "meas"
circuit.measure_all()
# Choose the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Generate a preset pass manager
# This will be used to convert the abstract circuit to an
# equivalent Instruction Set Architecture (ISA) circuit.
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=0
)
# Transpile the circuit
isa_circuit = preset_pass_manager.run(circuit)
Tambahkan CircuitItem
Selanjutnya, tambahkan circuit target, yang sudah ditranspile sesuai dengan instruction set architecture (ISA) backend, ke QuantumProgram. Karena circuit ini memiliki dua parameter, kita juga harus menyediakan nilai parameter (10 set dalam contoh ini). Menjalankan CircuitItem ini adalah tugas pertama yang akan dilakukan program.
# Append the transpiled circuit and an array
# containing 10 sets of parameter values to the program
program.append_circuit_item(
isa_circuit,
circuit_arguments=np.random.rand(
10, 2
), # 10 sets of parameter values and 2 parameters
)
Tambahkan SamplexItem
Item circuit dieksekusi tanpa jenis pengacakan apapun. Sebaliknya, item samplex memungkinkan kamu menentukan cara mengacak kontennya. Sel berikut menggunakan fungsi generate_boxing_pass_manager() untuk mengelompokkan gate dan pengukuran circuit ke dalam kotak dan menambahkan anotasi twirling ke setiap kotak. Kemudian ia menghasilkan pasangan template circuit dan samplex menggunakan fungsi build().
Menjalankan SamplexItem ini adalah tugas kedua yang akan dilakukan program.
Lihat dokumentasi API Samplomatic untuk detail lengkap tentang samplex dan argumen-argumennya. Lihat panduan Transpiler Samplomatic untuk informasi tentang penggunaan fungsi generate_boxing_pass_manager().
# Transpile the circuit, additionally grouping gates and measurements into annotated boxes
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=0
)
# Use the boxing pass manager to group gates
# and measurements into boxes and add
# a`Twirl` annotation.
preset_pass_manager.post_scheduling = generate_boxing_pass_manager(
# Add gate twirling
enable_gates=True,
# Add measurement twirling
enable_measures=True,
)
boxed_circuit = preset_pass_manager.run(circuit)
# Build the template circuit and the samplex. The template circuit has parametric gates
# without fixed values and the samplex randomly generates the parameter
# values on the server side at runtime to perform twirling.
template_circuit, samplex = build(boxed_circuit)
# Determine what arguments are required by the samplex.
# Input the arguments in samplex_arguments.
print(samplex.inputs())
TensorInterface(<
- 'parameter_values' <float64[2]>: Input parameter values to use during sampling.
>)
# Append the template circuit and samplex as a samplex item
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
# the arguments required by the samplex.sample method
"parameter_values": np.random.rand(10, 2),
},
shape=(28, 10), # 28 randomizations and 10 sets of parameter values
)
# Initialize an Executor with the default options
executor = Executor(mode=backend)
# Submit the job
job = executor.run(program)
# Retrieve the result
result = job.result()
Output
Output Executor adalah QuantumProgramResult, yang merupakan iterable. Ini berisi satu entri per QuantumProgramItem input dengan urutan yang sama seperti item input. Masing-masing item output ini adalah dictionary di mana kuncinya adalah string yang sesuai dengan nama register klasik dalam circuit input (di antaranya), sehingga kamu tidak perlu lagi menghafal nama-nama ini seperti yang kamu lakukan dengan output Sampler. Nilai dictionary bertipe np.ndarray.
Hasil dari contoh sebelumnya berisi item-item ini:
Hasil CircuitItem
Item pertama berisi hasil menjalankan tugas pertama (sebuah CircuitItem) dalam program. Ini berisi satu kunci, meas, yang merupakan nama register klasik dalam circuit input. Nilai kunci ini memetakan ke np.ndarray berbentuk (set parameter, shot, bit register), yang adalah (10, 1024, 3) untuk contoh di atas.
Kode berikut mengilustrasikan cara mengakses informasi ini:
# Access the results of the classical register of task #0, a CircuitItem
result_0 = result[0]["meas"]
print(f"Result shape: {result_0.shape}")
Result shape: (10, 1024, 3)
Hasil SamplexItem
Item kedua berisi hasil menjalankan tugas kedua (sebuah SamplexItem) dalam program. Item ini berisi beberapa kunci. Kunci meas, yang merupakan nama register klasik circuit input, memetakan ke array hasil register tersebut. Array ini berbentuk (randomisasi, set parameter, shot, bit klasik), atau (28, 10, 1024, 3) dalam contoh ini. Selain itu, output berisi kunci measurement_flips.meas, yang merupakan koreksi bit-flip untuk membatalkan measurement twirling bagi register meas. Bentuk output ini akan menjadi (28, 10, 1, 3) untuk contoh kita karena hanya satu shot yang diperlukan untuk melakukan bit-flip.
# Access the results of the classical register of task #1
result_1 = result[1]["meas"]
print(f"Result shape: {result_1.shape}")
# Access the bit-flip corrections
flips_1 = result[1]["measurement_flips.meas"]
print(f"Bit-flip corrections shape: {flips_1.shape}")
# Undo the bit flips via classical XOR
unflipped_result_1 = result_1 ^ flips_1
Result shape: (28, 10, 1024, 3)
Bit-flip corrections shape: (28, 10, 1, 3)
Langkah selanjutnya
- Jelajahi contoh-contoh yang menggunakan Executor.
- Pelajari tentang model eksekusi terarah.
- Pahami broadcasting Executor.