Lewati ke konten utama

Bandingkan pengaturan transpiler

Versi paket

Kode pada halaman ini dikembangkan menggunakan persyaratan berikut. Kami merekomendasikan menggunakan versi ini atau yang lebih baru.

qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1

Pengaturan Transpiler yang berbeda memberikan jenis optimasi yang berbeda pada Circuit, sering kali dengan mengorbankan waktu pemrosesan klasik yang lebih lama. Panduan ini menjelaskan proses lengkap membuat, men-transpilasi, dan mengirimkan Circuit untuk mendemonstrasikan pengujian performa berbagai pengaturan.

Perhatikan bahwa pengaturan yang sama bisa meningkatkan hasil satu sirkuit sementara menghambat Circuit lain. Pastikan untuk memeriksa Circuit hasil transpilasi sebelum menjalankannya pada hardware sungguhan.

Siapkan dan buat Circuit contoh

# 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 grover_operator, DiagonalGate

# 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

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.

oracle = DiagonalGate([1] * 7 + [-1])
qc = QuantumCircuit(3)
qc.h([0, 1, 2])
qc = qc.compose(grover_operator(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

Transpilasi

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.

important

Contoh ini menggunakan hardware IBM Quantum®, tetapi kamu bisa mencobanya pada QPU mana pun yang kompatibel dengan Qiskit. Hasilmu mungkin berbeda.

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.

# Use Qiskit Runtime to run jobs on hardware
from qiskit_ibm_runtime import (
QiskitRuntimeService,
SamplerV2 as Sampler,
)
# 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_marrakesh'
# 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): 12

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 dynamical 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.

from qiskit_ibm_runtime.transpiler.passes.scheduling import (
ASAPScheduleAnalysis,
PadDynamicalDecoupling,
)

# 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

Eksekusi Circuit

Pada tahap ini, kamu punya list Circuit yang sudah di-transpilasi dengan pengaturan yang berbeda-beda. Selanjutnya, jalankan Circuit ini menggunakan primitif Sampler dan simpan hasilnya ke result.

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

Lihat hasil

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 dynamical 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.985
0.989
0.988

Langkah selanjutnya

Rekomendasi