Langkau ke kandungan utama

Kernel quantum dengan fractional gates

Anggaran penggunaan: kurang daripada 30 saat pada pemproses Heron r2 (NOTA: Ini hanyalah anggaran. Masa jalan sebenar anda mungkin berbeza.)

Hasil pembelajaran

  • Apakah fractional gates dan bagaimana ia mengurangkan kedalaman dan tempoh litar pada QPU IBM®

  • Kekangan yang berkaitan dengan penggunaan fractional gates (khususnya, julat sudut RZZ)

  • Cara membina aliran kerja kernel quantum yang menggunakan fractional gates dengan IBM Quantum Compute Service

  • Cara membandingkan metrik pelaksanaan perkakasan (kedalaman, tempoh, kiraan gate bukan-tempatan, fidelity) dengan dan tanpa fractional gates

  • Cara menggunakan hanya fractional RX gates sambil mengekalkan aliran kerja corak Qiskit standard

Prasyarat

Latar belakang

Fractional gates pada IBM QPUs

Fractional gates ialah quantum gates berparameter yang membolehkan pelaksanaan terus putaran sudut sewenang-wenangnya (dalam had tertentu), menghapuskan keperluan untuk menguraikannya kepada beberapa basis gates. Dengan memanfaatkan interaksi asli antara qubit fizikal, kamu boleh melaksanakan beberapa unitari dengan lebih cekap pada perkakasan.

IBM Quantum® Heron QPU menyokong fractional gates berikut:

  • RZZ(θ)R_{ZZ}(\theta) untuk 0<θ<π/20 < \theta < \pi / 2
  • RX(θ)R_X(\theta) untuk sebarang nilai nyata θ\theta

Gate-gate ini boleh mengurangkan dengan ketara kedalaman dan tempoh litar quantum. Ia amat berguna dalam aplikasi yang banyak bergantung pada RZZR_{ZZ} dan RXR_X, seperti simulasi Hamiltonian, Quantum Approximate Optimization Algorithm (QAOA), dan kaedah kernel quantum. Dalam tutorial ini, kita fokus pada kernel quantum sebagai contoh praktikal.

Had

Fractional gates kini merupakan ciri eksperimen dan ada beberapa kekangan:

Fractional gates memerlukan aliran kerja yang berbeza berbanding pendekatan standard. Tutorial ini menerangkan cara bekerja dengan fractional gates melalui aplikasi praktikal.

Lihat yang berikut untuk maklumat lanjut tentang fractional gates.

Pendekatan aliran kerja untuk kekangan sudut RZZ

Aliran kerja untuk menggunakan fractional gates secara amnya mengikut aliran kerja Qiskit patterns. Perbezaan utama ialah semua sudut RZZ mesti memenuhi kekangan 0<θπ/20 < \theta \leq \pi/2. Terdapat dua pendekatan untuk memastikan syarat ini dipenuhi, seperti yang kita bincangkan di bawah. Kita mengesyorkan pendekatan kedua, dan dalam tutorial ini, kita menunjukkannya melalui contoh yang diilhamkan oleh kaedah kernel quantum. Untuk lebih memahami di mana kernel quantum berkemungkinan berguna, kami mengesyorkan membaca Liu, Arunachalam & Temme (2021).

Kamu juga boleh melalui tutorial Quantum kernel training dan pelajaran Quantum kernels dalam kursus Quantum machine learning di IBM Quantum® Learning.

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-basis-constructor qiskit-ibm-runtime

1. Jana nilai parameter yang memenuhi kekangan sudut RZZ

Jika anda yakin bahawa semua sudut RZZ berada dalam julat yang sah, anda boleh mengikuti aliran kerja Qiskit patterns standard. Dalam kes ini, anda hanya perlu menghantar nilai parameter sebagai sebahagian daripada PUB. Aliran kerja berjalan seperti 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 anda cuba menghantar PUB yang mengandungi RZZ gate dengan sudut di luar julat yang sah, anda akan mendapat mesej ralat 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 mengelak ralat ini, gunakan pendekatan kedua yang diterangkan di bawah.

