Partilhar via


Execute trabalhos de computação quântica híbrida com um perfil adaptável target

A computação híbrida combina processos de computação clássica e quântica para resolver problemas complexos.

Na computação híbrida, o código clássico controla a execução de operações quânticas com base em medições de circuito intermediário, enquanto os qubits físicos permanecem ativos. Num programa quântico único, você pode usar técnicas de programação comuns, como condicionais aninhados, loops e chamadas de função, para executar problemas complexos, reduzindo o número de execuções necessárias. Com técnicas de reutilização de qubit, programas maiores podem ser executados em máquinas usando um número menor de qubits.

Este artigo explica como enviar trabalhos híbridos para o Azure Quantum usando o Adaptive RItarget perfil. O Adaptive RItarget perfil oferece suporte para medições a meio do circuito, fluxo de controlo baseado em medições, redefinição de qubit e computação de inteiros clássica.

Pré-requisitos

  • Uma conta do Azure com uma subscrição ativa. Se não tiver uma conta do Azure, registe-se gratuitamente e inscreva-se numa subscrição pré-paga.
  • Um espaço de trabalho do Azure Quantum. Para obter mais informações, consulte Criar um espaço de trabalho do Azure Quantum.

Se quiser submeter Q# programas autónomos, também precisa dos seguintes requisitos:

Se quiseres submeter Python e Q# programas, então também precisas dos seguintes pré-requisitos:

  • Um ambiente Python com Python e Pip instalados.

  • A biblioteca Python mais recente qdk com o extra opcional azure .

    pip install --upgrade "qdk[azure]"
    

Suportado targets

Para executar trabalhos de computação quântica híbrida, você precisa selecionar um provedor quântico que suporte o Adaptive RItarget perfil.

Atualmente, o perfil adaptável target no Azure Quantum é suportado no Quantinuumtargets.

Envio de trabalhos de RI adaptáveis

Para enviar trabalhos de computação quântica híbrida, você precisa configurar o target perfil como Adaptive RI, onde RI significa "qubit Reset e Integer computations".

O Adaptive RItarget perfil oferece suporte para medições a meio do circuito, fluxo de controlo baseado em medições, redefinição de qubit e computação de inteiros clássica.

Você pode enviar trabalhos quânticos híbridos para o Azure Quantum como Q# programas autónomos ou programas mistos com Python Q#. Para configurar o perfil target para trabalhos quânticos híbridos, consulte as secções a seguir.

Para configurar o target perfil para trabalhos híbridos no Visual Studio Code, escolha uma das seguintes opções:

  • Se o Q# arquivo não fizer parte de um Q# projeto, abra o arquivo e insira @EntryPoint(Adaptive_RI) antes da operação de ponto de entrada do programa.

  • Se o arquivo Q# fizer parte de um projeto Q#, adicione o seguinte ao seu arquivo qsharp.json:

    {
      "targetProfile": "adaptive_ri"
    }
    

Ao definir seu target perfil para Adaptive RI, você pode enviar seu programa como um trabalho quântico Q# híbrido para a Quantinuum. Para fazer isso, execute as seguintes etapas:

  1. Abra o menu Exibir e escolha Paleta de comandos, digite QDK: Conectar-se a um espaço de trabalho do Azure Quantum e pressione Enter.
  2. Selecione Conta do Azure e siga as instruções para se conectar ao seu diretório, assinatura e espaço de trabalho preferidos.
  3. Depois de se conectar, no painel Explorer , expanda Espaços de trabalho quânticos.
  4. Expanda seu espaço de trabalho e expanda o provedor Quantinuum .
  5. Selecione um Quantinuum disponível target, por exemplo quantinuum.sim.h2-1e.
  6. Selecione o ícone de reprodução à direita do target nome para começar a submeter o programa atual Q#.
  7. Insira um nome para identificar o trabalho e o número de disparos.
  8. Pressione Enter para enviar o trabalho. O status do trabalho é exibido na parte inferior da tela.
  9. Expanda Trabalhos e passe o mouse sobre seu trabalho, que exibe os horários e o status do seu trabalho.

