Compartilhar via


Execute trabalhos de computação quântica híbrida com 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. Você pode usar técnicas comuns de programação, como condicionais aninhadas, loops e chamadas de função, em um único programa quântico para executar problemas complexos, reduzindo o número de disparos necessários. Com técnicas de reutilização de qubits, 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 QIR Adaptive RItarget perfil. O perfil de RI target adaptável oferece suporte para medições de circuito intermediário, fluxo de controle baseado em medição, redefinição de qubit e computação inteira clássica.

Pré-requisitos

  • Uma conta do Azure com uma assinatura ativa. Se você não tiver uma conta do Azure, registre-se gratuitamente e inscreva-se para uma assinatura paga conforme o uso.
  • Um workspace do Azure Quantum. Para obter mais informações, confira Criar um workspace do Azure Quantum.
  • Se você deseja enviar Q# programas independentes, precisa dos seguintes pré-requisitos:
    • Visual Studio Code com a extensão do Azure Quantum Development Kit instalada.
    • A versão mais recente da extensão do AzureQuantum Development Kit.
  • Se você deseja enviar programas Python + Q# , precisa dos seguintes pré-requisitos:
    • Um ambiente Python com Python e Pip instalados.

    • O Azure Quantum azure-quantum e qsharp os pacotes.

      pip install --upgrade azure-quantum qsharp
      

targets com suporte

Para executar trabalhos de computação quântica híbrida, você precisa selecionar um provedor quântico que dê suporte ao perfil de RI target adaptável.

Atualmente, há suporte para o perfil adaptável target no Azure Quantum no Quantinuumtargets.

Envio de trabalhos de RI adaptável

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

O QIR Adaptive RItarget perfil oferece suporte para medições de circuito intermediário, fluxo de controle baseado em medição, redefinição de qubit e computação inteira clássica.

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

Para configurar o target perfil para trabalhos híbridos no Visual Studio Code, siga estas etapas:

  1. Abra um Q# programa no Visual Studio Code.
  2. Select Exibir -> Paleta de Comandos e digite Q#: Definir o perfil target do QIR do Azure Quantum. Pressione Enter.
  3. Selecione QIR Adaptive RI.

Depois de definir QIR Adaptive RI como target perfil, você pode enviar seu Q# programa como um trabalho quântico híbrido para o Quantinuum.

  1. Selecione Exibir –> Paleta de Comandos e digite Q#: Conectar-se a um workspace do Azure Quantum. Pressione Enter.
  2. Selecione Conta do Azure e siga os prompts para se conectar ao diretório, à assinatura e ao workspace de sua preferência.
  3. Depois de conectado, no painel Explorer , expanda Workspaces do Quantum.
  4. Expanda seu espaço de trabalho e expanda o provedor Quantinuum .
  5. Selecione qualquer Quantinuum disponível target, por exemplo , quantinuum.sim.h1-1e.
  6. Selecione o ícone de reprodução à direita do nome para começar a target enviar o programa atual Q# .
  7. Adicione um nome para identificar o trabalho e o número de fotos.
  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 exibirá os horários e o status do trabalho.

Recursos com suporte

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

Recurso com suporte Observações
Valores dinâmicos Bools e inteiros cujo valor depende de um resultado de medição
Loops Somente loops delimitados classicamente
Fluxo de controle arbitrário Uso da ramificação if/else
Medição de circuito intermediário Utiliza recursos de registro clássicos
Reutilização de qubit Com suporte
Computação clássica em tempo real Aritmética inteira com sinal de 64 bits
Utiliza recursos de registro clássicos

O QDK fornece targetcomentários específicos quando Q# os recursos de linguagem não são compatíveis com o target. Se o Q# programa contiver recursos sem suporte ao executar trabalhos quânticos híbridos, você receberá uma mensagem de erro em tempo de design. Para obter mais informações, consulte a página wiki do QIR.

Observação

Você precisa selecionar o perfil apropriado QIR Adaptive RItarget para obter comentários apropriados ao usar Q# recursos que target não dão suporte.

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

import Microsoft.Quantum.Measurement.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.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
}

O Quantinuum suporta bools e inteiros dinâmicos, o que significa bools e inteiros que dependem dos resultados da medição. Observe que r0 é um Result tipo que pode ser usado para gerar valores booleanos e inteiros dinâmicos.

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

O Quantinuum suporta bools e inteiros dinâmicos, no entanto, não suporta valores dinâmicos para outros tipos de dados, como double. 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 os valores dinâmicos de tipagem com suporte não podem ser usados em determinadas situações. Por exemplo, o Quantinuum não oferece suporte a matrizes dinâmicas, ou seja, matrizes cujo tamanho depende de um resultado de medição. O Quantinuum também não oferece suporte a 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);  
        }

O Quantinuum suporta fluxo de controle, incluindo 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 com base nos resultados da medição.

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

O 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 intermediário, 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);
        }

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

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

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

  1. No workspace do Azure Quantum, selecione Gerenciamento de trabalhos.
  2. Selecione o trabalho que você enviou.
  3. No pop-up Detalhes do trabalho , selecione Estimativa de custo para exibir quantos eHQCs (créditos do emulador Quantinuum) foram usados. Esse número se traduz diretamente no número de HQCs (créditos quânticos do Quantinuum) necessários para executar o trabalho no hardware do Quantinuum.

Estimativa de custo

Observação

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

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

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

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

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

Ele aproveita os recursos de computação híbrida integrados 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 exemplo de código aqui.

Estimativa de fase iterativa

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

O circuito começa codificando o par de vetores no qubit e no target 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 exemplo de código aqui.

Observação

Este código de exemplo foi escrito por membros da equipe KPMG Quantum na Austrália e está sob uma licença do MIT. Ele demonstra recursos QIR Adaptive RItargets expandidos e faz uso de loops limitados, chamadas de função clássicas em tempo de execução, instruções if condicionais aninhadas, medições de circuito intermediário e reutilização de qubit.