2. Tetapkan nilai parameter kepada litar sebelum transpilasi

Pakej qiskit-ibm-runtime menyediakan pas Transpiler khusus yang dipanggil FoldRzzAngle. Pas ini mengubah litar quantum supaya semua sudut RZZ mematuhi kekangan sudut RZZ. Jika anda memberikan Backend kepada generate_preset_pass_manager atau transpile, Qiskit secara automatik akan menggunakan FoldRzzAngle pada litar quantum. Ini memerlukan anda menetapkan nilai parameter kepada litar quantum sebelum transpilasi. Aliran kerja berjalan seperti 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)])

Perhatikan bahawa aliran kerja ini menanggung kos pengiraan yang lebih tinggi daripada pendekatan pertama, kerana ia melibatkan penetapan nilai parameter kepada litar quantum dan menyimpan litar terikat-parameter secara setempat.

awas

Ambil perhatian tentang isu yang diketahui dalam qiskit-ibm-runtime v0.47.0 di mana gate RZZ dengan sudut tidak sah mungkin kekal dalam litar walaupun selepas transpilasi dalam senario tertentu.

Lihat qiskit-ibm-runtime#2441 untuk menjejaki kemajuan isu ini. Kami mengesyorkan penyelesaian sementara berikut sehingga ia diselesaikan.

pm = generate_preset_pass_manager(backend=backend, ...)
pm.post_optimization = PassManager(
[
FoldRzzAngle(),
Optimize1qGatesDecomposition(target=backend.target),
RemoveIdentityEquivalent(target=backend.target),
]
)
... = pm.run(...)

Keperluan

Sebelum memulakan tutorial ini, pastikan anda telah memasang yang berikut:

  • Qiskit SDK v2.0 atau lebih baharu, dengan sokongan visualisasi
  • Qiskit Runtime v0.41 atau lebih baharu (pip install qiskit-ibm-runtime)
  • Qiskit Aer v0.17 atau lebih baharu (pip install qiskit-aer)
  • Qiskit Basis Constructor (pip install qiskit_basis_constructor)

Persediaan

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 UGate, n_local, unitary_overlap
from qiskit.transpiler import Target, PassManager
from qiskit.transpiler.passes import (
Optimize1qGatesDecomposition,
RemoveIdentityEquivalent,
)
from qiskit_aer.primitives import SamplerV2 as AerSampler
from qiskit_basis_constructor import DEFAULT_EQUIVALENCE_LIBRARY
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
from qiskit_ibm_runtime.transpiler.passes import FoldRzzAngle

Aktifkan fractional gates dan semak basis gates

Untuk menggunakan fractional gates, anda boleh mendapatkan Backend yang menyokongnya dengan menetapkan pilihan use_fractional_gates=True. Jika Backend menyokong fractional gates, anda akan nampak rzz dan rx tersenarai dalam 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_marrakesh
No fractional gates: ['cz', 'id', 'rz', 'sx', 'x']
With fractional gates: ['cz', 'id', 'rx', 'rz', 'rzz', 'sx', 'x']

Contoh simulator berskala kecil

Dalam bahagian ini, kita melalui empat langkah aliran kerja Qiskit patterns pada simulator, menggunakan litar kernel quantum sebagai contoh praktikal.

Langkah 1: Petakan input klasikal kepada masalah quantum

Circuit kernel quantum

Dalam bahagian ini, kita meneroka Circuit kernel quantum menggunakan RZZ gates untuk memperkenalkan aliran kerja bagi fractional gates.

