Lewati ke konten utama

Bandingkan pengaturan transpiler

Estimasi penggunaan: kurang dari satu menit pada prosesor Eagle r3 (CATATAN: Ini hanya estimasi. Waktu eksekusi aktual bisa berbeda-beda.)

Latar Belakang​

Untuk memastikan hasil yang lebih cepat dan efisien, mulai 1 Maret 2024, Circuit dan observable perlu diubah agar hanya menggunakan instruksi yang didukung oleh QPU (quantum processing unit) sebelum dikirimkan ke primitif Qiskit Runtime. Kita menyebut ini sebagai Circuit dan observable instruction set architecture (ISA). Salah satu cara umum untuk melakukannya adalah menggunakan fungsi generate_preset_pass_manager dari Transpiler. Namun, kamu juga bisa memilih proses yang lebih manual.

Misalnya, kamu mungkin ingin menargetkan subset Qubit tertentu pada perangkat tertentu. Panduan ini menguji performa berbagai pengaturan Transpiler dengan menyelesaikan proses lengkap membuat, men-transpilasi, dan mengirimkan Circuit.

Persyaratan​

Sebelum memulai, pastikan kamu sudah menginstal hal-hal berikut:

  • Qiskit SDK v1.2 atau lebih baru, dengan dukungan visualisasi
  • Qiskit Runtime v0.28 atau lebih baru (pip install qiskit-ibm-runtime)

Setup​

# Added by doQumentation β€” required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
# Create circuit to test transpiler on
from qiskit import QuantumCircuit
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import GroverOperator, Diagonal

# Use Statevector object to calculate the ideal output
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_histogram
from qiskit.transpiler import PassManager

from qiskit.circuit.library import XGate
from qiskit.quantum_info import hellinger_fidelity

# Qiskit Runtime
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Batch,
SamplerV2 as Sampler,
)
from qiskit_ibm_runtime.transpiler.passes.scheduling import (
ASAPScheduleAnalysis,
PadDynamicalDecoupling,
)

Langkah 1: Petakan input klasik ke masalah kuantum​

Buat Circuit kecil untuk dicoba dioptimalkan oleh Transpiler. Contoh ini membuat Circuit yang menjalankan algoritma Grover dengan oracle yang menandai state 111. Selanjutnya, simulasikan distribusi ideal (apa yang kamu harapkan jika kamu menjalankan ini pada komputer kuantum sempurna sebanyak tak terhingga kali) untuk perbandingan nanti.

# To run on hardware, select the backend with the fewest number of jobs in the queue
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
backend.name
'ibm_brisbanse'
oracle = Diagonal([1] * 7 + [-1])
qc = QuantumCircuit(3)
qc.h([0, 1, 2])
qc = qc.compose(GroverOperator(oracle))

qc.draw(output="mpl", style="iqp")

Output of the previous code cell

ideal_distribution = Statevector.from_instruction(qc).probabilities_dict()

plot_histogram(ideal_distribution)

Output of the previous code cell

Langkah 2: Optimalkan masalah untuk eksekusi pada hardware kuantum​

Selanjutnya, transpilasikan Circuit untuk QPU. Kamu akan membandingkan performa Transpiler dengan optimization_level yang diatur ke 0 (terendah) dan 3 (tertinggi). Level optimasi terendah hanya melakukan yang minimum yang diperlukan agar Circuit bisa berjalan di perangkat; ia memetakan Qubit Circuit ke Qubit perangkat dan menambahkan swap Gate untuk memungkinkan semua operasi dua Qubit. Level optimasi tertinggi jauh lebih cerdas dan menggunakan banyak trik untuk mengurangi jumlah Gate secara keseluruhan. Karena multi-Qubit Gate memiliki tingkat error yang tinggi dan Qubit mengalami dekoherensi seiring waktu, Circuit yang lebih pendek seharusnya memberikan hasil yang lebih baik.

Sel berikut men-transpilasikan qc untuk kedua nilai optimization_level, mencetak jumlah Gate dua Qubit, dan menambahkan Circuit yang telah di-transpilasi ke sebuah list. Beberapa algoritma Transpiler bersifat acak, sehingga seed ditetapkan untuk reprodusibilitas.

# Need to add measurements to the circuit
qc.measure_all()

# Find the correct two-qubit gate
twoQ_gates = set(["ecr", "cz", "cx"])
for gate in backend.basis_gates:
if gate in twoQ_gates:
twoQ_gate = gate

circuits = []
for optimization_level in [0, 3]:
pm = generate_preset_pass_manager(
optimization_level, backend=backend, seed_transpiler=0
)
t_qc = pm.run(qc)
print(
f"Two-qubit gates (optimization_level={optimization_level}): ",
t_qc.count_ops()[twoQ_gate],
)
circuits.append(t_qc)
Two-qubit gates (optimization_level=0):  21
Two-qubit gates (optimization_level=3): 14

Karena CNOT biasanya memiliki tingkat error yang tinggi, Circuit yang di-transpilasi dengan optimization_level=3 seharusnya berkinerja jauh lebih baik.

Cara lain untuk meningkatkan performa adalah melalui dynamic decoupling, dengan menerapkan serangkaian Gate pada Qubit yang sedang idle. Ini membatalkan beberapa interaksi yang tidak diinginkan dengan lingkungan. Sel berikut menambahkan dynamic decoupling ke Circuit yang di-transpilasi dengan optimization_level=3 dan menambahkannya ke list.

# Get gate durations so the transpiler knows how long each operation takes
durations = backend.target.durations()

# This is the sequence we'll apply to idling qubits
dd_sequence = [XGate(), XGate()]

# Run scheduling and dynamic decoupling passes on circuit
pm = PassManager(
[
ASAPScheduleAnalysis(durations),
PadDynamicalDecoupling(durations, dd_sequence),
]
)
circ_dd = pm.run(circuits[1])

# Add this new circuit to our list
circuits.append(circ_dd)
circ_dd.draw(output="mpl", style="iqp", idle_wires=False)

Output of the previous code cell

Langkah 3: Eksekusi menggunakan primitif Qiskit​

Pada tahap ini, kamu punya list Circuit yang sudah di-transpilasi untuk QPU yang ditentukan. Selanjutnya, buat instance dari primitif Sampler dan mulai batched job menggunakan context manager (with ...:), yang secara otomatis membuka dan menutup batch.

Di dalam context manager, sample Circuit dan simpan hasilnya ke result.

with Batch(backend=backend):
sampler = Sampler()
job = sampler.run(
[(circuit) for circuit in circuits], # sample all three circuits
shots=8000,
)
result = job.result()

Langkah 4: Pasca-proses dan kembalikan hasil dalam format klasik yang diinginkan​

Terakhir, plot hasil dari device run terhadap distribusi ideal. Kamu bisa melihat bahwa hasil dengan optimization_level=3 lebih dekat ke distribusi ideal karena jumlah Gate yang lebih rendah, dan optimization_level=3 + dd bahkan lebih dekat lagi berkat dynamic decoupling.

binary_prob = [
{
k: v / res.data.meas.num_shots
for k, v in res.data.meas.get_counts().items()
}
for res in result
]
plot_histogram(
binary_prob + [ideal_distribution],
bar_labels=False,
legend=[
"optimization_level=0",
"optimization_level=3",
"optimization_level=3 + dd",
"ideal distribution",
],
)

Output of the previous code cell

Kamu bisa mengonfirmasi ini dengan menghitung Hellinger fidelity antara setiap set hasil dan distribusi ideal (semakin tinggi semakin baik, dan 1 adalah fidelity sempurna).

for prob in binary_prob:
print(f"{hellinger_fidelity(prob, ideal_distribution):.3f}")
0.848
0.945
0.990
Source: IBM Quantum docs β€” updated 1 Apr 2026
English version on doQumentation β€” updated 7 Mei 2026
This translation based on the English version of 11 Mar 2026