Creare un gestore di passaggi per il disaccoppiamento dinamico
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.5.1 qiskit-ibm-runtime~=0.47.0
In questa pagina viene illustrato come utilizzare il PadDynamicalDecoupling per aggiungere al circuito una tecnica di soppressione degli errori chiamata disaccoppiamento dinamico.
Il disaccoppiamento dinamico funziona aggiungendo sequenze di impulsi (note come sequenze di disaccoppiamento dinamico ) ai qubit inattivi per farli girare intorno alla sfera di Bloch, annullando l'effetto dei canali di rumore e sopprimendo così la decoerenza. Queste sequenze di impulsi sono simili agli impulsi di rifocalizzazione utilizzati nella risonanza magnetica nucleare. Per una descrizione completa, si veda A Quantum Engineer's Guide to Superconducting Qubits.
Poiché il passaggio PadDynamicalDecoupling opera solo su circuiti programmati e coinvolge porte che non sono necessariamente porte di base del nostro obiettivo, sono necessari i parametri ALAPScheduleAnalysis e BasisTranslator anche i passaggi.
Recupera le target informazioni dal backend e salva i nomi delle operazioni come, basis_gates poiché il target dovrà essere modificato per aggiungere le informazioni temporali relative ai gate utilizzati nel disaccoppiamento dinamico.
In questi esempi viene utilizzato il backend FakeSherbrooke``qiskit_ibm_runtime fittizio di, ma è possibile provarlo su qualsiasi backend reale o fittizio compatibile con Qiskit. I tuoi risultati potrebbero essere diversi.
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.target
basis_gates = list(target.operation_names)Creare un circuito efficient_su2 come esempio. Per prima cosa, si traspila il circuito nel backend, perché gli impulsi di disaccoppiamento dinamico devono essere aggiunti dopo che il circuito è stato transpilato e programmato. Il disaccoppiamento dinamico funziona spesso al meglio quando i circuiti quantistici hanno molto tempo di inattività, cioè ci sono qubit che non vengono utilizzati mentre altri sono attivi. Questo è il caso di questo circuito, perché le porte a due qubit ecr sono applicate in sequenza in questo ansatz.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)
qc_t = pm.run(qc)
qc_t.draw("mpl", fold=-1, idle_wires=False)Output:
Una sequenza di disaccoppiamento dinamico è una serie di porte che si compongono all'identità e sono distanziate regolarmente nel tempo. Ad esempio, iniziamo a creare una semplice sequenza chiamata XY4 composta da quattro porte.
from qiskit.circuit.library import XGate, YGate
X = XGate()
Y = YGate()
dd_sequence = [X, Y, X, Y]A causa della regolarità delle sequenze di disaccoppiamento dinamico, le informazioni relative al YGate devono essere aggiunte al target poiché non si tratta di un gate di base, mentre il XGate lo è. Sappiamo a priori che ha YGate la stessa durata ed errore di XGate, quindi possiamo semplicemente recuperare tali proprietà da target e aggiungerle nuovamente agli YGate oggetti. Questo è anche il motivo per cui i basis_gates sono stati salvati separatamente, poiché stiamo aggiungendo YGate l'istruzione al target anche se non è un vero e proprio gate di base di ibm_fez.
from qiskit.transpiler import InstructionProperties
y_gate_properties = {}
for qubit in range(target.num_qubits):
y_gate_properties.update(
{
(qubit,): InstructionProperties(
duration=target["x"][(qubit,)].duration,
error=target["x"][(qubit,)].error,
)
}
)
target.add_instruction(YGate(), y_gate_properties)I circuiti Ansatz come efficient_su2 sono parametrizzati, quindi devono avere un valore vincolato prima di essere inviati al backend. Qui si assegnano parametri casuali.
import numpy as np
rng = np.random.default_rng(1234)
qc_t.assign_parameters(
rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True
)Quindi, eseguire i passaggi personalizzati. Istanziare PassManager con ALAPScheduleAnalysis e PadDynamicalDecoupling. Eseguire prima ALAPScheduleAnalysis per aggiungere informazioni sulla tempistica del circuito quantistico prima di poter aggiungere le sequenze di disaccoppiamento dinamico a distanza regolare. Questi passaggi vengono eseguiti sul circuito con .run().
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)
dd_pm = PassManager(
[
ALAPScheduleAnalysis(target=target),
PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
]
)
qc_dd = dd_pm.run(qc_t)Utilizzare lo strumento di visualizzazione timeline_drawer per vedere la temporizzazione del circuito e confermare che nel circuito compaia una sequenza regolarmente distanziata di XGate oggetti e YGate oggetti.
from qiskit.visualization import timeline_drawer
timeline_drawer(qc_dd, idle_wires=False, target=target)Output:
Infine, poiché YGate non è un vero e proprio gate di base del nostro backend, applicare manualmente il passaggio BasisTranslator (è un passaggio predefinito, ma viene eseguito prima della programmazione, quindi deve essere applicato di nuovo). La libreria delle equivalenze di sessione è una libreria di equivalenze circuitali che consente al transpiler di decomporre i circuiti in porte di base, come specificato anche come argomento.
from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.transpiler.passes import BasisTranslator
qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)
qc_dd.draw("mpl", fold=-1, idle_wires=False)Output:
Ora, YGate gli oggetti sono assenti dal nostro circuito e ci sono informazioni esplicite sulla temporizzazione sotto forma di Delay porte. Questo circuito trasposto con disaccoppiamento dinamico è ora pronto per essere inviato al backend.
Passi successivi
- Per imparare a usare la funzione
generate_preset_passmanagerinvece di scrivere i propri passaggi, iniziare con l'argomento Impostazioni predefinite e opzioni di configurazione di Transpilation. - Prova la guida Confronta le impostazioni del transpiler.
- Consulta la documentazione dell'API Transpile.