Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Use Microsoft Quantum Development Kit (QDK) para compilar um programa lógico Q# ou OpenQASM para Quantum Intermediate Representation (QIR) e, em seguida, use qdk.simulation.run_qir para executar o programa por meio de um qodec. Configure um modelo de ruído e escolha o decodificador de síndrome integrado ou o decodificador de nível de circuito opcional deq.
Prerequisites
Conclua estas tarefas antes de começar:
- Instale QDK para correção de erros.
- Desenvolva e valide um protocolo QEC ou obtenha um conjunto completo qodec de outra fonte.
- Audite o/a qodec usando
qdk.ec.audit.
Os exemplos Q# usam um qodec chamado protocol que tem instruções para o código C4. Para criar um, consulte Desenvolver e validar um protocolo 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))
Audite o qodec antes de executá-lo. O runtime confia nas verificações, leituras, sinalizadores e equações de quadro do qodec, de modo que declarações inválidas podem causar resultados lógicos incorretos ou falhas de decodificador.
Esse fluxo de trabalho usa qdk.simulation.run_qir com um qodec. As ferramentas qodec usam o pacote separado StimPython para analisar circuitos de dispositivos no formato Stim. Ele não invoca qdk.stim.run. No LinuxArm64 ou WindowsArm64, instale Stim a partir do código-fonte e reinicie Python ou o kernel Jupyter antes de executar um qodec que tenha circuitos no formato Stim.
Corresponder chamadas QIR a instruções qodec
Corresponda cada chamada quântica no programa QIR a uma instrução no conjunto de instruções superior de qodec. A instrução mnemônica deve corresponder exatamente ao nome do receptor QIR.
A tabela a seguir mostra mapeamentos de exemplo:
| Chamada de fonte | Mnemônico necessário qodec |
|---|---|
Q#
X(q) ou OpenQASMx q; |
__quantum__qis__x__body |
Q#
H(q) ou OpenQASMh q; |
__quantum__qis__h__body |
Q#
CNOT(a, b) ou OpenQASMcx a, b; |
__quantum__qis__cx__body |
Q#
Adjoint S(q) ou OpenQASMsdg q; |
__quantum__qis__s__adj |
Q#
M(q) ou OpenQASMc = measure q; |
__quantum__qis__m__body |
Q# Operação intrínseca Foo |
Foo |
OpenQASM portão intrínseco ou def denominado foo |
foo |
QIR os argumentos se vinculam aos qodec elementos de instrução nesta ordem:
- Argumentos de ponteiro de qubit são associados a operandos de bloco.
- Argumentos escalares são vinculados a parâmetros de instrução.
- Os argumentos de ponteiro de resultado recebem resultados de instrução e quaisquer sinalizadores retornados.
O compilador gerará um erro se uma chamada quântica não corresponder a uma instrução no conjunto de instruções de nível superior.
Declarar instruções lógicas em Q#
Um qodec compilado a partir do código C4 expõe instruções personalizadas como prepare_z_all, syndrome, measure_z_all e cx_all. Declare Q# operações intrínsecas com os mesmos nomes.
Inicialize Q# com o perfil de destino adaptável porque as operações de medição personalizadas exigem isso.
from qdk import TargetProfile, qsharp
qsharp.init(target_profile=TargetProfile.Adaptive_RI)
Declare as instruções C4 como operações Q#.
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; }
""")
Neste programa, cada Q#Qubit representa um bloco codificado. O C4 bloco tem dois qubits lógicos, portanto, cada operação de medida retorna dois resultados lógicos. Cada operação de preparação retorna um sinalizador de rejeição.
Compilar um experimento lógico Q#
Defina um experimento de SPAM (preparação e medição de estado).
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])
}
""")
Compile a operação TestSpamZ para QIR.
qir = str(qsharp.compile("TestSpamZ()"))
O QIR mantém as chamadas para prepare_z_all e measure_z_all. Quando o programa é executado, o runtime qodec compara esses nomes com o conjunto de instruções de nível superior e substitui cada chamada lógica por seu dispositivo.
Executar com o decodificador interno
Chame a função run_qir e passe o qodec. Se decoder estiver None, o runtime usará o decodificador interno de peso mínimo Pauli.
from qdk.simulation import run_qir
results = run_qir(
qir,
qodec=protocol,
type="stabilizer",
shots=100,
seed=42,
)
print(results[:5])
Para executar um qodec, use estas opções de simulador:
type valor |
Behavior |
|---|---|
None ou "stabilizer" |
Usar o back-end estabilizador |
"cpu" |
Usar o back-end de vetor de estado para programas compatíveis |
"gpu" |
Não é compatível com um qodec |
O runtime prepara cada qubit do programa antes de seu primeiro uso, a menos que a primeira instrução crie seu bloco. Uma instrução de preparação tem blocos de saída, nenhum bloco de entrada e uma ação que estabiliza o elemento lógico Z.
Correções de decodificador de qubit único Pauli e atualizações de quadro qodec usam um quadro sem ruído Pauli, não portas físicas barulhentas.
Configurar o ruído do simulador
Defina o ruído em operações de simulador, não em nomes de instrução qodec. O runtime converte cada instrução de camada inferior em uma ou mais operações de simulador, de modo que as configurações de ruído se aplicam a essas operações.
O C4 passo a passo usa estes mapeamentos:
| Instrução da camada inferior | Operação do simulador | campo NoiseConfig |
|---|---|---|
R |
Preparar ou redefinir para Z+ | mresetz |
H |
Hadamard | h |
CX |
Controlled X | cx |
M |
Medição na base Z | mresetz |
Crie um modelo de ruído simples de 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
Execute o experimento com ruído:
results = run_qir(
qir,
qodec=protocol,
noise=noise,
type="stabilizer",
shots=1000,
seed=42,
on_shot_failure="discard",
)
O ruído em mresetz atua no qubit após a medição ou preparação. Ele não inverte um bit de medição que o simulador já registrou. Para estudar inversões de bits registradas, use qodec modelos de falha de leitura e análise de gadget.
Falhas de disparo de controle
Use on_shot_failure para escolher como o runtime responde quando um sinalizador qodec, decodificador ou leitura não produz uma medição aceita.
| Value | Behavior |
|---|---|
"discard" |
Omita as capturas com falha da lista retornada. Esse valor é o padrão. |
"raise" |
Pare quando a primeira tentativa falhar. |
"retry" |
Reinicie a tentativa com falha, até max_retries tentativas adicionais. |
Com a política "discard", o argumento shots conta disparos tentados, de modo que a lista retornada pode ter menos itens do que shots.
Um sinalizador dispara a política de disparo somente quando o programa lógico não recebe esse sinalizador. Se uma operação Q#@Measurement() retornar um Result extra para o sinalizador, o programa receberá o sinalizador e decidirá se deseja rejeitar a tentativa.
No exemplo TestSpamZ, o programa retorna o sinalizador de preparação no primeiro array. Portanto, a on_shot_failure="discard" configuração não remove linhas em que o sinalizador retornado está One.
Selecionar um decodificador
Para escolher como os erros são decodificados, use o parâmetro decoder para passar um chamável de preparação do decodificador para cada camada codificada.
O QDK tem os seguintes decodificadores:
| Decodificador | Use para |
|---|---|
| Decodificador de síndrome padrão | Inferir correções de peso mínimo Pauli a partir da evidência de síndrome. Use decoder=None. |
| Decodificador de quadros | Acompanhe quadros sem ruído sem inferir falhas físicas. Use prepare_frame_decoder. |
| deq decodificador | Decodifique modelos de falha no nível do circuito com deq. Use prepare_deq_decoder. |
Usar a configuração padrão deq
Instalar deq e deq-runtime, em seguida, passar 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",
)
Por padrão, o deq adaptador usa a propagação de crença de retransmissão e um coordenador de janela. Para alterar essas configurações, use uma fábrica de runtime.
Configurar um runtime monolítico deq
Para escolher deq as configurações diretamente, passe uma fábrica de runtime para 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",
)
Retorne um novo Runtime de cada chamada de fábrica. O QDK inicia e encerra cada runtime.
Note
O adaptador deq requer o seguinte:
- Uma camada codificada
- Um rastreamento de execução independente de medição Clifford
- O back-end estabilizador
- Um modelo de ruído sem perda de qubit
O deq adaptador não dá suporte à política de repetição. Programas sem suporte geram um erro em vez de recorrer a outro decodificador.
Rejeitar resultados de baixa confiança deq
O deq adaptador retorna uma pontuação para cada leitura lógica. Pontuações mais baixas indicam uma preferência mais forte para a correção escolhida. As pontuações não são probabilidades de falha calibradas.
Para rejeitar resultados de baixa confiança, passe max_readout_score ao preparar o decodificador, como no exemplo a seguir:
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",
)
O runtime aceita uma tentativa somente quando cada leitura lógica retornada tem uma pontuação igual ou abaixo do limite. O limite não se aplica a flags brutas ou leituras intermediárias não utilizadas.
A rejeição baseada em pontuação pode reduzir a taxa de erros lógicos de disparos aceitos. Mas também reduz o número de tentativas aceitas e adiciona trabalho de decodificador.
Compilar OpenQASM programas
As operações padrão OpenQASM usam as mesmas QIR regras mnemônicas que as operações padrão 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)
Para executar este programa por meio de um qodec, verifique se o conjunto de instruções superior de qodec tem __quantum__qis__x__body e __quantum__qis__m__body com operandos de bloco compatíveis e um resultado de medida.
Uma OpenQASM porta intrínseca ou sub-rotina chamada foo usa o mnemônico foo. Argumentos qubit se vinculam a operandos de bloco. Os argumentos float, int e bool vinculam-se aos parâmetros da instrução na ordem de declaração.
OpenQASM tem essas limitações para chamadas qodec:
- Intrínsecos personalizados não podem retornar um QIR
Result. Para obter um resultado de medida, use a instrução padrãomeasure. -
OpenQASM os programas não podem executar medições personalizadas, receber vários resultados de uma chamada ou receber sinalizadores retornados. Para esses casos, use operações Q#
@Measurement(). - O runtime controla todos os sinalizadores que o programa OpenQASM não pode receber, e esses sinalizadores podem rejeitar uma tentativa.
Para obter exemplos detalhados de mapeamento, consulte os seguintes QDK notebooks:
Examinar requisitos e limitações
Examine esses requisitos, limitações e diferenças de resultados antes de executar um grande experimento.
Requisitos:
- Cada chamada quântica QIR deve resultar em uma instrução de camada superior qodec.
- Audite o protocolo antes de executá-lo. O qodec runtime confia nas equações que você escreve e não as verifica.
Limitações:
- GPU A simulação não dá suporte à qodec execução.
- O conjunto de falhas padrão do gadget pode crescer exponencialmente, de modo que pesquisas de distância exata podem levar muito tempo.
- Os pacotes deq e Stim têm limitações de plataforma. Para obter mais informações, consulte Instalação QDK para correção de erro.
Diferenças de resultados:
- As contagens exatas de saída podem variar de acordo com o decodificador.
- As políticas de descarte e repetição podem alterar a distribuição de resultados retornada.
Para obter um experimento completo Q# com varreduras de ruído, deq decodificação e rejeição baseada em confiança, consulte o passo a passo do protocolo QEC.