Kita mulakan dengan membina Circuit quantum untuk mengira entri individu matriks kernel. Ini dilakukan dengan menggabungkan Circuit peta ciri ZZ dengan tindih tindih unitari. Fungsi kernel mengambil vektor dalam ruang yang dipetakan ciri dan mengembalikan hasil darab dalamnya sebagai entri matriks kernel: K(x,y)=Φ(x)Φ(y),K(x, y) = \langle \Phi(x) | \Phi(y) \rangle, di mana Φ(x)|\Phi(x)\rangle mewakili keadaan quantum yang dipetakan ciri.

Kita bina secara manual Circuit peta ciri ZZ menggunakan RZZ gates. Walaupun Qiskit menyediakan zz_feature_map terbina dalam, ia tidak menyokong RZZ gates setakat Qiskit v2.4.1 (lihat isu).

Seterusnya, kita kira fungsi kernel untuk input yang sama — contohnya, K(x,x)=1K(x, x) = 1. Pada komputer quantum beringar, nilai ini mungkin kurang daripada 1 disebabkan hingar. Hasil yang lebih hampir kepada 1 menunjukkan hingar yang lebih rendah dalam pelaksanaan. Dalam tutorial ini, kita merujuk nilai ini sebagai fideliti, yang ditakrifkan sebagai fidelity=K(x,x).\text{fidelity} = K(x, x).

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 kernel quantum dan nilai parameter yang sepadan dijana untuk sistem dengan 4 hingga 40 qubit, dan fideliti-fideliti mereka dinilai selepas itu.

qubits = list(range(4, 12, 2))
circuits = [quantum_kernel(i, reps=reps) for i in qubits]
params = [random_parameters(circ) for circ in circuits]

Circuit empat-qubit divisualisasikan di bawah.

circuits[0].draw("mpl", fold=-1)

Output of the previous code cell

Dalam aliran kerja Qiskit patterns standard, nilai parameter biasanya dihantar kepada primitif Sampler atau Estimator sebagai sebahagian daripada PUB. Walau bagaimanapun, apabila menggunakan Backend yang menyokong fractional gates, nilai parameter ini mesti ditetapkan secara eksplisit kepada Circuit quantum sebelum transpilasi.

b_qc = [
circ.assign_parameters(param) for circ, param in zip(circuits, params)
]
b_qc[0].draw("mpl", fold=-1)

Output of the previous code cell

Langkah 2: Optimumkan masalah untuk pelaksanaan perkakasan quantum

Kemudian kita transpilasi Circuit menggunakan pass manager mengikut corak Qiskit standard. Dengan memberikan Backend yang menyokong fractional gates kepada generate_preset_pass_manager, pas khusus yang dipanggil FoldRzzAngle akan dimasukkan secara automatik. Pas ini mengubah Circuit untuk mematuhi kekangan sudut RZZ. Hasilnya, RZZ gates dengan nilai negatif dalam rajah sebelumnya diubah menjadi nilai positif, dan beberapa gate X tambahan ditambah.

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
)
pm_f.post_optimization = PassManager(
[
FoldRzzAngle(),
Optimize1qGatesDecomposition(target=backend_f.target),
RemoveIdentityEquivalent(target=backend_f.target),
]
)
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})

Output of the previous code cell

Untuk menilai impak fractional gates, kita nilai bilangan gate bukan tempatan (CZ dan RZZ untuk Backend ini), bersama kedalaman Circuit dan tempoh, serta bandingkan metrik ini dengan aliran kerja standard kemudian.

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: Laksanakan menggunakan primitif Qiskit

Kita jalankan Circuit yang telah ditranspilasi dengan Backend yang menyokong fractional gates.

sampler_f = AerSampler.from_backend(backend_f)
job = sampler_f.run(t_qc_f, shots=shots)
print(job.job_id())
085ce928-767e-4200-93bf-3905e5411cfe

Langkah 4: Proses pasca dan kembalikan hasil dalam format klasikal yang dikehendaki

Anda boleh mendapatkan nilai fungsi kernel K(x,x)K(x, x) dengan mengukur kebarangkalian bitstring semua-sifar 00...00 dalam output.

