Lewati ke konten utama

QESEM: Sebuah Qiskit Function oleh Qedma

Lihat referensi API

Versi paket

Kode pada halaman ini dikembangkan menggunakan persyaratan berikut. Kami menyarankan untuk menggunakan versi ini atau yang lebih baru.

qiskit[all]~=2.5.0
qiskit-ibm-runtime~=0.47.0
Catatan

Qiskit Functions adalah fitur eksperimental yang hanya tersedia untuk pengguna IBM Quantum® Premium Plan, Flex Plan, dan On-Prem (via IBM Quantum Platform API) Plan users. Mereka dalam status rilis preview dan dapat berubah.

Gambaran Umum

Meskipun unit pemrosesan kuantum telah berkembang pesat dalam beberapa tahun terakhir, error akibat noise dan ketidaksempurnaan di perangkat keras yang ada tetap menjadi tantangan utama bagi pengembang algoritma kuantum. Seiring bidang ini mendekati komputasi kuantum skala utilitas yang tidak dapat diverifikasi secara klasik, solusi untuk menghilangkan noise dengan akurasi terjamin menjadi semakin penting. Untuk mengatasi tantangan ini, Qedma telah mengembangkan Quantum Error Mitigation (QESEM), yang terintegrasi secara mulus di IBM Quantum Platform sebagai Qiskit Function.

Dengan QESEM, pengguna bisa menjalankan sirkuit kuantum mereka di QPU yang berisik untuk mendapatkan hasil bebas error yang sangat akurat dengan overhead waktu QPU yang sangat efisien, mendekati batas fundamental. Untuk mencapai ini, QESEM memanfaatkan serangkaian metode proprietary yang dikembangkan oleh Qedma, untuk karakterisasi dan pengurangan error. Teknik pengurangan error mencakup optimisasi gate, transpilasi yang sadar noise, error suppression (ES), dan error mitigation (EM) yang tidak bias. Dengan kombinasi metode berbasis karakterisasi ini, pengguna bisa mendapatkan hasil yang andal dan bebas error untuk sirkuit kuantum bervolume besar yang generik, membuka aplikasi yang sebelumnya tidak bisa dicapai.

Untuk deskripsi lengkap komponen-komponen yang mendasarinya, serta demonstrasi skala utilitas, lihat makalah Reliable high-accuracy error mitigation for utility-scale quantum circuits.

Deskripsi

Kamu bisa menggunakan fungsi QESEM oleh Qedma untuk dengan mudah mengestimasi dan mengeksekusi sirkuitmu dengan error suppression dan mitigation, mencapai volume sirkuit yang lebih besar dan akurasi yang lebih tinggi. Untuk menggunakan QESEM, kamu menyediakan sebuah sirkuit kuantum, sekumpulan observabel untuk diukur, target akurasi statistik untuk setiap observabel, dan QPU yang dipilih. Sebelum menjalankan sirkuit ke akurasi target, kamu bisa mengestimasi waktu QPU yang dibutuhkan berdasarkan kalkulasi analitik yang tidak memerlukan eksekusi sirkuit. Setelah puas dengan estimasi waktu QPU, kamu bisa mengeksekusi sirkuit dengan QESEM.

Saat kamu mengeksekusi sebuah sirkuit, QESEM menjalankan protokol karakterisasi perangkat yang disesuaikan dengan sirkuitmu, menghasilkan model noise yang andal untuk error yang terjadi dalam sirkuit. Berdasarkan karakterisasi tersebut, QESEM pertama-tama mengimplementasikan transpilasi yang sadar noise untuk memetakan sirkuit input ke sekumpulan qubit fisik dan gate, yang meminimalkan noise yang memengaruhi observabel target. Ini mencakup gate yang tersedia secara native (CX/CZ di perangkat IBM®), serta gate tambahan yang dioptimalkan oleh QESEM, membentuk extended gate set QESEM. QESEM kemudian menjalankan sekumpulan sirkuit ES dan EM berbasis karakterisasi di QPU dan mengumpulkan hasil pengukurannya. Ini kemudian diproses secara klasik untuk memberikan nilai ekspektasi yang tidak bias dan error bar untuk setiap observabel, sesuai dengan akurasi yang diminta.

