Stim Suporte para correção quântica de erros no QDK

Stim é uma ferramenta de código aberto da Google Quantum AI para simulação e análise rápida de circuitos estabilizadores quânticos, especialmente circuitos de correção quântica de erros (QEC). Os protocolos QEC utilizam frequentemente rondas repetidas de Clifford operações e Pauli medições, e os investigadores analisam frequentemente os protocolos QEC com Pauli modelos de ruído. Esta estrutura de circuito é muito mais eficiente para simular classicamente do que um circuito quântico geral, pelo que os investigadores podem testar muitas execuções de grandes circuitos de correção de erros.

O Microsoft Quantum Development Kit (QDK-Stim) inclui Stim, que amplia QDK com funcionalidades adicionais. Podes escrever circuitos com o conjunto de Stim instruções, compilá-los para representação intermédia quântica (QIR), e executá-los nos QDK simuladores. QDK-Stim adiciona suporte para perda de qubits, pós-seleção, padrões de repetição até ao sucesso e operações não-Clifford.

Aceda a QDKQDK-Stim através do módulo qdk.stim. O módulo aceita Stim código-fonte e executa o programa compilado em QDK simuladores. A QDKPython API não tem toda a funcionalidade do stimPython pacote e não expõe classes como stim.Circuit, samplers compilados ou modelos de erro de detetores.

Para mais informações sobre Stim, consulte o Stim repositório no GitHub.

Prerequisites

Para usar Stim circuitos com o QDK, precisa:

  • Python 3.10 ou mais tarde.
  • pip ou outro Python gestor de pacotes.
  • Um Python ambiente, como um ambiente virtual ou Jupyter Notebook.
  • Familiaridade básica com o Stimformato de circuito.

Instalar e usar Stim com o QDK

Instale ou atualize o QDKPython pacote:

pip install --upgrade qdk

Importa o stim módulo de qdk, define um Stim circuito como uma cadeia e passa o circuito para stim.run. O exemplo seguinte prepara e mede um estado Bell:

from qdk import stim

bell = """
H 0
CX 0 1
M 0 1
"""

results = stim.run(bell, shots=100, type="stabilizer")
print(results[:5])

Cada item em results contém os resultados das medições de um disparo. Um resultado padrão é Result.Zero ou Result.One. QDK QDK-Stim inclui também Result.Loss para medições de qubits perdidos.

Para circuitos estabilizadores padrão Stim , comece por type="stabilizer". Para mais informações sobre os simuladores, veja Visão Geral dos simuladores quânticos no QDK.

QDK Características para Stim circuitos

QDK estende o conjunto de instruções Stim e liga-o a QIR e aos simuladores QDK. Estas adições suportam fluxos de trabalho de simulação que não estão disponíveis em Stim.

Compilar Stim circuitos em QIR

O QDK compila Stim o código-fonte do circuito para QIR antes de executar o circuito. A função stim.run executa ambos os passos numa única chamada. Usa stim.compile quando quiseres inspecionar o QIR gerado ou executá-lo noutro simulador ou serviço.

A stim.compile função devolve o QIR código-fonte e o QDKNoiseConfig que o simulador precisa. O exemplo seguinte compila um circuito de estado Bell e imprime o QIR:

from qdk import stim

bell = """
H 0
CX 0 1
M 0 1
"""

qir, noise = stim.compile(bell)
print(qir)

Adicionar ruído a Stim circuitos

Pode adicionar ruído a um Stim circuito com Stim instruções de ruído ou com um QDKNoiseConfig. Escolha o método que melhor corresponde à forma como define o circuito e o modelo de ruído:

Método de ruído Como utilizá-lo Utilizar quando
Stim Instruções de ruído Adicionar instruções como X_ERROR, DEPOLARIZE1 e CORRELATED_ERROR ao código Stim. O ruído faz parte da definição do Stim circuito.
QDK Modelo de ruído Defina um NoiseConfig e passe-o com o argumento noise. Deves aplicar um modelo de ruído existente QDK a um Stim circuito que não contenha instruções de ruído.

O NoiseConfig devolvido por stim.compile representa as instruções de ruído no circuito Stim. Não é um modelo de ruído separado.

Caution

Escolha um método de geração de ruído. Utilize instruções de ruído Stim ou um QDKNoiseConfig. Se usares ambos, o simulador aplica ambos os modelos de ruído.

O exemplo seguinte define um Stim circuito que tem ruído despolarizante:

from qdk import stim

noisy_bell = """
H 0
CX 0 1
DEPOLARIZE2(0.01) 0 1
M 0 1
"""

results = stim.run(noisy_bell, shots=1000, type="stabilizer")

Para mais informações, veja Como construir modelos de ruído para simulações quânticas no simulador QDK.

Modelar perda de qubits

O QDK adiciona instruções de perda e alvos ao formato de circuito Stim. A medição de um qubit perdido devolve Result.Loss em vez de Result.Zero ou Result.One.

Construir Sintaxe Behavior
Erro de perda de dados LOSS_ERROR(p) 0 1 Perde cada alvo independentemente com probabilidade p.
Meta de perda correlacionada L0 Representa a perda de um qubit num evento CORRELATED_ERROR ou ELSE_CORRELATED_ERROR.
Inspeção de sinistros PEEK_LOSS 0 1 Adiciona 1 para um qubit perdido e 0 para um qubit presente sem o medir ou reinicializar.

O exemplo seguinte aplica perda independente a dois qubits, inspeciona o seu estado de perda e depois mede-os:

from qdk import Result, stim

loss_program = """
H 0
LOSS_ERROR(0.2) 0 1
PEEK_LOSS 0 1
M 0 1
"""

results = stim.run(loss_program, shots=100, type="stabilizer")

symbols = {
    Result.Zero: "0",
    Result.One: "1",
    Result.Loss: "L",
}

formatted = ["".join(symbols[value] for value in shot) for shot in results[:10]]

print(formatted)

Cada captura formatada contém quatro caracteres. Os dois primeiros caracteres são os PEEK_LOSS valores, e os dois últimos são os resultados da medição. Um final L significa que o qubit correspondente foi perdido.

Utilize L alvos para combinar perdas e Pauli erros num evento correlacionado:

CORRELATED_ERROR(0.1) L0 X1
ELSE_CORRELATED_ERROR(0.1) L1

Note

Em QDKQDK-Stim, CORRELATED_ERROR e ELSE_CORRELATED_ERROR devem vir um imediatamente após o outro. Em Stim, não precisam necessariamente de o fazer.

Resultados da medição pós-selecionados

Adiciona QDKSELECT blocos para padrões de pós-seleção e repetição até sucesso, baseados em medições de paridade e verificações de perda de qubits. Se uma condição num SELECT bloco falhar, o simulador repete esse bloco até que todas as suas condições passem. Um bloco aninhado reinicia independentemente do seu bloco envolvente.

Construir Sintaxe Behavior
Bloco de seleção SELECT { ... } Reexecuta o corpo do bloco até que todas as condições de seleção passem.
Condição de paridade REQUIRE rec[-1] Requer que os registos de medição referenciados tenham paridade par. Um registo perdido também não cumpre a condição.
Registo invertido REQUIRE !rec[-1] Inverte um registo antes da verificação de paridade. Com um registo, isto mantém o resultado 1da medição.
Condição apenas de perdas NOTLEAKED rec[-1] Exige que as medições referenciadas não tenham perda, mas não restringe os seus valores de bits.

Liste múltiplos rec[...] destinos numa única instrução REQUIRE para selecionar a sua paridade conjunta. O programa seguinte mantém apenas os resultados não perdidos com paridade par, pelo que as medições finais são 00 ou 11:

from qdk import stim

post_selected = """
SELECT {
    H 0
    H 1
    LOSS_ERROR(0.1) 0 1
    M 0 1
    REQUIRE rec[-1] rec[-2]
}
"""

results = stim.run(post_selected, shots=1000, type="stabilizer")

Utilize NOTLEAKED quando ambos 0 e 1 são resultados válidos, mas quer descartar as medições dos qubits perdidos:

SELECT {
    H 0
    LOSS_ERROR(0.2) 0
    M 0
    NOTLEAKED rec[-1]
}

Cada condição deve referenciar pelo menos um registo que o bloco SELECT atual ou um bloco aninhado produz. O compilador rejeita uma condição se uma reexecução do bloco não puder alterar nenhum dos seus registos referenciados.

Simular operações não-Clifford

Stim foca-se em circuitos estabilizadores e não suporta operações não-Clifford, como portas T e Toffoli. QDK QDK-Stim adiciona operações semelhantes às suportadas por Clifft, um simulador para circuitos quase-Clifford.

Categoria Instruções Agrupamento de destinos
Marcos de fase T, T_DAG Um qubit por alvo
Pauli-fases de aprovação do produto TPP, TPP_DAG Um Pauli produto por grupo-alvo
Gates controlados CH Pares consecutivos
Portões controlados CCX, CCZ Triplos consecutivos
Rotações de um qubit R_X(a), R_Y(a), R_Z(a) Um qubit por alvo
Portas gerais de um qubit U3(t, p, l), U(t, p, l) Um qubit por alvo
Rotações de dois qubits R_XX(a), R_YY(a), R_ZZ(a) Pares consecutivos
Pauli-rotações de produtos R_PAULI(a) Um Pauli produto por grupo-alvo

Por defeito, os argumentos de rotação usam meias voltas. Por exemplo, R_X(0.5) roda $\pi/2$ radianos. Adicione o sufixo rad para especificar diretamente os radianos, como R_X(0.5rad). Podes usar ou U3 ou U para misturar unidades de ângulo porque ambas são iguais.

O circuito seguinte utiliza uma porta de Toffoli e uma rotação Y arbitrária:

from qdk import stim

near_clifford = """
X 0 1
CCX 0 1 2
R_Y(0.25) 3
M 0 1 2 3
"""

results = stim.run(near_clifford, shots=1000, type="stabilizer")

O QDK simulador do estabilizador ramifica a decomposição do estabilizador quando se depara com uma Clifford operação não-. Esta abordagem mantém-se eficiente quando as operações não-Clifford são escassas, mas o espaço de estados necessário cresce exponencialmente com o número de operações não-Clifford. Use type="cpu" ou type="gpu" para circuitos que contenham muitas não-Clifford operações.

Para as definições completas de portas não-Clifford, veja a Clifft referência de portas suportadas.

Limitações atuais

O QDK suporta a maioria das instruções na Stim referência de gate, com as seguintes limitações. Para o estado atual da implementação, veja a QDKQDK-Stim questão de rastreio de funcionalidades em falta.

Funcionalidade do Stim Comportamento atual QDK
DETECTOR e OBSERVABLE_INCLUDE Processado e ignorado. O QDK não fornece detetor nem amostragem observável.
HERALDED_ERASE e HERALDED_PAULI_CHANNEL_1 A compilação falha porque QDK não suporta estas instruções.
MPAD A compilação falha porque QDK não suporta estas instruções.
Alvos sweep-bit, tais como CX sweep[5] 7 A compilação falha porque o QDK não suporta alvos sweep-bit.
Pauli produtos que se reduzem à identidade, como MPP Z0*Z0 A compilação falha porque QDK não suporta o destino identity resultante.

Use Stim quando precisar de modelos de erro de detetores, samplers compilados Stim, Sinter ou outras StimPython APIs. Usa qdk.stim quando quiseres compilar código Stim para QIR e executar o QIR em simuladores QDK, ou usa a perda QDK, a pós-seleção e as extensões não Clifford.