Jalankan dan dekode program logis

Gunakan Microsoft Quantum Development Kit (QDK) untuk mengompilasi program Q# atau OpenQASM logis ke Quantum Intermediate Representation (QIR), lalu gunakan qdk.simulation.run_qir untuk menjalankan program melalui qodec. Siapkan model kebisingan, lalu pilih dekoder sindrom bawaan atau deq dekoder tingkat sirkuit opsional.

Prerequisites

Selesaikan tugas-tugas ini sebelum Anda memulai:

Contoh menggunakan Q#qodec yang bernama protocol yang memiliki instruksi untuk kode C4. Untuk membuatnya, lihat Mengembangkan dan memvalidasi protokol QEC.

import qodec
from qdk import ec

c4 = qodec.Code(
    "C4",
    stabilizers=["X_0 X_1 X_2 X_3", "Z_0 Z_1 Z_2 Z_3"],
    x=["X_0 X_1", "X_0 X_2"],
    z=["Z_0 Z_2", "Z_0 Z_1"],
)

protocol = ec.build_qodec(
    c4,
    strategy="bare-css/v1",
    strict=False,
)

report = ec.audit(protocol)
if report.errors or report.warnings:
    raise ValueError(str(report))

Audit qodec sebelum Anda menjalankannya. Runtime mempercayai pemeriksaan, bacaan, bendera, dan persamaan bingkai milik qodec, sehingga deklarasi yang tidak valid dapat menyebabkan hasil logis yang salah atau kegagalan dekoder.

Alur kerja ini menggunakan qdk.simulation.run_qir dengan qodec. tooling ini qodec menggunakan paket terpisah StimPython untuk mengurai sirkuit gadget berformat Stim. Ini tidak memanggil qdk.stim.run. Pada LinuxArm64 atau WindowsArm64, instal Stim dari sumber dan mulai ulang Python atau kernel Jupyter sebelum Anda menjalankan qodec yang memiliki sirkuit berformat Stim.

Cocokkan panggilan QIR dengan instruksi qodec

Cocokkan setiap panggilan kuantum dalam program QIR dengan instruksi dalam set instruksi teratas milik qodec. Mnemonic instruksi harus sama persis dengan nama callee QIR.

Tabel berikut ini memperlihatkan contoh pemetaan:

Panggilan asal Mnemonik yang diperlukan qodec
Q# X(q) atau OpenQASMx q; __quantum__qis__x__body
Q# H(q) atau OpenQASMh q; __quantum__qis__h__body
Q# CNOT(a, b) atau OpenQASMcx a, b; __quantum__qis__cx__body
Q# Adjoint S(q) atau OpenQASMsdg q; __quantum__qis__s__adj
Q# M(q) atau OpenQASMc = measure q; __quantum__qis__m__body
Q# operasi intrinsik Foo Foo
OpenQASM gate intrinsik atau def bernama foo foo

QIR argumen terikat ke elemen instruksi qodec dalam urutan ini:

  1. Argumen pointer qubit terikat ke operand blok.
  2. Argumen skalar terikat ke parameter instruksi.
  3. Argumen penunjuk hasil menerima hasil instruksi dan bendera yang dikembalikan.

Pengkompilasi menimbulkan kesalahan jika panggilan kuantum tidak cocok dengan instruksi di set instruksi tingkat atas.

Deklarasikan instruksi logis di Q#

qodec yang dibuat dari kode C4 mengekspos instruksi kustom seperti prepare_z_all, measure_z_all, syndrome, dan cx_all. Deklarasikan Q# operasi intrinsik dengan nama yang sama.

Inisialisasi Q# dengan profil target adaptif karena operasi pengukuran kustom memerlukannya.

from qdk import TargetProfile, qsharp

qsharp.init(target_profile=TargetProfile.Adaptive_RI)

Nyatakan C4 instruksi sebagai Q# operasi.