Gambaran umum Qedma QESEM QESEM telah terbukti memberikan hasil akurasi tinggi untuk berbagai aplikasi kuantum dan pada volume sirkuit terbesar yang dapat dicapai saat ini. QESEM menawarkan fitur-fitur berikut yang menghadap pengguna, yang didemonstrasikan di bagian benchmark di bawah:

  • Akurasi terjamin: QESEM menghasilkan estimasi yang tidak bias untuk nilai ekspektasi observabel. Metode EM-nya dilengkapi dengan jaminan teoretis, yang — bersama karakterisasi mutakhir Qedma — memastikan mitigasi konvergen ke output sirkuit tanpa noise hingga akurasi yang ditentukan pengguna. Berbeda dengan banyak metode EM heuristik yang rentan terhadap error sistematis atau bias, akurasi terjamin QESEM sangat penting untuk memastikan hasil yang andal pada sirkuit kuantum dan observabel yang generik.
  • Skalabilitas ke QPU besar: Waktu QPU QESEM bergantung pada volume sirkuit, tetapi tidak bergantung pada jumlah qubit. Qedma telah mendemonstrasikan QESEM pada perangkat kuantum terbesar yang tersedia saat ini, termasuk IBM Quantum 127-qubit Eagle dan perangkat Heron 133-qubit.
  • Agnostik aplikasi: QESEM telah didemonstrasikan pada berbagai aplikasi, termasuk simulasi Hamiltonian, VQE, QAOA, dan estimasi amplitudo. Pengguna bisa memasukkan sirkuit kuantum dan observabel apa pun untuk diukur, dan mendapatkan hasil bebas error yang akurat. Satu-satunya batasan ditentukan oleh spesifikasi perangkat keras dan waktu QPU yang dialokasikan, yang menentukan volume sirkuit yang dapat diakses dan akurasi output. Sebaliknya, banyak solusi pengurangan error yang spesifik aplikasi atau melibatkan heuristik yang tidak terkontrol, sehingga tidak berlaku untuk sirkuit kuantum dan aplikasi yang generik.
  • Extended gate set: QESEM mendukung gate dengan sudut fraksional, dan menyediakan gate Rzz(θ)Rzz(\theta) sudut fraksional yang dioptimalkan Qedma di perangkat IBM Quantum Heron dan Eagle. Extended gate set ini memungkinkan kompilasi yang lebih efisien dan membuka volume sirkuit yang lebih besar hingga faktor 2 dibandingkan kompilasi CX/CZ default.
  • Observabel multibase: QESEM mendukung observabel input yang terdiri dari banyak Pauli string yang tidak komuter, seperti Hamiltonian generik. Pemilihan basis pengukuran dan optimisasi alokasi sumber daya QPU (shots dan sirkuit) kemudian dilakukan secara otomatis oleh QESEM untuk meminimalkan waktu QPU yang dibutuhkan untuk akurasi yang diminta. Optimisasi ini, yang memperhitungkan fidelitas perangkat keras dan laju eksekusi, memungkinkan kamu menjalankan sirkuit yang lebih dalam dan mendapatkan akurasi yang lebih tinggi.

Benchmark

QESEM telah diuji pada berbagai kasus penggunaan dan aplikasi. Contoh-contoh berikut dapat membantu kamu menilai jenis workload apa yang bisa kamu jalankan dengan QESEM.

Ukuran kinerja utama untuk mengkuantifikasi tingkat kesulitan baik error mitigation maupun simulasi klasik untuk sirkuit dan observabel tertentu adalah volume aktif: jumlah gate CNOT yang memengaruhi observabel dalam sirkuit. Volume aktif bergantung pada kedalaman dan lebar sirkuit, bobot observabel, dan struktur sirkuit, yang menentukan light cone dari observabel. Untuk detail lebih lanjut, lihat pembicaraan dari IBM Quantum Summit 2024. QESEM memberikan nilai yang sangat besar di regime volume tinggi, memberikan hasil yang andal untuk sirkuit dan observabel yang generik.

Volume aktif

AplikasiJumlah qubitPerangkatDeskripsi sirkuitAkurasiTotal waktuPenggunaan runtime
Sirkuit VQE8Eagle (r3)21 total layer, 9 basis pengukuran, rantai 1D98%35 menit14 menit
Kicked Ising28Eagle (r3)3 layer unik x 3 langkah, topologi heavy-hex 2D97%22 menit4 menit
Kicked Ising28Eagle (r3)3 layer unik x 8 langkah, topologi heavy-hex 2D97%116 menit23 menit
Simulasi Hamiltonian Trotterisasi40Eagle (r3)2 layer unik x 10 langkah Trotter, rantai 1D97%3 jam25 menit
Simulasi Hamiltonian Trotterisasi119Eagle (r3)3 layer unik x 9 langkah Trotter, topologi heavy-hex 2D95%6,5 jam45 menit
Kicked Ising136Heron (r2)3 layer unik x 15 langkah, topologi heavy-hex 2D99%52 menit9 menit

