Pengoptimuman Transpilasi dengan SABRE
Anggaran penggunaan: kurang daripada satu minit pada pemproses Heron r2 (NOTA: Ini hanya anggaran sahaja. Masa larian anda mungkin berbeza.)
Latar Belakang​
Transpilasi ialah langkah kritikal dalam Qiskit yang menukar litar kuantum kepada bentuk yang serasi dengan perkakasan kuantum tertentu. Ia melibatkan dua peringkat utama: susun atur qubit (memetakan qubit logikal kepada qubit fizikal pada peranti) dan penghalaan gate (memastikan gate berbilang qubit mematuhi sambungan peranti dengan memasukkan gate SWAP mengikut keperluan).
SABRE (SWAP-Based Bidirectional heuristic search algorithm) ialah alat pengoptimuman yang berkuasa untuk kedua-dua susun atur dan penghalaan. Ia sangat berkesan untuk litar berskala besar (100+ qubit) dan peranti dengan peta gandingan yang kompleks, seperti IBM® Heron, di mana pertumbuhan eksponen dalam kemungkinan pemetaan qubit memerlukan penyelesaian yang cekap.
Kenapa guna SABRE?​
SABRE meminimumkan bilangan gate SWAP dan mengurangkan kedalaman litar, meningkatkan prestasi litar pada perkakasan sebenar. Pendekatan berasaskan heuristiknya menjadikannya sesuai untuk perkakasan lanjutan dan litar yang besar dan kompleks. Penambahbaikan terkini yang diperkenalkan dalam algoritma LightSABRE seterusnya mengoptimumkan prestasi SABRE, menawarkan masa larian yang lebih pantas dan gate SWAP yang lebih sedikit. Penambahbaikan ini menjadikannya lebih berkesan lagi untuk litar berskala besar.
Apa yang akan anda pelajari​
Tutorial ini dibahagikan kepada dua bahagian:
- Pelajari cara menggunakan SABRE dengan corak Qiskit untuk pengoptimuman lanjutan litar besar.
- Manfaatkan qiskit_serverless untuk memaksimumkan potensi SABRE bagi transpilasi yang berskala dan cekap.
Anda akan:
- Mengoptimumkan SABRE untuk litar dengan 100+ qubit, melampaui tetapan transpilasi lalai seperti
optimization_level=3. - Meneroka penambahbaikan LightSABRE yang meningkatkan masa larian dan mengurangkan bilangan gate.
- Menyesuaikan parameter utama SABRE (
swap_trials,layout_trials,max_iterations,heuristic) untuk mengimbangi kualiti litar dan masa larian transpilasi.
Keperluan​
Sebelum memulakan tutorial ini, pastikan anda telah memasang yang berikut:
- Qiskit SDK v1.0 atau lebih baru, dengan sokongan visualisasi
- Qiskit Runtime v0.28 atau lebih baru (
pip install qiskit-ibm-runtime) - Serverless (
pip install qiskit-ibm-catalog qiskit_serverless)
Persediaan​
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-catalog qiskit-ibm-runtime qiskit-serverless
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorOptions
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit.transpiler import CouplingMap
from qiskit.transpiler.passes import SabreLayout, SabreSwap
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
import matplotlib.pyplot as plt
import numpy as np
import time
Bahagian I. Menggunakan SABRE dengan corak Qiskit​
SABRE boleh digunakan dalam Qiskit untuk mengoptimumkan litar kuantum dengan mengendalikan kedua-dua peringkat susun atur qubit dan penghalaan gate. Dalam bahagian ini, kami akan membimbing anda melalui contoh minimal menggunakan SABRE dengan corak Qiskit, dengan fokus utama pada langkah 2 pengoptimuman.
Untuk menjalankan SABRE, anda memerlukan:
- Perwakilan DAG (Graf Tak Berlingkar Berarah) bagi litar kuantum anda.
- Peta gandingan daripada backend, yang menentukan cara qubit disambungkan secara fizikal.
- Laluan SABRE, yang menggunakan algoritma untuk mengoptimumkan susun atur dan penghalaan.
Untuk bahagian ini, kita akan fokus pada laluan SabreLayout. Ia menjalankan ujian susun atur dan penghalaan, berusaha mencari susun atur awal yang paling cekap sambil meminimumkan bilangan gate SWAP yang diperlukan. Yang penting, SabreLayout secara dalaman mengoptimumkan kedua-dua susun atur dan penghalaan dengan menyimpan penyelesaian yang menambah bilangan gate SWAP paling sedikit. Perlu diambil perhatian bahawa apabila menggunakan SabreLayout sahaja, kita tidak boleh mengubah heuristik SABRE, tetapi kita boleh menyesuaikan bilangan layout_trials.
Langkah 1: Petakan input klasikal kepada masalah kuantum​
Litar GHZ (Greenberger-Horne-Zeilinger) ialah litar kuantum yang menyediakan keadaan terbelit di mana semua qubit berada dalam keadaan |0...0⟩ atau |1...1⟩. Keadaan GHZ untuk qubit diwakili secara matematik sebagai:
Ia dibina dengan menggunakan:
- Gate Hadamard pada qubit pertama untuk mencipta superposisi.
- Satu siri gate CNOT untuk membelitkan qubit yang selebihnya dengan yang pertama.
Untuk contoh ini, kita sengaja membina litar GHZ topologi bintang dan bukannya topologi linear. Dalam topologi bintang, qubit pertama bertindak sebagai "hab," dan semua qubit lain dibelit secara langsung dengannya menggunakan gate CNOT. Pilihan ini disengajakan kerana, walaupun keadaan GHZ topologi linear secara teorinya boleh dilaksanakan dalam kedalaman pada peta gandingan linear tanpa gate SWAP, SABRE akan dengan mudah mencari penyelesaian optimum dengan memetakan litar GHZ 100 qubit kepada subgraf peta gandingan heavy-hex backend.
Litar GHZ topologi bintang menimbulkan masalah yang jauh lebih mencabar. Walaupun ia masih secara teorinya boleh dilaksanakan dalam kedalaman tanpa gate SWAP, mencari penyelesaian ini memerlukan pengenalpastian susun atur awal yang optimum, yang jauh lebih sukar disebabkan oleh sambungan litar yang tidak linear. Topologi ini berfungsi sebagai kes ujian yang lebih baik untuk menilai SABRE, kerana ia menunjukkan bagaimana parameter konfigurasi mempengaruhi prestasi susun atur dan penghalaan dalam keadaan yang lebih kompleks.

Perlu diperhatikan:
- Alat HighLevelSynthesis boleh menghasilkan penyelesaian kedalaman yang optimum untuk litar GHZ topologi bintang tanpa memperkenalkan gate SWAP, seperti yang ditunjukkan dalam gambar di atas.
- Sebagai alternatif, laluan StarPrerouting boleh mengurangkan kedalaman dengan lebih lanjut dengan membimbing keputusan penghalaan SABRE, walaupun ia mungkin masih memperkenalkan beberapa gate SWAP. Walau bagaimanapun, StarPrerouting meningkatkan masa larian dan memerlukan integrasi ke dalam proses transpilasi awal.
Untuk tujuan tutorial ini, kita mengecualikan HighLevelSynthesis dan StarPrerouting untuk mengasingkan dan menyerlahkan kesan langsung konfigurasi SABRE terhadap masa larian dan kedalaman litar. Dengan mengukur nilai jangkaan untuk setiap pasangan qubit, kita menganalisis:
- Seberapa baik SABRE mengurangkan gate SWAP dan kedalaman litar.
- Kesan pengoptimuman ini terhadap ketepatan litar yang dilaksanakan, di mana penyelewengan daripada menunjukkan kehilangan belitan.!
# set seed for reproducibility
seed = 42
num_qubits = 110
# Create GHZ circuit
qc = QuantumCircuit(num_qubits)
qc.h(0)
for i in range(1, num_qubits):
qc.cx(0, i)
qc.measure_all()
Seterusnya, kita akan memetakan operator yang diminati untuk menilai tingkah laku sistem. Khususnya, kita akan menggunakan operator ZZ antara qubit untuk memeriksa bagaimana belitan merosot apabila qubit semakin berjauhan. Analisis ini adalah kritikal kerana ketidaktepatan dalam nilai jangkaan untuk qubit yang jauh boleh mendedahkan kesan bunyi dan ralat dalam pelaksanaan litar. Dengan mengkaji penyelewengan ini, kita mendapat gambaran tentang seberapa baik litar memelihara belitan di bawah konfigurasi SABRE yang berbeza dan seberapa berkesan SABRE meminimumkan kesan kekangan perkakasan.
# ZZII...II, ZIZI...II, ... , ZIII...IZ
operator_strings = [
"Z" + "I" * i + "Z" + "I" * (num_qubits - 2 - i)
for i in range(num_qubits - 1)
]
print(operator_strings)
print(len(operator_strings))
operators = [SparsePauliOp(operator) for operator in operator_strings]
['ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZI', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZ']
109
Langkah 2: Optimumkan masalah untuk pelaksanaan perkakasan kuantum​
Dalam langkah ini, kita fokus pada pengoptimuman susun atur litar untuk pelaksanaan pada peranti perkakasan kuantum tertentu dengan 127 qubit. Inilah fokus utama tutorial ini, kerana kita melakukan pengoptimuman SABRE dan transpilasi untuk mencapai prestasi litar yang terbaik. Menggunakan laluan SabreLayout, kita menentukan pemetaan qubit awal yang meminimumkan keperluan gate SWAP semasa penghalaan. Dengan menghantar coupling_map dari backend sasaran, SabreLayout menyesuaikan susun atur dengan kekangan sambungan peranti.
Kita akan menggunakan generate_preset_pass_manager dengan optimization_level=3 untuk proses transpilasi dan menyesuaikan laluan SabreLayout dengan konfigurasi yang berbeza. Matlamatnya adalah untuk mencari persediaan yang menghasilkan litar yang ditranspilasi dengan saiz dan/atau kedalaman terendah, menunjukkan kesan pengoptimuman SABRE.
Kenapa Saiz dan Kedalaman Litar Penting?​
- Saiz lebih rendah (bilangan gate): Mengurangkan bilangan operasi, meminimumkan peluang ralat terkumpul.
- Kedalaman lebih rendah: Memendekkan jumlah masa pelaksanaan, yang kritikal untuk mengelakkan dekoherensi dan mengekalkan ketepatan keadaan kuantum.
Dengan mengoptimumkan metrik ini, kita meningkatkan kebolehpercayaan litar dan ketepatan pelaksanaan pada perkakasan kuantum yang berombak. Pilih backend.
service = QiskitRuntimeService()
# backend = service.least_busy(
# operational=True, simulator=False, min_num_qubits=127
# )
backend = service.backend("ibm_boston")
print(f"Using backend: {backend.name}")
Using backend: ibm_boston
Untuk menilai kesan konfigurasi yang berbeza terhadap pengoptimuman litar, kita akan mencipta tiga pengurus laluan, masing-masing dengan tetapan unik untuk laluan SabreLayout. Konfigurasi ini membantu menganalisis pertukaran antara kualiti litar dan masa transpilasi.
Parameter utama​
max_iterations: Bilangan lelaran penghalaan maju-undur untuk memperhalusi susun atur dan mengurangkan kos penghalaan.layout_trials: Bilangan susun atur awal rawak yang diuji, memilih yang meminimumkan gate SWAP.swap_trials: Bilangan ujian penghalaan untuk setiap susun atur, memperhalusi penempatan gate untuk penghalaan yang lebih baik.
Tingkatkan layout_trials dan swap_trials untuk melakukan pengoptimuman yang lebih menyeluruh, dengan kos peningkatan masa transpilasi.
Konfigurasi dalam tutorial ini​
-
pm_1: Tetapan lalai denganoptimization_level=3.max_iterations=4layout_trials=20swap_trials=20
-
pm_2: Meningkatkan bilangan ujian untuk penerokaan yang lebih baik.max_iterations=4layout_trials=200swap_trials=200
-
pm_3: Melanjutkanpm_2dengan meningkatkan bilangan lelaran untuk pemurnian selanjutnya.max_iterations=8layout_trials=200swap_trials=200
Dengan membandingkan hasil konfigurasi ini, kita bertujuan untuk menentukan mana yang mencapai keseimbangan terbaik antara kualiti litar (contohnya, saiz dan kedalaman) dan kos pengiraan.
# Get the coupling map from the backend
cmap = CouplingMap(backend().configuration().coupling_map)
# Create the SabreLayout passes for the custom configurations
sl_2 = SabreLayout(
coupling_map=cmap,
seed=seed,
max_iterations=4,
layout_trials=200,
swap_trials=200,
)
sl_3 = SabreLayout(
coupling_map=cmap,
seed=seed,
max_iterations=8,
layout_trials=200,
swap_trials=200,
)
# Create the pass managers, need to first create then configure the SabreLayout passes
pm_1 = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=seed
)
pm_2 = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=seed
)
pm_3 = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=seed
)
Kini kita boleh mengkonfigurasi laluan SabreLayout dalam pengurus laluan tersuai. Untuk melakukan ini, kita tahu bahawa untuk generate_preset_pass_manager lalai pada optimization_level=3, laluan SabreLayout berada pada indeks 2, kerana SabreLayout berlaku selepas laluan SetLayout dan VF2Laout. Kita boleh mengakses laluan ini dan mengubah parameternya.
pm_2.layout.replace(index=2, passes=sl_2)
pm_3.layout.replace(index=2, passes=sl_3)
Dengan setiap pengurus laluan dikonfigurasi, kita kini akan melaksanakan proses transpilasi untuk setiap satu. Untuk membandingkan hasil, kita akan menjejak metrik utama, termasuk masa transpilasi, kedalaman litar (diukur sebagai kedalaman gate dua-qubit), dan jumlah bilangan gate dalam litar yang ditranspilasi.
# Transpile the circuit with each pass manager and measure the time
t0 = time.time()
tqc_1 = pm_1.run(qc)
t1 = time.time() - t0
t0 = time.time()
tqc_2 = pm_2.run(qc)
t2 = time.time() - t0
t0 = time.time()
tqc_3 = pm_3.run(qc)
t3 = time.time() - t0
# Obtain the depths and the total number of gates (circuit size)
depth_1 = tqc_1.depth(lambda x: x.operation.num_qubits == 2)
depth_2 = tqc_2.depth(lambda x: x.operation.num_qubits == 2)
depth_3 = tqc_3.depth(lambda x: x.operation.num_qubits == 2)
size_1 = tqc_1.size()
size_2 = tqc_2.size()
size_3 = tqc_3.size()
# Transform the observables to match the backend's ISA
operators_list_1 = [op.apply_layout(tqc_1.layout) for op in operators]
operators_list_2 = [op.apply_layout(tqc_2.layout) for op in operators]
operators_list_3 = [op.apply_layout(tqc_3.layout) for op in operators]
# Compute improvements compared to pass manager 1 (default)
depth_improvement_2 = ((depth_1 - depth_2) / depth_1) * 100
depth_improvement_3 = ((depth_1 - depth_3) / depth_1) * 100
size_improvement_2 = ((size_1 - size_2) / size_1) * 100
size_improvement_3 = ((size_1 - size_3) / size_1) * 100
time_increase_2 = ((t2 - t1) / t1) * 100
time_increase_3 = ((t3 - t1) / t1) * 100
print(
f"Pass manager 1 (4,20,20) : Depth {depth_1}, Size {size_1}, Time {t1:.4f} s"
)
print(
f"Pass manager 2 (4,200,200): Depth {depth_2}, Size {size_2}, Time {t2:.4f} s"
)
print(f" - Depth improvement: {depth_improvement_2:.2f}%")
print(f" - Size improvement: {size_improvement_2:.2f}%")
print(f" - Time increase: {time_increase_2:.2f}%")
print(
f"Pass manager 3 (8,200,200): Depth {depth_3}, Size {size_3}, Time {t3:.4f} s"
)
print(f" - Depth improvement: {depth_improvement_3:.2f}%")
print(f" - Size improvement: {size_improvement_3:.2f}%")
print(f" - Time increase: {time_increase_3:.2f}%")
Pass manager 1 (4,20,20) : Depth 439, Size 2346, Time 0.5775 s
Pass manager 2 (4,200,200): Depth 395, Size 2070, Time 3.9927 s
- Depth improvement: 10.02%
- Size improvement: 11.76%
- Time increase: 591.43%
Pass manager 3 (8,200,200): Depth 375, Size 1873, Time 2.3079 s
- Depth improvement: 14.58%
- Size improvement: 20.16%
- Time increase: 299.67%
Hasilnya menunjukkan bahawa meningkatkan bilangan ujian (layout_trials dan swap_trials) boleh meningkatkan kualiti litar dengan ketara dengan mengurangkan kedua-dua kedalaman dan saiz. Walau bagaimanapun, peningkatan ini sering datang dengan kos peningkatan masa larian disebabkan oleh pengiraan tambahan yang diperlukan untuk meneroka lebih banyak susun atur dan laluan penghalaan yang berpotensi.
Meningkatkan max_iterations boleh seterusnya meningkatkan pengoptimuman dengan memperhalusi susun atur melalui lebih banyak kitaran penghalaan maju-undur. Dalam kes ini, meningkatkan max_iterations menghasilkan pengurangan paling ketara dalam kedalaman dan saiz litar, malah mengurangkan masa larian berbanding pm_2, mungkin dengan memperkemaskan peringkat pengoptimuman seterusnya. Walau bagaimanapun, adalah penting untuk diambil perhatian bahawa keberkesanan meningkatkan max_iterations boleh berbeza-beza dengan ketara bergantung pada litar. Walaupun lebih banyak lelaran mungkin menghasilkan pilihan susun atur dan penghalaan yang lebih baik, ia tidak memberikan jaminan dan bergantung sangat pada struktur litar dan kerumitan kekangan sambungan.
# Plot the results of the metrics
times = [t1, t2, t3]
depths = [depth_1, depth_2, depth_3]
sizes = [size_1, size_2, size_3]
pm_names = [
"pm_1 (4 iter, 20 trials)",
"pm_2 (4 iter, 200 trials)",
"pm_3 (8 iter, 200 trials)",
]
colors = plt.cm.viridis(np.linspace(0.2, 0.8, len(pm_names)))
# Create a figure with three subplots
fig, axs = plt.subplots(3, 1, figsize=(6, 9), sharex=True)
axs[0].bar(pm_names, times, color=colors)
axs[0].set_ylabel("Time (s)", fontsize=12)
axs[0].set_title("Transpilation Time", fontsize=14)
axs[0].grid(axis="y", linestyle="--", alpha=0.7)
axs[1].bar(pm_names, depths, color=colors)
axs[1].set_ylabel("Depth", fontsize=12)
axs[1].set_title("Circuit Depth", fontsize=14)
axs[1].grid(axis="y", linestyle="--", alpha=0.7)
axs[2].bar(pm_names, sizes, color=colors)
axs[2].set_ylabel("Size", fontsize=12)
axs[2].set_title("Circuit Size", fontsize=14)
axs[2].set_xticks(range(len(pm_names)))
axs[2].set_xticklabels(pm_names, fontsize=10, rotation=15)
axs[2].grid(axis="y", linestyle="--", alpha=0.7)
# Add some spacing between subplots
plt.tight_layout()
plt.show()
Langkah 3: Laksanakan menggunakan primitif Qiskit​
Dalam langkah ini, kita menggunakan primitif Estimator untuk mengira nilai jangkaan bagi operator ZZ, menilai belitan dan kualiti pelaksanaan litar yang ditranspilasi. Untuk sejajar dengan aliran kerja pengguna biasa, kita menghantar tugas untuk pelaksanaan dan menggunakan penindasan ralat menggunakan penguraian dinamik, teknik yang mengurangkan dekoherensi dengan memasukkan jujukan gate untuk memelihara keadaan qubit. Selain itu, kita menentukan tahap ketahanan untuk mengatasi bunyi, dengan tahap yang lebih tinggi memberikan hasil yang lebih tepat dengan kos masa pemprosesan yang meningkat. Pendekatan ini menilai prestasi setiap konfigurasi pengurus laluan dalam keadaan pelaksanaan yang realistik.
options = EstimatorOptions()
options.resilience_level = 2
options.dynamical_decoupling.enable = True
options.dynamical_decoupling.sequence_type = "XY4"
# Create an Estimator object
estimator = Estimator(backend, options=options)
# Submit the circuit to Estimator
job_1 = estimator.run([(tqc_1, operators_list_1)])
job_1_id = job_1.job_id()
print(job_1_id)
job_2 = estimator.run([(tqc_2, operators_list_2)])
job_2_id = job_2.job_id()
print(job_2_id)
job_3 = estimator.run([(tqc_3, operators_list_3)])
job_3_id = job_3.job_id()
print(job_3_id)
d5k0qs7853es738dab6g
d5k0qsf853es738dab70
d5k0qsf853es738dab7g
# Run the jobs
result_1 = job_1.result()[0]
print("Job 1 done")
result_2 = job_2.result()[0]
print("Job 2 done")
result_3 = job_3.result()[0]
print("Job 3 done")
Job 1 done
Job 2 done
Job 3 done
Langkah 4: Proses selepas dan kembalikan hasil dalam format klasikal yang dikehendaki​
Setelah tugas selesai, kita menganalisis hasil dengan memplot nilai jangkaan untuk setiap qubit. Dalam simulasi ideal, semua nilai sepatutnya 1, mencerminkan belitan sempurna merentasi qubit. Walau bagaimanapun, disebabkan bunyi dan kekangan perkakasan, nilai jangkaan biasanya menurun apabila i meningkat, mendedahkan bagaimana belitan merosot mengikut jarak.
Dalam langkah ini, kita membandingkan hasil daripada setiap konfigurasi pengurus laluan dengan simulasi ideal. Dengan memeriksa penyelewengan daripada 1 untuk setiap konfigurasi, kita boleh mengukur seberapa baik setiap pengurus laluan memelihara belitan dan mengurangkan kesan bunyi. Analisis ini secara langsung menilai kesan pengoptimuman SABRE terhadap ketepatan pelaksanaan dan menyerlahkan konfigurasi mana yang paling mengimbangi kualiti pengoptimuman dan prestasi pelaksanaan.
Hasilnya akan divisualisasikan untuk menyerlahkan perbezaan merentasi pengurus laluan, menunjukkan bagaimana penambahbaikan dalam susun atur dan penghalaan mempengaruhi pelaksanaan litar akhir pada perkakasan kuantum yang berombak.
data = list(range(1, len(operators) + 1)) # Distance between the Z operators
values_1 = list(result_1.data.evs)
values_2 = list(result_2.data.evs)
values_3 = list(result_3.data.evs)
plt.plot(
data,
values_1,
marker="o",
label="pm_1 (iters=4, swap_trials=20, layout_trials=20)",
)
plt.plot(
data,
values_2,
marker="s",
label="pm_2 (iters=4, swap_trials=200, layout_trials=200)",
)
plt.plot(
data,
values_3,
marker="^",
label="pm_3 (iters=8, swap_trials=200, layout_trials=200)",
)
plt.xlabel("Distance between qubits $i$")
plt.ylabel(r"$\langle Z_i Z_0 \rangle / \langle Z_1 Z_0 \rangle $")
plt.legend()
plt.show()

Analisis Hasil​
Plot menunjukkan nilai jangkaan sebagai fungsi jarak antara qubit untuk tiga konfigurasi pengurus laluan dengan tahap pengoptimuman yang semakin meningkat. Dalam kes ideal, nilai-nilai ini kekal hampir 1, menunjukkan korelasi yang kuat merentasi litar. Apabila jarak meningkat, bunyi dan ralat terkumpul membawa kepada kemerosotan dalam korelasi, mendedahkan seberapa baik setiap strategi transpilasi memelihara struktur asas keadaan.
Di antara ketiga-tiga konfigurasi, pm_1 jelas berprestasi paling buruk. Nilai korelasinya merosot dengan cepat apabila jarak meningkat dan mendekati sifar lebih awal berbanding dua konfigurasi yang lain. Tingkah laku ini konsisten dengan kedalaman litar dan bilangan gate yang lebih besar, di mana bunyi terkumpul dengan cepat merendahkan korelasi jarak jauh.
Kedua-dua pm_2 dan pm_3 mewakili penambahbaikan ketara berbanding pm_1 merentasi hampir semua jarak. Secara purata, pm_3 menunjukkan prestasi keseluruhan yang terkuat, mengekalkan nilai korelasi yang lebih tinggi pada jarak yang lebih jauh dan menunjukkan kemerosotan yang lebih beransur-ansur. Ini sejajar dengan pengoptimuman yang lebih agresif, yang menghasilkan litar yang lebih cetek yang umumnya lebih tahan terhadap pengumpulan bunyi.
Walau demikian, pm_2 menunjukkan ketepatan yang lebih baik pada jarak pendek berbanding pm_3, walaupun mempunyai kedalaman dan bilangan gate yang sedikit lebih besar. Ini mencadangkan bahawa kedalaman litar sahaja tidak sepenuhnya menentukan prestasi; struktur khusus yang dihasilkan oleh transpilasi, termasuk cara gate membelit disusun dan cara ralat merebak melalui litar, juga memainkan peranan penting. Dalam sesetengah kes, transformasi yang digunakan oleh pm_2 nampaknya lebih baik memelihara korelasi tempatan, walaupun ia tidak berskala dengan baik pada jarak yang lebih jauh.
Secara keseluruhannya, hasil ini menyerlahkan pertukaran antara kepadatan litar dan struktur litar. Walaupun pengoptimuman yang meningkat umumnya meningkatkan kestabilan jarak jauh, prestasi terbaik untuk sesuatu boleh cerapan bergantung pada kedua-dua pengurangan kedalaman litar dan penghasilan struktur yang sepadan baik dengan ciri bunyi perkakasan.
Bahagian II. Mengkonfigurasi heuristik dalam SABRE dan menggunakan Serverless​
Selain menyesuaikan bilangan ujian, SABRE menyokong penyesuaian heuristik penghalaan yang digunakan semasa transpilasi. Secara lalai, SabreLayout menggunakan heuristik pereputan, yang secara dinamik memberi berat kepada qubit berdasarkan kebarangkalian mereka untuk ditukar. Untuk menggunakan heuristik yang berbeza (seperti heuristik lookahead), anda boleh mencipta laluan SabreSwap tersuai dan menghubungkannya dengan SabreLayout dengan menjalankan PassManager dengan FullAncillaAllocation, EnlargeWithAncilla, dan ApplyLayout. Apabila menggunakan SabreSwap sebagai parameter untuk SabreLayout, hanya satu ujian susun atur dilakukan secara lalai. Untuk menjalankan berbilang ujian susun atur dengan cekap, kita memanfaatkan masa larian serverless untuk selarian. Untuk maklumat lanjut tentang serverless, lihat dokumentasi Serverless.
Cara Menukar Heuristik Penghalaan​
- Cipta laluan
SabreSwaptersuai dengan heuristik yang dikehendaki. - Gunakan
SabreSwaptersuai ini sebagai kaedah penghalaan untuk laluanSabreLayout.
Walaupun ia mungkin untuk menjalankan berbilang ujian susun atur menggunakan gelung, masa larian serverless adalah pilihan yang lebih baik untuk eksperimen berskala besar dan lebih gigih. Serverless menyokong pelaksanaan selari bagi ujian susun atur, mempercepatkan pengoptimuman litar yang lebih besar dan sapuan eksperimen yang besar dengan ketara. Ini menjadikannya sangat berharga apabila bekerja dengan tugas yang memerlukan sumber yang intensif atau apabila kecekapan masa adalah kritikal.
Bahagian ini hanya fokus pada langkah 2 pengoptimuman: meminimumkan saiz dan kedalaman litar untuk mencapai litar yang ditranspilasi sebaik mungkin. Berdasarkan hasil awal, kita kini meneroka bagaimana penyesuaian heuristik dan selarian serverless boleh seterusnya meningkatkan prestasi pengoptimuman, menjadikannya sesuai untuk transpilasi litar kuantum berskala besar.
Hasil tanpa masa larian serverless (1 ujian susun atur):​
swap_trials = 1000
# Default PassManager with `SabreLayout` and `SabreSwap`, using heuristic "decay"
sr_default = SabreSwap(
coupling_map=cmap, heuristic="decay", trials=swap_trials, seed=seed
)
sl_default = SabreLayout(
coupling_map=cmap, routing_pass=sr_default, seed=seed
)
pm_default = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=seed
)
pm_default.layout.replace(index=2, passes=sl_default)
pm_default.routing.replace(index=1, passes=sr_default)
t0 = time.time()
tqc_default = pm_default.run(qc)
t_default = time.time() - t0
size_default = tqc_default.size()
depth_default = tqc_default.depth(lambda x: x.operation.num_qubits == 2)
# Custom PassManager with `SabreLayout` and `SabreSwap`, using heuristic "lookahead"
sr_custom = SabreSwap(
coupling_map=cmap, heuristic="lookahead", trials=swap_trials, seed=seed
)
sl_custom = SabreLayout(coupling_map=cmap, routing_pass=sr_custom, seed=seed)
pm_custom = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=seed
)
pm_custom.layout.replace(index=2, passes=sl_custom)
pm_custom.routing.replace(index=1, passes=sr_custom)
t0 = time.time()
tqc_custom = pm_custom.run(qc)
t_custom = time.time() - t0
size_custom = tqc_custom.size()
depth_custom = tqc_custom.depth(lambda x: x.operation.num_qubits == 2)
print(
f"Default (heuristic='decay') : Depth {depth_default}, Size {size_default}, Time {t_default}"
)
print(
f"Custom (heuristic='lookahead'): Depth {depth_custom}, Size {size_custom}, Time {t_custom}"
)
Default (heuristic='decay') : Depth 443, Size 3115, Time 1.034372091293335
Custom (heuristic='lookahead'): Depth 432, Size 2856, Time 0.6669301986694336
Di sini kita lihat bahawa heuristik lookahead berprestasi lebih baik daripada heuristik decay dari segi kedalaman litar, saiz, dan masa. Penambahbaikan ini menyerlahkan bagaimana kita boleh meningkatkan SABRE melampaui sekadar ujian dan lelaran untuk litar dan kekangan perkakasan anda yang khusus. Perlu diambil perhatian bahawa hasil ini berdasarkan satu ujian susun atur sahaja. Untuk mencapai hasil yang lebih tepat, kami mengesyorkan menjalankan berbilang ujian susun atur, yang boleh dilakukan dengan cekap menggunakan masa larian serverless.
Hasil dengan masa larian serverless (berbilang ujian susun atur)​
Qiskit Serverless memerlukan penyediaan fail .py beban kerja anda ke dalam direktori khusus. Sel kod berikut ialah fail Python dalam direktori source_files bernama transpile_remote.py. Fail ini mengandungi fungsi yang menjalankan proses transpilasi.
# This cell is hidden from users, it makes sure the `source_files` directory exists
from pathlib import Path
Path("source_files").mkdir(exist_ok=True)
%%writefile source_files/transpile_remote.py
import time
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.passes import SabreLayout, SabreSwap
from qiskit.transpiler import CouplingMap
from qiskit_serverless import get_arguments, save_result, distribute_task, get
from qiskit_ibm_runtime import QiskitRuntimeService
@distribute_task(target={
"cpu": 1,
"mem": 1024 * 1024 * 1024
})
def transpile_remote(qc, optimization_level, backend_name, seed, swap_trials, heuristic):
"""Transpiles an abstract circuit into an ISA circuit for a given backend."""
service = QiskitRuntimeService()
backend = service.backend(backend_name)
pm = generate_preset_pass_manager(
optimization_level=optimization_level,
backend=backend,
seed_transpiler=seed
)
# Changing the `SabreLayout` and `SabreSwap` passes to use the custom configurations
cmap = CouplingMap(backend().configuration().coupling_map)
sr = SabreSwap(coupling_map=cmap, heuristic=heuristic, trials=swap_trials, seed=seed)
sl = SabreLayout(coupling_map=cmap, routing_pass=sr, seed=seed)
pm.layout.replace(index=2, passes=sl)
pm.routing.replace(index=1, passes=sr)
# Measure the transpile time
start_time = time.time() # Start timer
tqc = pm.run(qc) # Transpile the circuit
end_time = time.time() # End timer
transpile_time = end_time - start_time # Calculate the elapsed time
return tqc, transpile_time # Return both the transpiled circuit and the transpile time
# Get program arguments
arguments = get_arguments()
circuit = arguments.get("circuit")
backend_name = arguments.get("backend_name")
optimization_level = arguments.get("optimization_level")
seed_list = arguments.get("seed_list")
swap_trials = arguments.get("swap_trials")
heuristic = arguments.get("heuristic")
# Transpile the circuits
transpile_worker_references = [
transpile_remote(circuit, optimization_level, backend_name, seed, swap_trials, heuristic)
for seed in seed_list
]
results_with_times = get(transpile_worker_references)
# Separate the transpiled circuits and their transpile times
transpiled_circuits = [result[0] for result in results_with_times]
transpile_times = [result[1] for result in results_with_times]
# Save both results and transpile times
save_result({"transpiled_circuits": transpiled_circuits, "transpile_times": transpile_times})
Overwriting source_files/transpile_remote.py
Sel berikut memuat naik fail transpile_remote.py sebagai program Qiskit Serverless dengan nama transpile_remote_serverless.
serverless = QiskitServerless()
transpile_remote_demo = QiskitFunction(
title="transpile_remote_serverless",
entrypoint="transpile_remote.py",
working_dir="./source_files/",
)
serverless.upload(transpile_remote_demo)
transpile_remote_serverless = serverless.load("transpile_remote_serverless")
Jana 20 benih yang berbeza untuk mewakili 20 ujian susun atur yang berbeza.
num_seeds = 20 # represents the different layout trials
seed_list = [seed + i for i in range(num_seeds)]
Jalankan program yang dimuat naik dan hantar input untuk heuristik lookahead.
job_lookahead = transpile_remote_serverless.run(
circuit=qc,
backend_name=backend.name,
optimization_level=3,
seed_list=seed_list,
swap_trials=swap_trials,
heuristic="lookahead",
)
job_lookahead.job_id
'15767dfc-e71d-4720-94d6-9212f72334c2'
job_lookahead.status()
'QUEUED'
Terima log dan hasil daripada masa larian serverless.
logs_lookahead = job_lookahead.logs()
print(logs_lookahead)
No logs yet.
Setelah program berstatus DONE, anda boleh menggunakan job.results() untuk mendapatkan hasil yang disimpan dalam save_result().
# Run the job with lookahead heuristic
start_time = time.time()
results_lookahead = job_lookahead.result()
end_time = time.time()
job_lookahead_time = end_time - start_time
Kini lakukan perkara yang sama untuk heuristik decay.
job_decay = transpile_remote_serverless.run(
circuit=qc,
backend_name=backend.name,
optimization_level=3,
seed_list=seed_list,
swap_trials=swap_trials,
heuristic="decay",
)
job_decay.job_id
'00418c76-d6ec-4bd8-9f70-05d0fa14d4eb'
logs_decay = job_decay.logs()
print(logs_decay)
No logs yet.
# Run the job with the decay heuristic
start_time = time.time()
results_decay = job_decay.result()
end_time = time.time()
job_decay_time = end_time - start_time
# Extract transpilation times
transpile_times_decay = results_decay["transpile_times"]
transpile_times_lookahead = results_lookahead["transpile_times"]
# Calculate total transpilation time for serial execution
total_transpile_time_decay = sum(transpile_times_decay)
total_transpile_time_lookahead = sum(transpile_times_lookahead)
# Print total transpilation time
print("=== Total Transpilation Time (Serial Execution) ===")
print(f"Decay Heuristic : {total_transpile_time_decay:.2f} seconds")
print(f"Lookahead Heuristic: {total_transpile_time_lookahead:.2f} seconds")
# Print serverless job time (parallel execution)
print("\n=== Serverless Job Time (Parallel Execution) ===")
print(f"Decay Heuristic : {job_decay_time:.2f} seconds")
print(f"Lookahead Heuristic: {job_lookahead_time:.2f} seconds")
# Calculate and print average runtime per transpilation
avg_transpile_time_decay = total_transpile_time_decay / num_seeds
avg_transpile_time_lookahead = total_transpile_time_lookahead / num_seeds
avg_job_time_decay = job_decay_time / num_seeds
avg_job_time_lookahead = job_lookahead_time / num_seeds
print("\n=== Average Time Per Transpilation ===")
print(f"Decay Heuristic (Serial) : {avg_transpile_time_decay:.2f} seconds")
print(f"Decay Heuristic (Serverless): {avg_job_time_decay:.2f} seconds")
print(
f"Lookahead Heuristic (Serial) : {avg_transpile_time_lookahead:.2f} seconds"
)
print(
f"Lookahead Heuristic (Serverless): {avg_job_time_lookahead:.2f} seconds"
)
# Calculate and print serverless improvement percentage
decay_improvement_percentage = (
(total_transpile_time_decay - job_decay_time) / total_transpile_time_decay
) * 100
lookahead_improvement_percentage = (
(total_transpile_time_lookahead - job_lookahead_time)
/ total_transpile_time_lookahead
) * 100
print("\n=== Serverless Improvement ===")
print(f"Decay Heuristic : {decay_improvement_percentage:.2f}%")
print(f"Lookahead Heuristic: {lookahead_improvement_percentage:.2f}%")
=== Total Transpilation Time (Serial Execution) ===
Decay Heuristic : 112.37 seconds
Lookahead Heuristic: 85.37 seconds
=== Serverless Job Time (Parallel Execution) ===
Decay Heuristic : 5.72 seconds
Lookahead Heuristic: 5.85 seconds
=== Average Time Per Transpilation ===
Decay Heuristic (Serial) : 5.62 seconds
Decay Heuristic (Serverless): 0.29 seconds
Lookahead Heuristic (Serial) : 4.27 seconds
Lookahead Heuristic (Serverless): 0.29 seconds
=== Serverless Improvement ===
Decay Heuristic : 94.91%
Lookahead Heuristic: 93.14%
Hasil ini menunjukkan keuntungan kecekapan yang besar daripada menggunakan pelaksanaan serverless untuk transpilasi litar kuantum. Berbanding dengan pelaksanaan bersiri, pelaksanaan serverless mengurangkan masa larian keseluruhan dengan ketara untuk kedua-dua heuristik decay dan lookahead dengan menselarikan ujian transpilasi yang bebas. Walaupun pelaksanaan bersiri mencerminkan kos kumulatif penuh penerokaan berbilang ujian susun atur, masa tugas serverless menyerlahkan bagaimana pelaksanaan selari mengecut kos ini kepada masa jam dinding yang jauh lebih pendek. Akibatnya, masa pelaksanaan yang berkesan setiap transpilasi dikurangkan kepada sebahagian kecil daripada yang diperlukan dalam tetapan bersiri, sebahagian besarnya bebas daripada heuristik yang digunakan. Keupayaan ini amat penting untuk mengoptimumkan SABRE ke potensi penuhnya. Banyak keuntungan prestasi SABRE yang terkuat datang daripada meningkatkan bilangan ujian susun atur dan penghalaan, yang boleh terlalu mahal apabila dilaksanakan secara berurutan. Pelaksanaan serverless menghapuskan halangan ini, membolehkan sapuan parameter berskala besar dan penerokaan yang lebih mendalam bagi konfigurasi heuristik dengan overhead yang minimum.
Secara keseluruhannya, penemuan ini menunjukkan bahawa pelaksanaan serverless adalah kunci untuk menskalakan pengoptimuman SABRE, menjadikan eksperimen dan pemurnian yang agresif praktikal berbanding dengan pelaksanaan bersiri. Dapatkan hasil daripada masa larian serverless dan bandingkan hasil heuristik lookahead dan decay. Kita akan membandingkan saiz dan kedalaman.
# Extract sizes and depths
sizes_lookahead = [
circuit.size() for circuit in results_lookahead["transpiled_circuits"]
]
depths_lookahead = [
circuit.depth(lambda x: x.operation.num_qubits == 2)
for circuit in results_lookahead["transpiled_circuits"]
]
sizes_decay = [
circuit.size() for circuit in results_decay["transpiled_circuits"]
]
depths_decay = [
circuit.depth(lambda x: x.operation.num_qubits == 2)
for circuit in results_decay["transpiled_circuits"]
]
def create_scatterplot(x, y1, y2, xlabel, ylabel, title, labels, colors):
plt.figure(figsize=(8, 5))
plt.scatter(
x, y1, label=labels[0], color=colors[0], alpha=0.8, edgecolor="k"
)
plt.scatter(
x, y2, label=labels[1], color=colors[1], alpha=0.8, edgecolor="k"
)
plt.xlabel(xlabel, fontsize=12)
plt.ylabel(ylabel, fontsize=12)
plt.title(title, fontsize=14)
plt.legend(fontsize=10)
plt.grid(axis="y", linestyle="--", alpha=0.7)
plt.tight_layout()
plt.show()
create_scatterplot(
seed_list,
sizes_lookahead,
sizes_decay,
"Seed",
"Size",
"Circuit Size",
["lookahead", "Decay"],
["blue", "red"],
)
create_scatterplot(
seed_list,
depths_lookahead,
depths_decay,
"Seed",
"Depth",
"Circuit Depth",
["lookahead", "Decay"],
["blue", "red"],
)


Setiap titik dalam plot serakan di atas mewakili satu ujian susun atur, dengan paksi-x menunjukkan kedalaman litar dan paksi-y menunjukkan saiz litar. Hasilnya mendedahkan bahawa heuristik lookahead umumnya mengatasi heuristik decay dalam meminimumkan kedalaman dan saiz litar. Dalam aplikasi praktikal, matlamatnya adalah untuk mengenal pasti ujian susun atur yang optimum untuk heuristik pilihan anda, sama ada mengutamakan kedalaman atau saiz. Ini boleh dicapai dengan memilih ujian dengan nilai terendah untuk metrik yang dikehendaki. Yang penting, meningkatkan bilangan ujian susun atur meningkatkan peluang untuk mencapai hasil yang lebih baik dari segi saiz atau kedalaman, tetapi ia datang dengan kos overhead pengiraan yang lebih tinggi.
min_depth_lookahead = min(depths_lookahead)
min_depth_decay = min(depths_decay)
min_size_lookahead = min(sizes_lookahead)
min_size_decay = min(sizes_decay)
print(
"Lookahead: Min Depth",
min_depth_lookahead,
"Min Size",
min_size_lookahead,
)
print("Decay: Min Depth", min_depth_decay, "Min Size", min_size_decay)
Lookahead: Min Depth 399 Min Size 2452
Decay: Min Depth 415 Min Size 2611
Dalam perbandingan awal kita menggunakan satu ujian susun atur, heuristik lookahead menunjukkan prestasi yang sedikit lebih baik dalam kedua-dua kedalaman dan saiz litar. Dengan memperluaskan kajian ini kepada berbilang ujian susun atur menggunakan QiskitServerless, kita dapat meneroka ruang permulaan SABRE yang jauh lebih luas, membolehkan perbandingan yang lebih representatif antara heuristik.
Daripada plot serakan dan hasil terbaik yang diperhatikan, adalah jelas bahawa prestasi berbeza dengan ketara mengikut benih rawak yang digunakan oleh SABRE. Kedua-dua heuristik menunjukkan penyebaran yang luas dalam kedalaman dan saiz litar merentasi benih, menunjukkan bahawa satu larian sering tidak mencukupi untuk menangkap hasil hampir optimum. Kebolehubahan ini menyerlahkan kepentingan menjalankan banyak ujian dengan benih yang berbeza apabila bertujuan untuk meminimumkan kedalaman dan/atau bilangan gate. Merentasi keseluruhan set ujian, kedua-dua heuristik lookahead dan decay mampu menghasilkan hasil yang kompetitif. Dalam sesetengah kes, heuristik decay menyamai atau bahkan mengatasi lookahead untuk benih tertentu. Walau bagaimanapun, untuk litar tertentu ini, hasil keseluruhan terbaik diperoleh menggunakan heuristik lookahead, walaupun dengan margin yang sederhana. Ini mencadangkan bahawa walaupun lookahead memberikan hasil yang terkuat di sini, kelebihannya berbanding decay tidak mutlak.
Secara keseluruhannya, hasil ini mengukuhkan dua perkara utama. Pertama, memanfaatkan banyak benih adalah penting untuk mendapatkan prestasi terbaik yang mungkin daripada SABRE, tanpa mengira heuristik yang digunakan. Kedua, walaupun pilihan heuristik penting, struktur litar memainkan peranan dominan, dan prestasi relatif lookahead dan decay mungkin berbeza untuk litar lain. Oleh itu, eksperimen berskala besar dan berbilang benih adalah kritikal untuk transpilasi litar kuantum yang kukuh dan berkesan.
# This cell is hidden from users, it cleans up the `source_files` directory
from pathlib import Path
Path("source_files/transpile_remote.py").unlink()
Path("source_files").rmdir()
Kesimpulan​
Dalam tutorial ini, kita meneroka cara mengoptimumkan litar besar menggunakan SABRE dalam Qiskit. Kita menunjukkan cara mengkonfigurasi laluan SabreLayout dengan parameter yang berbeza untuk mengimbangi kualiti litar dan masa larian transpilasi. Kita juga menunjukkan cara menyesuaikan heuristik penghalaan dalam SABRE dan menggunakan masa larian QiskitServerless untuk menselarikan ujian susun atur dengan cekap apabila SabreSwap terlibat. Dengan melaraskan parameter dan heuristik ini, anda boleh mengoptimumkan susun atur dan penghalaan litar besar, memastikan ia dilaksanakan dengan cekap pada perkakasan kuantum.
Tinjauan tutorial​
Sila ambil tinjauan ringkas ini untuk memberikan maklum balas tentang tutorial ini. Pandangan anda akan membantu kami menambah baik kandungan dan pengalaman pengguna kami.
Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.