Langkau ke kandungan utama

Pembatalan ralat kebarangkalian dengan lightcone berlorek

Anggaran penggunaan: 10 minit pada pemproses Heron (NOTA: Ini hanyalah anggaran sahaja. Masa jalan sebenar anda mungkin berbeza.)

Hasil pembelajaran

  • Apa itu pembatalan ralat kebarangkalian (PEC), dan mengapa overhed pensampelannya γ2\gamma^2 berkembang secara eksponen dengan jumlah hingar yang bertindak pada Circuit

  • Bagaimana lightcone berlorek (SLC) menghadkan sumbangan setiap terma hingar kepada cerapan sasaran, supaya kamu boleh membelanjakan bajet mitigasi di tempat yang penting — dan bagaimana, melangkaui pengurangan overhed sifar-bias yang sudah disediakan oleh lightcone geometri tulen, pelorekan membolehkan kamu menukar bias baki terhad dengan overhed pensampelan yang lebih rendah lagi

  • Bagaimana untuk mempelajari hingar lapisan dengan NoiseLearnerV3 dan menyuntik anti-hingar melalui samplomatic dan primitive Executor

  • Bagaimana untuk menggabungkan PEC dan PEC+SLC dengan TREX dan pascapemilihan untuk menganggarkan nilai jangkaan pada perkakasan

Prasyarat

Latar Belakang

Tutorial ini menunjukkan cara mengurangkan ralat dengan menggunakan addon shaded lightcone (SLC). Addon ini adalah evolusi daripada teknik pembatalan ralat berkebarangkalian (PEC), di mana pengguna mempelajari hingar lapisan unik dalam Circuit dan kemudian membatalkan hingar itu dengan menggunakan Gate satu-Qubit dan teknik pasca-pemprosesan. Berbanding kaedah lain, PEC menawarkan sempadan yang lebih kukuh pada bias hasil yang dikurangkan, tetapi cenderung mengalami overhead yang lebih tinggi dari segi masa QPU. Semasa PEC, untuk mengimbangi pengecilan nilai jangkaan oleh hingar, hasil purata diskalakan semula dengan faktor γ=exp(l,σ2λl,σ)\gamma = \exp(\sum_{l,\sigma} 2\lambda_{l,\sigma}), di mana λl,σ\lambda_{l,\sigma} ialah kadar hingar yang dipelajari bagi ralat Pauli σ\sigma pada lapisan ll dalam Circuit. Penskalaan semula ini meningkatkan varians dengan faktor γ2\gamma^2, dan dengan itu juga menggandakan bilangan pelaksanaan Circuit yang diperlukan pada QPU dengan γ2\gamma^2, yang kita panggil kos pensampelan atau overhead pensampelan. Oleh kerana γ\gamma berkembang secara eksponen, PEC selalunya terhad kepada Circuit yang cetek atau bilangan Qubit yang kecil. Ketahui lebih lanjut tentang PEC dalam Probabilistic error cancellation with sparse Pauli-Lindblad models on noisy quantum processors.

Jika kita boleh mengenal pasti ralat yang tidak perlu dikurangkan, kita boleh mengurangkan kos pensampelan ini secara eksponen. Langkah pertama ke arah ini ialah melaksanakan pengurangan ralat yang peka-tempatan (locally-aware), yang menggunakan "lightcone" konvensional yang boleh dikira dengan pantas untuk mengurangkan overhead PEC dengan menyempadankan sensitiviti sesuatu observable terhadap ralat di seluruh Circuit, memanjangkan kebolehlaksanaan PEC kepada skala yang lebih besar bagi sesetengah masalah. Ralat di luar lightcone ini tidak boleh menjejaskan hasil yang diukur dan oleh itu boleh dikecualikan daripada prosedur pembatalan ralat. Pengecualian ini mengurangkan overhead pensampelan, dalam sesetengah kes secara ketara, tanpa memperkenalkan bias tambahan. Khususnya, untuk mengukur observable tempatan OO bagi Circuit kedalaman tetap, overhead pensampelan yang diperlukan akhirnya menjadi rata apabila menskalakan bilangan Qubit dalam Circuit (lihat Rajah 2b dalam Locality and error mitigation of quantum circuits).

Shaded lightcones (SLC) melangkah lebih jauh, menggunakan simulasi klasik untuk menyempadankan sensitiviti terhadap ralat di seluruh Circuit dengan lebih ketat. Ini menukar sebahagian masa QPU untuk masa CPU dan mengurangkan overhead pensampelan yang diperlukan untuk menormalkan semula bias. Bukannya potongan tegas, setiap ralat yang berpotensi dalam Circuit diberikan "lorekan" (shade) bergred yang menyempadan-atas kepekaan nilai jangkaan observable terhadap ralat itu. (Bagi sempadan diperambat-belakang yang diperkenalkan di bawah, kepekaan ini juga bergantung pada keadaan awal Circuit — keadaan semua-sifar dalam aliran kerja tipikal, dan dalam tutorial ini.) Pencirian yang diperhalusi ini membolehkan aplikasi PEC yang lebih cekap dan bersasar dengan varians yang dikurangkan, sambil memberikan pengguna keupayaan untuk menala bias secara terkawal dalam penganggaran observable. Lihat Lightcone shading for classically accelerated quantum error mitigation untuk butiran lanjut.

Aliran kerja kami untuk addon SLC memanfaatkan pustaka samplomatic bersama-sama dengan kelas QuantumProgram dan Executor yang ditambah pada Qiskit Runtime dalam qiskit-ibm-runtime v0.47.0, membolehkan pengguna mempunyai kawalan yang lebih modular terhadap tetapan pelaksanaan untuk penindasan dan pengurangan ralat sambil mengekalkan kemudahan penggunaan. Baca lebih lanjut dalam panduan directed execution model.

Aliran kerja mitigasi ralat SLC sepintas lalu

Untuk memodelkan hingar QPU, kami menggunakan model hingar sparse Pauli-Lindblad dengan kadar ralat Pauli satu- dan dua-Qubit, dijana secara tempatan pada setiap Qubit dan tepi peranti. Dengan pilihan ini, aliran kerja pengurangan ralat SLC yang dibentangkan dalam tutorial ini adalah seperti berikut:

a. CPU — Sempadankan kesan setiap ralat bagi ralat Pauli satu- dan dua-Qubit

  1. Perambatan hadapan (sempadan kesan pada observable). Rambatkan setiap ralat ke penghujung Circuit dan kira kommutatornya dengan observable.

    • Potong sebutan operator semasa evolusi untuk mengekalkan pengiraan boleh diurus.

    • Ketatkan lagi sempadan ini dengan perambatan-belakang longgar bagi observable berdasarkan had kelajuan kuantum.

  2. Perambatan belakang (sempadan kesan pada keadaan awal). Rambatkan setiap ralat ke permulaan Circuit dan kira kommutatornya dengan keadaan awal.

b. QPU — Pelajari kadar hingar. Gunakan NoiseLearnerV3 untuk menganggarkan kadar model hingar Pauli-Lindblad.