Akurasi diukur di sini relatif terhadap nilai ideal observabel: OidealϵOideal\frac{\langle O \rangle_{ideal} - \epsilon}{\langle O \rangle_{ideal}}, di mana 'ϵ\epsilon' adalah presisi absolut mitigasi (ditetapkan oleh input pengguna), dan Oideal\langle O \rangle_{ideal} adalah observabel pada sirkuit tanpa noise. 'Penggunaan runtime' mengukur penggunaan benchmark dalam mode batch (jumlah penggunaan job individual), sedangkan 'total waktu' mengukur penggunaan dalam mode sesi (waktu dinding eksperimen), yang mencakup waktu klasik dan komunikasi tambahan. QESEM tersedia untuk eksekusi dalam kedua mode, sehingga pengguna bisa memanfaatkan sumber daya yang tersedia sebaik mungkin.

Sirkuit Kicked Ising 28-qubit mensimulasikan Discrete Time Quasicrystal yang dipelajari oleh Shinjo et al. (lihat arXiv 2403.16718 dan Q2B24 Tokyo) pada tiga loop terhubung dari ibm_kawasaki. Parameter sirkuit yang digunakan di sini adalah (θx,θz)=(0.9π,0)(\theta_x, \theta_z) = (0.9 \pi, 0), dengan keadaan awal feromagnetik ψ0=0n| \psi_0 \rangle = | 0 \rangle ^{\otimes n}. Observabel yang diukur adalah nilai absolut magnetisasi M=128i=027ZiM = |\frac{1}{28} \sum_{i=0}^{27} \langle Z_i \rangle|. Eksperimen Kicked Ising skala utilitas dijalankan pada 136 qubit terbaik dari ibm_fez; benchmark khusus ini dijalankan pada sudut Clifford (θx,θz)=(π,0)(\theta_x, \theta_z) = (\pi, 0), di mana volume aktif tumbuh perlahan seiring kedalaman sirkuit, yang — bersama fidelitas perangkat yang tinggi — memungkinkan akurasi tinggi pada waktu runtime yang singkat.

Sirkuit simulasi Hamiltonian Trotterisasi untuk model Ising Transverse-Field pada sudut fraksional: (θzz,θx)=(π/4,π/8)(\theta_{zz}, \theta_x) = (\pi / 4, \pi /8) dan (θzz,θx)=(π/6,π/8)(\theta_{zz}, \theta_x) = (\pi / 6, \pi / 8) secara berurutan (lihat Q2B24 Tokyo). Sirkuit skala utilitas dijalankan pada 119 qubit terbaik dari ibm_brisbane, sedangkan eksperimen 40-qubit dijalankan pada rantai terbaik yang tersedia. Akurasi dilaporkan untuk magnetisasi; hasil akurasi tinggi juga diperoleh untuk observabel dengan bobot yang lebih tinggi.

Sirkuit VQE dikembangkan bersama peneliti dari Center for Quantum Technology and Applications di Deutsches Elektronen-Synchrotron (DESY). Observabel target di sini adalah Hamiltonian yang terdiri dari sejumlah besar Pauli string yang tidak komuter, menekankan kinerja QESEM yang dioptimalkan untuk observabel multi-basis. Mitigasi diterapkan pada ansatz yang dioptimalkan secara klasik; meskipun hasil ini masih belum dipublikasikan, hasil dengan kualitas yang sama akan diperoleh untuk sirkuit yang berbeda dengan properti struktural yang serupa.

Memulai

Autentikasi menggunakan kunci API IBM Quantum Platform-mu, dan pilih Qiskit Function QESEM sebagai berikut. (Cuplikan ini mengasumsikan kamu sudah menyimpan akunmu ke lingkungan lokalmu.)

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-catalog qiskit-ibm-runtime
import qiskit
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# verify that you have access to the function
catalog.list()
# load the function
qesem_function = catalog.load("qedma/qesem")

Contoh

Contoh job estimasi waktu

Job estimasi waktu berguna untuk memperkirakan waktu QPU yang dibutuhkan untuk pub dan backend_name tertentu. backend_name juga bisa diatur ke backend simulator mana pun; misalnya, fake_fez.

QESEM menggunakan metode EM berbasis karakterisasi yang bersifat kuasi-probabilistik. Metode ini memiliki overhead waktu QPU yang kira-kira berskala sebagai:

TQPU=aeαIFVaϵ2+bT_{QPU} = a \frac{e^{\alpha IF\cdot V_a}}{\epsilon^2} + b

Di mana VaV_a adalah volume aktif dari circuit, ϵ\epsilon adalah presisi target, dan IFIF adalah infidelity dari native gate.

Perhatikan bahwa "estimate_time_only": "empirical" menggunakan beberapa menit waktu QPU untuk memperkirakan waktu yang dibutuhkan untuk job (jika backend adalah perangkat nyata; jika berupa simulator, maka tidak ada waktu QPU yang digunakan). Ini biasanya membutuhkan waktu sekitar 5 menit, tapi tidak lebih dari 10 menit. Jika infidelity berubah secara drastis antara job estimasi waktu empiris dan job mitigasi, waktu QPU juga akan berubah secara drastis.

