Novidades no QDK Moderno (Kit de Desenvolvimento do Azure Quantum)

O QDK Moderno é a versão mais recente das ferramentas de desenvolvimento e linguagem Q#. Com um volume menor e um desempenho mais rápido, é uma extensão de Visual Studio Code com um clique e apresenta aprimoramentos de linguagem, suporte integrado ao Python e Jupyter Notebook, realce de nova sintaxe, suporte ao depurador, suporte a projeto de vários arquivos, mensagens de erro e conectividade integrada do Azure. Ao eliminar as dependências do QDK clássico anterior, ele agora é verdadeiramente independente de plataforma, em execução no Windows, Mac, Linux e na Web.

Integração do Visual Studio Code

O QDK moderno é totalmente integrado ao ambiente de desenvolvimento Visual Studio Code. Os novos recursos incluem:

  • Um novo Avaliador de Recursos para VS Code que você pode executar localmente sem a necessidade de uma conta do Azure
  • Um depurador do Q# para depuração integrada com pontos de interrupção, etapas e exibição de variáveis locais e quânticas
  • Suporte para projetos Q# de vários arquivos
  • Melhorias no servidor de linguagem com mensagens de erro, realce de sintaxe, conclusões de código, informações de foco e ir para definições
  • Conectividade integrada do workspace do Azure e envio de trabalho
  • Um simulador interno esparso (sem ruído)
  • Jupyter Notebook integração com codificação Q# em células e realce de sintaxe
  • Geração de QIR para programas Q#

Em breve

  • A computação híbrida integrada com perfil adaptável ainda não tem suporte com o QDK Moderno. Se você precisar executar projetos de computação híbrida, confira Continuar trabalhando no QDK Clássico.

Recursos preteridos

Atualizações de linguagem Q#

À medida que as descobertas quânticas e as inovações continuam evoluindo rapidamente, a linguagem Q# e o Kit de Desenvolvimento do Azure Quantum continuam evoluindo para atender às necessidades atuais e futuras de desenvolvimento quântico. As seções a seguir descrevem as alterações, as atualizações e os aprimoramentos no QDK Moderno.

Atualizações de sintaxe de linguagem

Baseado em expressão

A linguagem Q# agora é baseada em expressão em vez de baseada em instrução. Isso permite o novo uso da sintaxe existente, como a inserção de uma expressão if em outra expressão:

let x = if check { 0 } else { 1 };

Retorno implícito

O exemplo anterior também aproveita o uso de instruções sem um ponto e vírgula à direita no final de um bloco para retornar um valor desse bloco. Esse padrão pode ser usado em vez de expressões de retorno explícitas em um callable:

function ReturnsThree() : Int {
    return 3;
}

function AlsoReturnsThree() : Int {
    3
}

Expressões de bloco

O Q# agora dá suporte a expressões de bloco que podem organizar várias linhas, variáveis de escopo e retornar um valor:

let flip = {
    use q = Qubit();
    H(q);
    if M(q) == One {
        X(q);
        "Heads"
    } else {
        "Tails"
    }
} ;

Itens como instruções

Itens como newtype, operationfunction e até agora open podem aparecer como instruções dentro de um escopo local. Isso permite a definição de tipos auxiliares locais e callables, bem como inclusões com escopo. Por exemplo, uma função auxiliar local pode ser definida pouco antes de ser necessária:

function ShowDecrement() : Unit {
    open Microsoft.Quantum.Arrays;
    let before = [1, 2, 3];

    function SubOne(in : Int) : Int {
        in - 1
    }

    let after = Mapped(SubOne, before);
    // after will be [0, 1, 2]
}

A função SubOne e a abertura do Microsoft.Quantum.Arrays namespace têm como escopo a função e não afetam o ShowDecrement código fora dela.

Sombreamento de nome

O Q# agora permite sombreamento de nomes resolvidos em que isso foi permitido anteriormente. Isso permite a reutilização mais fácil do código que inclui nomes variáveis ou chamáveis sem a necessidade de uma variável mutável:

function Shadowing(input : Int) : Double {
    let input = 2 * input;
    let output = Calculate(input);
    let output = IntAsDouble(output);
    return output;
}

Tipos explícitos para variáveis locais