result = job.result()
fidelity_f = [fidelity(result=res) for res in result]
print(fidelity_f)
[0.929, 0.882, 0.8645, 0.817]

Perbandingan aliran kerja dan Circuit tanpa fractional gates

Dalam bahagian ini, kami membentangkan aliran kerja Qiskit patterns standard menggunakan Backend yang tidak menyokong fractional gates. Dengan membandingkan Circuit yang ditranspilasi, anda akan perasan bahawa versi menggunakan fractional gates (dari bahagian sebelumnya) lebih padat berbanding 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})

Output of the previous code cell

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 = AerSampler.from_backend(backend_c)
job = sampler_c.run(pubs=zip(t_qc_c, params), shots=shots)
print(job.job_id())
f2cca29d-7263-4976-9e51-13a91b75c3ae
# step 4: post-processing
result = job.result()
fidelity_c = [fidelity(res) for res in result]
print(fidelity_c)
[0.8625, 0.7605, 0.702, 0.671]

Perbandingan kedalaman, tempoh, dan fidelity

Dalam bahagian ini, kita bandingkan bilangan gate bukan-tempatan dan kesetiaan antara Circuit yang menggunakan dan tidak menggunakan fractional gates. Ini menunjukkan potensi manfaat penggunaan fractional gates dari segi kecekapan pelaksanaan dan kualiti.

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 0x116af3cb0>

Output of the previous code cell

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 0x11ea4f4d0>

Output of the previous code cell

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 0x1247fc440>

Output of the previous code cell

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 0x120b792b0>

Output of the previous code cell

Contoh perkakasan berskala besar

Dalam bahagian ini, kita menanda aras aliran kerja kernel quantum dengan dan tanpa fractional gates pada perkakasan quantum dengan sehingga 40 qubit.

Langkah 1-4 digabungkan

Aliran kerja mengikut struktur yang sama seperti contoh berskala kecil. Kita transpilasikan semua litar dengan dan tanpa fractional gates, kumpulkan metrik, dan kemudian hantarkan litar ke perkakasan quantum sebenar.

# -------------------------Step 1-------------------------
qubits = list(range(4, 44, 4))
circuits = [quantum_kernel(i, reps=reps) for i in qubits]
params = [random_parameters(circ) for circ in circuits]
b_qc = [
circ.assign_parameters(param) for circ, param in zip(circuits, params)
]

def benchmark(b_qc, backend):
# -------------------------Step 2-------------------------
pm = generate_preset_pass_manager(optimization_level, backend=backend)
if "rzz" in backend.target.operation_names:
# workaround until https://github.com/Qiskit/qiskit-ibm-runtime/issues/2441 is resolved
pm.post_optimization = PassManager(
[
FoldRzzAngle(),
Optimize1qGatesDecomposition(target=backend.target),
RemoveIdentityEquivalent(target=backend.target),
]
)
t_qc = pm.run(b_qc)
nnl = [qc.num_nonlocal_gates() for qc in t_qc]
depth = [qc.depth() for qc in t_qc]
duration = [
qc.estimate_duration(backend_f.target, unit="u") for qc in t_qc
]

# -------------------------Step 3-------------------------
sampler = SamplerV2(mode=backend)
sampler.options.dynamical_decoupling.enable = True
sampler.options.dynamical_decoupling.sequence_type = "XY4"
sampler.options.dynamical_decoupling.skip_reset_qubits = True
sampler.options.environment.job_tags = ["TUT_FG"]
job = sampler.run(t_qc, shots=shots)
job_id = job.job_id()
return nnl, depth, duration, job_id

def postprocessing(job_id: str):
# -------------------------Step 4-------------------------
job = service.job(job_id)
result = job.result()
fidelities = [fidelity(result=res) for res in result]
usage = job.usage()
return fidelities, usage

