Panimula sa fractional gates
Tantiya ng paggamit: hindi hihigit sa 30 segundo sa isang Heron r2 processor (PAALALA: Ito ay tantiya lamang. Maaaring mag-iba ang iyong runtime.)
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, maaaring mas epektibong magpatupad ang mga user ng 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.
Pangkalahatang-ideya​
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. Nakatuon at inirerekomenda ng tutorial na ito ang pangalawang paraan.
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-basis-constructor qiskit-ibm-runtime
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, dapat ninyong isaalang-alang 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.
Hinihiling nito 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 nag-uudyok ng mas mataas na computational cost kaysa sa unang paraan, dahil kabilang dito ang pag-assign ng parameter values sa mga quantum circuit at pag-iimbak ng parameter-bound circuits nang lokal. Bukod pa riyan, may kilalang isyu sa Qiskit kung saan maaaring mabigo ang transformation ng RZZ gates sa ilang sitwasyon. Para sa workaround, mangyaring sumangguni sa seksyong Troubleshooting. Ipinapakita ng tutorial na ito kung paano gumamit ng fractional gates sa pamamagitan ng pangalawang paraan sa pamamagitan ng halimbawa na binuo ng quantum kernel method. Upang mas maunawaan kung saan malamang na maging kapaki-pakinabang ang mga quantum kernel, 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.
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.37 o mas bago (
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
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_fez
No fractional gates: ['cz', 'id', 'rz', 'sx', 'x']
With fractional gates: ['cz', 'id', 'rx', 'rz', 'rzz', 'sx', 'x']
Workflow na may fractional gates​
Step 1: I-map ang classical inputs sa quantum problem​
Quantum kernel circuit​
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.0.2 (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, 44, 4))
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
)
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 = 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
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.
# 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]
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 = 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]
Paghahambing ng depths 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 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>
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: 7 seconds
fractional gates: 7 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 lang ninyo ang fractional RX gates at hindi isasama ang fractional RZZ gates, maaari pa rin ninyong 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 inyong 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 inyong i-disable ang isang tiyak na basis gate sa isang Target object. Dito, ginagamit natin ito upang i-disable ang RZZ gates.
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
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, ipapakita natin kung paano i-optimize ang U gates gamit ang fractional RX gates, na binuo sa parehong circuit na ipinakilala sa nakaraang seksyon.
Kakailanganin ninyong i-install ang qiskit-basis-constructor package para sa seksyong ito.
Ito ay beta version ng bagong transpilation plugin para sa Qiskit, na maaaring isama sa Qiskit sa hinaharap.
# %pip install qiskit-basis-constructor
from qiskit.circuit.library import UGate
from qiskit_basis_constructor import DEFAULT_EQUIVALENCE_LIBRARY
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)])
Troubleshooting​
Isyu: Maaaring manatili ang invalid RZZ angles pagkatapos ng transpilation​
Simula Qiskit v2.0.3, may mga kilalang isyu kung saan ang RZZ gates na may invalid angles ay maaaring manatili sa mga circuit kahit pagkatapos ng transpilation. Ang isyu ay karaniwang lumilitaw sa ilalim ng mga sumusunod na kundisyon.
Pagkabigo kapag gumagamit ng target option sa generate_preset_pass_manager o transpiler​
Kapag ginagamit ang target option sa generate_preset_pass_manager o transpiler, ang specialized transpiler pass FoldRzzAngle ay hindi tinatawag.
Upang matiyak ang wastong paghawak ng RZZ angles para sa fractional gates, inirerekomenda namin na palaging gamitin ang backend option sa halip.
Tingnan ang issue na ito para sa higit pang detalye.
Pagkabigo kapag ang circuits ay naglalaman ng ilang gates​
Kung ang inyong circuit ay sumasaklaw ng ilang gates tulad ng XXPlusYYGate, ang Qiskit transpiler ay maaaring bumuo ng RZZ gates na may invalid angles.
Kung nakakatagpo kayo ng isyung ito, tingnan ang GitHub issue na ito para sa workaround.
Tutorial survey​
Mangyaring sagutan ang maikling survey na ito upang magbigay ng feedback sa tutorial na ito. Ang inyong mga insight ay makakatulong sa amin na mapabuti ang aming mga content offerings at user experience.