Quantum kernels na may fractional gates
Tantiya ng paggamit: mas mababa sa 30 segundo sa isang Heron r2 processor (PAALALA: Ito ay tantiya lamang. Maaaring mag-iba ang runtime mo.)
Mga resulta ng pagkatuto
-
Ano ang fractional gates at kung paano nila binabawasan ang circuit depth at duration sa mga IBM® QPU
-
Ang mga hadlang na kaugnay sa paggamit ng fractional gates (partikular, ang RZZ angle range)
-
Kung paano bumuo ng quantum kernel workflow na gumagamit ng fractional gates gamit ang IBM Quantum Compute Service
-
Kung paano ihambing ang mga hardware-execution metrics (depth, duration, non-local gate count, fidelity) na may at walang fractional gates
-
Kung paano gumamit lamang ng fractional RX gates habang pinapanatili ang standard Qiskit patterns workflow
Prerequisites
-
Ang Qiskit patterns workflow
-
Ang Fractional gates guide
-
Ang Pagsasanay sa Quantum kernel tutorial at ang Mga Quantum kernel lesson ng Quantum machine learning course
Background
Fractional gates sa IBM QPUs
Ang fractional gates ay mga parameterized quantum gates na nagbibigay-daan sa direktang pagpapatupad ng arbitrary-angle rotations (sa loob ng mga tiyak na hangganan), na inaalis ang pangangailangang hatiin ang mga ito sa maraming basis gates. Sa pamamagitan ng paggamit ng native interactions sa pagitan ng mga physical qubit, maaari mong mas epektibong magpatupad ang ilang unitaries sa hardware.
Sinusuportahan ng IBM Quantum® Heron QPUs ang mga sumusunod na fractional gates:
- para sa
- para sa anumang real value
Ang mga gates na ito ay maaaring makabuluhang magpababa ng depth at duration ng mga quantum circuit. Partikular silang kapaki-pakinabang sa mga aplikasyon na lubhang umaasa sa at , tulad ng Hamiltonian simulation, ang Quantum Approximate Optimization Algorithm (QAOA), at mga quantum kernel methods. Sa tutorial na ito, nakatuon tayo sa quantum kernel bilang praktikal na halimbawa.
Mga Limitasyon
Ang fractional gates ay kasalukuyang isang experimental feature at may ilang mga hadlang:
- Ang ay limitado sa mga angle sa saklaw na .
- Ang paggamit ng fractional gates ay hindi suportado para sa dynamic circuits, Pauli twirling, probabilistic error cancellation (PEC), at zero-noise extrapolation (ZNE) (gamit ang probabilistic error amplification (PEA)).
Ang fractional gates ay nangangailangan ng naiibang workflow kumpara sa standard approach. Ipinaliwanag ng tutorial na ito kung paano gumana sa fractional gates sa pamamagitan ng praktikal na aplikasyon.
Tingnan ang mga sumusunod para sa mas detalyadong impormasyon tungkol sa fractional gates.
Mga paraan ng workflow para sa RZZ angle constraint
Ang workflow para sa paggamit ng fractional gates ay karaniwang sumusunod sa Qiskit patterns workflow. Ang pangunahing pagkakaiba ay ang lahat ng RZZ angles ay dapat matugunan ang hadlang na . May dalawang paraan upang matiyak na natutugunan ang kundisyong ito, gaya ng tatalakayin natin sa ibaba. Inirerekomenda namin ang pangalawang paraan, at sa tutorial na ito, ipinapakita namin ito sa pamamagitan ng isang halimbawang inspirasyon mula sa quantum kernel method. Upang mas maunawaan kung saan malamang na magiging kapaki-pakinabang ang quantum kernels, inirerekomenda naming basahin ang Liu, Arunachalam & Temme (2021).
Maaari rin ninyong gawin ang Quantum kernel training tutorial at ang Quantum kernels lesson sa Quantum machine learning course sa IBM Quantum® Learning.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "qiskit": "qiskit", "qiskit_aer": "qiskit-aer", "qiskit_basis_constructor": "qiskit-basis-constructor", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
1. Bumuo ng parameter values na nakakatugon sa RZZ angle constraint
Kung nakakatiyak kayo na ang lahat ng RZZ angles ay nasa loob ng wastong saklaw, maaari kayong sumunod sa standard Qiskit patterns workflow. Sa kasong ito, isusumite lang ninyo ang parameter values bilang bahagi ng isang PUB. Magpapatuloy ang workflow sa mga sumusunod.
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)])
Kung susubukan ninyong magsumite ng PUB na may kasamang RZZ gate na may angle sa labas ng wastong saklaw, makakasalubong kayo ng error message tulad ng:
'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].'
Upang maiwasan ang error na ito, gamitin ang pangalawang paraan na inilarawan sa ibaba.
2. Mag-assign ng parameter values sa circuits bago ang transpilation
Ang qiskit-ibm-runtime package ay nagbibigay ng specialized transpiler pass na tinatawag na FoldRzzAngle.
Binabago ng pass na ito ang mga quantum circuit upang ang lahat ng RZZ angles ay sumunod sa RZZ angle constraint.
Kung ibibigay ninyo ang backend sa generate_preset_pass_manager o transpile, awtomatikong inilalapat ng Qiskit ang FoldRzzAngle sa mga quantum circuit.
Ang approach na ito ay hinihiling sa inyo na mag-assign ng parameter values sa mga quantum circuit bago ang transpilation.
Magpapatuloy ang workflow sa mga sumusunod.
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)])
Tandaan na ang workflow na ito ay nagdudulot ng mas mataas na computational cost kaysa sa unang paraan, dahil kinasasangkutan nito ang pag-assign ng parameter values sa mga quantum circuit at pag-imbak ng parameter-bound circuits nang lokal.
Pansinin ang isang kilalang isyu sa qiskit-ibm-runtime v0.47.0 kung saan ang mga RZZ gate na may invalid angles ay maaaring manatili sa mga circuit kahit pagkatapos ng transpilation sa ilang partikular na sitwasyon.
Tingnan ang qiskit-ibm-runtime#2441 upang masubaybayan ang progreso sa isyung ito. Inirerekomenda namin ang sumusunod na workaround hanggang sa ito ay malutas.
pm = generate_preset_pass_manager(backend=backend, ...)
pm.post_optimization = PassManager(
[
FoldRzzAngle(),
Optimize1qGatesDecomposition(target=backend.target),
RemoveIdentityEquivalent(target=backend.target),
]
)
... = pm.run(...)
Mga Kinakailangan
Bago magsimula ng tutorial na ito, siguraduhing mayroon kayong mga sumusunod na naka-install:
- Qiskit SDK v2.0 o mas bago, na may visualization support
- Qiskit Runtime v0.41 o mas bago (
pip install qiskit-ibm-runtime) - Qiskit Aer v0.17 o mas bago (
pip install qiskit-aer) - 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 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
I-enable ang fractional gates at suriin ang basis gates
Upang gumamit ng fractional gates, makakakuha kayo ng backend na sumusuporta sa mga ito sa pamamagitan ng pagtatakda ng use_fractional_gates=True option.
Kung sinusuportahan ng backend ang fractional gates, makikita ninyo ang rzz at rx na nakalista sa kanyang basis gates.
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']
Halimbawa ng small-scale na simulator
Sa seksyong ito, dadaanan natin ang apat na hakbang ng Qiskit patterns workflow sa isang simulator, gamit ang quantum kernel circuit bilang isang praktikal na halimbawa.
Step 1: I-map ang classical inputs sa isang quantum problem
Circuit ng quantum kernel
Sa seksyong ito, tuklasin natin ang quantum kernel circuit gamit ang RZZ gates upang ipakilala ang workflow para sa fractional gates.
Magsisimula tayo sa pamamagitan ng pagbuo ng quantum circuit upang kalkulahin ang mga indibidwal na entry ng kernel matrix. Ginagawa ito sa pamamagitan ng pagsasama ng ZZ feature map circuits sa isang unitary overlap. Ang kernel function ay kumukuha ng mga vector sa feature-mapped space at ibinabalik ang kanilang inner product bilang entry ng kernel matrix: kung saan ang ay kumakatawan sa feature-mapped quantum state.
Manu-manong bubuo tayo ng ZZ feature map circuit gamit ang RZZ gates.
Bagamat nagbibigay ang Qiskit ng built-in zz_feature_map, hindi pa nito sinusuportahan ang RZZ gates simula Qiskit v2.4.1 (tingnan ang issue).
Susunod, kakalkulahin natin ang kernel function para sa magkaparehong inputs - halimbawa, . Sa mga maingay na quantum computer, ang halagang ito ay maaaring mas mababa sa 1 dahil sa ingay. Ang resulta na mas malapit sa 1 ay nagsasaad ng mas mababang ingay sa execution. Sa tutorial na ito, tinutukoy natin ang halagang ito bilang fidelity, na tinukoy bilang
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
Ang mga quantum kernel circuits at ang kanilang kaukulang parameter values ay nabubuo para sa mga system na may 4 hanggang 40 qubits, at ang kanilang fidelities ay susunod na susuriin.
qubits = list(range(4, 12, 2))
circuits = [quantum_kernel(i, reps=reps) for i in qubits]
params = [random_parameters(circ) for circ in circuits]
Ang four-qubit circuit ay ipinapakita sa ibaba.
circuits[0].draw("mpl", fold=-1)
Sa standard Qiskit patterns workflow, ang parameter values ay karaniwang ipinapasa sa Sampler o Estimator primitive bilang bahagi ng PUB. Gayunpaman, kapag gumagamit ng backend na sumusuporta sa fractional gates, ang parameter values na ito ay dapat tahasang i-assign sa quantum circuit bago ang transpilation.
b_qc = [
circ.assign_parameters(param) for circ, param in zip(circuits, params)
]
b_qc[0].draw("mpl", fold=-1)
Step 2: I-optimize ang problem para sa quantum hardware execution
Pagkatapos, iti-transpile natin ang circuit gamit ang pass manager na sumusunod sa standard Qiskit pattern.
Sa pamamagitan ng pagbibigay ng backend na sumusuporta sa fractional gates sa generate_preset_pass_manager, awtomatikong kasama ang specialized pass na tinatawag na FoldRzzAngle.
Binabago ng pass na ito ang circuit upang sumunod sa RZZ angle constraints.
Bilang resulta, ang mga RZZ gate na may negatibong values sa nakaraang figure ay binabago sa positibong values, at ang ilang karagdagang X gates ay idinaragdag.
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})
Upang tasahin ang epekto ng fractional gates, susurihin natin ang bilang ng non-local gates (CZ at RZZ para sa backend na ito), kasama ang circuit depths at durations, at ikukumpara ang mga metrics na ito sa mga galing sa standard workflow mamaya.
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
]
Step 3: Isagawa gamit ang Qiskit primitives
Patakbuhin natin ang transpiled circuit sa backend na sumusuporta sa 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
Step 4: Iproseso at ibalik ang resulta sa nais na classical format
Makukuha ninyo ang kernel function value sa pamamagitan ng pagsukat ng probability ng all-zero bitstring 00...00 sa output.
result = job.result()
fidelity_f = [fidelity(result=res) for res in result]
print(fidelity_f)
[0.929, 0.882, 0.8645, 0.817]
Paghahambing ng workflow at circuit na walang fractional gates
Sa seksyong ito, ipinapakita natin ang standard Qiskit patterns workflow gamit ang backend na hindi sumusuporta sa fractional gates. Sa pamamagitan ng paghahambing ng mga transpiled circuit, mapapansin ninyo na ang bersyon na gumagamit ng fractional gates (mula sa nakaraang seksyon) ay mas compact kaysa sa isa na walang 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 = 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]
Paghahambing ng depths, durations, at fidelities
Sa seksyong ito, ihahambingin natin ang bilang ng non-local gates at ang fidelities sa pagitan ng mga circuit na may at walang fractional gates. Ito ay nagha-highlight ng mga potensyal na benepisyo ng paggamit ng fractional gates sa mga tuntunin ng execution efficiency at kalidad.
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>
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>
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>
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>
Halimbawa ng large-scale na hardware
Sa seksyong ito, bina-benchmark natin ang quantum kernel workflow na may at walang fractional gates sa quantum hardware na may hanggang 40 qubits.
Pinagsamang Hakbang 1-4
Ang workflow ay sumusunod sa parehong istruktura ng small-scale example. Iti-transpile natin ang lahat ng circuit na may at walang fractional gates, kokolektahin ang mga metrics, at pagkatapos ay isusumite ang mga circuit sa tunay na quantum hardware.
# -------------------------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
Pagkatapos ay ihahambing natin ang mga metrics.
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>
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>
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>
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>
Ihahambingin natin ang QPU usage time na may at walang fractional gates. Ang mga resulta sa sumusunod na cell ay nagpapakita na ang QPU usage times ay halos magkapareho.
print(f"no fractional gates: {usage_c} seconds")
print(f"fractional gates: {usage_f} seconds")
no fractional gates: 8 seconds
fractional gates: 8 seconds
Advanced topic: Paggamit lamang ng fractional RX gates
Ang pangangailangan para sa binagong workflow kapag gumagamit ng fractional gates ay pangunahing nagmumula sa paghihigpit sa RZZ gate angles. Gayunpaman, kung gagamitin mo lang ang fractional RX gates at hindi isasama ang fractional RZZ gates, maaari mo pa ring sundin ang standard Qiskit patterns workflow. Ang diskarteng ito ay maaari pa ring mag-alok ng makabuluhang mga benepisyo, lalo na sa mga circuit na sumasaklaw ng malaking bilang ng RX gates at U gates, sa pamamagitan ng pagbawas sa kabuuang gate count at potensyal na pagpapabuti ng performance. Sa seksyong ito, ipapakita natin kung paano i-optimize ang iyong mga circuit gamit lamang ang fractional RX gates, habang inaalisan ang RZZ gates.
Upang suportahan ito, nagbibigay kami ng utility function na nagbibigay-daan sa iyong i-disable ang isang tiyak na basis gate sa isang Target object. Dito, ginagamit natin ito upang i-disable ang RZZ gates.
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
Gagamitin natin ang circuit na binubuo ng U, CZ, at RZZ gates bilang halimbawa.
qc = n_local(3, "u", "cz", "linear", reps=1)
qc.rzz(1.1, 0, 1)
qc.draw("mpl")
Una, iti-transpile natin ang circuit para sa backend na hindi sumusuporta sa 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})
Pagkatapos, iti-transpile natin ang parehong circuit gamit ang fractional RX gates, habang inaalisan ang RZZ gates. Ito ay nagreresulta sa bahagyang pagbawas sa kabuuang gate count, salamat sa mas epektibong implementasyon ng RX gates.
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})
I-optimize ang U gates gamit ang fractional RX gates
Sa seksyong ito, ipinapakita natin kung paano i-optimize ang mga U gate gamit ang fractional RX gates, batay sa parehong circuit na ipinakilala sa nakaraang seksyon. Iti-transpile natin ang circuit gamit lamang ang fractional RX gates, na hindi kasama ang RZZ gates. Sa pamamagitan ng pagpapakilala ng custom decomposition rule, tulad ng ipinapakita sa sumusunod, mababawasan natin ang bilang ng single-qubit gates na kinakailangan upang magpatupad ng U gate.
Ang feature na ito ay kasalukuyang pinag-uusapan sa GitHub issue na ito.
# 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)
Susunod, ilalapat natin ang transpiler gamit ang constructor-beta translation na ibinigay ng qiskit-basis-constructor package.
Bilang resulta, ang kabuuang bilang ng gates ay nabawasan kumpara sa nakaraang transpilation.
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})
Mga susunod na hakbang
Kung nakakita ka ng kawili-wili ang gawaing ito, maaaring interesado ka sa mga sumusunod na materyal:
- Fractional gates guide
- Kailan hindi dapat gumamit ng fractional gates
FoldRzzAngletranspiler pass API reference- Ang Quantum kernel training tutorial
- Ang Quantum kernels lesson sa Quantum machine learning course