As variáveis locais agora podem ser digitados explicitamente usando a mesma sintaxe que os tipos para declarações de argumento chamáveis:

let x : Int[] = [];

Tipos explícitos não são necessários, mas às vezes podem ser úteis ao resolver a ambiguidade de tipo para funções que aceitam genéricos, como Length. Não há mais suporte para o padrão anterior para lidar com isso , adicionando tipos concretos a uma invocação de função genérica com sintaxe como Length<Int[]>([]); .

Prelúdio de namespace implícito

A resolução de nomes agora incorpora um prelúdio implícito que é um conjunto de namespaces que são tratados como se tivessem sido abertos, desde que nenhum outro nome resolvido os substitua. Os namespaces tratados dessa maneira são Microsoft.Quantum.Core, Microsoft.Quantum.Canone Microsoft.Quantum.Intrinsic. Eles não precisam ser abertos explicitamente, exceto ao usar aliases ou diferenciar-se de possíveis conflitos.

Biblioteca padrão

A biblioteca padrão do Q# agora está hospedada no mesmo repositório que o compilador e o runtime e pode ser encontrada na pasta de biblioteca de nível superior. Nem todas as funcionalidades e recursos foram migrados das bibliotecas clássicas do Q#, que ainda podem ser acessadas em https://github.com/microsoft/QuantumLibraries. Se um item da biblioteca anterior for necessário para um programa, esse item e quaisquer dependências poderão ser copiados para o programa de origem. Se qualquer funcionalidade de biblioteca for essencial para um fluxo de trabalho e deve ser considerada para inclusão na nova biblioteca padrão, registre um problema do GitHub com os detalhes.

Simulação

Simulação esparsa por padrão

O QDK moderno usa um simulador quântico de estado esparso interno como o padrão target para simulação local. Esse simulador é escrito no Rust e vem do repositório qir runner , permitindo que ele seja compilado para WASM e executado em vários ambientes. Atualmente, esse é o único back-end de simulação disponível no QDK, embora outros back-ends estejam em consideração para integração futura. Para obter mais informações sobre o design de simulação esparsa, consulte Testando algoritmos quânticos grandes usando simulação esparsa.

Verificações mais rigorosas na versão do qubit

O QDK Clássico historicamente flexibilizou a exigência de que os qubits estejam no solo ou no estado |0⟩ antes de serem liberados no final de seu escopo, de modo que um qubit que tenha sido medido e não operado em nenhum outro estado também fosse seguro de liberar, pois o simulador redefiniria automaticamente o qubit. No entanto, isso causou confusão quando o mesmo programa foi executado em hardware quântico real em que tal redefinição automática não está presente e qubits podem ser reutilizados em um estado inesperado. Para o QDK Moderno, retornamos ao comportamento mais rigoroso de impor que os qubits são necessários para estar no estado de base na versão. Isso ajuda os autores de algoritmo a verificar o comportamento de seu algoritmo para correção na preparação para execução no hardware.

Portões multicontrolados decompostos

O QDK Moderno agora usa estratégias de decomposição para portões multicontrolado. Embora isso não aproveite os atalhos disponíveis para simulação em que portões multicontrolados são facilmente implementados, ele corresponde mais de perto ao comportamento de sistemas quânticos físicos. Isso significa que executar uma porta com um grande número de qubits de controle incorrerá em alocações de qubit adicionais e portões de preparação, da mesma forma que faria quando compilado para execução no hardware. Para obter mais detalhes sobre os algoritmos de decomposição usados, consulte a implementação na biblioteca padrão.

Geração de QIR

O QDK moderno produz QIR gerando a representação textual de LLVM (.ll) em vez de usar bitcode (.bc). A maioria das targets ferramentas e que aceitam bitcode também podem analisar LLVM textual, incluindo ferramentas como PyQIR e QIR Runner.

Atualmente, o QDK Moderno está limitado à geração de QIR para programas compatíveis com o Perfil Base do QIR. Quando a compilação de Perfil Base é configurada, o compilador e a extensão VSCode produzem erros para padrões que não são compatíveis com o target. O compilador também pode ignorar condicionalmente a compilação de itens que têm atributos que indicam que eles são específicos para uma compilação targetsespecífica:

@Config(Unrestricted)
function ResultAsBool(input : Result) : Bool {
    input == One
}