Skip to main content
IBM Quantum Platform

Porte frazionarie

  • Il codice di questa pagina è stato sviluppato in base ai seguenti requisiti. Si consiglia di utilizzare queste versioni o versioni più recenti.

    qiskit[all]~=2.3.1
    qiskit-ibm-runtime~=0.45.1
    

Questa pagina introduce due nuovi tipi di gate supportati dalla flotta di QPU IBM Quantum®. Queste porte frazionali sono supportate sulle QPU Heron sotto forma di:

  • RZZ(θ)R_{ZZ}(\theta) per 0<θπ/20 \lt \theta \leq \pi/2
  • RX(θ)R_X(\theta) per qualsiasi θ\theta

In questa pagina vengono illustrati i casi d'uso in cui l'implementazione di porte frazionarie può migliorare l'efficienza dei vostri flussi di lavoro, nonché le modalità di utilizzo di queste porte sulle QPU Quantum di IBM.


Come utilizzare i gate frazionari

Internamente, questi gate frazionari funzionano eseguendo direttamente una rotazione RZZ(θ)R_{ZZ}(\theta) e RX(θ)R_X(\theta) per un angolo arbitrario. L'uso del gate RX(θ)R_X(\theta) può ridurre fino a un fattore due la durata e l'errore delle rotazioni di un singolo qubit con angolo arbitrario. L'esecuzione diretta della rotazione del gate dell' RZZ(θ)R_{ZZ}(\theta) e evita la scomposizione in più CZGate oggetti, riducendo in modo simile la durata e l'errore di un circuito. Ciò è particolarmente utile per i circuiti che contengono molte rotazioni a uno e due qubit, come quando si simula la dinamica di un sistema quantistico o quando si utilizza un approccio variazionale con molti parametri.

Sebbene questi tipi di porte facciano parte della libreria di porte standard di cui QuantumCircuit si può disporre, possono essere utilizzati solo su specifiche QPU IBM Quantum, che devono essere caricate con il flag use_fractional_gates impostato su True (come mostrato di seguito). Questo flag garantirà che i gate frazionari vengano inclusi nel backend Target del transpiler.

service = QiskitRuntimeService()
backend = service.backend('ibm_torino', use_fractional_gates=True)

Questo esempio di codice mostra come utilizzare le porte frazionali nel contesto di un flusso di lavoro che simula la dinamica di una catena di Ising utilizzando porte frazionali. La durata del circuito viene quindi confrontata con un backend che non utilizza porte frazionarie.

Nota sui tassi di errore riportati

Il valore di errore riportato nel sito Target di un backend con gate frazionali abilitati è solo una copia della controparte del gate non frazionale (che potrebbe non essere la stessa). Questo perché la segnalazione dei tassi di errore sulle porte frazionali non è ancora supportata.

Tuttavia, poiché il tempo di gate delle porte frazionarie e di quelle non frazionarie è lo stesso, è ragionevole supporre che i loro tassi di errore siano comparabili, soprattutto quando la fonte 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")

Output:

Output of the previous code cell

Specificare due oggetti backend: uno con le porte frazionarie abilitate e l'altro con le porte disabilitate, quindi transpilare 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)

Visualizzate la linea temporale del circuito che utilizza i due tipi di porte.

# 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(),
)

Output:

Output of the previous code cell
# 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(),
)

Output:

Output of the previous code cell

Vincoli angolari

Per il gate “ RZZ(θ)R_{ZZ}(\theta) ” a due qubit, sull’hardware IBM Quantum è possibile eseguire solo gli angoli compresi tra 00 e π/2\pi/2. Se un circuito contiene porte di tipo “ RZZ(θ)R_{ZZ}(\theta) ” con un angolo al di fuori di questo intervallo, la pipeline di transpilazione standard provvederà generalmente a correggere tale anomalia mediante un’adeguata trasformazione del circuito (attraverso il pass FoldRzzAngle ). Tuttavia, per qualsiasi gate di tipo “ RZZ(θ)R_{ZZ}(\theta) ” contenente una o più Parameter“s”, il transpiler presupporrà che a questi parametri vengano assegnati angoli compresi in tale intervallo in fase di esecuzione. Il processo non andrà a buon fine se uno qualsiasi dei valori dei parametri specificati nel file “ PUB ” inviato al servizio di calcolo IBM Quantum non rientra in questo intervallo.