backend_f = service.backend(backend_name, use_fractional_gates=True)
nnl_f, depth_f, duration_f, job_id_f = benchmark(
b_qc, backend_f
) # step 2 & 3
print("job id (w/ fractional gates):", job_id_f)
fidelity_f, usage_f = postprocessing(job_id_f) # step 4
job id (w/ fractional gates): d8uasitbh0os73eqnpig
backend_c = service.backend(backend_name, use_fractional_gates=False)
nnl_c, depth_c, duration_c, job_id_c = benchmark(b_qc, backend_c)
print("job id (w/o fractional gates):", job_id_c)
fidelity_c, usage_c = postprocessing(job_id_c)
job id (w/o fractional gates): d8uav3lposuc738pruug

Kemudian kita membandingkan metrik.

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 0x12461e660>

Output of the previous code cell

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 0x11f2ac980>

Output of the previous code cell

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 0x125c91be0>

Output of the previous code cell

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 0x11fcf6e40>

Output of the previous code cell

Kita bandingkan masa penggunaan QPU dengan dan tanpa fractional gates. Keputusan dalam sel berikut menunjukkan bahawa masa penggunaan QPU adalah hampir sama.

print(f"no fractional gates: {usage_c} seconds")
print(f"fractional gates: {usage_f} seconds")
no fractional gates: 8 seconds
fractional gates: 8 seconds

Topik lanjutan: Menggunakan hanya fractional RX gates

Keperluan untuk alur kerja yang diubah suai apabila menggunakan fractional gates terutamanya berpunca daripada sekatan pada sudut gate RZZ. Walau bagaimanapun, jika anda hanya menggunakan fractional RX gates dan tidak menggunakan fractional RZZ gates, anda boleh terus mengikuti alur kerja standard Qiskit patterns. Pendekatan ini masih boleh memberikan manfaat yang bermakna, terutamanya dalam Circuit yang melibatkan banyak gate RX dan gate U, dengan mengurangkan jumlah bilangan gate dan berpotensi meningkatkan prestasi. Dalam bahagian ini, kami tunjukkan cara untuk mengoptimumkan Circuit anda menggunakan hanya fractional RX gates, sambil mengetepikan gate RZZ.

Untuk menyokong ini, kami menyediakan fungsi utiliti yang membolehkan anda melumpuhkan gate asas tertentu dalam objek Target. Di sini, kita gunakannya untuk melumpuhkan gate RZZ.

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 gunakan Circuit yang terdiri daripada 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")

Output of the previous code cell

Kita dahulukan dengan mentranspilasikan Circuit untuk Backend yang tidak menyokong 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})

Output of the previous code cell

Kemudian, kita transpilasikan Circuit yang sama menggunakan fractional RX gates, sambil mengecualikan gate RZZ. Ini menghasilkan sedikit pengurangan dalam jumlah bilangan gate, berkat pelaksanaan gate RX yang lebih cekap.

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})

Output of the previous code cell

Optimumkan gate U dengan fractional RX gates

Dalam bahagian ini, kita menunjukkan cara mengoptimumkan gate U menggunakan fractional RX gates, berdasarkan litar yang sama yang diperkenalkan dalam bahagian sebelumnya. Kita transpilasikan litar menggunakan hanya fractional RX gates, mengecualikan gate RZZ. Dengan memperkenalkan peraturan penguraian tersuai, seperti yang ditunjukkan berikut, kita boleh mengurangkan bilangan gate single-qubit yang diperlukan untuk melaksanakan gate U.

Ciri ini sedang dalam perbincangan dalam isu GitHub 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)

Seterusnya, kita terapkan Transpiler menggunakan terjemahan constructor-beta yang disediakan oleh pakej qiskit-basis-constructor. Hasilnya, jumlah bilangan gate berkurangan berbanding 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})

Output of the previous code cell

Langkah seterusnya

Recommendations

Jika anda mendapati kerja ini menarik, anda mungkin berminat dengan bahan berikut: