Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Usare il Microsoft Quantum Development Kit (QDK) per compilare un programma logico OpenQASM o Q# per Quantum Intermediate Representation (QIR) e quindi usare qdk.simulation.run_qir per eseguire il programma tramite qodec. Configurare un modello di disturbo e quindi scegliere il decodificatore di sindrome predefinito o il decodificatore a livello di circuito facoltativo deq .
Prerequisites
Completare queste attività prima di iniziare:
- Installa QDK per la correzione degli errori.
- Sviluppare e convalidare un protocollo QEC o ottenere un pacchetto completo qodec da un'altra origine.
- Controllare qodec usando
qdk.ec.audit.
Negli Q# esempi viene usato un qodec oggetto denominato protocol che contiene istruzioni per il C4 codice. Per crearne uno, vedere Sviluppare e convalidare un protocollo QEC.
import qodec
from qdk import ec
c4 = qodec.Code(
"C4",
stabilizers=["X_0 X_1 X_2 X_3", "Z_0 Z_1 Z_2 Z_3"],
x=["X_0 X_1", "X_0 X_2"],
z=["Z_0 Z_2", "Z_0 Z_1"],
)
protocol = ec.build_qodec(
c4,
strategy="bare-css/v1",
strict=False,
)
report = ec.audit(protocol)
if report.errors or report.warnings:
raise ValueError(str(report))
Controllare qodec prima di eseguirlo. Il runtime considera attendibili i qodeccontrolli, le letture, i flag e le equazioni dei fotogrammi, quindi le dichiarazioni non valide possono causare risultati logici non corretti o errori del decodificatore.
Questo flusso di lavoro usa qdk.simulation.run_qir con un oggetto qodec. Gli qodec strumenti usano il pacchetto separato StimPython pacchetto per analizzare i circuiti gadget in formato Stim. Non lo richiama qdk.stim.run. Su LinuxArm64 o WindowsArm64, installa Stim dai sorgenti e riavvia Python o il kernel Jupyter prima di eseguire un qodec che contiene circuiti in formato Stim.
Associare le chiamate QIR alle istruzioni qodec
Abbina ogni chiamata quantistica nel programma QIR a un'istruzione nel set di istruzioni principale di qodec. Il mnemonico dell'istruzione deve corrispondere esattamente al nome della funzione chiamata QIR.
La tabella seguente illustra i mapping di esempio:
| Chiamata sorgente | Mnemonico richiesto qodec |
|---|---|
Q#
X(q) o OpenQASMx q; |
__quantum__qis__x__body |
Q#
H(q) o OpenQASMh q; |
__quantum__qis__h__body |
Q#
CNOT(a, b) o OpenQASMcx a, b; |
__quantum__qis__cx__body |
Q#
Adjoint S(q) o OpenQASMsdg q; |
__quantum__qis__s__adj |
Q#
M(q) o OpenQASMc = measure q; |
__quantum__qis__m__body |
Q# operazione intrinseca Foo |
Foo |
OpenQASM porta intrinseca o def denominato foo |
foo |
QIR gli argomenti vengono associati agli qodec elementi dell'istruzione in questo ordine:
- Gli argomenti del puntatore Qubit vengono associati agli operandi di blocco.
- Gli argomenti scalari si collegano ai parametri dell'istruzione.
- Gli argomenti del puntatore di risultato ricevono gli esiti dell'istruzione ed eventuali flag restituiti.
Il compilatore genera un errore se una chiamata quantistica non corrisponde a un'istruzione nel set di istruzioni di livello superiore.
Dichiara istruzioni logiche in Q#
Un oggetto qodec compilato dal codice C4 espone istruzioni personalizzate come prepare_z_all, measure_z_all, syndrome e cx_all. Dichiara Q# operazioni intrinseche con gli stessi nomi.
Inizializzare Q# con il profilo di destinazione adattivo perché le operazioni di misurazione personalizzate lo richiedono.
from qdk import TargetProfile, qsharp
qsharp.init(target_profile=TargetProfile.Adaptive_RI)
Dichiarare le C4 istruzioni come Q# operazioni.
qsharp.eval("""
@Measurement()
operation prepare_z_all(block : Qubit) : Result { body intrinsic; }
@Measurement()
operation prepare_x_all(block : Qubit) : Result { body intrinsic; }
@Measurement()
operation measure_z_all(block : Qubit) : (Result, Result) { body intrinsic; }
@Measurement()
operation measure_x_all(block : Qubit) : (Result, Result) { body intrinsic; }
operation cx_all(control : Qubit, target : Qubit) : Unit { body intrinsic; }
operation syndrome(block : Qubit) : Unit { body intrinsic; }
""")
In questo programma, ciascun elemento Q#Qubit rappresenta un blocco codificato. Il C4 blocco ha due qubit logici, quindi ogni operazione di misurazione restituisce due risultati logici. Ogni operazione di preparazione restituisce un flag di rifiuto.
Compilare un esperimento logico Q#
Definire un esperimento di preparazione e misurazione dello stato (SPAM).
qsharp.eval("""
operation TestSpamZ() : (Result[], Result[]) {
use block = Qubit();
let reject = prepare_z_all(block);
let (left, right) = measure_z_all(block);
([reject], [left, right])
}
""")
Compila l'operazione TestSpamZ in QIR.
qir = str(qsharp.compile("TestSpamZ()"))
QIR conserva le chiamate a prepare_z_all e measure_z_all. Quando il programma viene eseguito, il qodec runtime confronta questi nomi con il set di istruzioni superiore e sostituisce ogni chiamata logica con il relativo gadget.
Esegui con il decodificatore integrato
Chiama run_qir e passa qodec. Se decoder è None, il runtime usa il decodificatore predefinito a peso minimo Pauli.
from qdk.simulation import run_qir
results = run_qir(
qir,
qodec=protocol,
type="stabilizer",
shots=100,
seed=42,
)
print(results[:5])
Per eseguire un qodec, usare queste opzioni del simulatore:
Valore type |
Behavior |
|---|---|
None oppure "stabilizer" |
Usare il backend stabilizer |
"cpu" |
Usare il back-end del vettore di stato per i programmi supportati |
"gpu" |
Non supportato con qodec |
Il runtime prepara ogni qubit del programma prima del suo primo uso, a meno che la prima istruzione non ne crei il blocco. Un'istruzione di preparazione include blocchi di output, nessun blocco di input e un'azione che stabilizza l'elemento logico Z.
Le correzioni del decodificatore a singolo qubit Pauli e gli aggiornamenti del frame qodec usano un frame senza Pauli rumore, non i cancelli fisici rumorosi.
Configurare il rumore del simulatore
Definisci il disturbo sulle operazioni del simulatore, non sui nomi delle istruzioni. Il runtime converte ogni istruzione di livello inferiore in una o più operazioni del simulatore, quindi le impostazioni di disturbo si applicano a tali operazioni.
La procedura guidata C4 usa queste mappature:
| Istruzione dello strato inferiore | Funzionamento del simulatore |
NoiseConfig Campo |
|---|---|---|
R |
Prepara o reimposta su Z+ | mresetz |
H |
Hadamard | h |
CX |
Controllo X | cx |
M |
Misurazione nella Z-basis | mresetz |
Creare un semplice modello di rumore dell'1%:
from qdk.simulation import NoiseConfig
noise = NoiseConfig()
for gate in (noise.h, noise.cx):
gate.set_depolarizing(0.01)
noise.mresetz.x = 0.01
Eseguire l'esperimento con rumore:
results = run_qir(
qir,
qodec=protocol,
noise=noise,
type="stabilizer",
shots=1000,
seed=42,
on_shot_failure="discard",
)
Il rumore su mresetz agisce sul qubit dopo la misurazione o la preparazione. Non inverte un bit di misurazione già registrato dal simulatore. Per studiare i capovolgimenti di bit registrati, usare qodec i modelli di errore di lettura e l'analisi dei gadget.
Guasti dei control shot
Usare on_shot_failure per scegliere il modo in cui il runtime risponde quando un qodec flag, un decodificatore o un readout non produce uno scatto accettato.
| Value | Behavior |
|---|---|
"discard" |
Omettere i colpi non riusciti dall'elenco restituito. Si tratta del valore predefinito. |
"raise" |
Interrompi quando il primo colpo ha esito negativo. |
"retry" |
Riavvia il colpo non riuscito, fino a max_retries tentativi aggiuntivi. |
Con il criterio "discard", l'argomento shots conta i tentativi di tiro, in modo che l'elenco restituito possa avere un numero di elementi inferiore a shots.
Un flag attiva il criterio di scatto solo quando il programma logico non riceve tale flag. Se un'operazione Q#@Measurement() restituisce un extra Result per il flag, il programma riceve il flag e decide se rifiutare lo shot.
Nell'esempio TestSpamZ il programma restituisce il flag di preparazione nel primo array. L'impostazione on_shot_failure="discard" non rimuove quindi le righe in cui il flag restituito è One.
Seleziona un decodificatore
Per scegliere la modalità di decodifica degli errori, usare il parametro decoder per passare una callable di preparazione del decoder per ogni livello codificato.
QDK ha i seguenti decodificatori:
| Decoder | Usalo per |
|---|---|
| Decodificatore di sindrome standard | Inferire le correzioni minime di peso Pauli dall'evidenza del syndrome. Utilizzare il decoder=None. |
| Decodificatore di frame | Monitora fotogrammi privi di rumore senza dedurre guasti fisici. Utilizzare il prepare_frame_decoder. |
| deq decoder | Decodifica i modelli di errore a livello di circuito con deq. Utilizzare il prepare_deq_decoder. |
Usare la configurazione predefinita deq
Installa deq e deq-runtime, quindi passa prepare_deq_decoder.
from qdk.simulation.decoders import prepare_deq_decoder
results = run_qir(
qir,
qodec=protocol,
decoder=prepare_deq_decoder,
noise=noise,
type="stabilizer",
shots=1000,
seed=42,
on_shot_failure="discard",
)
Per impostazione predefinita, l'adattatore deq usa relay belief propagation e un coordinatore finestra. Per modificare queste impostazioni, usare una factory di runtime.
Configurare un runtime monolitico deq
Per scegliere deq direttamente le impostazioni, passare una factory di runtime a prepare_deq_decoder.
from functools import partial
from deq.runtime import Runtime
from qdk.simulation import decoders
def make_runtime(seed: int) -> Runtime:
return Runtime(
decoder="black-box-relay-bp",
decoder_config={"parallel": 1, "seed": seed},
coordinator="monolithic",
controller="jit",
)
results = run_qir(
qir,
qodec=protocol,
decoder=partial(
decoders.prepare_deq_decoder,
runtime_factory=make_runtime,
),
noise=noise,
type="stabilizer",
shots=1000,
seed=42,
on_shot_failure="discard",
)
Restituire un nuovo oggetto Runtime da ogni chiamata factory. Il QDK si avvia e si chiude a ogni runtime.
Note
L'adattatore deq richiede:
- Un livello codificato
- Traccia di esecuzione indipendente dalla misura Clifford
- backend dello stabilizzatore
- Un modello di disturbo senza perdita di qubit
L'adattatore deq non supporta il criterio di ripetizione. I programmi non supportati generano un errore anziché eseguire il fallback a un altro decodificatore.
Rifiuta i deq risultati con bassa attendibilità
L'adattatore deq restituisce un punteggio per ogni readout logico. I punteggi inferiori indicano una preferenza più forte per la correzione scelta. I punteggi non sono probabilità di fallimento calibrate.
Per rifiutare i risultati con bassa attendibilità, passare max_readout_score quando si prepara il decodificatore, come nell'esempio seguente:
from functools import partial
from qdk.simulation import decoders
scored_decoder = partial(
decoders.prepare_deq_decoder,
max_readout_score=0.2,
)
results = run_qir(
qir,
qodec=protocol,
decoder=scored_decoder,
noise=noise,
type="stabilizer",
shots=1000,
on_shot_failure="discard",
)
Il runtime accetta uno shot solo quando ogni readout logico restituito ha un punteggio pari o inferiore alla soglia. La soglia non si applica ai flag non elaborati o alle letture intermedie inutilizzate.
Lo scarto in base al punteggio può ridurre la frequenza di errore logica delle esecuzioni accettate. Ma riduce anche il numero di scatti accettati e aggiunge lavoro al decodificatore.
OpenQASM Compilare programmi
Le operazioni standard OpenQASM usano le stesse QIR regole mnemoniche delle operazioni standard Q# .
from qdk import TargetProfile, openqasm
source = """
OPENQASM 3.0;
include "stdgates.inc";
qubit q;
bit c;
x q;
c = measure q;
"""
qir = openqasm.compile(
source,
target_profile=TargetProfile.Adaptive_RI,
)
print(qir)
Per eseguire questo programma tramite un qodec, verificare che il set di istruzioni di livello superiore di qodec includa __quantum__qis__x__body e __quantum__qis__m__body, con operandi a blocchi compatibili e un risultato di misurazione.
Un OpenQASM gate intrinseco o un sottoprogramma denominato foo usa il mnemonico foo. Gli argomenti qubit vengono associati a operandi del blocco. Gli argomenti float, int e bool vengono associati ai parametri dell'istruzione nell'ordine di dichiarazione.
OpenQASM presenta queste limitazioni per qodec le chiamate:
- Le funzioni intrinseche personalizzate non possono restituire un QIR
Result. Per ottenere un risultato di misurazione, usare l'istruzione standardmeasure. -
OpenQASM i programmi non possono eseguire misurazioni personalizzate, ricevere diversi risultati da una chiamata o ricevere flag restituiti. Per questi casi, usare le operazioni Q#
@Measurement(). - Il runtime controlla tutti i flag che il programma OpenQASM non può ricevere e questi flag possono rifiutare un tentativo.
Per esempi dettagliati di mapping, vedere i notebook seguenti QDK :
Esaminare i requisiti e le limitazioni
Esaminare questi requisiti, limitazioni e differenze di risultato prima di eseguire un esperimento di grandi dimensioni.
Requisiti:
- Ogni QIR chiamata quantistica deve essere risolta in un'istruzione del livello qodec superiore.
- Verificare il protocollo prima di eseguirlo. Il qodec runtime considera attendibili le equazioni scritte e non le controlla.
Limitazioni:
- GPU la simulazione non supporta l'qodecesecuzione.
- L'insieme di guasti del gadget predefinito può crescere in modo esponenziale, quindi le ricerche esatte sulla distanza possono richiedere molto tempo.
- I pacchetti deq e Stim presentano limitazioni della piattaforma. Per altre informazioni, vedere Install QDK per la correzione degli errori.
Differenze nei risultati:
- I conteggi di output esatti possono variare in base al decodificatore.
- Le politiche di scarto e di ripetizione dei tentativi possono modificare la distribuzione dei risultati restituita.
Per un esperimento completo Q# con sweep di rumore, deq decodifica e rifiuto basato sulla confidenza, vedere la procedura dettagliata del protocollo QEC.