Funcionalidades suportadas

A tabela a seguir lista os recursos com suporte para computação quântica híbrida com Quantinuum no Azure Quantum.

Funcionalidade suportada Notas
Valores dinâmicos Boóis e inteiros cujo valor depende de um resultado de medição
Ciclos Apenas loops limitados classicamente
Fluxo de controle arbitrário Utilização de ramificações if/else
Medição a meio do circuito Utiliza recursos de registro clássicos
Reutilização de Qubit Suportado
Computação clássica em tempo real Aritmética de inteiros assinados de 64 bits, utiliza recursos de registro clássicos

O QDK fornece feedback específico de target quando os recursos da linguagem Q# não são suportados para o target selecionado. Se o seu Q# programa contiver recursos não suportados quando o utilizador executa trabalhos quânticos híbridos, então irá receber uma mensagem de erro durante a fase de conceção. Para obter mais informações, consulte a QIR página wiki.

Nota

Você precisa selecionar o perfil apropriado Adaptive RItarget para obter feedback apropriado quando usar Q# recursos que o target não suporta.

Para ver os recursos suportados em ação, copie o código a seguir em um Q# arquivo e adicione os trechos de código subsequentes.

import Std.Measurement.*;
import Std.Math.*;
import Std.Convert.*;

operation Main() : Result {
    use (q0, q1) = (Qubit(), Qubit());
    H(q0);
    let r0 = MResetZ(q0);

    // Copy here the code snippets below to see the supported features 
    // in action.
    // Supported features include dynamic values, classically-bounded loops, 
    // arbitrary control flow, and mid-circuit measurement.

    r0
}

Quantinuum suporta boóis dinâmicos e inteiros, o que significa boóis e inteiros que dependem dos resultados da medição. Note que r0 é um Result tipo que pode ser usado para gerar bool dinâmico e valores inteiros.

    let dynamicBool = r0 != Zero; 
    let dynamicBool = ResultAsBool(r0); 
    let dynamicInt = dynamicBool ? 0 | 1; 

O Quantinuum suporta boóis e inteiros dinâmicos, no entanto, não suporta valores dinâmicos para outros tipos de dados, como duplo. Copie o código a seguir para ver comentários sobre as limitações dos valores dinâmicos.

    let dynamicDouble = r0 == One ? 1. | 0.; // cannot use a dynamic double value
    let dynamicInt = r0 == One ? 1 | 0;
    let dynamicDouble = IntAsDouble(dynamicInt); // cannot use a dynamic double value
    let dynamicRoot = Sqrt(dynamicDouble); // cannot use a dynamic double value

Embora não haja suporte para valores dinâmicos para alguns tipos de dados, esses tipos de dados ainda podem ser usados com valores estáticos.

    let staticRoot = Sqrt(4.0);
    let staticBigInt = IntAsBigInt(2);

Mesmo valores dinâmicos de tipos suportados não podem ser usados em certas situações. Por exemplo, o Quantinuum não suporta matrizes dinâmicas, ou seja, matrizes cujo tamanho depende de um resultado de medição. O Quantinuum também não suporta loops limitados dinamicamente. Copie o código a seguir para ver as limitações dos valores dinâmicos.

    let dynamicInt = r0 == Zero ? 2 | 4;
    let dynamicallySizedArray = [0, size = dynamicInt]; // cannot use a dynamically-sized array
    let staticallySizedArray = [0, size = 10];
    // Loops with a dynamic condition are not supported by Quantinuum.
    for _ in 0..dynamicInt {
         Rx(PI(), q1);
    }
        
    // Loops with a static condition are supported.
    let staticInt = 3;
    for _ in 0..staticInt {  
         Rx(PI(), q1);  
    }

Quantinuum suporta fluxo de controle, incluindo a if/else ramificação, usando condições estáticas e dinâmicas. A ramificação em condições dinâmicas também é conhecida como ramificação baseada em resultados de medição.

    let dynamicInt = r0 == Zero ? 0 | 1; 
    if dynamicInt > 0 {
        X(q1);
     }
    let staticInt = 1;
    if staticInt > 5 {
         Y(q1);
    } else {
         Z(q1);
    }

Quantinuum suporta loops com condições clássicas e incluindo if expressões.

    for idx in 0..3 {
        if idx % 2 == 0 {
            Rx(ArcSin(1.), q0);
            Rz(IntAsDouble(idx) * PI(), q1)
        } else {
            Ry(ArcCos(-1.), q1);
             Rz(IntAsDouble(idx) * PI(), q1)
        }
     }

O Quantinuum suporta medição de circuito médio, ou seja, ramificação com base nos resultados da medição.

    if r0 == One {
        X(q1);
    }
    let r1 = MResetZ(q1);
    if r0 != r1 {
        let angle = PI() + PI() + PI()* Sin(PI()/2.0);
        Rxx(angle, q0, q1);
    } else {
        Rxx(PI() + PI() + 2.0 * PI() * Sin(PI()/2.0), q1, q0);
    }

Estimar o custo de um trabalho de computação quântica híbrida

Você pode estimar o custo para executar um trabalho de computação quântica híbrida no hardware Quantinuum executando o trabalho em um emulador primeiro.

Após uma execução bem-sucedida no emulador:

  1. No espaço de trabalho do Azure Quantum, selecione Gerenciamento de tarefas.
  2. Selecione o trabalho enviado.
  3. No popup Detalhes do trabalho, selecione Estimativa de custo para visualizar quantos eHQCs (créditos do emulador Quantinuum) foram usados. Esse número se traduz diretamente no número de HQCs (créditos quânticos Quantinuum) necessários para executar o trabalho no hardware Quantinuum.

Estimativa de custos

Nota

O Quantinuum desenrola todo o circuito e calcula o custo em todos os caminhos de código, sejam eles executados condicionalmente ou não.

Amostras de computação quântica híbrida

Os exemplos a seguir podem ser encontrados no repositórioQ# código. Eles demonstram o conjunto de recursos atual para a computação quântica híbrida.

Código de repetição de três qubits

Este exemplo demonstra como criar um código de três qubits de repetição que pode ser usado para detetar e corrigir erros de inversão de bits.

Ele aproveita recursos de computação híbrida integrada para contar o número de vezes que a correção de erros foi executada enquanto o estado de um registro de qubit lógico é coerente.

Você pode encontrar o código neste exemplo.

Estimativa iterativa da fase

Este programa de exemplo demonstra uma estimativa de fase iterativa dentro do Q#. Ele usa estimativa de fase iterativa para calcular um produto interno entre dois vetores bidimensionais codificados em um qubit target e um qubit auxiliar. Um qubit de controle adicional também é inicializado, que é o único qubit usado para medição.

O circuito começa por codificar o par de vetores no qubit target e no qubit ancilla. Em seguida, ele aplica um operador Oracle a todo o registro, controlado pelo qubit de controle, que é configurado no estado $\ket +$. O operador Oracle controlado gera uma fase no estado $\ket 1$ do qubit de controle. Isso pode ser lido aplicando uma porta H ao qubit de controle para tornar a fase observável durante a medição.

Você pode encontrar o código neste exemplo.

Nota

Este código de exemplo foi escrito por membros da equipe KPMG Quantum na Austrália e se enquadra em uma licença MIT. Ele demonstra as capacidades expandidas de Adaptive RItargets e faz uso de loops limitados, chamadas de funções clássicas em tempo de execução, estruturas condicionais 'if' aninhadas, medições no meio do circuito e reutilização de qubits.