Peringkat Transpiler
Versi pakej
Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan penggunaan versi ini atau yang lebih baharu.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Halaman ini menerangkan peringkat saluran transpilasi prabina dalam Qiskit SDK. Terdapat enam peringkat:
initlayoutroutingtranslationoptimizationscheduling
Fungsi generate_preset_pass_manager mencipta pengurus laluan berperingkat pratetap yang terdiri daripada peringkat-peringkat ini. Laluan khusus yang membentuk setiap peringkat bergantung kepada argumen yang dihantar kepada generate_preset_pass_manager. optimization_level ialah argumen kedudukan yang mesti ditentukan; ia adalah integer yang boleh bernilai 0, 1, 2, atau 3. Nilai yang lebih tinggi menunjukkan pengoptimuman yang lebih berat tetapi lebih mahal (lihat Tetapan lalai dan pilihan konfigurasi transpilasi).
Cara yang disyorkan untuk mentranspilasi Circuit ialah dengan mencipta pengurus laluan berperingkat pratetap dan kemudian menjalankan pengurus laluan tersebut pada Circuit, seperti yang diterangkan dalam Transpilasi dengan pengurus laluan. Walau bagaimanapun, alternatif yang lebih mudah tetapi kurang boleh disesuaikan ialah menggunakan fungsi transpile. Fungsi ini menerima Circuit secara langsung sebagai argumen. Seperti generate_preset_pass_manager, laluan Transpiler khusus yang digunakan bergantung kepada argumen, seperti optimization_level, yang dihantar kepada transpile. Malah, secara dalaman fungsi transpile memanggil generate_preset_pass_manager untuk mencipta pengurus laluan berperingkat pratetap dan menjalankannya pada Circuit.
Peringkat Initβ
Peringkat pertama ini melakukan sangat sedikit secara lalai dan terutamanya berguna jika anda ingin menyertakan pengoptimuman awal anda sendiri. Memandangkan kebanyakan algoritma susun atur dan penghalaan hanya direka bentuk untuk berfungsi dengan Gate satu- dan dua-Qubit, peringkat ini juga digunakan untuk menterjemah sebarang Gate yang beroperasi pada lebih daripada dua Qubit, menjadi Gate yang hanya beroperasi pada satu atau dua Qubit.
Untuk maklumat lanjut tentang melaksanakan pengoptimuman awal anda sendiri untuk peringkat ini, lihat bahagian tentang plugin dan penyesuaian pengurus laluan.
Peringkat Layoutβ
Peringkat seterusnya melibatkan susun atur atau ketersambungan Backend yang akan dihantar Circuit. Secara umum, Circuit kuantum adalah entiti abstrak yang Qubit-nya merupakan representasi "maya" atau "logik" daripada Qubit sebenar yang digunakan dalam pengiraan. Untuk melaksanakan urutan Gate, pemetaan satu-ke-satu daripada Qubit "maya" ke Qubit "fizikal" dalam peranti kuantum sebenar diperlukan. Pemetaan ini disimpan sebagai objek Layout dan merupakan sebahagian daripada kekangan yang ditakrifkan dalam seni bina set arahan (ISA) Backend.

