Contoh Executor
Versi paket
Kode di halaman ini dikembangkan menggunakan persyaratan berikut. Kami sarankan pakai 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
Contoh-contoh di bagian ini mengilustrasikan beberapa cara umum menggunakan primitif Executor. Sebelum menjalankan contoh-contoh ini, ikuti instruksi di Instal Qiskit dan Quickstart Executor.
Sebelum memulai
Beberapa contoh kode di halaman ini menggunakan samplex, yang merupakan bagian dari paket Samplomatic. Oleh karena itu, sebelum menjalankan blok kode tersebut, Anda harus menginstal Samplomatic, seperti yang ditunjukkan dalam blok kode berikut. Untuk info lebih lanjut, lihat dokumentasi Samplomatic.
pip install samplomatic
# For visualization support, include the visualization dependencies.
# pip install samplomatic[vis]
Contoh: Sirkuit berparameter
Contoh ini mengilustrasikan cara menambahkan item sirkuit dengan parameter, serta cara menambahkan item samplex. Terdiri dari langkah-langkah berikut:
- Siapkan sirkuit: Hasilkan dan transpile sirkuit target.
- Siapkan samplex: Kelompokkan gate dan pengukuran ke dalam kotak beranotasi dan hasilkan pasangan template sirkuit dan samplex.
- Eksekusi: Tambahkan item sirkuit dan item samplex ke
QuantumProgramdan eksekusi keduanya dalam satu job.
Siapkan sirkuit
Siapkan state GHZ tiga qubit, rotasi qubit di sekitar sumbu Pauli-Z, dan ukur qubit dalam basis komputasi.
from qiskit.circuit import Parameter, QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np
from samplomatic import build
from samplomatic.transpiler import generate_boxing_pass_manager
# Generate the circuit
circuit = QuantumCircuit(3)
circuit.h(0)
circuit.h(1)
circuit.cz(0, 1)
circuit.h(1)
circuit.h(2)
circuit.cz(1, 2)
circuit.h(2)
circuit.rz(Parameter("theta"), 0)
circuit.rz(Parameter("phi"), 1)
circuit.rz(Parameter("lam"), 2)
circuit.measure_all()
Tentukan Backend dan transpile sirkuit agar hanya menggunakan instruksi yang didukung oleh QPU (disebut sebagai sirkuit instruction set architecture (ISA)).
# Initialize the service and choose a backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Transpile the circuit to ISA
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=3
)
isa_circuit = preset_pass_manager.run(circuit)
Siapkan samplex
Gunakan fungsi kemudahan generate_boxing_pass_manager dan parameter twirling-nya untuk mengelompokkan gate dua qubit dan pengukuran ke dalam kotak dan menerapkan anotasi twirling.
boxing_pm = generate_boxing_pass_manager(
# Add gate twirling
enable_gates=True,
# Add measurement twirling
enable_measures=True,
)
boxed_circuit = boxing_pm.run(isa_circuit)
Gunakan metode build untuk menghasilkan template sirkuit dan samplex.
# Build the template circuit and the samplex
template_circuit, samplex = build(boxed_circuit)
Eksekusi sirkuit
Executor menjalankan objek QuantumProgram. Setiap QuantumProgram bisa mengandung beberapa item. Contoh ini menambahkan item sirkuit dan item samplex untuk dieksekusi. Untuk detail lengkap, lihat Input dan output Executor.
Langkah pertama adalah menginisialisasi program kosong, meminta 1024 shots untuk setiap konfigurasi dari setiap item.
# Generate a quantum program
program = QuantumProgram(shots=1024)
Tambahkan item sirkuit ke QuantumProgram. Item sirkuit ini terdiri dari dua bagian - sirkuit ISA dan 10 set nilai parameternya.
# Append the circuit and the parameter values to the program
program.append_circuit_item(
isa_circuit,
circuit_arguments=np.random.rand(10, 3), # 10 sets of parameter values
)
Tambahkan item samplex ke QuantumProgram dengan argumen-argumen ini:
- Template sirkuit dan samplex yang dihasilkan oleh fungsi
build - Sepuluh set nilai parameter untuk sirkuit asli
- Jumlah randomisasi yang akan dilakukan
# Append the template circuit and samplex as a samplex item
program.append_samplex_item(
template_circuit,
samplex=samplex,
samplex_arguments={
"parameter_values": np.random.rand(
10, 3
), # 10 sets of parameter values
},
shape=(2, 14, 10),
)
Jalankan job Executor
# initialize an Executor with default options
executor = Executor(mode=backend)
# Submit the job
job = executor.run(program)
# Retrieve the result
result = job.result()
Ambil hasil untuk setiap tugas.
# Access the results of the classical register of task #0, the CircuitItem
result_0 = result[0]["meas"]
# Access the results of the classical register of task #1, the SamplexItem
result_1 = result[1]["meas"]
Contoh: Lakukan PEC
Contoh ini menunjukkan cara menggunakan item samplex untuk melakukan probabilistic error cancellation (PEC) untuk mitigasi error.
Pertimbangkan versi mirrored dari sirkuit dengan sepuluh qubit dan dua layer unik gate CX. Ini adalah tugas-tugas utamanya:
- Eksekusi sirkuit dengan twirling.
- Eksekusi sirkuit dengan mitigasi PEC, seperti dalam paper "Probabilistic error cancellation with sparse Pauli-Lindblad models on noisy quantum processors".
Pipeline terdiri dari langkah-langkah berikut:
- Siapkan: Hasilkan sirkuit target dan kelompokkan operasinya ke dalam kotak.
- Pelajari: Pelajari noise dari instruksi yang ingin kita mitigasi dengan PEC.
- Eksekusi: Jalankan sirkuit pada Backend.
- Analisis: Post-process dan analisis hasilnya.
Untuk perbandingan, kita akan menjalankan sirkuit mirrored ini dua kali. Sekali hanya dengan Pauli-twirling yang diterapkan, dan sekali dengan mitigasi PEC yang diterapkan.
Penggunaan untuk contoh ini adalah sekitar 10 menit pada prosesor Heron r2.
Siapkan sirkuit
Pilih Backend dan siapkan sirkuit 10 qubit.
from qiskit_ibm_runtime import QiskitRuntimeService, Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.transpiler import generate_preset_pass_manager
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic import build
# Initialize the service and choose a backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Prepare a circuit
num_qubits = 10
num_layers = 10
qubits = list(range(num_qubits))
circuit = QuantumCircuit(num_qubits)
for layer_idx in range(num_layers):
circuit.rx(Parameter(f"theta_{layer_idx}"), qubits)
for i in range(num_qubits // 2):
circuit.cz(qubits[2 * i], qubits[2 * i + 1])
circuit.rx(Parameter(f"phi_{layer_idx}"), qubits)
for i in range(num_qubits // 2 - 1):
circuit.cz(qubits[2 * i] + 1, qubits[2 * i + 1] + 1)
circuit.draw("mpl", scale=0.35, fold=100)
Gabungkan sirkuit dengan inversnya untuk membuat sirkuit mirror.
mirror_circuit = circuit.compose(circuit.inverse())
mirror_circuit.measure_all()
mirror_circuit.draw("mpl", scale=0.35, fold=100)
Atur beberapa nilai parameter:
import numpy as np
parameter_values = np.random.rand(mirror_circuit.num_parameters)
Gunakan pass manager untuk mentranspile sirkuit menjadi sirkuit ISA.
preset_pass_manager = generate_preset_pass_manager(
backend=backend,
optimization_level=3,
)
isa_circuit = preset_pass_manager.run(mirror_circuit)
Selanjutnya, kelompokkan gate dan pengukuran ke dalam kotak beranotasi. Kamu bisa melakukan ini secara manual atau menggunakan fungsi generate_boxing_pass_manager dari Samplomatic untuk kemudahan. Sirkuit pertama hanya akan memiliki twirling yang diterapkan dan oleh karena itu hanya memerlukan anotasi Twirl. Sirkuit kedua akan dijalankan dengan mitigasi PEC penuh dan memerlukan anotasi Twirl dan InjectNoise.
# Pass manager used to create twirled-annotated boxes.
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
)
mirror_circuit_twirl = boxing_pm.run(isa_circuit)
# Pass manager used to create a new boxed circuit with
# both Twirl and InjectNoise annotations.
boxing_pm = generate_boxing_pass_manager(
enable_gates=True,
enable_measures=True,
inject_noise_targets="gates", # no measurement mitigation
inject_noise_strategy="uniform_modification",
)
mirror_circuit_pec = boxing_pm.run(isa_circuit)
Pelajari noise
Untuk meminimalkan jumlah eksperimen pembelajaran noise, identifikasi instruksi unik dalam sirkuit kedua (yang memiliki kotak beranotasi InjectNoise). Dalam mendefinisikan keunikan, dua instruksi kotak sama jika keduanya benar:
- Kontennya sama, hingga gate satu qubit.
- Anotasi
Twirlmereka sama (setiap anotasi lain diabaikan).
Ini menghasilkan tiga instruksi unik, yaitu kotak gate ganjil dan genap, dan kotak pengukuran akhir.
from samplomatic.utils import find_unique_box_instructions
unique_box_instructions = find_unique_box_instructions(
mirror_circuit_pec.data
)
assert len(unique_box_instructions) == 3
Inisialisasi NoiseLearnerV3, pilih parameter pembelajaran dengan mengatur opsinya, dan jalankan job pembelajaran noise.
from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3
learner = NoiseLearnerV3(backend)
learner.options.shots_per_randomization = 128
learner.options.num_randomizations = 32
learner.options.layer_pair_depths = [0, 1, 2, 4, 16, 32]
learner_job = learner.run(unique_box_instructions)
learner_job.job_id()
learner_result = learner_job.result()
Konversi result ke objek yang diperlukan oleh samplex menggunakan metode result.to_dict.
noise_maps = learner_result.to_dict(
instructions=unique_box_instructions, require_refs=False
)
Eksekusi sirkuit
Executor menjalankan objek QuantumProgram. Setiap QuantumProgram bisa mengandung beberapa item, yang ditambahkan ke program. Setiap item adalah tugas yang harus dilakukan program.
Inisialisasi program kosong, meminta 1000 shots untuk setiap konfigurasi dari setiap item.
from qiskit_ibm_runtime.quantum_program import QuantumProgram
# Initialize an empty QuantumProgram
program = QuantumProgram(shots=1000)
Selanjutnya, bangun template sirkuit dan samplex untuk mirror_circuit_twirl dan tambahkan ke program. Juga minta 900 randomisasi dari samplex. Ini berarti samplex akan menghasilkan 900 set parameter, dan setiap set akan dieksekusi 1000 kali (jumlah shots) di QPU.
Ini adalah tugas pertama program (hasil 0).
template_twirl, samplex_twirl = build(mirror_circuit_twirl)
program.append_samplex_item(
template_twirl,
samplex=samplex_twirl,
samplex_arguments={"parameter_values": parameter_values},
shape=(900,),
)
Demikian pula, tambahkan template sirkuit dan samplex yang dibangun untuk mirror_circuit_pec, meminta 900 randomisasi. Ini adalah tugas kedua program (hasil 1).
template_pec, samplex_pec = build(mirror_circuit_pec)
program.append_samplex_item(
template_pec,
samplex=samplex_pec,
samplex_arguments={
"parameter_values": parameter_values,
"pauli_lindblad_maps": noise_maps,
"noise_scales": {
ref: -1.0 for ref in noise_maps
}, # Set the scales to -1 for PEC
},
shape=(900,),
)
Import Executor dan kirimkan job.
from qiskit_ibm_runtime.executor import Executor
executor = Executor(backend)
executor_job = executor.run(program)
executor_job.job_id()
executor_results = executor_job.result()
executor_results
twirl_result = executor_results[0]
print(f"Twirl result keys:\n {list(twirl_result.keys())}\n")
print(f"Shape of results: {twirl_result['meas'].shape}")
pec_result = executor_results[1]
print(f"PEC result keys:\n {list(pec_result.keys())}\n")
print(f"Shape of results: {pec_result['meas'].shape}")
Twirl result keys:
['meas', 'measurement_flips.meas']
Shape of results: (900, 1000, 10)
PEC result keys:
['meas', 'measurement_flips.meas', 'pauli_signs']
Shape of results: (900, 1000, 10)
Analisis hasil
Terakhir, post-process hasilnya untuk memperkirakan nilai ekspektasi operator Pauli-Z satu qubit yang bertindak pada masing-masing dari sepuluh qubit aktif (nilai yang diharapkan: 1.0).
# Undo measurement twirling
twirl_result_unflipped = (
twirl_result["meas"] ^ twirl_result["measurement_flips.meas"]
)
# Calculate the expectation values of single-qubit Z operators
exp_vals = 1 - 2 * twirl_result_unflipped.mean(axis=1).mean(axis=0)
for qubit, val in enumerate(exp_vals):
print(f"Qubit {qubit} -> {np.round(val, 2)}")
Qubit 0 -> 0.77
Qubit 1 -> 0.76
Qubit 2 -> 0.66
Qubit 3 -> 0.71
Qubit 4 -> 0.69
Qubit 5 -> 0.67
Qubit 6 -> 0.62
Qubit 7 -> 0.59
Qubit 8 -> 0.62
Qubit 9 -> 0.68
# Undo measurement twirling
pec_result_unflipped = (
pec_result["meas"] ^ pec_result["measurement_flips.meas"]
)
# Calculate the signs for PEC mitigation
signs = np.prod((-1) ** pec_result["pauli_signs"], axis=-1)
signs = signs.reshape((signs.shape[0], 1))
# Calculate the expectation values of single-qubit Z operators as required by
# PEC mitigation
exp_vals = 1 - (2 * pec_result_unflipped.mean(axis=1) * signs).mean(axis=0)
for qubit, val in enumerate(exp_vals):
print(f"Qubit {qubit} -> {np.round(val, 2)}")
Qubit 0 -> 0.98
Qubit 1 -> 0.99
Qubit 2 -> 0.96
Qubit 3 -> 0.98
Qubit 4 -> 0.98
Qubit 5 -> 0.98
Qubit 6 -> 0.98
Qubit 7 -> 0.95
Qubit 8 -> 0.95
Qubit 9 -> 0.94
Langkah berikutnya
- Tinjau gambaran umum broadcasting.
- Pelajari cara menggunakan opsi Executor.
- Pahami model eksekusi terarah.
- Tinjau dokumentasi Samplomatic.
- Pelajari cara menggabungkan teknik mitigasi error yang berbeda saat menggunakan model eksekusi terarah dalam tutorial Probabilistic error cancellation with shaded lightcones.