Dove utilizzare i gate frazionari

Storicamente, le porte di base disponibili sulle QPU Quantum di IBM sono state CZ, X, RZ, SX, e **ID**che non possono rappresentare in modo efficiente circuiti con rotazioni a uno o due qubit che non siano multipli di π/2\pi / 2. Ad esempio, una porta RX(θ)R_X(\theta), quando viene trasposta, deve decomporsi in una serie di porte RZRZ e X\sqrt{X}, il che crea un circuito con due porte di durata finita invece di una.

Allo stesso modo, quando le rotazioni a due qubit, come un gate RZZ(θ)R_{ZZ}(\theta), vengono transpilate, la decomposizione richiede due gate e diversi gate a singolo qubit, il che aumenta la profondità del circuito CZ e diverse porte a singolo qubit, il che aumenta la profondità del circuito. Queste scomposizioni sono mostrate nel codice seguente.

qc = QuantumCircuit(1)
param = Parameter("θ")
qc.rx(param, 0)
qc.draw("mpl")

Output:

Output of the previous code cell
# 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)

Output:

Output of the previous code cell
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")

Output:

Output of the previous code cell
# 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)

Output:

Output of the previous code cell

Per i flussi di lavoro che richiedono molte rotazioni a un solo qubit RX(θ)R_X(\theta) o a due qubit (come in un'ansatz variazionale o nella simulazione dell'evoluzione temporale dei sistemi quantistici), questo vincolo fa crescere rapidamente la profondità del circuito. Tuttavia, le porte frazionali eliminano questo requisito, poiché le rotazioni a uno e due qubit vengono eseguite direttamente, e creano un circuito quantistico più efficiente (e quindi a prova di errore).


Quando non utilizzare i gate frazionari

È importante sottolineare che i gate frazionari sono una funzionalità sperimentale e che il comportamento del flag use_fractional_gates potrebbe subire modifiche in futuro. Per qiskit-ibm-runtime ulteriori informazioni, consultare le note di rilascio delle nuove versioni di. Si veda anche la documentazione di riferimento dell'API per QiskitRuntimeService.backend, che descrive use_fractional_gates.

Inoltre, il transpiler Qiskit ha una capacità limitata di utilizzare RZZ(θ)R_{ZZ}(\theta) nei suoi passaggi di ottimizzazione. Ciò richiede una maggiore attenzione nella realizzazione e nell'ottimizzazione dei circuiti che contengono queste istruzioni.

Infine, l'utilizzo di porte frazionali non è supportato per:

Leggete la guida sulle opzioni primitive per saperne di più sulla personalizzazione delle tecniche di attenuazione e soppressione degli errori per un determinato carico di lavoro quantistico.


Quali backend supportano i gate frazionari?

Non tutti i backend supportano i gate frazionari. Corri service.backends(use_fractional_gates=True) per trovare quelli che lo fanno. Con il rilascio di v0.48qiskit-ibm-runtime , è anche possibile eseguire il comando per service.least_busy(fractional_gates=True) individuare il backend meno carico che supporti i gate frazionari. Un backend fittizio supporta i gate frazionari solo se il relativo backend “reale” li supporta.

Si noti che i backend fittizi non supportano i gate frazionari per impostazione predefinita, poiché tali gate sono disabilitati di default. Per abilitare i gate frazionari su un backend fittizio che li supporti, aggiorna la sua configurazione.

Esempio:

service = QiskitRuntimeService()
fake_backend = FakeBoston()
fake_backend.refresh(service=service, use_fractional_gates=True)

Passi successivi

Suggerimenti
Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.