Untuk memulai, coba contoh dasar ini tentang mengestimasi waktu QPU yang dibutuhkan untuk menjalankan QESEM untuk pub tertentu:

# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend_name = service.least_busy().name
backend_name = "fake_fez"

circ = qiskit.QuantumCircuit(5)
circ.cx(0, 1)
circ.cx(2, 3)
circ.cx(1, 2)
circ.cx(3, 4)

avg_magnetization = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("Z", [q], 1 / 5) for q in range(5)], num_qubits=5
)
other_observable = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("ZZ", [0, 1], 1.0), ("XZ", [1, 4], 0.5)], num_qubits=5
)

time_estimation_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
options={
"estimate_time_only": "empirical",
},
backend_name=backend_name, # example: "fake_fez", "ibm_fez"
)
time_estimate_result = (
time_estimation_job.result()
) # a list of results per pub (circuit)

Cuplikan kode berikut menjelaskan cara mengambil berbagai metrik eksekusi dari job estimasi waktu (estimate_time_only diset):

pub_result = time_estimate_result[0]

print(
f"The estimated QPU time for mitigation for this PUB is: {pub_result.metadata['time_estimation_sec']}"
)
print(
f"The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f"Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f"Total shots: {pub_result.metadata['total_shots']}")
print(f"Resource usage breakdown: {pub_result.metadata['resource_usage']}")
The estimated QPU time for mitigation for this PUB is: 300
The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): 0
Gates fidelity measured during the experiment: {'CZ': 0.9951354916722668, 'ID1Q': 0.9991246627329172}
Total shots: 220000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 33.6066133165732, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 184.53575124032795, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

Ketika estimasi waktu empiris diaktifkan, QESEM menjalankan sejumlah kecil circuit untuk memberikan estimasi waktu QPU yang lebih akurat. Hasil mitigasi dari circuit-circuit ini tersedia di field empirical_estimation_mitigation_results pada job.

Karena hasil-hasil ini diperoleh dari sampel circuit yang terbatas, hasilnya jauh lebih tidak akurat dibandingkan dengan hasil akhir yang diperoleh dari job mitigasi QESEM lengkap. Namun, ketika circuit kecil atau presisi target rendah, mitigasi yang dilakukan selama estimasi waktu empiris mungkin sudah cukup untuk mencapai presisi yang diinginkan, dan job mitigasi lengkap mungkin tidak diperlukan.

Field empirical_estimation_mitigation_results adalah daftar objek PrimitiveResult per parameter input. Jika circuit tidak diparameterisasi, daftar tersebut akan memiliki panjang 1.

empirical_estimation_mitigation_results = time_estimate_result[0].metadata[
"empirical_estimation_mitigation_results"
][0] # a list per parameter
print("Partial results for the observables:")

print(
f" Mitigated expectation values: {empirical_estimation_mitigation_results.data.evs}"
)
print(
f" Mitigated error bars: {empirical_estimation_mitigation_results.data.stds}"
)
print(
f" Number of shots used for mitigation: {empirical_estimation_mitigation_results.metadata['mitigation_shots']}"
)
transpiled_circ = empirical_estimation_mitigation_results.metadata[
"transpiled_circ"
]
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Number of measurement bases: {transpiled_circ['num_measurement_bases']}\n"
)

# results per obs
emp_obs_results = empirical_estimation_mitigation_results.metadata["results"][
0
]
# print(f"Results for each observable: {results}")
print("Results for each observable:")

for i, (obs_array, result_dict) in enumerate(emp_obs_results):
# obs_array, result_dict = results
print(f"Observable {i+1}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} \u00b1 {result_dict['qesem']['error_bar']}"
)
Partial results for the observables:
Mitigated expectation values: [1.00347302 1.00693905]
Mitigated error bars: [0.00304061 0.00714276]
Number of shots used for mitigation: 180000
Qubit mapping: [[[0, 136], [1, 143], [2, 142], [3, 141], [4, 140]]]
Number of measurement bases: 2

Results for each observable:
Observable 1: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.003473015776871 ± 0.0030406128032204015
Observable 2: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0069390542613554 ± 0.0071427606736885925

Contoh job mitigasi QESEM

Contoh berikut mengeksekusi sebuah job QESEM:

sample_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
backend_name=backend_name, # example: "ibm_fez"
# options = {
# "estimate_time_only": "empirical",
# "default_precision": 0.2, # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
# "max_execution_time": 3600, # You can specify a maximum QPU time in seconds, see API reference for more details
# "transpilation_level": "standard", # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
# "parallel_execution": True, # True for parallel execution, see API reference for more details
# },
)

Untuk deskripsi rinci setiap field input dan opsi, lihat referensi API QESEM. Kamu bisa menggunakan API Qiskit Serverless yang familiar untuk memeriksa status workload Qiskit Function-mu atau mengembalikan hasilnya:

# Print the ID so you can use it later, if necessary
print(sample_job.job_id)
print(sample_job.status())
sample_result = sample_job.result()
3ac6b2df-15b0-4dc0-8f48-cf14bd20a1c8
DONE

Cuplikan kode berikut mendemonstrasikan cara mengambil hasil mitigasi dan metrik eksekusi. Ini berisi data penting yang memungkinkan pemahaman lebih mendalam tentang bagaimana parameter berbeda memengaruhi eksekusi QESEM. Ini juga mungkin relevan saat menulis makalah berdasarkan penelitianmu.

for pub_idx, pub_result in enumerate(
sample_result
): # each element in the list is a result for a different pub, here we sent only one pub
print(f"\nPUB {pub_idx}:")
print(
f" The QPU time that this job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f" Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f" Total shots: {pub_result.metadata['total_shots']}")
print(
f" Number of shots used for mitigation: {pub_result.metadata['mitigation_shots']}"
)
print(
f" Resource usage breakdown: {pub_result.metadata['resource_usage']}"
)
PUB 0:
The QPU time that this job took is (here it is 0 because we used fake_fez): 0.0
Gates fidelity measured during the experiment: {'CZ': 0.9953704216147041, 'ID1Q': 0.9991834123567518}
Total shots: 446000
Number of shots used for mitigation: 194000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 32.52745003718883, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 257.850521848537, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

Di metadata["results"], hasil dikelompokkan pertama berdasarkan circuit instance dan kemudian berdasarkan observable.

print("Full QESEM mitigation results:")

for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")

print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata.get("noisy_results")
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")

print(" Transpiled circuits:")
for circ_idx, transpiled_circ in enumerate(
pub_result.metadata["transpiled_circs"]
):
print(f" Circuit {circ_idx}:")
# print(f" Circuit: \n {transpiled_circ['circuit']}") # not printing it because it's long but you can see the transpiled circuit itself
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Measurement bases: {transpiled_circ['num_measurement_bases']}"
)

print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Full QESEM mitigation results:

PUB 0:
Mitigated expectation values: [1.00648343 1.00636289]
Mitigated error bars: [0.00253812 0.00693586]
Unmitigated expectation values: [0.98031429 0.96357143]
Unmitigated error bars: [0.00124128 0.00578812]
Transpiled circuits:
Circuit 0:
Qubit mapping: [[[0, 140], [1, 141], [2, 142], [3, 143], [4, 136]]]
Measurement bases: 2
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.0064834305181962 ± 0.002538119914534849
Unmitigated value: 0.9803142857142859 ± 0.0012412835813609938
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0063628870614818 ± 0.006935859820870656
Unmitigated value: 0.9635714285714285 ± 0.005788121870526659

Rincian hasil utama:

  • mitigated: nilai ekspektasi QESEM yang sepenuhnya termitigasi.
  • unmitigated: hasil noise fisik mentah tanpa mitigasi error.

Hasil ekstrapolasi heuristik QESEM

Dalam run QESEM standar dengan satu float precision, hasilnya juga menyertakan titik penskalaan noise yang tersedia secara otomatis yang digunakan untuk heuristik QESEM. Titik-titik ini dihitung tanpa sumber daya QPU tambahan.

Skala 1.0 merepresentasikan tingkat noise perangkat fisik dengan mitigasi readout (REM), sedangkan skala 2.0 adalah titik komplementer dengan noise yang diperkuat, juga dengan REM. Titik-titik ini digunakan untuk menghasilkan hasil qesem_heuristic.

  • qesem_heuristic: estimasi bergaya ZNE yang dihitung dari data hasil penskalaan noise yang tersedia. Saat ini, ini menggunakan ekstrapolasi eksponensial.

  • noise_scaling.results_with_REM: nilai ekspektasi pada skala noise yang berbeda, semuanya dengan mitigasi readout (REM).

Detail yang halus namun penting adalah bahwa hasil skala 1.0 tidak sama dengan hasil unmitigated. Keduanya sesuai dengan tingkat noise perangkat fisik, tetapi titik skala 1.0 menyertakan mitigasi readout, sedangkan unmitigated tidak.

print("QESEM heuristic results:")

for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
qesem_heuristic = result_dict["qesem_heuristic"][0]
print(" QESEM heuristic:")
print(
f" Value: {qesem_heuristic['value']} ± {qesem_heuristic['error_bar']}"
)
print(
f" Extrapolation: {qesem_heuristic['extrapolation']}"
)
print(
f" Scale factors: {qesem_heuristic['scale_factors']}"
)
noise_scaling = result_dict["noise_scaling"]
print(" Noise scaling results:")
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QESEM heuristic results:

PUB 0:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM heuristic:
Value: 1.0008161638888535 ± 0.0038859458884403964
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9918395459270772 ± 0.0012565417579355634
Scale factor 2.0: 0.982943441922748 ± 0.0028919278067695018
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM heuristic:
Value: 0.9960853148925298 ± 0.013811635038961175
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9902860583785115 ± 0.005921236914723409
Scale factor 2.0: 0.984520565414274 ± 0.006909522262347639
catatan

Contoh berikut fokus pada input dan hasil yang spesifik untuk fitur tertentu, jadi mereka tidak mencetak metrik eksekusi lengkap setiap kali. Metadata tingkat atas yang ditunjukkan sebelumnya, seperti total_qpu_time, gate_fidelities, total_shots, mitigation_shots, dan resource_usage, juga tersedia untuk job-job ini.

Beberapa variabel dari contoh sebelumnya, termasuk backend, observable, dan parameter circuit dasar, digunakan kembali di bawah ini demi keringkasan.

catatan

Semua contoh berikut juga bisa dijalankan dengan estimasi waktu empiris. Untuk mengaktifkannya, sertakan "estimate_time_only": "empirical" dalam opsi fungsi.

Contoh circuit terparameterisasi

Banyak algoritma mengevaluasi circuit yang sama pada beberapa nilai parameter. Mengirim circuit terparameterisasi sebagai satu job QESEM memungkinkan QESEM berbagi karakterisasi dan kalibrasi di seluruh circuit instance, yang bisa mengurangi overhead waktu QPU dibandingkan dengan menjalankan job terpisah.

Mengirimkan circuit terparameterisasi memerlukan penggunaan level transpilasi "minimal_with_layout_opt". Circuit yang dikirim pada level ini seharusnya sudah dinyatakan menggunakan basis gate backend, tergantung pada backend. Pada level ini, QESEM menjaga struktur yang dikirim sedekat mungkin dengan circuit input, menghormati barrier selama layerification (mengelompokkan operasi ke dalam layer gate dua-qubit paralel), dan tetap menangani pemetaan hardware ke qubit dengan fidelitas tinggi dan konektivitas perangkat secara otomatis.

Dalam praktiknya, ini berarti kamu harus mentranspilasi circuit ke basis gate backend target sebelum pengiriman. Contoh transpilasi basis gate sederhana ditunjukkan di bawah ini.

QESEM saat ini hanya mendukung satu observable per parameter set. Dua baris parameter di bawah ini di-zip dengan dua observable: baris pertama diukur dengan avg_magnetization, dan baris kedua diukur dengan other_observable.

# Transpile to the backend basis gates only. With minimal_with_layout_opt, QESEM handles hardware mapping/connectivity and observable layout internally.
from qiskit_ibm_runtime.fake_provider import FakeFez

backend = FakeFez()
basis = backend.operation_names
print(basis)

param0 = qiskit.circuit.Parameter("param0")
param1 = qiskit.circuit.Parameter("param1")
parametrized_circ = qiskit.QuantumCircuit(5)
parametrized_circ.rx(param0, 0)
parametrized_circ.rx(param1, 1)
parametrized_circ.cx(0, 1)
parametrized_circ.cx(2, 3)
parametrized_circ.cx(1, 2)
parametrized_circ.cx(3, 4)

parametrized_circ = qiskit.transpile(
parametrized_circ, basis_gates=basis, optimization_level=1
)
parametrized_parameter_values = [[0.5, 0.1], [0.0, 0.6]]
parametrized_observables = [avg_magnetization, other_observable]

parametrized_job = qesem_function.run(
pubs=[
(
parametrized_circ,
parametrized_observables,
parametrized_parameter_values,
0.1,
)
],
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
},
)
print(parametrized_job.job_id)
print(parametrized_job.status())
d1b0e29b-196c-4896-aec6-44a268ebd874
DONE
parametrized_result = parametrized_job.result()
print("Parameterized circuit QESEM results:")

for pub_idx, pub_result in enumerate(parametrized_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each parameter value:")
for param_idx, param_results in enumerate(pub_result.metadata["results"]):
print(
f" Parameter set {param_idx}: {parametrized_parameter_values[param_idx]}"
)
for obs_idx, (obs_array, result_dict) in enumerate(param_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Parameterized circuit QESEM results:

PUB 0:
Mitigated expectation values: [0.92392021 0.82517653]
Mitigated error bars: [0.00565281 0.00616016]
Unmitigated expectation values: [0.9028 0.78771429]
Unmitigated error bars: [0.00335142 0.00925413]
Results for each parameter value:
Parameter set 0: [0.5, 0.1]
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.923920210615709 ± 0.005652811570890183
Unmitigated value: 0.9028 ± 0.0033514176105045447
Parameter set 1: [0.0, 0.6]
Observable 0: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 0.8251765289285893 ± 0.006160161743353999
Unmitigated value: 0.7877142857142858 ± 0.009254130564027902

Contoh multi-pub

Eksekusi multi-pub berguna ketika kamu ingin menjalankan beberapa circuit terkait dalam satu job QESEM. Seperti eksekusi terparameterisasi, ini bisa mengurangi overhead karena QESEM bisa berbagi karakterisasi dan kalibrasi di seluruh circuit instance alih-alih mengulanginya dalam job terpisah.

Ini sangat berguna untuk circuit dengan struktur layer bersama, seperti workload bertipe Trotter, di mana circuit yang berbeda menggunakan kembali layer unik yang sama. Dalam kasus itu, menjalankannya bersama-sama bisa mengurangi biaya karakterisasi dibandingkan dengan job QESEM independen.

Job multi-pub memerlukan "transpilation_level": "minimal_with_layout_opt". Seperti pada contoh terparameterisasi, circuit harus ditranspilasi ke basis gate backend target sebelum pengiriman. QESEM kemudian menangani konektivitas perangkat, layout, dan pemetaan ke qubit dengan fidelitas tinggi secara internal.

Setiap PUB di bawah ini berisi satu circuit dan dua observable yang sama yang digunakan sebelumnya dalam notebook, sehingga PrimitiveResult yang dikembalikan berisi satu PubResult per circuit input.

Contoh di bawah ini menggunakan dua circuit Trotter sederhana dengan pola layer yang sama: circ_a memiliki satu layer Trotter, dan circ_b mengulangi pola layer yang sama dua kali. Ini membuat struktur bersama menjadi eksplisit.

def make_trotter_circuit(num_qubits, num_layers, zz_angle=0.2, x_angle=0.1):
trotter_circ = qiskit.QuantumCircuit(num_qubits)
for _ in range(num_layers):
for q in range(num_qubits):
trotter_circ.rx(x_angle, q)
trotter_circ.barrier()
for q in range(0, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
for q in range(1, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
return trotter_circ

circ_a = make_trotter_circuit(num_qubits=5, num_layers=1)
circ_b = make_trotter_circuit(num_qubits=5, num_layers=2)
multi_pubs = [
(
qiskit.transpile(qci, basis_gates=basis, optimization_level=1),
[avg_magnetization, other_observable],
)
for qci in [circ_a, circ_b]
]

multi_circ_job = qesem_function.run(
pubs=multi_pubs,
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
"default_precision": 0.1,
},
)
print(multi_circ_job.job_id)
print(multi_circ_job.status())
e34565b8-7262-4133-a120-de42ce624a99
DONE
multi_circ_result = multi_circ_job.result()
print("Multi-pub QESEM results:")

for pub_idx, pub_result in enumerate(multi_circ_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Multi-pub QESEM results:

PUB 0:
Mitigated expectation values: [0.99502406 1.02209332]
Mitigated error bars: [0.00483819 0.00707488]
Unmitigated expectation values: [0.96934286 0.97271429]
Unmitigated error bars: [0.00124855 0.00617294]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.9950240647925642 ± 0.004838188086259301
Unmitigated value: 0.9693428571428573 ± 0.0012485470362492692
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0220933230604674 ± 0.007074884384355636
Unmitigated value: 0.9727142857142859 ± 0.006172939375512439

PUB 1:
Mitigated expectation values: [0.98850017 1.02555188]
Mitigated error bars: [0.0077912 0.01672652]
Unmitigated expectation values: [0.93682857 0.95371429]
Unmitigated error bars: [0.00156245 0.00665735]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.988500171577252 ± 0.007791203181151346
Unmitigated value: 0.9368285714285716 ± 0.001562451883089579
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.02555188098689 ± 0.016726524388086233
Unmitigated value: 0.9537142857142858 ± 0.006657345655544263

Contoh Quasi-probabilistic Error Tuning (QET)

Quasi-probabilistic Error Tuning (QET) meminta nilai ekspektasi pada faktor skala noise yang dipilih. Ini berguna untuk studi penskalaan noise kustom dan workflow Zero-Noise Extrapolation. Skala 1.0 adalah tingkat noise fisik, nilai antara 0.0 dan 1.0 mengurangi noise sebagian, dan nilai di atas 1.0 memperkuat noise.

Untuk menggunakan QET dengan Qiskit Function, teruskan dictionary sebagai presisi PUB. Dictionary tersebut memetakan setiap skala noise yang diminta ke presisi targetnya. Hasil scale-factor yang dikembalikan disimpan dalam noise_scaling.results_with_REM dan menyertakan mitigasi readout. Titik skala 1.0 karena itu tidak identik dengan nilai unmitigated, karena 1.0 menyertakan mitigasi readout sedangkan unmitigated tidak.

Ketika sebuah skala diminta, QESEM juga mengembalikan skala komplementer di sekitar 1.0 tanpa penggunaan QPU tambahan. Misalnya, meminta 0.5 juga bisa mengembalikan 1.5, dan meminta 1.3 juga bisa mengembalikan 0.7. Presisi pada skala komplementer tidak dijamin.

noise_scale_precision = {0.5: 0.15, 1.3: 0.2}

qet_job = qesem_function.run(
pubs=[
(
circ,
[avg_magnetization, other_observable],
None,
noise_scale_precision,
)
],
backend_name=backend_name,
options={"max_execution_time": 300},
)
print(qet_job.job_id)
print(qet_job.status())
8195fa58-f037-4651-8715-36ce1cdc5521
DONE
qet_result = qet_job.result()
print("QET noise-scaling results:")

for pub_idx, pub_result in enumerate(qet_result):
print(f"\nPUB {pub_idx}:")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
noise_scaling = result_dict["noise_scaling"]
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QET noise-scaling results:

PUB 0:
Unmitigated expectation values: [0.97822857 0.96171429]
Unmitigated error bars: [0.00123812 0.00672958]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 0.9938730340199383 ± 0.0032116907357568275
Scale factor 0.7: 0.9963976191853445 ± 0.00036300258869586616
Scale factor 1.0: 0.9898115079506586 ± 0.0012525947426560995
Scale factor 1.3: 0.9864667065580341 ± 0.002633221613518526
Scale factor 1.5: 0.9838755527197551 ± 0.002948417797996015
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 1.0006538544450332 ± 0.002121742014777343
Scale factor 0.7: 1.0004159801523036 ± 0.0021671375357823794
Scale factor 1.0: 0.9898058846339917 ± 0.00690183710903159
Scale factor 1.3: 0.9948946719997267 ± 0.002146532859610311
Scale factor 1.5: 0.9927220368192772 ± 0.0020875057190323882

Ambil pesan error

Jika status workloadmu ERROR, gunakan job.result() untuk mengambil pesan error sebagai berikut:

# Get the result and truncate for readability
result = sample_job.result()
result_str = str(result)
max_length = 500 # Adjust this value as necessary

if len(result_str) > max_length:
truncated = (
result_str[:max_length]
+ f"... (truncated {len(result_str) - max_length} characters)"
)
else:
truncated = result_str

print(truncated)
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(2,), dtype=float64>), stds=np.ndarray(<shape=(2,), dtype=float64>), shape=(2,)), metadata={'gate_fidelities': {'CZ': 0.9979444718552628, 'ID1Q': 0.9991994239814883}, 'total_shots': 498600, 'mitigation_shots': 223400, 'transpiled_circs': [{'circuit': 'OPENQASM 3.0;\ninclude "stdgates.inc";\nbit[76] c0;\nqubit[76] q0;\nrx(0) q0[54];\nrx(0) q0[59];\nrx(0) q0[75];\nrz(pi/2) q0[54];\nrz(pi/2) q0[59];\nrz(pi/2) q0[75];\nrx(pi/2) q0[54];\nr... (truncated 3771 characters)

Dapatkan dukungan

Tim dukungan Qedma siap membantu! Jika kamu mengalami masalah atau memiliki pertanyaan tentang penggunaan Qiskit Function QESEM, jangan ragu untuk menghubungi kami. Staf dukungan kami yang berpengetahuan dan ramah siap membantu kamu dengan masalah teknis atau pertanyaan apa pun yang kamu miliki.

Kamu bisa menghubungi kami melalui email di support@qedma.com untuk bantuan. Sertakan detail sebanyak mungkin tentang masalah yang kamu alami untuk membantu kami memberikan respons yang cepat dan akurat. Kamu juga bisa menghubungi perwakilan POC Qedma yang ditugaskan untukmu melalui email atau telepon.

Untuk membantu kami membantu kamu lebih efisien, silakan berikan informasi berikut saat menghubungi kami:

  • Deskripsi detail tentang masalah tersebut

  • ID job

  • Pesan error atau kode apa pun yang relevan

Kami berkomitmen untuk memberikan dukungan yang cepat dan efektif untuk memastikan kamu mendapatkan pengalaman terbaik dengan Qiskit Function kami.

Kami selalu berusaha meningkatkan produk kami dan kami menyambut saranmu! Jika kamu memiliki ide tentang bagaimana kami bisa meningkatkan layanan atau fitur yang ingin kamu lihat, silakan kirimkan pemikiranmu ke support@qedma.com.

Langkah selanjutnya