Pengenalan fractional gates
Estimasi penggunaan: di bawah 30 detik pada prosesor Heron r2 (CATATAN: Ini hanya estimasi. Waktu aktual bisa berbeda.)
Latar Belakang​
Fractional Gates pada IBM QPU​
Fractional gates adalah quantum gates berparameter yang memungkinkan eksekusi langsung rotasi sudut sembarang (dalam batas tertentu), menghilangkan kebutuhan untuk menguraikannya menjadi beberapa basis gates. Dengan memanfaatkan interaksi alami antara qubit fisik, pengguna dapat mengimplementasikan unitary tertentu secara lebih efisien pada perangkat keras.
IBM Quantum® Heron QPU mendukung fractional gates berikut:
- untuk
- untuk nilai real apa pun
Gates ini dapat secara signifikan mengurangi kedalaman maupun durasi quantum circuit. Keunggulannya terutama terasa pada aplikasi yang banyak mengandalkan dan , seperti simulasi Hamiltonian, Quantum Approximate Optimization Algorithm (QAOA), dan metode quantum kernel. Dalam tutorial ini, kita fokus pada quantum kernel sebagai contoh praktis.
Keterbatasan​
Fractional gates saat ini merupakan fitur eksperimental dan memiliki beberapa batasan:
- dibatasi pada sudut dalam rentang .
- Penggunaan fractional gates tidak didukung untuk dynamic circuits, Pauli twirling, probabilistic error cancellation (PEC), dan zero-noise extrapolation (ZNE) (menggunakan probabilistic error amplification (PEA)).
Fractional gates memerlukan alur kerja yang berbeda dibandingkan pendekatan standar. Tutorial ini menjelaskan cara bekerja dengan fractional gates melalui aplikasi praktis.
Lihat referensi berikut untuk detail lebih lanjut tentang fractional gates.
Ikhtisar​
Alur kerja untuk menggunakan fractional gates umumnya mengikuti alur kerja Qiskit patterns. Perbedaan utamanya adalah semua sudut RZZ harus memenuhi batasan . Ada dua pendekatan untuk memastikan kondisi ini terpenuhi. Tutorial ini berfokus pada dan merekomendasikan pendekatan kedua.
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-basis-constructor qiskit-ibm-runtime
1. Buat nilai parameter yang memenuhi batasan sudut RZZ​
Jika kamu yakin semua sudut RZZ berada dalam rentang yang valid, kamu bisa mengikuti alur kerja Qiskit patterns standar. Dalam hal ini, kamu cukup mengirimkan nilai parameter sebagai bagian dari PUB. Alur kerjanya adalah sebagai berikut.
pm = generate_preset_pass_manager(backend=backend, ...)
t_circuit = pm.run(circuit)
t_observable = observable.apply_layout(t_circuit.layout)
sampler.run([(t_circuit, parameter_values)])
estimator.run([(t_circuit, t_observable, parameter_values)])
Jika kamu mencoba mengirimkan PUB yang menyertakan gate RZZ dengan sudut di luar rentang yang valid, kamu akan menemui pesan error seperti:
'The instruction rzz is supported only for angles in the range [0, pi/2], but an angle (20.0) outside of this range has been requested; via parameter value(s) γ[0]=10.0, substituted in parameter expression 2.0*γ[0].'
Untuk menghindari error ini, pertimbangkan pendekatan kedua yang dijelaskan di bawah.
2. Tetapkan nilai parameter ke circuit sebelum transpilasi​
Paket qiskit-ibm-runtime menyediakan transpiler pass khusus bernama FoldRzzAngle.
Pass ini mengubah quantum circuit agar semua sudut RZZ memenuhi batasan sudut RZZ.
Jika kamu menyediakan backend ke generate_preset_pass_manager atau transpile, Qiskit secara otomatis menerapkan FoldRzzAngle ke quantum circuit.
Ini mengharuskan kamu menetapkan nilai parameter ke quantum circuit sebelum transpilasi.
Alur kerjanya adalah sebagai berikut.
pm = generate_preset_pass_manager(backend=backend, ...)
b_circuit = circuit.assign_parameters(parameter_values)
t_circuit = pm.run(b_circuit)
t_observable = observable.apply_layout(t_circuit.layout)
sampler.run([(t_circuit,)])
estimator.run([(t_circuit, t_observable)])
Perlu diperhatikan bahwa alur kerja ini menimbulkan biaya komputasi lebih tinggi dibandingkan pendekatan pertama, karena melibatkan penetapan nilai parameter ke quantum circuit dan penyimpanan circuit yang sudah terikat parameter secara lokal. Selain itu, ada isu yang diketahui dalam Qiskit di mana transformasi gate RZZ bisa gagal dalam skenario tertentu. Untuk solusinya, silakan lihat bagian Pemecahan Masalah. Tutorial ini menunjukkan cara menggunakan fractional gates melalui pendekatan kedua dengan contoh yang terinspirasi dari metode quantum kernel. Untuk lebih memahami di mana quantum kernel kemungkinan berguna, kami merekomendasikan membaca Liu, Arunachalam & Temme (2021).
Kamu juga bisa mempelajari tutorial Quantum kernel training dan pelajaran Quantum kernels dalam kursus Quantum machine learning di IBM Quantum Learning.
Persyaratan​
Sebelum memulai tutorial ini, pastikan kamu sudah menginstal hal-hal berikut:
- Qiskit SDK v2.0 atau lebih baru, dengan dukungan visualisasi
- Qiskit Runtime v0.37 atau lebih baru (
pip install qiskit-ibm-runtime) - Qiskit Basis Constructor (
pip install qiskit_basis_constructor)
Setup​
import matplotlib.pyplot as plt
import numpy as np
from qiskit import QuantumCircuit, generate_preset_pass_manager
from qiskit.circuit import ParameterVector
from qiskit.circuit.library import unitary_overlap
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
Aktifkan fractional gates dan periksa basis gates​
Untuk menggunakan fractional gates, kamu bisa mendapatkan backend yang mendukungnya dengan mengatur opsi use_fractional_gates=True.
Jika backend mendukung fractional gates, kamu akan melihat rzz dan rx tercantum di antara basis gates-nya.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=133
) # backend should be a heron device or later
backend_name = backend.name
backend_c = service.backend(backend_name) # w/o fractional gates
backend_f = service.backend(
backend_name, use_fractional_gates=True
) # w/ fractional gates
print(f"Backend: {backend_name}")
print(f"No fractional gates: {backend_c.basis_gates}")
print(f"With fractional gates: {backend_f.basis_gates}")
if "rzz" not in backend_f.basis_gates:
print(f"Backend {backend_name} does not support fractional gates")
Backend: ibm_fez
No fractional gates: ['cz', 'id', 'rz', 'sx', 'x']
With fractional gates: ['cz', 'id', 'rx', 'rz', 'rzz', 'sx', 'x']
Workflow dengan fractional gates​
Langkah 1: Petakan input klasik ke masalah kuantum​
Circuit quantum kernel​
Di bagian ini, kita mengeksplorasi circuit quantum kernel menggunakan Gate RZZ untuk memperkenalkan workflow fractional gates.
Kita mulai dengan membangun Circuit kuantum untuk menghitung entri-entri individual dari matriks kernel. Ini dilakukan dengan menggabungkan Circuit ZZ feature map dengan unitary overlap. Fungsi kernel mengambil vektor dalam ruang yang dipetakan fitur dan mengembalikan hasil kali dalamnya sebagai entri matriks kernel: di mana merepresentasikan state kuantum yang dipetakan fitur.
Kita membangun Circuit ZZ feature map secara manual menggunakan Gate RZZ.
Meskipun Qiskit menyediakan zz_feature_map bawaan, fitur ini belum mendukung Gate RZZ per Qiskit v2.0.2 (lihat issue).
Selanjutnya, kita menghitung fungsi kernel untuk input yang identik — misalnya, . Pada komputer kuantum yang bising, nilai ini bisa kurang dari 1 akibat noise. Hasil yang lebih mendekati 1 menunjukkan noise yang lebih rendah dalam eksekusi. Dalam tutorial ini, kita menyebut nilai ini sebagai fidelitas, yang didefinisikan sebagai
optimization_level = 2
shots = 2000
reps = 3
rng = np.random.default_rng(seed=123)
def my_zz_feature_map(num_qubits: int, reps: int = 1) -> QuantumCircuit:
x = ParameterVector("x", num_qubits * reps)
qc = QuantumCircuit(num_qubits)
qc.h(range(num_qubits))
for k in range(reps):
K = k * num_qubits
for i in range(num_qubits):
qc.rz(x[i + K], i)
pairs = [(i, i + 1) for i in range(num_qubits - 1)]
for i, j in pairs[0::2] + pairs[1::2]:
qc.rzz((np.pi - x[i + K]) * (np.pi - x[j + K]), i, j)
return qc
def quantum_kernel(num_qubits: int, reps: int = 1) -> QuantumCircuit:
qc = my_zz_feature_map(num_qubits, reps=reps)
inner_product = unitary_overlap(qc, qc, "x", "y", insert_barrier=True)
inner_product.measure_all()
return inner_product
def random_parameters(inner_product: QuantumCircuit) -> np.ndarray:
return np.tile(rng.random(inner_product.num_parameters // 2), 2)
def fidelity(result) -> float:
ba = result.data.meas
return ba.get_int_counts().get(0, 0) / ba.num_shots
Circuit quantum kernel beserta nilai parameter-nya dibuat untuk sistem dengan 4 hingga 40 Qubit, lalu fidelitasnya dievaluasi.
qubits = list(range(4, 44, 4))
circuits = [quantum_kernel(i, reps=reps) for i in qubits]
params = [random_parameters(circ) for circ in circuits]
Circuit empat-Qubit divisualisasikan di bawah ini.
circuits[0].draw("mpl", fold=-1)

Dalam workflow Qiskit patterns standar, nilai parameter biasanya diteruskan ke primitif Sampler atau Estimator sebagai bagian dari PUB. Namun, ketika menggunakan Backend yang mendukung fractional gates, nilai parameter tersebut harus ditetapkan secara eksplisit ke Circuit kuantum sebelum transpilasi.
b_qc = [
circ.assign_parameters(param) for circ, param in zip(circuits, params)
]
b_qc[0].draw("mpl", fold=-1)

Langkah 2: Optimalkan masalah untuk eksekusi perangkat keras kuantum​
Kita kemudian men-transpile Circuit menggunakan pass manager sesuai pola Qiskit standar.
Dengan menyediakan Backend yang mendukung fractional gates ke generate_preset_pass_manager, sebuah pass khusus bernama FoldRzzAngle dimasukkan secara otomatis.
Pass ini memodifikasi Circuit agar memenuhi batasan sudut RZZ.
Hasilnya, Gate RZZ dengan nilai negatif pada gambar sebelumnya diubah menjadi nilai positif, dan beberapa Gate X tambahan ditambahkan.
backend_f = service.backend(name=backend_name, use_fractional_gates=True)
# pm_f includes `FoldRzzAngle` pass
pm_f = generate_preset_pass_manager(
optimization_level=optimization_level, backend=backend_f
)
t_qc_f = pm_f.run(b_qc)
print(t_qc_f[0].count_ops())
t_qc_f[0].draw("mpl", fold=-1)
OrderedDict([('rz', 35), ('rzz', 18), ('x', 13), ('rx', 9), ('measure', 4), ('barrier', 2)])

Untuk menilai dampak fractional gates, kita mengevaluasi jumlah gate non-lokal (CZ dan RZZ untuk Backend ini), beserta kedalaman dan durasi Circuit, dan membandingkan metrik-metrik ini dengan workflow standar nanti.
nnl_f = [qc.num_nonlocal_gates() for qc in t_qc_f]
depth_f = [qc.depth() for qc in t_qc_f]
duration_f = [
qc.estimate_duration(backend_f.target, unit="u") for qc in t_qc_f
]
Langkah 3: Eksekusi menggunakan primitif Qiskit​
Kita menjalankan Circuit yang sudah di-transpile dengan Backend yang mendukung fractional gates.
sampler_f = SamplerV2(mode=backend_f)
sampler_f.options.dynamical_decoupling.enable = True
sampler_f.options.dynamical_decoupling.sequence_type = "XY4"
sampler_f.options.dynamical_decoupling.skip_reset_qubits = True
job = sampler_f.run(t_qc_f, shots=shots)
print(job.job_id())
d4bninsi51bc738j97eg
Langkah 4: Pasca-proses dan kembalikan hasil dalam format klasik yang diinginkan​
Kamu bisa mendapatkan nilai fungsi kernel dengan mengukur probabilitas bitstring semua-nol 00...00 pada output.
# job = service.job("d1obougt0npc73flhiag")
result = job.result()
fidelity_f = [fidelity(result=res) for res in result]
print(fidelity_f)
usage_f = job.usage()
[0.9005, 0.647, 0.3345, 0.355, 0.3315, 0.174, 0.1875, 0.149, 0.1175, 0.085]
Perbandingan workflow dan Circuit tanpa fractional gates​
Di bagian ini, kita menyajikan workflow Qiskit patterns standar menggunakan Backend yang tidak mendukung fractional gates. Dengan membandingkan Circuit yang di-transpile, kamu akan melihat bahwa versi yang menggunakan fractional gates (dari bagian sebelumnya) lebih ringkas dibanding yang tanpa fractional gates.
# step 1: map classical inputs to quantum problem
# `circuits` and `params` from the previous section are reused here
# step 2: optimize circuits
backend_c = service.backend(backend_name) # w/o fractional gates
pm_c = generate_preset_pass_manager(
optimization_level=optimization_level, backend=backend_c
)
t_qc_c = pm_c.run(circuits)
print(t_qc_c[0].count_ops())
t_qc_c[0].draw("mpl", fold=-1)
OrderedDict([('rz', 130), ('sx', 80), ('cz', 36), ('measure', 4), ('barrier', 2)])

nnl_c = [qc.num_nonlocal_gates() for qc in t_qc_c]
depth_c = [qc.depth() for qc in t_qc_c]
duration_c = [
qc.estimate_duration(backend_c.target, unit="u") for qc in t_qc_c
]
# step 3: execute
sampler_c = SamplerV2(backend_c)
sampler_c.options.dynamical_decoupling.enable = True
sampler_c.options.dynamical_decoupling.sequence_type = "XY4"
sampler_c.options.dynamical_decoupling.skip_reset_qubits = True
job = sampler_c.run(pubs=zip(t_qc_c, params), shots=shots)
print(job.job_id())
d4bnirvnmdfs73ae3a2g
# step 4: post-processing
# job = service.job("d1obp8j3rr0s73bg4810")
result = job.result()
fidelity_c = [fidelity(res) for res in result]
print(fidelity_c)
usage_c = job.usage()
[0.6675, 0.5725, 0.098, 0.102, 0.065, 0.0235, 0.006, 0.0015, 0.0015, 0.002]
Perbandingan kedalaman dan fidelitas​
Di bagian ini, kita membandingkan jumlah gate non-lokal dan fidelitas antara Circuit dengan dan tanpa fractional gates. Ini menonjolkan potensi manfaat penggunaan fractional gates dari segi efisiensi eksekusi dan kualitas.
plt.plot(qubits, depth_c, "-o", label="no fractional gates")
plt.plot(qubits, depth_f, "-o", label="with fractional gates")
plt.xlabel("number of qubits")
plt.ylabel("depth")
plt.title("Comparison of depths")
plt.grid()
plt.legend()
<matplotlib.legend.Legend at 0x12bcaac50>
plt.plot(qubits, duration_c, "-o", label="no fractional gates")
plt.plot(qubits, duration_f, "-o", label="with fractional gates")
plt.xlabel("number of qubits")
plt.ylabel("duration (µs)")
plt.title("Comparison of durations")
plt.grid()
plt.legend()
<matplotlib.legend.Legend at 0x12bdef310>
plt.plot(qubits, nnl_c, "-o", label="no fractional gates")
plt.plot(qubits, nnl_f, "-o", label="with fractional gates")
plt.xlabel("number of qubits")
plt.ylabel("number of non-local gates")
plt.title("Comparison of numbers of non-local gates")
plt.grid()
plt.legend()
<matplotlib.legend.Legend at 0x12be8ac90>
plt.plot(qubits, fidelity_c, "-o", label="no fractional gates")
plt.plot(qubits, fidelity_f, "-o", label="with fractional gates")
plt.xlabel("number of qubits")
plt.ylabel("fidelity")
plt.title("Comparison of fidelities")
plt.grid()
plt.legend()
<matplotlib.legend.Legend at 0x12bea8290>
Kita membandingkan waktu penggunaan QPU dengan dan tanpa fractional gates. Hasil pada sel berikut menunjukkan bahwa waktu penggunaan QPU hampir identik.
print(f"no fractional gates: {usage_c} seconds")
print(f"fractional gates: {usage_f} seconds")
no fractional gates: 7 seconds
fractional gates: 7 seconds
Topik lanjutan: Menggunakan hanya fractional RX gates​
Kebutuhan workflow yang dimodifikasi saat menggunakan fractional gates terutama berasal dari pembatasan sudut Gate RZZ. Namun, jika kamu hanya menggunakan fractional RX gates dan mengecualikan fractional RZZ gates, kamu tetap bisa mengikuti workflow Qiskit patterns standar. Pendekatan ini masih bisa memberikan manfaat yang berarti, terutama pada Circuit yang banyak menggunakan Gate RX dan Gate U, dengan mengurangi jumlah gate keseluruhan dan berpotensi meningkatkan performa. Di bagian ini, kita menunjukkan cara mengoptimalkan Circuit menggunakan hanya fractional RX gates, tanpa Gate RZZ.
Untuk mendukung ini, kita menyediakan fungsi utilitas yang memungkinkan kamu menonaktifkan basis gate tertentu dalam objek Target. Di sini, kita menggunakannya untuk menonaktifkan Gate RZZ.
from qiskit.circuit.library import n_local
from qiskit.transpiler import Target
def remove_instruction_from_target(target: Target, gate_name: str) -> Target:
new_target = Target(
description=target.description,
num_qubits=target.num_qubits,
dt=target.dt,
granularity=target.granularity,
min_length=target.min_length,
pulse_alignment=target.pulse_alignment,
acquire_alignment=target.acquire_alignment,
qubit_properties=target.qubit_properties,
concurrent_measurements=target.concurrent_measurements,
)
for name, qarg_map in target.items():
if name == gate_name:
continue
instruction = target.operation_from_name(name)
if qarg_map == {None: None}:
qarg_map = None
new_target.add_instruction(instruction, qarg_map, name=name)
return new_target
Kita menggunakan Circuit yang terdiri dari Gate U, CZ, dan RZZ sebagai contoh.
qc = n_local(3, "u", "cz", "linear", reps=1)
qc.rzz(1.1, 0, 1)
qc.draw("mpl")
Pertama, kita men-transpile Circuit untuk Backend yang tidak mendukung fractional gates.
pm_c = generate_preset_pass_manager(
optimization_level=optimization_level, backend=backend_c
)
t_qc = pm_c.run(qc)
print(t_qc.count_ops())
t_qc.draw("mpl")
OrderedDict([('rz', 23), ('sx', 16), ('cz', 4)])

Kemudian, kita men-transpile Circuit yang sama menggunakan fractional RX gates, dengan mengecualikan Gate RZZ. Ini menghasilkan sedikit pengurangan jumlah gate total, berkat implementasi Gate RX yang lebih efisien.
backend_f = service.backend(backend_name, use_fractional_gates=True)
target = remove_instruction_from_target(backend_f.target, "rzz")
pm_f = generate_preset_pass_manager(
optimization_level=optimization_level,
target=target,
)
t_qc = pm_f.run(qc)
print(t_qc.count_ops())
t_qc.draw("mpl")
OrderedDict([('rz', 22), ('sx', 14), ('cz', 4), ('rx', 1)])

Optimalkan Gate U dengan fractional RX gates​
Di bagian ini, kita menunjukkan cara mengoptimalkan Gate U menggunakan fractional RX gates, berdasarkan Circuit yang sama dari bagian sebelumnya.
Kamu perlu menginstal paket qiskit-basis-constructor untuk bagian ini.
Ini adalah versi beta dari plugin transpilasi baru untuk Qiskit, yang mungkin akan diintegrasikan ke dalam Qiskit di masa depan.
# %pip install qiskit-basis-constructor
from qiskit.circuit.library import UGate
from qiskit_basis_constructor import DEFAULT_EQUIVALENCE_LIBRARY
Kita men-transpile Circuit menggunakan hanya fractional RX gates, dengan mengecualikan Gate RZZ. Dengan memperkenalkan aturan dekomposisi kustom, seperti yang ditunjukkan berikut ini, kita bisa mengurangi jumlah gate single-qubit yang diperlukan untuk mengimplementasikan Gate U.
Fitur ini sedang dalam diskusi di GitHub issue ini.
# special decomposition rule for UGate
x = ParameterVector("x", 3)
zxz = QuantumCircuit(1)
zxz.rz(x[2] - np.pi / 2, 0)
zxz.rx(x[0], 0)
zxz.rz(x[1] + np.pi / 2, 0)
DEFAULT_EQUIVALENCE_LIBRARY.add_equivalence(UGate(x[0], x[1], x[2]), zxz)
Selanjutnya, kita menerapkan Transpiler menggunakan terjemahan constructor-beta yang disediakan oleh paket qiskit-basis-constructor.
Hasilnya, total jumlah gate berkurang dibandingkan transpilasi sebelumnya.
pm_f = generate_preset_pass_manager(
optimization_level=optimization_level,
target=target,
translation_method="constructor-beta",
)
t_qc = pm_f.run(qc)
print(t_qc.count_ops())
t_qc.draw("mpl")
OrderedDict([('rz', 16), ('rx', 9), ('cz', 4)])
Pemecahan masalah​
Masalah: Sudut RZZ yang tidak valid mungkin tersisa setelah transpilasi​
Per Qiskit v2.0.3, terdapat masalah yang diketahui di mana Gate RZZ dengan sudut tidak valid mungkin masih ada dalam Circuit bahkan setelah transpilasi. Masalah ini biasanya muncul dalam kondisi berikut.
Kegagalan saat menggunakan opsi target dengan generate_preset_pass_manager atau transpiler​
Ketika opsi target digunakan dengan generate_preset_pass_manager atau transpiler, pass Transpiler khusus FoldRzzAngle tidak dipanggil.
Untuk memastikan penanganan sudut RZZ yang benar untuk fractional gates, kami menyarankan untuk selalu menggunakan opsi backend.
Lihat issue ini untuk detail lebih lanjut.
Kegagalan ketika Circuit mengandung gate tertentu​
Jika Circuit kamu mencakup gate tertentu seperti XXPlusYYGate, Transpiler Qiskit mungkin menghasilkan Gate RZZ dengan sudut yang tidak valid.
Jika kamu menemui masalah ini, lihat GitHub issue ini untuk solusinya.
Survei tutorial​
Silakan isi survei singkat ini untuk memberikan masukan tentang tutorial ini. Wawasanmu akan membantu kami meningkatkan konten dan pengalaman pengguna.
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.