c. CPU — Utamakan pengurangan

  1. Kemas kini sempadan gabungan dengan kadar hingar yang dipelajari. Gabungkan sempadan hadapan dan belakang yang telah dikira sebelum ini dan kemas kininya dengan kadar hingar yang dipelajari.

  2. Susun komponen hingar untuk dikurangkan mengikut keutamaan dengan menggunakan sempadan yang dikira dan kadar yang dipelajari. Utamakan setiap ralat hingar yang mungkin berdasarkan kesan anggarannya terhadap bias dan kos berkaitan untuk membetulkannya.

d. QPU — Masukkan anti-hingar dan jalankan. Laksanakan Circuit yang diminati dengan anti-hingar (hingar songsang) yang ditentukan dengan menggunakan anotasi Box.

e. CPU — Anggarkan observable. Kira nilai jangkaan, menggunakan pemilihan-pasca berasaskan pengukuran untuk mengurangkan kesan hingar bukan-Markov.

Gambaran keseluruhan pembelajaran hingar

Pembelajaran hingar (noise learning) ialah langkah biasa dalam beberapa kaedah pengurangan ralat, dijalankan oleh noise learner; ia juga muncul dalam tutorial probabilistic error amplification. Dalam NoiseLearnerV3, anda boleh mengenal pasti secara khusus lapisan hingar yang hendak dipelajari sebagai objek CircuitInstruction, supaya anda boleh mengira sempadan hingar SLC yang dikehendaki bagi setiap lapisan dengan cara yang diterangkan di atas. Model Pauli-Lindblad yang dipelajari menyediakan pekali untuk digunakan dalam keutamaan PEC+SLC. Cara Gate dikumpulkan ke dalam lapisan boleh ditentukan dengan menggunakan fungsi kemudahan generate_boxing_pass_manager dan find_unique_box_instructions, dan kemudian dimasukkan ke dalam fungsi utiliti SLC generate_noise_model_paulis, seperti yang diterangkan dalam Langkah 2 di bawah.

Bahagian 1Bahagian 2Bahagian 3
Pauli-twirl lapisan get dua-qubitUlangi pasangan identiti lapisan dan pelajari hingarTerbitkan kesetiaan (ralat bagi setiap saluran hingar)
Pauli twirlingPelajari lapisanPadanan lengkung

Gambaran keseluruhan pasca-pemprosesan

Selepas dilaksanakan pada perkakasan kuantum dengan menggunakan rangka kerja samplomatic dan Executor, kami menukarkan pengukuran bitstring kami kepada nilai observable yang dikehendaki. Dalam tutorial ini, kami menunjukkan aliran kerja pada Circuit Ising bercermin (dibina dalam Langkah 1 di bawah), di mana nilai jangkaan ideal bagi observable yang diukur ialah 1 kerana separuh kedua Circuit membatalkan separuh pertama. Apabila mengira nilai observable dengan fungsi executor_expectation_values, kami menggunakan beberapa teknik pasca-pemprosesan yang mengurangkan kesan hingar. Ini termasuk membuang shot yang terjejas oleh hingar bukan-Markov, pengurangan ralat bacaan (readout-error mitigation), dan mengambil kira butiran pelaksanaan PEC kami. Butiran dibincangkan dalam Langkah 4 di bawah.

Requirements

Sebelum memulakan tutorial ini, pastikan anda telah memasang perkara berikut:

  • Qiskit SDK v2.2 atau lebih baharu, dengan sokongan visualization

  • Qiskit Runtime v0.47 atau lebih baharu (pip install qiskit-ibm-runtime)

  • Shaded lightcones Qiskit addon v0.1 atau lebih baharu (pip install qiskit-addon-slc)

  • Qiskit addon utils v0.3 atau lebih baharu (pip install qiskit-addon-utils)

  • Samplomatic v0.13 atau lebih baharu (pip install samplomatic)

Setup

Pertama, import pakej dan fungsi yang diperlukan untuk menjalankan notebook ini.

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-addon-slc qiskit-addon-utils qiskit-ibm-runtime samplomatic
from multiprocessing import set_start_method

# Setting this value prevents itertools.starmap deadlock on UNIX systems
set_start_method("spawn")

# Needed to prevent PySCF from parallelizing internally (SLC only)
%set_env OMP_NUM_THREADS=1
env: OMP_NUM_THREADS=1
import numpy as np
from matplotlib import pyplot as plt

from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager, PassManager

from qiskit_ibm_runtime import (
QiskitRuntimeService,
QuantumProgram,
Executor,
NoiseLearnerV3,
)

import samplomatic
from samplomatic.utils import find_unique_box_instructions
from samplomatic.transpiler import generate_boxing_pass_manager

from qiskit_addon_utils.exp_vals.measurement_bases import (
get_measurement_bases,
)
from qiskit_addon_utils.exp_vals.expectation_values import (
executor_expectation_values,
)
from qiskit_addon_utils.noise_management import (
gamma_from_noisy_boxes,
trex_factors,
)
from qiskit_addon_utils.noise_management.post_selection import PostSelector
from qiskit_addon_utils.noise_management.post_selection.transpiler.passes import (
AddPostSelectionMeasures,
AddSpectatorMeasures,
)

from qiskit_addon_slc.bounds import (
compute_backward_bounds,
compute_forward_bounds,
compute_local_scales,
merge_bounds,
tighten_with_speed_limit,
)
from qiskit_addon_slc.utils import (
generate_noise_model_paulis,
map_modifier_ref_to_ref,
)
from qiskit_addon_slc.visualization import draw_shaded_lightcone

Contoh simulator berskala kecil

Seperti kaedah pengurangan ralat berasaskan pembelajaran yang lain, PEC dengan shaded lightcones mengurangkan hingar fizikal bagi pemproses kuantum tertentu, jadi ia bergantung pada perkhidmatan perkakasan yang tiada analog bermakna pada simulator ideal:

  • NoiseLearnerV3 mencirikan secara eksperimen saluran hingar sparse Pauli-Lindblad pada setiap lapisan dua-Qubit yang unik. Pada simulator tanpa hingar, tiada hingar untuk dibatalkan.

  • Primitif Executor mengambil sampel Circuit yang di-twirl dan disuntik anti-hingar yang dijana oleh samplomatic pada Backend.

Pengiraan sempadan shaded-lightcone adalah klasik, tetapi ia hanya bermakna berbanding dengan kadar hingar perkakasan yang dipelajari, yang menetapkan bajet pengurangan dan overhead pensampelan. Atas sebab-sebab ini kami melangkau contoh simulator berskala kecil dan menunjukkan aliran kerja penuh PEC+SLC secara langsung pada perkakasan, dengan setiap langkah corak Qiskit dipecahkan di bawah.

Contoh perkakasan berskala besar

Kami menjalankan aliran kerja penuh PEC+SLC pada Circuit Ising bercermin 20-Qubit yang dilaksanakan pada perkakasan IBM Quantum®, mengikuti empat langkah corak Qiskit.

Langkah 1: Petakan masalah

Demonstrasi kami disediakan seperti berikut:

  1. Kami memilih untuk melakukan evolusi masa di bawah Hamiltonian rantai Ising 1D. Rantai Ising 1D memberikan struktur Circuit yang padat dengan baik, yang mudah untuk menonjolkan pelaksanaan PEC.

  2. Kami memilih untuk mengukur observable X6Z13\langle X_6 Z_{13}\rangle, yang mengandungi satu komponen XX dan satu komponen ZZ. Ini memudahkan untuk menonjolkan cara sempadan SLC melayan jenis ralat yang berbeza secara berbeza.

  3. Kami mahu nilai jangkaan ideal bagi observable ini menjadi tepat 1, supaya kualiti anggaran yang dikurangkan mudah dinilai. Mencerminkan Circuit membawa kita hampir ke sana: bagi setiap Gate dalam separuh kedua Circuit terdapat Gate songsang dalam separuh pertama, supaya Circuit ideal bertindak sebagai identiti.

  4. Akhirnya, memperoleh nilai jangkaan ideal 1 memerlukan Circuit bermula — dan oleh itu, berkat pencerminan, secara ideal juga berakhir — dalam eigenstate +1 bagi observable. Oleh kerana observable mengandungi komponen bukan-ZZ, dan primitif Executor mengambil kira asas pengukuran yang dikehendaki pada penghujung Circuit, kami menambahkan Gate penyediaan-asas yang berkaitan di permulaan Circuit cermin dengan fungsi prepare_basis. Kami menggunakan fungsi get_measurement_bases untuk mengenal pasti Gate mana yang diperlukan dan di mana untuk meletakkannya, sambil mengekalkan penjejakan kehalusan indeks-Qubit yang timbul daripada konvensyen anotasi box, seperti yang dibincangkan dalam bahagian tentang penyediaan pengukuran asas kanonik.

# Width of the Ising chain (a free parameter of this demonstration)
num_qubits = 20

# The observable to measure: one X component (on qubit 6) and one Z component
# (on qubit 13), as motivated in "Step 1: Map the problem" above
target_obs_sparse = [("XZ", [6, 13], 1.0)]
observable = SparsePauliOp.from_sparse_list(
target_obs_sparse, num_qubits=num_qubits
)
# Determine the measurement basis each qubit requires for this observable.
# The reverser is used during post-processing in Step 4.
bases_virt, reverser_virt = get_measurement_bases(observable)
# Free parameters of the demonstration circuit: the number of Trotter steps
# sets the circuit depth, and rx_angle is the transverse-field rotation angle
# applied in each step (pi/4 makes the dynamics non-Clifford)
num_trotter_steps = 10
rx_angle = np.pi / 4
def construct_ising_circuit(
num_qubits: int,
num_trotter_steps: int,
rx_angle: float,
) -> QuantumCircuit:
circuit = QuantumCircuit(num_qubits)

for _ in range(num_trotter_steps):
circuit.rx(rx_angle, range(num_qubits))
for first_qubit in (1, 2):
for idx in range(first_qubit, num_qubits, 2):
# equivalent to Rzz(-pi/2):
circuit.sdg([idx - 1, idx])
circuit.cz(idx - 1, idx)

return circuit

def prepare_basis(
circuit: QuantumCircuit, basis: list[int]
) -> QuantumCircuit:
# basis is a list of integer values from 0 to 3. These map to the basis measurement as:
# 0 = I; 1 = Z; 2 = X; 3 = Y
assert len(basis) == circuit.num_qubits

out_circ = circuit.copy_empty_like()
for qb, bas in enumerate(basis):
if bas == 2:
out_circ.h(qb)
elif bas == 3:
out_circ.rx(-np.pi / 2, qb)

out_circ.barrier()
out_circ.compose(circuit, inplace=True)
return out_circ

def mirror_circuit(circuit: QuantumCircuit) -> QuantumCircuit:
mirror_circ = circuit.copy_empty_like()
mirror_circ.compose(circuit.inverse(), inplace=True)
mirror_circ.barrier()
mirror_circ.compose(circuit, inplace=True)
mirror_circ.measure_active()
return mirror_circ
# Instantiate the mirrored circuit and prepend the basis-preparation gates
circuit = construct_ising_circuit(num_qubits, num_trotter_steps, rx_angle)
mirrored_circuit = mirror_circuit(circuit)
mirrored_circuit = prepare_basis(mirrored_circuit, bases_virt[0])
mirrored_circuit.draw(
"mpl", fold=-1, scale=0.3, idle_wires=False, measure_arrows=False
)

Output of the previous code cell

Langkah 2: Optimumkan

Kami mengoptimumkan butiran yang berkaitan dengan Circuit yang hendak dijalankan, observable yang hendak diukur, dan parameter pembelajaran hingar. Sebagai titik permulaan, kami memilih pemproses Heron yang paling kurang sibuk dan menghasilkannya dengan Gate pecahan dihidupkan. Gate pecahan ini membolehkan sensitiviti yang lebih besar dalam sesetengah penapisan pemilihan-pasca kami.

# Initialize IBM Quantum Compute Service using your saved credentials
service = QiskitRuntimeService()

# Select the least busy Heron device. This tutorial targets Heron processors:
# the usage estimate and the non-Markovian-noise post-selection discussed in
# Step 4 are specific to this processor family.
backend = service.least_busy(
operational=True,
simulator=False,
filters=lambda b: b.processor_type["family"] == "Heron",
)
# Re-fetch with fractional gates enabled (least_busy does not forward this)
# Fractional gates are enabled so the non-Clifford Rx rotations are supported natively.
backend = service.backend(backend.name, use_fractional_gates=True)
print(f"Selected backend: {backend.name}")
Selected backend: ibm_kingston

Pertama, kami akan mentranspile Circuit kami kepada arahan ISA, seperti yang diperlukan untuk pelaksanaan pada QPU kami. Pemilihan Qubit fizikal untuk dijalankan mempunyai kesan besar terhadap kualiti hasil, kerana masa koheren dan kesetiaan Gate berbeza-beza merentasi peranti dan hanyut dari semasa ke semasa. Untuk eksperimen yang teliti, ia boleh berbaloi untuk memilih sendiri rantai Qubit berdasarkan eksperimen penanda aras pantas (lihat, sebagai contoh, tutorial Real-time benchmarking for qubit selection). Bagi tujuan tutorial ini, kami bergantung pada Transpiler Qiskit untuk memilih susun atur berdasarkan peta gandingan Backend dan data kalibrasi terkininya.

isa_pm = generate_preset_pass_manager(backend=backend, optimization_level=1)

isa_circuit = isa_pm.run(mirrored_circuit)

# The chain of physical qubits selected by the transpiler
layout = isa_circuit.layout.final_index_layout()
print(f"Selected layout: {layout}")

isa_observable = observable.apply_layout(
layout, num_qubits=isa_circuit.num_qubits
)
Selected layout: [71, 58, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 36, 21, 22, 23, 16, 3, 2]
wire_order = layout + [
q for q in range(isa_circuit.num_qubits) if q not in layout
]
isa_circuit.draw(
"mpl",
fold=-1,
scale=0.3,
idle_wires=False,
wire_order=wire_order,
measure_arrows=False,
)

Output of the previous code cell

Kotakkan litar

Untuk kemudahan pelaksanaan, kami menggunakan pas transpilasi generate_boxing_pass_manager, yang meletakkan arahan Circuit ke dalam kotak beranotasi. Kotak ini menunjukkan dengan jelas di mana, dalam kes PEC, anti-hingar harus disuntik ke dalam Circuit. Untuk butiran tentang tetapan, rujuk dokumentasi Samplomatic.

Perhatikan bahawa aliran kerja SLC memerlukan penggunaan inject_noise_strategy="individual_modification" kemudian dalam proses kerana ini membolehkan kita mengenal pasti secara unik anotasi InjectNoise bagi arahan BoxOp dalam Circuit. (Kotak tanpa anotasi InjectNoise tidak boleh dikenal pasti dengan cara ini.)

awas

Pengiraan batas SLC pada masa ini menganggap bahawa anotasi InjectNoise diletakkan dengan site="after" (lihat qiskit-addon-slc#33). Oleh kerana nilai lalai tetapan ini berubah dalam versi terkini samplomatic (lihat samplomatic#372), kami menetapkan inject_noise_site="after" secara eksplisit di bawah.

Fungsi find_unique_box_instructions mengulangi Circuit berkotak yang disediakan dan mengenal pasti yang mempunyai lapisan dua-Qubit (2Q) atau pengukuran yang unik, bagi tujuan pembelajaran hingar dan suntikan hingar.

# Box circuit with Twirl and InjectNoise annotations
boxes_pm = generate_boxing_pass_manager(
twirling_strategy="active",
inject_noise_strategy="individual_modification",
inject_noise_site="after",
inject_noise_targets="gates",
measure_annotations="all",
)

boxed_circuit = boxes_pm.run(isa_circuit)

# Find the unique instructions (layers) from boxed circuit
unique_2q_instructions = find_unique_box_instructions(
boxed_circuit, normalize_annotations=None, undress_boxes=True
)
boxed_circuit.draw(
"mpl",
fold=-1,
scale=0.3,
idle_wires=False,
wire_order=wire_order,
measure_arrows=False,
)

Output of the previous code cell

Sediakan pengukuran asas kanonik

Perhatikan bahawa kita mesti mengambil berat khusus untuk menjejaki susunan Qubit. Di bawah, kami memperkenalkan konsep canonical_qubits sebagai cara untuk mengemas kini susunan Qubit dengan sewajarnya apabila menyediakannya kepada Executor, akibat daripada cara susunan Qubit ditangkap semasa mengkotakkan Circuit dan mencari arahan unik. Lihat dokumentasi Qubit ordering convention untuk butiran.

# Determine the canonical qubits order
meas_box = boxed_circuit.data[-1]
canonical_qubits = [
idx
for idx, qubit in enumerate(boxed_circuit.qubits)
if qubit in meas_box.qubits
]

# map canonical qubit to physical (isa) qubit
c_2_p = {c: p for c, p in enumerate(canonical_qubits)}
# map physical (isa) qubit to virtual qubit (index in original circuit)
p_2_v = {p: v for v, p in enumerate(layout)}
# compute map between virtual and canonical qubit indices.
c_2_v = {c: p_2_v[p] for c, p in c_2_p.items()}

assert len(c_2_v) == num_qubits

bases_canon = [
np.array([base_i[c_2_v[c]] for c in range(num_qubits)], dtype=np.uint8)
for base_i in bases_virt
]

Aliran kerja untuk pelorekan kon cahaya, pembelajaran hingar, dan suntikan anti-hingar

nota

Dalam tutorial ini, kami menjalankan pengiraan batas SLC sebelum pembelajaran hingar selesai, supaya litar yang akan dikurangkan dijalankan sedekat mungkin dari segi masa dengan model hingar yang dipelajari. Pada dasarnya aliran kerja ini boleh diselaraskan lagi: pekerjaan pembelajaran hingar boleh berjalan manakala, secara selari, batas hingar dianggarkan. Bagi litar kuantum sewenang-wenangnya, pengiraan batas hingar boleh berskala dengan kebergantungan eksponen yang lemah, jadi menyelaraskan pengiraan batas (contohnya, merentasi banyak teras CPU) menghasilkan batas yang lebih ketat untuk belanjawan masa pengiraan tertentu, dan pelaksanaan QPU serta pengiraan batas itu sendiri boleh diselaraskan untuk aliran kerja yang paling cekap.

Ramalkan Pauli model-hingar yang akan dipelajari

Sebelum menjalankan sebarang pembelajaran hingar pada perkakasan, kami mula-mula menyenaraikan sebutan ralat Pauli yang akan dikandungi oleh model hingar kami. Ingat bahawa kami memodelkan hingar setiap lapisan unik sebagai model sparse Pauli-Lindblad dengan satu kadar ralat bagi setiap Pauli berat-satu (XX, YY, atau ZZ) pada setiap Qubit aktif, dan satu bagi setiap Pauli berat-dua pada setiap pasangan Qubit aktif yang bersambung. Fungsi generate_noise_model_paulis melalui setiap lapisan berkotak unik bagi Circuit yang disediakan dan menjana senarai sebutan Pauli ini dengan tepat, mengambil kira konektiviti Qubit Circuit itu.

Dengan kata lain, langkah ini meramalkan struktur model hingar yang kemudiannya akan diisi oleh NoiseLearnerV3 dengan kadar yang dipelajari. Mengetahui struktur ini terlebih dahulu adalah yang membolehkan kita mengira sempadan hadapan dan sempadan belakang bagi setiap ralat berpotensi sebelum pembelajaran hingar pun dijalankan.

noise_model_paulis = generate_noise_model_paulis(
unique_2q_instructions, backend.coupling_map, boxed_circuit
)
noise_model_rates = {ref: None for ref in noise_model_paulis}
a. Kira sempadan hadapan

Fungsi compute_forward_bounds menilai hubungan kommutasi antara Gate dalam setiap lapisan dan sebutan Pauli yang dijana di atas dari segi bagaimana ralat perambatan-hadapan menjejaskan observable AA yang dikehendaki. Bagi Gate yang berkommut dengan sebutan Pauli, tiada apa yang dilakukan. Bagi Gate Clifford, ia ditolak ke arah permulaan Circuit. Bagi Gate bukan-Clifford, kami menganggarkan pengaruhnya ke atas observable sasaran untuk kemudiannya diutamakan bagi pembatalan hingar (selepas semua sempadan digabungkan). Sempadan ini dicapai dengan mula-mula menggunakan norma L2 (iaitu, punca kuasa dua bagi hasil tambah kuasa dua pekali sebutan-Pauli yang berkaitan). Apabila terdapat terlalu banyak sebutan Qubit yang terlibat, kami kembali kepada sempadan yang lebih longgar yang menggunakan ketaksamaan segitiga.

Tetapkan parameter pengiraan sempadan

Tetapan berikut mengawal pengiraan sempadan klasik:

  • slc_atol: toleransi mutlak bagi pengiraan. Sebutan operator dengan pekali di bawah ambang ini dianggap remeh dan dibuang.

  • slc_eigval_max_qubits: bilangan maksimum Qubit di mana sempadan yang lebih ketat, berasaskan nilai eigen (norma-L2), dinilai. Operator yang disokong pada lebih banyak Qubit daripada ini akan kembali kepada sempadan ketaksamaan segitiga yang lebih longgar yang diterangkan di atas.

  • slc_evolution_max_terms: bilangan maksimum sebutan Pauli yang dikekalkan semasa merambatkan operator melalui Circuit. Memotong sebutan terkecil mengekalkan pengiraan boleh diurus dengan kos sempadan yang sedikit lebih longgar.

  • slc_num_processes: bilangan proses CPU yang menjadi selari kepada pengiraan sempadan.

  • slc_timeout: bajet masa (dalam saat) untuk pengiraan sempadan. Sebarang lapisan yang tidak dicapai dalam bajet ini diberikan sempadan remeh iaitu 2.

nota

Dalam tutorial ini, tamat masa dicapai secara sengaja: kami mengekalkan slc_timeout sengaja kecil supaya buku nota berjalan dengan pantas, dan untuk menunjukkan bahawa mencapai tamat masa adalah selamat. Lorekan yang dikira adalah batas atas pada setiap peringkat, jadi mencapai tamat masa hanya menjadikan batas lebih longgar (remeh) untuk lapisan yang tidak dicapai; ia tidak pernah menganggarkan kesan ralat secara rendah. Ini kelihatan dalam visualisasi di bawah sebagai lapisan paling kiri diisi sepenuhnya dengan batas remeh. Meningkatkan tamat masa (atau bilangan proses) mengetatkan batas dan mengurangkan lagi overhead pensampelan.

slc_atol = 1e-8
slc_eigval_max_qubits = 18
slc_evolution_max_terms = 1000
slc_num_processes = 8
slc_timeout = 60
forward_bounds = compute_forward_bounds(
boxed_circuit,
noise_model_paulis,
isa_observable,
evolution_max_terms=slc_evolution_max_terms,
eigval_max_qubits=slc_eigval_max_qubits,
atol=slc_atol,
num_processes=slc_num_processes,
timeout=slc_timeout,
)
Bounds computation timed out.

Visualisasikan SLC untuk pemeriksaan manual

Anda boleh mentafsir tingkah laku sempadan lorekan (shaded bounds) dengan memeriksa bagaimana pengukuran dan sebutan Pauli berinteraksi dengan ralat tempatan. Corak-corak ini adalah ciri masalah evolusi-masa Hamiltonian Ising terhentak (kicked Ising) ini dan juga muncul dalam kertas Lightcone Shading for Classically Accelerated Quantum Error Mitigation, dengan beberapa ciri yang boleh dikenal pasti:

  • Kita boleh membezakan dengan jelas dua kon yang timbul daripada dua Pauli bukan-identiti dalam observable.

  • Kita boleh melihat bahawa pengukuran X pada qubit 6 berkommut dengan ralat X dalam lapisan paling kanan.

  • Kita boleh melihat bahawa Pauli Z pada qubit 13 berkommut dengan ralat Z dalam lapisan paling kanan.

  • Apabila kita mencapai had masa (timeout) yang dinyatakan di atas, lapisan yang tinggal di sebelah kiri diisi sepenuhnya dengan sempadan remeh iaitu dua.

for p in "XYZ":
display(
draw_shaded_lightcone(
boxed_circuit,
forward_bounds,
noise_model_paulis,
pauli_filter=p,
scale=0.15,
fold=-1,
idle_wires=False,
wire_order=wire_order,
measure_arrows=False,
)
)

Output of the previous code cell

Output of the previous code cell

Output of the previous code cell

b. Ketatkan sempadan hadapan dengan had kelajuan kuantum

Seterusnya kami mengetatkan sempadan dengan menggunakan fungsi tighten_with_speed_limit. Penyebaran geometri lightcone bagi observable telah pun diambil kira sepenuhnya dalam sempadan hadapan yang dikira di atas. Apa yang fungsi ini tambah ialah laluan konsistensi-diri yang memanfaatkan kelajuan terhad di mana maklumat boleh mengalir melalui Circuit — lightcone berkembang paling banyak satu Qubit bagi setiap lapisan Gate dua-Qubit — untuk mengetatkan sempadan yang dikira sebelum ini antara satu sama lain. Maklumat mengalir dalam kedua-dua arah:

  1. Daripada sempadan kommutator kepada sempadan pada observable yang dirambat-belakang: jika observable berkommut dengan ralat ZZ pada suatu Qubit, maka ia tidak boleh mempunyai banyak komponen XX atau YY di situ.

  2. Daripada sempadan pada observable yang dirambat-belakang kepada sempadan kommutator: jika observable mempunyai sedikit komponen XX dan YY pada suatu Qubit, maka ia mesti hampir berkommut dengan ZZ di situ.

forward_bounds_tighter = tighten_with_speed_limit(
forward_bounds, boxed_circuit, noise_model_paulis, isa_observable
)

Visualisasikan SLC untuk pemeriksaan manual

Pada dasarnya, pengetatan ini menyediakan peralihan yang lebih lancar antara sempadan yang dikira dan sempadan remeh yang diberikan kepada lapisan melebihi had masa. Dalam contoh ini kesannya hampir tidak kelihatan, kerana lightcone telah pun tersebar ke tepi Circuit pada masa had masa dicapai.

for p in "XYZ":
display(
draw_shaded_lightcone(
boxed_circuit,
forward_bounds_tighter,
noise_model_paulis,
pauli_filter=p,
scale=0.15,
fold=-1,
idle_wires=False,
wire_order=wire_order,
measure_arrows=False,
)
)

Output of the previous code cell

Output of the previous code cell

Output of the previous code cell

c. Kira sempadan belakang

Bahagian ramalan hingar ini menilai bagaimana ralat pada lapisan tertentu boleh menjejaskan keadaan input ρ\rho. Fungsi compute_backward_bounds mula-mula menyongsangkan Circuit dan membuang Gate pengukuran, dan kemudian meneruskan dengan analisis yang serupa dengan yang dilakukan untuk pengiraan sempadan-hadapan.

backward_bounds = compute_backward_bounds(
boxed_circuit,
noise_model_paulis,
evolution_max_terms=slc_evolution_max_terms,
num_processes=slc_num_processes,
timeout=slc_timeout,
)

Visualisasikan SLC untuk pemeriksaan manual

Daripada mengira sempadan belakang, kita boleh melihat bagaimana struktur keadaan awal mengawal tingkah laku awal perambatan ralat:

  • Kita boleh melihat dengan jelas bagaimana ralat Z pada mulanya berkommut dengan keadaan awal |0⟩.

  • Hanya pada qubit 6, di mana kita memulakan eigenstate +1 bagi asas X, ralat Z gagal berkommut, sedangkan ralat X memang berkommut.

for p in "XYZ":
display(
draw_shaded_lightcone(
boxed_circuit,
backward_bounds,
noise_model_paulis,
pauli_filter=p,
scale=0.15,
fold=-1,
idle_wires=False,
wire_order=wire_order,
measure_arrows=False,
)
)

Output of the previous code cell

Output of the previous code cell

Output of the previous code cell

Pratonton sempadan gabungan tanpa kadar hingar yang dipelajari

Fungsi merged_bounds menentukan titik dalam Circuit di mana beralih daripada sempadan belakang kepada sempadan hadapan meminimumkan jumlah anggaran bias pada observable yang dikehendaki. Bias ini dikira sebagai jumlah sumbangan sempadan-belakang bagi semua lokasi hingar sebelum titik itu, ditambah sumbangan sempadan-hadapan bagi semua lokasi hingar selepasnya. Buat masa ini, ini dilakukan secara seragam bagi semua Qubit.

Nota penting

Titik optimum untuk beralih daripada sempadan belakang kepada hadapan bergantung pada kadar hingar yang dipelajari. Pada peringkat ini kita masih belum mempelajari sebarang kadar: noise_model_rates telah diinisialisasikan kepada None bagi setiap lapisan, yang mana merge_bounds menganggap sebagai kadar hingar seragam. Sempadan gabungan yang ditunjukkan di sini oleh itu hanyalah pratonton; kami mengira semula dengan kadar sebenar yang dipelajari dalam Langkah 3.

merged_bounds = merge_bounds(
boxed_circuit,
forward_bounds_tighter,
backward_bounds,
noise_model_rates,
)
Missing noise rates. Partitioning backward/forward commutator bounds by assuming uniform error rates.
Optimal spacetime partitioning not implemented!Just partitioning list of noisy boxes.

Visualisasikan SLC untuk pemeriksaan manual

Selepas menggabungkan sempadan belakang dan sempadan hadapan yang telah diketatkan, tingkah laku SLC gabungan menjadi jelas:

  • Fungsi di atas memberitahu kita bahawa satu partisi dipilih di mana peralihan daripada sempadan belakang kepada sempadan hadapan yang diketatkan berlaku.

  • Kita boleh lihat di bawah bahawa SLC kini mengandungi sebahagian sempadan belakang dan sebahagian sempadan hadapan yang diketatkan.

for p in "XYZ":
display(
draw_shaded_lightcone(
boxed_circuit,
merged_bounds,
noise_model_paulis,
pauli_filter=p,
scale=0.15,
fold=-1,
idle_wires=False,
wire_order=wire_order,
measure_arrows=False,
)
)

Output of the previous code cell

Output of the previous code cell

Output of the previous code cell

Langkah 3: Laksanakan

Dalam bahagian ini kami memulakan bahagian aliran kerja yang menggunakan peranti kuantum sebenar. Untuk kaedah pengurangan ralat berasaskan pembelajaran ini, terdapat dua langkah:

  1. Pelajari hingar dengan menggunakan NoiseLearnerV3.

  2. Laksanakan Circuit pengurangan ralat dengan rangka kerja samplomatic dan Executor.

Dengan ralat bersempadan daripada Circuit kuantum kami, kami mempelajari kadar hingar berkaitan untuk mengutamakan bajet ralat kami, menentukan overhead pensampelan, dan melaksanakan pada QPU.

a. Pelajari kadar hingar

Noise learner mencirikan proses hingar yang menjejaskan Gate dalam satu atau lebih Circuit yang diminati, berdasarkan model hingar Pauli-Lindblad yang sparse. Kaedah run() melancarkan tugas pembelajaran hingar bagi lapisan dua-Qubit unik yang disediakan, menggunakan pilihan yang dinyatakan dalam konfigurasi noise learner. Pilihan ini mengawal strategi Pauli-twirling, bilangan rawakan dan shot, kedalaman pembelajaran, dan pemilihan-pasca.

Kami juga memilih kedalaman pembelajaran secara sengaja. Satu penemuan praktikal untuk pengurangan berasaskan pembelajaran dengan samplomatic ialah adalah amat bermanfaat bagi kedalaman pembelajaran paling dalam untuk sepadan dengan kedalaman Circuit yang anda ingin kurangkan. Oleh kerana layer_pair_depths NLv3 diukur dalam pasangan lapisan (satu lapisan ditambah songsangannya), kami menetapkan nilai paling dalam kepada separuh kedalaman lapisan-dua-Qubit Circuit.

post_selection_enabled = True
# Match the deepest noise-learning depth to the depth of the circuit being
# mitigated. NLv3 ``layer_pair_depths`` are measured in layer pairs (a layer
# plus its inverse), so the deepest value is half the circuit's two-qubit-layer
# depth. Learning to this depth markedly improves the quality of the mitigation.
#
# We measure the two-qubit-layer depth on the pre-boxed ISA circuit: after
# boxing, every two-qubit gate is hidden inside a full-width ``BoxOp``, so a
# ``num_qubits == 2`` filter on ``boxed_circuit`` matches nothing (and
# ``QuantumCircuit.depth`` does not recurse into boxes).
depth_2q = isa_circuit.depth(lambda instr: instr.operation.num_qubits == 2)
max_layer_pair_depth = depth_2q // 2 # dividing by 2 since we want pairs

# Use a fixed schedule of learning depths, but drop any that exceed the circuit's
# depth and always cap the deepest value at ``max_layer_pair_depth`` so we never
# learn deeper than the circuit being mitigated.
candidate_depths = [1, 2, 4, 8, 12, 16, 24, 32, 40, 48]
layer_pair_depths = sorted(
{d for d in candidate_depths if d < max_layer_pair_depth}
| {max_layer_pair_depth}
)

noise_learner_options = {
"num_randomizations": 64,
"shots_per_randomization": 128,
"layer_pair_depths": layer_pair_depths,
"post_selection": {
"enable": post_selection_enabled,
"strategy": "edge",
"x_pulse_type": "rx",
},
"environment": {"job_tags": ["TUT_SLC"]},
}

noise_learner = NoiseLearnerV3(backend, noise_learner_options)
noise_learner_job = noise_learner.run(unique_2q_instructions)
noise_learner_result = noise_learner_job.result()
if post_selection_enabled:
print(
"Minimum fraction of shots kept for noise learning experiments: ",
end="",
)
print(
f"{min([min(d.values()) for d in [nlr.metadata['post_selection']['fraction_kept'] for nlr in noise_learner_result[:2]]]):.2f}"
)
Minimum fraction of shots kept for noise learning experiments: 0.71
# Get a dict mapping each InjectNoise.ref to its learned PauliLindbladMap
refs_2_plm = noise_learner_result.to_dict(
unique_2q_instructions, require_refs=False
)

b.i. Kemas kini sempadan gabungan dengan kadar hingar sebenar yang dipelajari

Sekarang setelah model hingar khusus dipelajari, kita boleh menggunakan kadar hingar yang dipelajari pada sempadan hingar yang diramalkan dan memperoleh penentuan akhir tentang sempadan mana yang mempunyai kesan paling besar terhadap meminimumkan bias.

merged_bounds = merge_bounds(
boxed_circuit,
forward_bounds_tighter,
backward_bounds,
refs_2_plm,
)
Optimal spacetime partitioning not implemented!Just partitioning list of noisy boxes.

b.ii. Kira local_scales untuk pelaksanaan perkakasan

compute_local_scales melihat setiap ralat hingar yang mungkin dalam Circuit dan menganggarkan berapa banyak ralat itu boleh membiaskan pengukuran akhir, serta betapa mahalnya untuk membetulkannya. Ia kemudian menyusun ralat mengikut keutamaan berdasarkan sejauh mana berbaloi untuk dikurangkan dan memilih subset yang mengurangkan bias sebanyak mungkin, sambil kekal dalam bajet kos-pensampelan yang dibenarkan (atau mencapai ketepatan yang dikehendaki). Hasilnya ialah satu set faktor penskalaan yang menunjukkan ralat mana yang akan dikurangkan secara aktif dan mana yang akan dibiarkan tanpa dikurangkan (local_scales), bersama-sama dengan overhead kos pensampelan jumlah yang diramalkan (sampling_costs) dan baki bias (residual_bias_bound).

Keupayaan untuk mengawal baki bias yang dikehendaki adalah ciri kritikal bagi pelaksanaan SLC PEC. Sedangkan dalam pelaksanaan asal, overhead pensampelan sentiasa menyasarkan bias sifar, kita boleh menala overhead pensampelan yang diperlukan dengan pertukaran dalam jangkaan baki bias. Ini membantu pengguna kekal dalam bajet pensampelan tetap, yang boleh amat berguna semasa membina prototaip aliran kerja pada peringkat awal.

id_map = map_modifier_ref_to_ref(boxed_circuit)
summed_rates = 0.0
for box_id, noise_id in id_map.items():
learned_plm = refs_2_plm[noise_id]
summed_rates += np.sum(learned_plm.rates)
# print(f"{box_id}:\tgamma = {np.exp(2 * summed_rates):1.6e}\tsampling cost = {np.exp(4 * summed_rates):1.6e}")
total_gamma = np.exp(2 * summed_rates)
print(
f"Full PEC gamma={total_gamma}, sampling cost (gamma^2) = {total_gamma**2}"
)
Full PEC gamma=12.750876317157042, sampling cost (gamma^2) = 162.58484685543633
biases = []
costs = []
for bias in [0.0] + np.arange(0.001, 0.102, 0.01).tolist():
_, cost_, bias_ = compute_local_scales(
boxed_circuit,
merged_bounds,
refs_2_plm,
sampling_cost_budget=np.inf,
bias_tolerance=bias,
)
biases.append(bias_)
costs.append(cost_)

Imbangi overhed pensampelan berbanding pincang baki

xticks = np.arange(0, 11)

fig, ax = plt.subplots()
ax.scatter(
[0], [total_gamma**2], marker="D", c="tab:orange", label="full PEC"
)
ax.plot(
100 * np.array(biases),
np.array(costs),
"o-",
c="tab:blue",
label="PEC+SLC",
)
ax.set_yscale("log")
ax.set_xticks(xticks, [f"{x:.1f}" for x in xticks])

ax.set_xlabel("Remaining bias [%]")
ax.set_ylabel(r"Sampling overhead, $\gamma^2$")
ax.grid()
ax.legend()
fig.suptitle("PEC sampling overhead reduction due to SLC")
Text(0.5, 0.98, 'PEC sampling overhead reduction due to SLC')

Output of the previous code cell

chosen_bias_thres = 0.1
local_scales, sampling_cost, residual_bias_bound = compute_local_scales(
boxed_circuit,
merged_bounds,
refs_2_plm,
sampling_cost_budget=np.inf,
bias_tolerance=chosen_bias_thres,
)
print(
f"PEC+SLC sampling cost (gamma^2) = {sampling_cost} "
f"w/ remaining bias = {100 * residual_bias_bound:.1f}%"
)
PEC+SLC sampling cost (gamma^2) = 48.13646509622307 w/ remaining bias = 10.0%

c. Laksanakan litar yang diminati dengan antihingar

c.i. Sediakan litar templat dengan menggunakan samplex

samplex ialah output daripada kaedah build bagi Samplomatic, yang mengekod semua maklumat yang diperlukan untuk menjana parameter rawak bagi template_circuit. Ini kemudiannya digunakan untuk menyediakan objek QuantumProgram, yang seterusnya dijalankan pada QPU dengan primitif Executor. Setiap QuantumProgram boleh mengandungi beberapa item, yang boleh anda fikirkan sebagai pasangan template dan samplex.

Lihat tutorial Hello samplomatic untuk butiran.

# Build template circuit and samplex for later use with the "Executor"
template_circuit, samplex = samplomatic.build(boxed_circuit)
# Set up postselection if it's been enabled
if post_selection_enabled:
# Set up post selection PM (to add PS instructions)
post_selection_pm = PassManager(
[
AddSpectatorMeasures(backend.coupling_map),
AddPostSelectionMeasures(x_pulse_type="rx"),
]
)
final_template_circuit = post_selection_pm.run(template_circuit)
else:
final_template_circuit = template_circuit

c.ii. Sediakan QuantumProgram

num_randomizations = 4096
shots_per_randomization = 64
chunk_size = 256
# Set up QuantumProgram
program = QuantumProgram(shots=shots_per_randomization, noise_maps=refs_2_plm)

# no EM

# Collect up a dict of the other arguments that need to be bound to samplex_inputs
samplex_inputs = {
f"noise_scales.{ref}": float(0) for ref in local_scales.keys()
}
samplex_inputs |= {"basis_changes": {"basis0": bases_canon[0]}}

# Convert samplex_inputs into a dict to pass to QuantumProgram
samplex_arguments = (
samplex.inputs().bind(**samplex_inputs).make_broadcastable()
)

program.append_samplex_item(
circuit=final_template_circuit,
samplex=samplex,
samplex_arguments=samplex_arguments,
shape=(num_randomizations,),
chunk_size=chunk_size,
)

# plain PEC

# Collect a dict of the other arguments that need to be bound to samplex_inputs
samplex_inputs = {
f"noise_scales.{ref}": float(-1) for ref in local_scales.keys()
}
samplex_inputs |= {"basis_changes": {"basis0": bases_canon[0]}}

# Convert samplex_inputs into a dict to pass to QuantumProgram
samplex_arguments = (
samplex.inputs().bind(**samplex_inputs).make_broadcastable()
)

program.append_samplex_item(
circuit=final_template_circuit,
samplex=samplex,
samplex_arguments=samplex_arguments,
shape=(num_randomizations,),
chunk_size=chunk_size,
)

# PEC+SLC

# Collect a dict of the other arguments that need to be bound to samplex_inputs
samplex_inputs = {
f"noise_scales.{ref}": float(-1) for ref in local_scales.keys()
}
samplex_inputs |= {"basis_changes": {"basis0": bases_canon[0]}}
samplex_inputs |= {"local_scales": local_scales}

# Convert samplex_inputs into a dict to pass to QuantumProgram
samplex_arguments = (
samplex.inputs().bind(**samplex_inputs).make_broadcastable()
)

program.append_samplex_item(
circuit=final_template_circuit,
samplex=samplex,
samplex_arguments=samplex_arguments,
shape=(num_randomizations,),
chunk_size=chunk_size,
)

c.iii. Execute program with the Executor primitive

executor = Executor(backend)
job_exec = executor.run(program)
results_exec = job_exec.result()

Langkah 4: Pasca-proses

Semasa kami mengira nilai jangkaan akhir yang diminati dengan menggunakan executor_expectation_values, kami melaksanakan beberapa teknik pasca-pemprosesan untuk membantu memastikan kami memperoleh hasil berkualiti tertinggi yang mungkin. Pertama, kami menggunakan twirled readout error extinction (TREX) kami, yang mengambil kira sebarang ralat yang berlaku semasa proses bacaan (readout). Kemudian, kami membetulkan ralat akibat hingar bukan-Markov pada Backend Heron kami dengan menggunakan kaedah pemilihan-pasca. Kaedah ini mengukur Qubit aktif dan spektator, kemudian menggunakan putaran perlahan pada setiap Qubit, dan kemudian mengukur semula. Dalam keadaan di mana kedua-dua pengukuran tidak mengesahkan Qubit terbalik seperti yang dijangkakan, shot ini dibuang dengan menggunakan mask daripada PostSelector. Dalam pengiraan mask, strategi khusus boleh ditetapkan untuk menapis berdasarkan nod satu-Qubit atau tepi spektator bersebelahan, yang boleh mempengaruhi kedua-dua bilangan shot yang ditapis keluar dan kualiti hasil.

measurement_noise_map = noise_learner_result[2].to_pauli_lindblad_map()
trex_scale_factors = trex_factors(measurement_noise_map, reverser_virt)
post_selection_strategy = "node"
def post_process_conv(datum, steps=16, gamma=None, ps=False, trex=False):
meas = datum["meas"]
flips = datum["measurement_flips.meas"]
signs = datum.get("pauli_signs", None)

meas_basis_axis = None
avg_axis = 0

mask = None
if ps and post_selection_enabled:
# Post-select the results
post_selector = PostSelector.from_circuit(
circuit=final_template_circuit, coupling_map=backend.coupling_map
)

# Compute the ps mask for filtering results
mask = post_selector.compute_mask(
datum, strategy=post_selection_strategy
)

# Compute fraction of shots kept from post selection
total_num_shots = num_randomizations * shots_per_randomization
ps_ratio = np.sum(mask) * 100 / total_num_shots / len(bases_canon)
print(
f"With {post_selection_strategy}-based post selection ({ps_ratio:.1f}% of shots kept):"
)

results = []
for i in range(steps, num_randomizations + 1, steps):
# Compute mitigated expvals w/out post-selection
res = executor_expectation_values(
meas[:i],
reverser_virt,
meas_basis_axis,
avg_axis=avg_axis,
measurement_flips=flips[:i],
pauli_signs=signs[:i] if signs is not None else None,
postselect_mask=mask[:i] if mask is not None else None,
rescale_factors=trex_scale_factors if trex else None,
gamma_factor=gamma,
)
results.append(res[0])
return results
gamma_pec = gamma_from_noisy_boxes(refs_2_plm, id_map)
gamma_slc = gamma_from_noisy_boxes(refs_2_plm, id_map, local_scales)
steps = 16
results = {}

for label, result_idx, gamma, use_ps, use_trex in [
("PEC", 1, gamma_pec, True, True),
("PEC+SLC", 2, gamma_slc, True, True),
("Unmitigated", 0, None, False, False),
]:
res = post_process_conv(
results_exec[result_idx],
steps=steps,
gamma=gamma,
ps=use_ps,
trex=use_trex,
)
results[label] = res
With node-based post selection (24.1% of shots kept):
With node-based post selection (24.2% of shots kept):

Daripada pemeriksaan hasil eksperimen, kita boleh membandingkan secara langsung tingkah laku pendekatan yang berbeza: PEC, PEC digabungkan dengan SLC, dan garis dasar tanpa pengurangan. Beberapa butiran khusus untuk ditonjolkan:

  • Hasil tanpa pengurangan terletak jauh di luar jalur bias 10% (berhampiran 0.35) dan tidak terjejas oleh bilangan rawakan.

  • Pada peranti ini, PEC penuh membawa overhead pensampelan sebanyak γ21.6×102\gamma^2 \approx 1.6\times10^2. Selepas ayunan awal yang besar, anggaran PEC-biasa memulihkan isyarat dan mantap sekitar 1.1, sedikit terlebih daripada nilai tepat. Perhatikan bahawa jalur bias 10% hanya terpakai kepada penganggar PEC+SLC: PEC biasa pada dasarnya tidak berbias, jadi sisihan baki ini tidak dilindungi oleh jaminan bias tetapi sebaliknya mencerminkan turun naik statistik dan ketidaksempurnaan dalam model hingar yang dipelajari, yang munasabah pada saiz masalah ini.

  • SLC mengurangkan overhead lagi kira-kira ~3.4 kali ganda (kepada γ248\gamma^2 \approx 48, bagi sempadan baki-bias kira-kira 10%). PEC+SLC juga berayun dengan kuat pada bilangan rawakan yang sedikit, pada mulanya malah mencapai kawasan yang tidak fizikal, tetapi anggarannya menumpu secara mantap kepada nilai tepat, mantap berhampiran 1.0 jauh di dalam jalur. Ia menyamai atau melebihi ketepatan PEC biasa pada kira-kira satu pertiga daripada kos pensampelan, menunjukkan manfaat lightcone shading.

  • Bar ralat bagi kedua-dua anggaran yang dikurangkan mengecut apabila rawakan bertambah; pada bilangan rawakan yang tetap, penganggar PEC+SLC mempunyai varians statistik yang lebih kecil, konsisten dengan γ2\gamma^2-nya yang lebih kecil.

Perhatikan bahawa kadar hingar yang dipelajari (dan oleh itu overhead dan anggaran yang dikurangkan) bergantung pada Backend dan kalibrasinya pada masa pelaksanaan, jadi menjalankan semula notebook ini boleh menghasilkan nilai yang berbeza secara kuantitatif.

fig, ax = plt.subplots(1, 1, figsize=(12, 6))

ax.axhline(1.0, color="black", label="Exact")
ax.fill_between(
[-50, 4100], -10, 0, color="grey", alpha=0.25, label="Unphysical"
)
ax.fill_between([-50, 4100], 1, 10, color="grey", alpha=0.25)
ax.fill_between(
[-50, 4100], 0.9, 1.1, color="red", alpha=0.25, label="10% bias"
)

for label, res in results.items():
ax.errorbar(
list(range(steps, num_randomizations + 1, steps)),
[r[0] for r in res],
yerr=[r[1] for r in res],
alpha=0.75,
marker="o",
linestyle="",
markerfacecolor="none",
label=label,
)

ax.set_ylabel(r"$\langle X_{6}Z_{13}\rangle$")
ax.set_xlabel("# randomizations")
ax.grid()

ax.legend(ncols=2)
ax.set_ylim([-0.1, 2.0])
ax.set_xlim([-50, 4100])
(-50.0, 4100.0)

Output of the previous code cell

Langkah seterusnya

Jika anda dapati kerja ini menarik, anda mungkin berminat dengan bahan berikut: