gate frazionari
Versioni dei pacchetti
Il codice in questa pagina è stato sviluppato utilizzando i seguenti requisiti. Si raccomanda di usare queste versioni o versioni più recenti.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Questa pagina presenta due nuovi tipi di gate supportati nel parco QPU di IBM Quantum®. Questi gate frazionari sono supportati sulle QPU Heron nelle seguenti forme:
- per
- per qualsiasi
Questa pagina tratta i casi d'uso in cui l'impiego dei gate frazionari può migliorare l'efficienza dei tuoi flussi di lavoro, oltre a spiegare come utilizzarli sulle QPU IBM Quantum.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
Come usare i gate frazionari​
Internamente, questi gate frazionari funzionano eseguendo direttamente una rotazione e per un angolo arbitrario. L'uso del gate può ridurre la durata e l'errore per le rotazioni a qubit singolo di angolo arbitrario fino a un fattore due. L'esecuzione diretta della rotazione del gate evita la decomposizione in più oggetti CZGate, riducendo in modo analogo la durata e l'errore del circuito. Questo è particolarmente utile per i circuiti che contengono molte rotazioni a uno e due qubit, come quando si simulano le dinamiche di un sistema quantistico o quando si usa un ansatz variazionale con molti parametri.
Sebbene questi tipi di gate siano presenti nella libreria di gate standard che un QuantumCircuit può possedere, possono essere usati solo su specifiche QPU IBM Quantum, che devono essere caricate con il flag use_fractional_gates impostato a True (come mostrato di seguito). Questo flag garantirà che i gate frazionari siano inclusi nel Target del backend per il transpiler.
service = QiskitRuntimeService()
backend = service.backend('ibm_torino', use_fractional_gates=True)
Questo esempio di codice mostra come usare i gate frazionari nel contesto di un flusso di lavoro che simula le dinamiche di una catena di Ising usando i gate frazionari. La durata del circuito viene poi confrontata con un backend che non usa gate frazionari.
Il valore di errore riportato nel Target di un backend con gate frazionari abilitati è semplicemente una copia dell'analogo gate non frazionario (che potrebbe non essere lo stesso). Questo perché la comunicazione dei tassi di errore sui gate frazionari non è ancora supportata.
Tuttavia, poiché il tempo di gate dei gate frazionari rispetto a quelli non frazionari è lo stesso, è ragionevole assumere che i loro tassi di errore siano comparabili — soprattutto quando la sorgente di errore dominante in un circuito è dovuta al rilassamento.
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization.timeline import draw as draw_timeline, IQXSimple
from qiskit_ibm_runtime import QiskitRuntimeService
num_qubits = 5
num_time_steps = 3
rx_angle = 0.1
rzz_angle = 0.1
ising_circuit = QuantumCircuit(num_qubits)
for i in range(num_time_steps):
# rx layer
for q in range(num_qubits):
ising_circuit.rx(rx_angle, q)
for q in range(1, num_qubits - 1, 2):
ising_circuit.rzz(rzz_angle, q, q + 1)
# 2nd rzz layer
for q in range(0, num_qubits - 1, 2):
ising_circuit.rzz(rzz_angle, q, q + 1)
ising_circuit.barrier()
ising_circuit.draw("mpl")
Specifica due oggetti backend: uno con i gate frazionari abilitati e l'altro con essi disabilitati, poi esegui il transpiling di entrambi.
service = QiskitRuntimeService()
backend_fractional = service.backend("ibm_torino", use_fractional_gates=True)
backend_conventional = service.backend(
"ibm_torino", use_fractional_gates=False
)
pm_fractional = generate_preset_pass_manager(
optimization_level=3, backend=backend_fractional, scheduling_method="alap"
)
pm_conventional = generate_preset_pass_manager(
optimization_level=3,
backend=backend_conventional,
scheduling_method="alap",
)
ising_circuit_fractional = pm_fractional.run(ising_circuit)
ising_circuit_conventional = pm_conventional.run(ising_circuit)
Visualizza la timeline del circuito usando i due tipi di gate.
# Draw timeline of circuit with conventional gates
draw_timeline(
ising_circuit_conventional,
idle_wires=False,
target=backend_conventional.target,
time_range=(0, 500),
style=IQXSimple(),
)
# Draw timeline of circuit with fractional gates
draw_timeline(
ising_circuit_fractional,
idle_wires=False,
target=backend_fractional.target,
time_range=(0, 500),
style=IQXSimple(),
)
Vincoli sugli angoli​
Per il gate a due qubit, sull'hardware IBM Quantum possono essere eseguiti solo angoli compresi tra e . Se un circuito contiene gate con un angolo fuori da questo intervallo, la pipeline di transpilation standard lo correggerà generalmente con un'appropriata trasformazione del circuito (tramite il pass FoldRzzAngle). Tuttavia, per qualsiasi gate che contiene uno o più Parameter, il transpiler assumerà che questi parametri riceveranno angoli compresi in questo intervallo a runtime. Il job fallirà se uno qualsiasi dei valori dei parametri specificati nel PUB inviato a Qiskit Runtime è fuori da questo intervallo.
Dove usare i gate frazionari​
Storicamente, i gate base disponibili sulle QPU IBM Quantum sono stati CZ, X, RZ, SX e ID, che non riescono a rappresentare in modo efficiente circuiti con rotazioni a uno e due qubit che non siano multipli di . Ad esempio, un gate , quando viene compilato, deve decomporsi in una serie di gate e , creando un circuito con due gate di durata finita invece di uno.
Allo stesso modo, quando rotazioni a due qubit come un gate vengono compilate, la decomposizione richiede due gate CZ e diversi gate a qubit singolo, aumentando la profondità del circuito. Queste decomposizioni sono mostrate nel codice seguente.
qc = QuantumCircuit(1)
param = Parameter("θ")
qc.rx(param, 0)
qc.draw("mpl")
# Decomposition of an RX(θ) gate using the IBM Quantum QPU basis
service = QiskitRuntimeService()
backend = service.backend("ibm_torino")
optimization_level = 3
pm = generate_preset_pass_manager(optimization_level, backend=backend)
transpiled_circuit = pm.run(qc)
transpiled_circuit.draw("mpl", idle_wires=False)
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
qc = QuantumCircuit(2)
param = Parameter("θ")
qc.rzz(param, 0, 1)
qc.draw("mpl")
# Decomposition of an RZZ(θ) gate using the IBM Quantum QPU basis
service = QiskitRuntimeService()
backend = service.backend("ibm_torino")
optimization_level = 3
pm = generate_preset_pass_manager(optimization_level, backend=backend)
transpiled_circuit = pm.run(qc)
transpiled_circuit.draw("mpl", idle_wires=False)
Per i flussi di lavoro che richiedono molte rotazioni a qubit singolo o a due qubit (come in un ansatz variazionale o quando si simula l'evoluzione temporale di sistemi quantistici), questo vincolo fa crescere rapidamente la profondità del circuito. I gate frazionari eliminano però questo requisito, perché le rotazioni a uno e due qubit vengono eseguite direttamente, creando un circuito quantistico più efficiente (e quindi con errori soppressi).
Quando non usare i gate frazionari​
È importante notare che i gate frazionari sono una funzionalità sperimentale e il comportamento del flag use_fractional_gates potrebbe cambiare in futuro. Consulta le note di rilascio delle nuove versioni di Qiskit Runtime per ulteriori informazioni. Consulta anche la documentazione di riferimento dell'API per QiskitRuntimeService.backend, che descrive use_fractional_gates.
Inoltre, il transpiler di Qiskit ha una capacità limitata di usare nei propri pass di ottimizzazione. Questo richiede maggiore attenzione nella costruzione e nell'ottimizzazione dei circuiti che contengono queste istruzioni.
Infine, l'uso dei gate frazionari non è supportato per:
- Circuiti dinamici
- Pauli twirling — tuttavia, il measurement twirling con TREX è supportato.
- Probabilistic error cancellation
- Zero-noise extrapolation (usando probabilistic error amplification)
Leggi la guida sulle opzioni delle primitive per saperne di più su come personalizzare le tecniche di mitigazione e soppressione degli errori per un dato carico di lavoro quantistico.
Passi successivi​
- Per saperne di più sulla transpilation, consulta la pagina introduzione alla transpilation.
- Leggi come scrivere un pass transpiler personalizzato.
- Scopri come configurare la mitigazione degli errori per Qiskit Runtime.