Pilihan pemetaan amat penting untuk meminimumkan bilangan operasi SWAP yang diperlukan untuk memetakan Circuit input kepada topologi peranti dan memastikan Qubit yang paling baik dikalibrasi digunakan. Disebabkan kepentingan peringkat ini, pengurus laluan pratetap mencuba beberapa kaedah berbeza untuk mencari susun atur terbaik. Biasanya ini melibatkan dua langkah: pertama, cuba mencari susun atur "sempurna" (susun atur yang tidak memerlukan sebarang operasi SWAP), dan kemudian, laluan heuristik yang cuba mencari susun atur terbaik untuk digunakan jika susun atur sempurna tidak dapat dijumpai. Terdapat dua Laluan yang biasanya digunakan untuk langkah pertama ini:
TrivialLayout: Memetakan setiap Qubit maya secara naif ke Qubit fizikal bernombor sama pada peranti (cth., [0,1,1,3] -> [0,1,1,3]). Ini adalah kelakuan sejarah yang hanya digunakan dalamoptimzation_level=1untuk cuba mencari susun atur sempurna. Jika gagal,VF2Layoutdicuba seterusnya.VF2Layout: Ini ialahAnalysisPassyang memilih susun atur ideal dengan menganggap peringkat ini sebagai masalah isomorfisme subgraf, diselesaikan oleh algoritma VF2++. Jika lebih daripada satu susun atur dijumpai, heuristik pemarkahan dijalankan untuk memilih pemetaan dengan ralat purata terendah.
Kemudian untuk peringkat heuristik, dua laluan digunakan secara lalai:
DenseLayout: Mencari sub-graf peranti dengan ketersambungan tertinggi dan yang mempunyai bilangan Qubit yang sama dengan Circuit (digunakan untuk tahap pengoptimuman 1 jika terdapat operasi aliran kawalan (seperti IfElseOp) dalam Circuit).SabreLayout: Laluan ini memilih susun atur dengan bermula dari susun atur rawak awal dan berulang kali menjalankan algoritmaSabreSwap. Laluan ini hanya digunakan dalam tahap pengoptimuman 1, 2, dan 3 jika susun atur sempurna tidak dijumpai melalui laluanVF2Layout. Untuk butiran lanjut tentang algoritma ini, rujuk kertas arXiv:1809.02573.
Peringkat Routingβ
Untuk melaksanakan Gate dua-Qubit antara Qubit yang tidak disambungkan secara langsung pada peranti kuantum, satu atau lebih Gate SWAP mesti disisipkan ke dalam Circuit untuk menggerakkan keadaan Qubit sehingga ia bersebelahan pada peta Gate peranti. Setiap Gate SWAP mewakili operasi yang mahal dan berderau untuk dilakukan. Oleh itu, mencari bilangan minimum Gate SWAP yang diperlukan untuk memetakan Circuit kepada peranti tertentu adalah langkah penting dalam proses transpilasi. Untuk kecekapan, peringkat ini biasanya dikira bersama peringkat Layout secara lalai, tetapi keduanya adalah berbeza secara logik. Peringkat Layout memilih Qubit perkakasan yang hendak digunakan, manakala peringkat Routing menyisipkan jumlah Gate SWAP yang sesuai untuk melaksanakan Circuit menggunakan susun atur yang dipilih.
Walau bagaimanapun, mencari pemetaan SWAP yang optimum adalah sukar. Malah, ia adalah masalah NP-sukar, dan oleh itu terlalu mahal untuk dikira untuk semua peranti kuantum dan Circuit input kecuali yang paling kecil. Untuk mengatasi ini, Qiskit menggunakan algoritma heuristik stokastik yang dipanggil SabreSwap untuk mengira pemetaan SWAP yang baik, tetapi tidak semestinya optimum. Penggunaan kaedah stokastik bermakna Circuit yang dijana tidak dijamin sama sepanjang penggunaan berulang. Sesungguhnya, menjalankan Circuit yang sama berulang kali menghasilkan taburan kedalaman Circuit dan bilangan Gate pada output. Atas sebab inilah banyak pengguna memilih untuk menjalankan fungsi penghalaan (atau keseluruhan StagedPassManager) berkali-kali dan memilih Circuit dengan kedalaman terendah daripada taburan output.
Sebagai contoh, mari kita ambil Circuit GHZ 15-Qubit yang dilaksanakan 100 kali, menggunakan initial_layout yang "buruk" (terputus).
# Added by doQumentation β required packages for this notebook
!pip install -q matplotlib qiskit qiskit-ibm-runtime
import matplotlib.pyplot as plt
from qiskit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeAuckland, FakeWashingtonV2
from qiskit.transpiler import generate_preset_pass_manager
backend = FakeAuckland()
ghz = QuantumCircuit(15)
ghz.h(0)
ghz.cx(0, range(1, 15))
depths = []
for seed in range(100):
pass_manager = generate_preset_pass_manager(
optimization_level=1,
backend=backend,
layout_method="trivial", # Fixed layout mapped in circuit order
seed_transpiler=seed, # For reproducible results
)
depths.append(pass_manager.run(ghz).depth())
plt.figure(figsize=(8, 6))
plt.hist(depths, align="left", color="#AC557C")
plt.xlabel("Depth", fontsize=14)
plt.ylabel("Counts", fontsize=14)
Text(0, 0.5, 'Counts')
Taburan luas ini menunjukkan betapa sukarnya bagi pemeta SWAP untuk mengira pemetaan terbaik. Untuk mendapat gambaran, mari kita lihat kedua-dua Circuit yang sedang dilaksanakan serta Qubit yang dipilih pada perkakasan.
ghz.draw("mpl", idle_wires=False)
from qiskit.visualization import plot_circuit_layout
# Plot the hardware graph and indicate which hardware qubits were chosen to run the circuit
transpiled_circ = pass_manager.run(ghz)
plot_circuit_layout(transpiled_circ, backend)
Seperti yang dapat anda lihat, Circuit ini perlu melaksanakan Gate dua-Qubit antara Qubit 0 dan 14, yang sangat jauh pada graf ketersambungan. Menjalankan Circuit ini dengan itu memerlukan penyisipan Gate SWAP untuk melaksanakan semua Gate dua-Qubit menggunakan laluan SabreSwap.
Perhatikan juga bahawa algoritma SabreSwap berbeza daripada kaedah SabreLayout yang lebih besar dalam peringkat sebelumnya. Secara lalai, SabreLayout menjalankan kedua-dua susun atur dan penghalaan, dan mengembalikan Circuit yang ditransformasi. Ini dilakukan untuk beberapa sebab teknikal khusus yang dinyatakan dalam halaman rujukan API laluan tersebut.
Peringkat Translationβ
Apabila menulis Circuit kuantum, anda bebas menggunakan sebarang Gate kuantum (operasi uniter) yang anda suka, bersama koleksi operasi bukan-Gate seperti arahan pengukuran atau set semula Qubit. Walau bagaimanapun, kebanyakan peranti kuantum hanya menyokong segelintir operasi Gate kuantum dan bukan-Gate secara natif. Gate natif ini merupakan sebahagian daripada takrifan ISA sasaran dan peringkat PassManager pratetap ini menterjemah (atau membuka gulungan) Gate yang ditentukan dalam Circuit ke Gate asas natif Backend yang ditentukan. Ini adalah langkah penting, kerana ia membolehkan Circuit dilaksanakan oleh Backend, tetapi biasanya menyebabkan peningkatan dalam kedalaman dan bilangan Gate.
Dua kes khas amat penting untuk ditonjolkan, dan membantu menggambarkan apa yang dilakukan oleh peringkat ini.
- Jika Gate SWAP bukan Gate natif pada Backend sasaran, ini memerlukan tiga Gate CNOT:
print("native gates:" + str(sorted(backend.operation_names)))
qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.decompose().draw("mpl")
native gates:['cx', 'delay', 'for_loop', 'id', 'if_else', 'measure', 'reset', 'rz', 'switch_case', 'sx', 'x']
Sebagai hasil tiga Gate CNOT, SWAP adalah operasi yang mahal untuk dilakukan pada peranti kuantum berderau. Walau bagaimanapun, operasi sedemikian biasanya diperlukan untuk membenamkan Circuit ke dalam ketersambungan Gate terhad banyak peranti. Oleh itu, meminimumkan bilangan Gate SWAP dalam Circuit adalah matlamat utama dalam proses transpilasi.
- Gate Toffoli, atau not-terkawal-terkawal (
ccx), ialah Gate tiga-Qubit. Memandangkan set Gate asas kita hanya termasuk Gate satu- dan dua-Qubit, operasi ini mesti diuraikan. Walau bagaimanapun, ia agak mahal:
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.decompose().draw("mpl")
Untuk setiap Gate Toffoli dalam Circuit kuantum, perkakasan mungkin melaksanakan sehingga enam Gate CNOT dan segelintir Gate satu-Qubit. Contoh ini menunjukkan bahawa sebarang algoritma yang menggunakan berbilang Gate Toffoli akan berakhir sebagai Circuit dengan kedalaman besar dan oleh itu akan terjejas dengan ketara oleh hingar.
Peringkat Optimizationβ
Peringkat ini berpusat pada penguraian Circuit kuantum ke dalam set Gate asas peranti sasaran, dan mesti berjuang menentang peningkatan kedalaman daripada peringkat susun atur dan penghalaan. Syukurlah, terdapat banyak rutin untuk mengoptimumkan Circuit sama ada dengan menggabungkan atau menghapuskan Gate. Dalam sesetengah kes, kaedah-kaedah ini begitu berkesan sehingga Circuit output mempunyai kedalaman yang lebih rendah daripada input, walaupun selepas susun atur dan penghalaan ke topologi perkakasan. Dalam kes lain, tidak banyak yang boleh dilakukan, dan pengiraan mungkin sukar dilakukan pada peranti berderau. Peringkat inilah di mana pelbagai tahap pengoptimuman mula berbeza.
- Untuk
optimization_level=1, peringkat ini menyediakanOptimize1qGatesDecompositiondanCXCancellation, yang menggabungkan rantaian Gate satu-Qubit dan membatalkan sebarang Gate CNOT berturut-turut. - Untuk
optimization_level=2, peringkat ini menggunakan laluanCommutativeCancellationsebagai gantiCXCancellation, yang menghapus Gate berlebihan dengan mengeksploitasi hubungan komutasi. - Untuk
optimization_level=3, peringkat ini menyediakan laluan-laluan berikut:
Selain itu, peringkat ini juga melaksanakan beberapa pemeriksaan akhir untuk memastikan semua arahan dalam Circuit terdiri daripada Gate asas yang tersedia pada Backend sasaran.
Contoh di bawah menggunakan keadaan GHZ menunjukkan kesan tetapan tahap pengoptimuman yang berbeza terhadap kedalaman Circuit dan bilangan Gate.
Output transpilasi berbeza disebabkan pemeta SWAP stokastik. Oleh itu, nombor-nombor di bawah kemungkinan akan berubah setiap kali anda menjalankan kod.
Kod berikut membina keadaan GHZ 15-Qubit dan membandingkan optimization_levels transpilasi dari segi kedalaman Circuit, bilangan Gate, dan bilangan Gate berbilang-Qubit yang terhasil.
ghz = QuantumCircuit(15)
ghz.h(0)
ghz.cx(0, range(1, 15))
depths = []
gate_counts = []
multiqubit_gate_counts = []
levels = [str(x) for x in range(4)]
for level in range(4):
pass_manager = generate_preset_pass_manager(
optimization_level=level,
backend=backend,
seed_transpiler=1234,
)
circ = pass_manager.run(ghz)
depths.append(circ.depth())
gate_counts.append(sum(circ.count_ops().values()))
multiqubit_gate_counts.append(circ.count_ops()["cx"])
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.bar(levels, depths, label="Depth")
ax1.set_xlabel("Optimization Level")
ax1.set_ylabel("Depth")
ax1.set_title("Output Circuit Depth")
ax2.bar(levels, gate_counts, label="Number of Circuit Operations")
ax2.bar(levels, multiqubit_gate_counts, label="Number of CX gates")
ax2.set_xlabel("Optimization Level")
ax2.set_ylabel("Number of gates")
ax2.legend()
ax2.set_title("Number of output circuit gates")
fig.tight_layout()
plt.show()
Penjadualanβ
Peringkat terakhir ini hanya dijalankan jika dipanggil secara eksplisit (sama seperti peringkat Init) dan tidak berjalan secara lalai (walaupun kaedah boleh ditentukan dengan menetapkan argumen scheduling_method apabila memanggil generate_preset_pass_manager). Peringkat penjadualan biasanya digunakan setelah Circuit diterjemahkan ke asas sasaran, dipetakan ke peranti, dan dioptimumkan. Laluan-laluan ini memberi tumpuan kepada mengambil kira semua masa terbiar dalam Circuit. Pada peringkat tinggi, laluan penjadualan boleh dianggap sebagai menyisipkan arahan kelewatan secara eksplisit untuk mengambil kira masa terbiar antara pelaksanaan Gate dan memeriksa berapa lama Circuit akan berjalan pada Backend.
Berikut adalah contoh:
ghz = QuantumCircuit(5)
ghz.h(0)
ghz.cx(0, range(1, 5))
# Use fake backend
backend = FakeWashingtonV2()
# Run with optimization level 3 and 'asap' scheduling pass
pass_manager = generate_preset_pass_manager(
optimization_level=3,
backend=backend,
scheduling_method="asap",
seed_transpiler=1234,
)
circ = pass_manager.run(ghz)
circ.draw(output="mpl", idle_wires=False)
Transpiler menyisipkan arahan Delay untuk mengambil kira masa terbiar pada setiap Qubit. Untuk mendapat gambaran yang lebih baik tentang masa Circuit kita juga boleh melihatnya dengan fungsi timeline.draw():
Penjadualan Circuit melibatkan dua bahagian: analisis dan pemetaan kekangan, diikuti oleh laluan padding. Bahagian pertama memerlukan menjalankan laluan analisis penjadualan (secara lalai ini ialah
ALAPSchedulingAnalysis), yang menganalisis Circuit dan merekod masa mula setiap arahan dalam Circuit ke dalam jadual. Setelah Circuit mempunyai jadual awal, laluan tambahan boleh dijalankan untuk mengambil kira sebarang kekangan masa pada Backend sasaran. Akhirnya, laluan padding seperti PadDelay atau PadDynamicalDecoupling boleh dilaksanakan.
Langkah seterusnyaβ
- Untuk mengetahui cara menggunakan fungsi
generate_preset_passmanager, mulakan dengan topik Tetapan lalai dan pilihan konfigurasi transpilasi. - Teruskan pembelajaran tentang transpilasi dengan topik Transpiler dengan pengurus laluan.
- Cuba panduan Bandingkan tetapan Transpiler.
- Lihat dokumentasi API Transpile.