qsharp.eval("""
@Measurement()
operation prepare_z_all(block : Qubit) : Result { body intrinsic; }

@Measurement()
operation prepare_x_all(block : Qubit) : Result { body intrinsic; }

@Measurement()
operation measure_z_all(block : Qubit) : (Result, Result) { body intrinsic; }

@Measurement()
operation measure_x_all(block : Qubit) : (Result, Result) { body intrinsic; }

operation cx_all(control : Qubit, target : Qubit) : Unit { body intrinsic; }
operation syndrome(block : Qubit) : Unit { body intrinsic; }
""")

Dalam program ini, masing-masing Q#Qubit mewakili satu blok yang dikodekan. C4 Blok ini memiliki dua kubit logis, sehingga setiap operasi pengukuran mengembalikan dua hasil logis. Setiap operasi persiapan mengembalikan satu flag penolakan.

Mengkompilasi eksperimen logis Q#

Tentukan eksperimen persiapan dan pengukuran keadaan (SPAM).

qsharp.eval("""
operation TestSpamZ() : (Result[], Result[]) {
    use block = Qubit();
    let reject = prepare_z_all(block);
    let (left, right) = measure_z_all(block);
    ([reject], [left, right])
}
""")

Kompilasikan operasi TestSpamZ ke QIR.

qir = str(qsharp.compile("TestSpamZ()"))

QIR mempertahankan panggilan ke prepare_z_all dan measure_z_all. Ketika program berjalan, qodec runtime mencocokkan nama-nama ini dengan set instruksi teratas dan mengganti setiap panggilan logis dengan gadget-nya.

Jalankan dengan dekoder bawaan

Hubungi run_qir dan berikan qodec. Jika decoder adalah None, runtime menggunakan dekoder Pauli berbobot minimum bawaan.

from qdk.simulation import run_qir

results = run_qir(
    qir,
    qodec=protocol,
    type="stabilizer",
    shots=100,
    seed=42,
)

print(results[:5])

Untuk menjalankan qodec, gunakan opsi simulator ini:

type Nilai Behavior
None atau "stabilizer" Gunakan backend stabilizer
"cpu" Gunakan backend state vector untuk program yang didukung
"gpu" Tidak didukung di qodec

Runtime menyiapkan setiap program qubit sebelum penggunaan pertamanya kecuali instruksi pertama membuat blok qubit tersebut. Instruksi persiapan memiliki blok output, tidak ada blok input, dan tindakan yang menstabilkan logical Z.

Koreksi dekoder Pauli qubit tunggal dan pembaruan qodec frame menggunakan frame Pauli bebas derau, bukan gerbang fisik yang bising.

Konfigurasikan kebisingan simulator

Tetapkan noise pada operasi simulator, bukan qodec nama instruksi. Runtime menerjemahkan setiap instruksi lapisan bawah ke dalam satu atau beberapa operasi simulator, sehingga pengaturan kebisingan berlaku untuk operasi tersebut.

Panduan C4 ini menggunakan pemetaan ini:

Instruksi lapisan bawah Pengoperasian simulator NoiseConfig bidang
R Menyiapkan atau mengatur ulang ke Z+ mresetz
H Hadamard h
CX X Terkendali cx
M Pengukuran basis Z mresetz

Buat model kebisingan 1% sederhana:

from qdk.simulation import NoiseConfig

noise = NoiseConfig()
for gate in (noise.h, noise.cx):
    gate.set_depolarizing(0.01)
noise.mresetz.x = 0.01

Jalankan eksperimen dengan kebisingan:

results = run_qir(
    qir,
    qodec=protocol,
    noise=noise,
    type="stabilizer",
    shots=1000,
    seed=42,
    on_shot_failure="discard",
)

Kebisingan pada mresetz memengaruhi qubit setelah pengukuran atau persiapan. Ini tidak membalikkan bit pengukuran yang sudah direkam simulator. Untuk mempelajari flip bit yang direkam, gunakan qodec model kesalahan pembacaan dan analisis gadget.

Kegagalan control shot

Gunakan on_shot_failure untuk memilih bagaimana runtime merespons saat qodec flag, dekoder, atau readout tidak menghasilkan bidikan yang diterima.

Value Behavior
"discard" Hilangkan bidikan yang gagal dari daftar yang dikembalikan. Ini adalah nilai default.
"raise" Berhenti saat percobaan pertama gagal.
"retry" Mulai ulang percobaan yang gagal, maksimal max_retries percobaan tambahan.

Dengan kebijakan "discard", argumen shots menghitung percobaan bidikan, sehingga daftar yang dikembalikan dapat memiliki lebih sedikit item daripada shots.

Flag memicu shot policy hanya ketika program logis tidak menerima flag tersebut. Jika operasi Q#@Measurement() mengembalikan Result tambahan untuk flag, program menerima flag dan memutuskan apakah akan menolak shot.

Dalam contoh TestSpamZ, program mengembalikan flag persiapan di array pertama. on_shot_failure="discard" Jadi pengaturan tidak menghapus baris di mana flag hasil pengembalian adalah One.

Pilih dekoder

Untuk memilih bagaimana kesalahan didekodekan, gunakan parameter decoder untuk meneruskan callable penyiap dekoder untuk setiap lapisan yang dikodekan.

QDK memiliki dekoder berikut:

Dekoder Gunakan untuk
Dekoder sindrom bawaan Tentukan koreksi berbobot minimum Pauli dari bukti sindrom. Gunakan decoder=None.
Dekoder frame Lacak frame bebas derau tanpa menyimpulkan kerusakan fisik. Gunakan prepare_frame_decoder.
deq dekoder Dekodekan model kesalahan tingkat sirkuit dengan deq. Gunakan prepare_deq_decoder.

Menggunakan konfigurasi default deq

Instal deq dan deq-runtime, lalu berikan prepare_deq_decoder.

from qdk.simulation.decoders import prepare_deq_decoder

results = run_qir(
    qir,
    qodec=protocol,
    decoder=prepare_deq_decoder,
    noise=noise,
    type="stabilizer",
    shots=1000,
    seed=42,
    on_shot_failure="discard",
)

Secara bawaan, deq adapter menggunakan relay belief propagation dan koordinator jendela. Untuk mengubah pengaturan ini, gunakan runtime factory.

Mengonfigurasi runtime monolitik deq

Untuk memilih deq pengaturan secara langsung, teruskan pabrik runtime ke prepare_deq_decoder.

from functools import partial
from deq.runtime import Runtime
from qdk.simulation import decoders


def make_runtime(seed: int) -> Runtime:
    return Runtime(
        decoder="black-box-relay-bp",
        decoder_config={"parallel": 1, "seed": seed},
        coordinator="monolithic",
        controller="jit",
    )


results = run_qir(
    qir,
    qodec=protocol,
    decoder=partial(
        decoders.prepare_deq_decoder,
        runtime_factory=make_runtime,
    ),
    noise=noise,
    type="stabilizer",
    shots=1000,
    seed=42,
    on_shot_failure="discard",
)

Setiap pemanggilan factory mengembalikan Runtime baru. QDK dimulai dan ditutup pada setiap runtime.

Note

deq Adaptor memerlukan:

  • Satu lapisan tersandi
  • Jejak eksekusi yang independen terhadap pengukuran Clifford
  • backend penstabil
  • Model kebisingan tanpa kehilangan qubit

Adaptor deq tidak mendukung kebijakan coba lagi. Program yang tidak didukung menimbulkan kesalahan alih-alih beralih ke dekoder lain sebagai cadangan.

Tolak hasil dengan tingkat keyakinan deq rendah

deq Adaptor mengembalikan skor untuk setiap pembacaan logis. Skor yang lebih rendah menunjukkan preferensi yang lebih kuat untuk koreksi yang dipilih. Skor tersebut bukan probabilitas kegagalan yang terkalibrasi.

Untuk menolak hasil dengan tingkat keyakinan rendah, teruskan max_readout_score saat Anda menyiapkan dekoder, seperti dalam contoh berikut:

from functools import partial
from qdk.simulation import decoders

scored_decoder = partial(
    decoders.prepare_deq_decoder,
    max_readout_score=0.2,
)

results = run_qir(
    qir,
    qodec=protocol,
    decoder=scored_decoder,
    noise=noise,
    type="stabilizer",
    shots=1000,
    on_shot_failure="discard",
)

Runtime menerima bidikan hanya ketika setiap pembacaan logis yang dikembalikan memiliki skor pada atau di bawah ambang batas. Ambang batas tidak berlaku untuk flag mentah atau hasil baca perantara yang tidak digunakan.

Penolakan berbasis skor dapat menurunkan tingkat kesalahan logis dari percobaan yang diterima. Tetapi juga mengurangi jumlah cuplikan yang diterima dan menambahkan pekerjaan dekoder.

Mengkompilasi OpenQASM program

Operasi standar OpenQASM menggunakan aturan mnemonic yang sama QIR dengan operasi standar Q# .

from qdk import TargetProfile, openqasm

source = """
OPENQASM 3.0;
include "stdgates.inc";
qubit q;
bit c;
x q;
c = measure q;
"""

qir = openqasm.compile(
    source,
    target_profile=TargetProfile.Adaptive_RI,
)

print(qir)

Untuk menjalankan program ini melalui qodec, pastikan set instruksi teratas dari qodec memiliki __quantum__qis__x__body dan __quantum__qis__m__body, dengan operand blok yang kompatibel dan satu hasil pengukuran.

Gerbang OpenQASM intrinsik atau subroutine bernama foo menggunakan mnemonic foo. Argumen qubit terikat pada operand blok. Argumen float, int, dan bool terikat ke parameter instruksi dalam urutan deklarasi.

OpenQASM memiliki batasan ini untuk panggilan qodec:

  • Intrinsik kustom tidak dapat mengembalikan QIRResult. Untuk mendapatkan satu hasil pengukuran, gunakan pernyataan standar measure .
  • OpenQASM program tidak dapat menjalankan measurement kustom, menerima beberapa hasil dari satu panggilan, atau menerima flag yang dikembalikan. Untuk kasus ini, gunakan tindakan Q#@Measurement().
  • Runtime mengontrol flag apa pun yang tidak dapat diterima program OpenQASM, dan flag ini dapat menyebabkan penolakan suatu operasi.

Untuk contoh pemetaan terperinci, lihat notebook berikut ini QDK:

Tinjau persyaratan dan batasan

Tinjau persyaratan, batasan, dan perbedaan hasil ini sebelum Anda menjalankan eksperimen besar.

Persyaratan:

  • Setiap QIR panggilan kuantum harus mengarah ke instruksi lapisan qodec atas.
  • Audit protokol sebelum Anda menjalankannya. qodec Runtime mempercayai persamaan yang Anda tulis dan tidak memeriksanya.

Limitations:

  • GPU Mode simulasi tidak mendukung qodec eksekusi.
  • Himpunan fault gadget default dapat tumbuh secara eksponensial, sehingga pencarian jarak yang tepat dapat memakan waktu lama.
  • Paket deq dan Stim memiliki batasan platform. Untuk informasi selengkapnya, lihat Instal QDK untuk koreksi kesalahan.

Perbedaan hasil:

  • Jumlah output yang tepat dapat bervariasi menurut dekoder.
  • Kebijakan buang dan coba lagi dapat mengubah distribusi hasil yang dikembalikan.

Untuk eksperimen lengkap Q# dengan sweep kebisingan, deq decoding, dan penolakan berbasis kepercayaan diri, lihat panduan protokol QEC.