Condividi tramite


Introduzione al linguaggio di programmazione quantistica Q#

Q# è un linguaggio di programmazione open source open source sviluppato da Microsoft per la scrittura di programmi quantistici. Q# è incluso in Quantum Development Kit (QDK). Per altre informazioni, vedere Configurare Quantum Development Kit.

Come linguaggio di programmazione quantistico, Q# soddisfa i requisiti seguenti per il linguaggio, il compilatore e il runtime:

  • Indipendente dall'hardware: i qubit negli algoritmi quantistici non sono associati a un hardware quantistico o a un layout specifico. Il compilatore e il runtime Q# gestiscono il mapping dai qubit del programma ai qubit fisici, consentendo l'esecuzione dello stesso codice in processori quantistici diversi.
  • L'integrazione del calcolo quantistico e classico:Q# consente l'integrazione di calcoli quantistici e classici, essenziali per il calcolo quantistico universale.
  • la gestione dei qubit:Q# fornisce operazioni e funzioni predefinite per la gestione dei qubit, tra cui la creazione di stati di sovrapposizione, l'entanglement dei qubit e l'esecuzione di misurazioni quantistiche.
  • Rispettare le leggi della fisica:Q# e algoritmi quantistici devono seguire le regole della fisica quantistica. Ad esempio, non è possibile copiare o accedere direttamente allo stato del qubit in Q#.

Per altre informazioni sulle origini di Q#, vedere il post di blog Perché è necessario Q#?.

Struttura di un Q# programma

Prima di iniziare a scrivere programmi Q#, è importante comprendere la struttura e i componenti. Si consideri il programma di Q# seguente, denominato sovrapposizione, che crea uno stato di sovrapposizione:

namespace Superposition {
    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit. By default, it's in the 0 state.  
        use q = Qubit();  
        // Apply the Hadamard operation, H, to the state.
        // It now has a 50% chance of being measured as 0 or 1.
        H(q);      
        // Measure the qubit in the Z-basis.
        let result = M(q);
        // Reset the qubit before releasing it.
        Reset(q);
        // Return the result of the measurement.
        return result;
    }
}

In base ai commenti (//), il Q# programma alloca prima un qubit, applica un'operazione per inserire il qubit in sovrapposizione, misura lo stato del qubit, reimposta il qubit e infine restituisce il risultato.

Analizziamo questo programma Q# nei suoi componenti.

Spazi dei nomi utente

Q# programmi possono opzionalmente iniziare con un namespace definito dall'utente, come:

namespace Superposition {
    // Your code goes here.
}

I namespace consentono di organizzare le funzionalità correlate. Gli spazi dei nomi sono facoltativi nei programmi Q#, ovvero è possibile scrivere un programma senza definire uno spazio dei nomi.

Ad esempio, il sovrapposizione programma dell'esempio può essere scritto anche senza uno spazio dei nomi come:

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit. By default, it's in the 0 state.  
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1.
    H(q);      
    // Measure the qubit in the Z-basis.
    let result = M(q);
    // Reset the qubit before releasing it.
    Reset(q);
    // Return the result of the measurement.
    return result;
}

Nota

Ogni Q# programma può avere un solo namespace. Se non si specifica uno spazio dei nomi, il compilatore Q# usa il nome file come spazio dei nomi.

Punti di ingresso

Ogni Q# programma deve avere un punto di ingresso, ovvero il punto di partenza del programma. Per impostazione predefinita, il compilatore avvia l'esecuzione del programma Q# dall'operazione Main(), se disponibile, che può trovarsi in qualsiasi punto del programma. Facoltativamente, è possibile usare l'attributo @EntryPoint() per specificare qualsiasi operazione nel programma come punto di esecuzione.

Ad esempio, nel programma sovrapposizione, l'operazione MeasureOneQubit() è il punto di ingresso del programma perché ha l'attributo @EntryPoint() prima della definizione dell'operazione:

@EntryPoint()
operation MeasureOneQubit() : Result {
    ...
}

Tuttavia, il programma può anche essere scritto senza l'attributo @EntryPoint() rinominando l'operazione di MeasureOneQubit() per Main(), ad esempio:

// The Q# compiler automatically detects the Main() operation as the entry point. 

operation Main() : Result {
    // Allocate a qubit. By default, it's in the 0 state.  
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1.
    H(q);      
    // Measure the qubit in the Z-basis.
    let result = M(q);
    // Reset the qubit before releasing it.
    Reset(q);
    // Return the result of the measurement.
    return result;
}

Tipi

I tipi sono essenziali in qualsiasi linguaggio di programmazione perché definiscono i dati che un programma può usare. Q# fornisce tipi predefiniti comuni alla maggior parte dei linguaggi, tra cui Int, Double, Boole Stringe tipi che definiscono intervalli, matrici e tuple.

Q# fornisce anche tipi specifici del calcolo quantistico. Ad esempio, il tipo di Result rappresenta il risultato di una misura qubit e può avere due valori: Zero o One.

Nel programma sovrapposizione, l'operazione MeasureOneQubit() restituisce un tipo Result, che corrisponde al tipo restituito dell'operazione M. Il risultato della misurazione viene archiviato in una nuova variabile definita usando l'istruzione let :

// The operation definition returns a Result type.
operation MeasureOneQubit() : Result {
    ...
    // Measure the qubit in the Z-basis, returning a Result type.
    let result = M(q);
    ...
}

Un altro esempio di tipo specifico del quantum è il tipo Qubit, che rappresenta un bit quantistico.

Q# consente anche di definire tipi personalizzati. Per altre informazioni, vedere dichiarazioni di tipo .

Allocazione di qubit

In Q#, allocare i qubit usando la parola chiave use e il tipo Qubit. I qubit vengono sempre allocati nello $\ket{0}$ stato .

Ad esempio, il programma sovrapposizione definisce un singolo qubit e lo archivia nella variabile q:

// Allocate a qubit.
use q = Qubit();

È anche possibile allocare più qubit e accedervi tramite il relativo indice:

use qubits = Qubit[2]; // Allocate two qubits.
H(qubits[0]); // Apply H to the first qubit.
X(qubits[1]); // Apply X to the second qubit.

Operazioni quantistiche

Dopo aver allocato un qubit, è possibile passarlo alle operazioni e alle funzioni. Le operazioni sono i blocchi predefiniti di base di un programma Q#. Un'operazione Q# è una subroutine quantistica o una routine chiamabile che contiene operazioni quantistico che modificano lo stato del registro qubit.

Per definire un'operazione Q# , specificare un nome per l'operazione, i relativi input e il relativo output. Nel programma sovrapposizione, l'operazione di MeasureOneQubit() non accetta parametri e restituisce un tipo di Result:

operation MeasureOneQubit() : Result {
    ...
}

Di seguito è riportato un esempio di base che non accetta parametri e non prevede alcun valore restituito. Il Unit valore è equivalente a NULL in altre lingue:

operation SayHelloQ() : Unit {
    Message("Hello quantum world!");
}

La Q# libreria standard fornisce anche operazioni che è possibile usare nei programmi quantistici, ad esempio l'operazione Hadamard, H, nel Superposition programma. Dato un qubit sulla base Z, H inserisce il qubit in una sovrapposizione uniforme, dove ha una probabilità del 50% di essere misurata come Zero o One.

Misurazione dei qubit

Anche se esistono molti tipi di misurazioni quantistiche, Q# si concentra sulle misurazioni proiettate su singoli qubit, note anche come misurazioni Pauli.

In Q#l'operazione Measure misura uno o più qubit nella base Pauli specificata, che può essere PauliX, PauliYo PauliZ. Measure restituisce un Result tipo di Zero o One.

Per implementare una misura nella base $computazionale \lbrace\ket{0},\ket{1}\rbrace$, è anche possibile usare l'operazione M , che misura un qubit in base a Pauli Z. Ciò equivale M a Measure([PauliZ], [qubit]).

Ad esempio, il programma sovrapposizione usa l'operazione M.

// Measure the qubit in the Z-basis.
let result = M(q);

Reimpostazione dei qubit

In Q#i qubit devono nello stato $\ket{0}$ quando vengono rilasciati per evitare errori nell'hardware quantistico. È possibile reimpostare un qubit sullo stato $\ket{0}$ usando l'operazione di Reset alla fine del programma. Il mancato ripristino di un qubit genera un errore di runtime.

// Reset a qubit.
Reset(q);

Spazi dei nomi della libreria standard

La Q# libreria standard include spazi dei nomi predefiniti che contengono funzioni e operazioni che è possibile usare nei programmi quantistici. Ad esempio, lo Microsoft.Quantum.Intrinsic spazio dei nomi contiene funzioni e operazioni di uso comune, ad esempio M per misurare i risultati e Message per visualizzare i messaggi utente in qualsiasi punto del programma.

Per chiamare una funzione o un'operazione, è possibile specificare lo spazio dei nomi completo o usare un'istruzione import , che rende disponibili tutte le funzioni e le operazioni per tale spazio dei nomi e rende il codice più leggibile. Gli esempi seguenti chiamano la stessa operazione:

Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
// imports all functions and operations from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.*;
Message("Hello quantum world!");

// imports just the `Message` function from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.Message;
Message("Hello quantum world!");
// namespaces in the standard library may be imported using `Std` instead of `Microsoft.Quantum`. 
import Std.Intrinsic.*;
Message("Hello quantum world!");

Nota

Il programma sovrapposizione non include istruzioni import o chiamate con spazi dei nomi completi. Questo perché l'ambiente Q# di sviluppo carica automaticamente due spazi dei nomi: Microsoft.Quantum.Core e Microsoft.Quantum.Intrinsic, che contengono funzioni e operazioni comunemente usate.

È possibile utilizzare lo spazio dei nomi Microsoft.Quantum.Measurement usando l'operazione MResetZ per ottimizzare il programma di sovrapposizione. MResetZ combina le operazioni di misurazione e reimpostazione in un unico passaggio, come nell'esempio seguente:

// Import the namespace for the MResetZ operation.
import Microsoft.Quantum.Measurement.*;

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit. By default, it's in the 0 state.      
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1. 
    H(q);   
    // Measure and reset the qubit, and then return the result value.
    return MResetZ(q);
}

Informazioni su come sviluppare programmi quantistici con Q# e Azure Quantum

Q# e Azure Quantum sono una combinazione potente per lo sviluppo e l'esecuzione di programmi quantistici. Con Q# e Azure Quantum è possibile scrivere programmi quantistici, simularne il comportamento, stimare i requisiti delle risorse ed eseguirli su hardware quantistico reale. Questa integrazione consente di esplorare il potenziale del calcolo quantistico e sviluppare soluzioni innovative per problemi complessi. Che tu sia un principiante o uno sviluppatore quantistico esperto, Q#, Azure Quantum fornisce gli strumenti e le risorse necessari per sbloccare la potenza del calcolo quantistico.

Il diagramma seguente illustra le fasi attraverso le quali passa un programma quantistico durante lo sviluppo con Q# e Azure Quantum. Il programma inizia con l'ambiente di sviluppo e termina con l'invio del processo all'hardware quantistico reale.

Diagramma che mostra il flusso di lavoro dello sviluppo di programmazione quantistica.

Di seguito vengono descritti i passaggi del diagramma.

Scegliere l'ambiente di sviluppo in uso

Eseguire i programmi quantistici nell'ambiente di sviluppo preferito. È possibile usare l'editor di codice online nel sito Web di Azure Quantum, i notebook jupyter ospitati nell'area di lavoro di Azure Quantum nel portale di Azure o un ambiente di sviluppo locale con Visual Studio Code. Per altre informazioni, vedere Diversi modi per eseguire Q# i programmi.

Scrivere il programma quantistico

È possibile scrivere programmi quantistici in Q# usando Quantum Development Kit (QDK). Per iniziare, vedere Avvio rapido: Creare il primo Q# programma.

Oltre a Q#, il QDK offre supporto per altri linguaggi per il calcolo quantistico, ad esempio Qiskit e Cirq.

Integrazione con Python

È possibile usare Q# da solo o insieme a Python in vari IDE. Ad esempio, è possibile usare un progetto Q# con un programma host Python per chiamare le operazioni di Q# o integrare Q# con Python in Jupyter Notebooks. Per altre informazioni, vedere integrazione di Q# e Python.

Il comando %%qsharp

Per impostazione predefinita, Q# i programmi in Jupyter Notebook usano il ipykernel pacchetto Python. Per aggiungere Q# codice a una cella del notebook, usare il comando %%qsharp, che è abilitato con il pacchetto Python qsharp, seguito dal codice Q#.

Quando si usa %%qsharp, tenere presente quanto segue:

  • È necessario prima eseguire import qsharp per abilitare %%qsharp.
  • %%qsharp ha come ambito la cella del notebook in cui viene visualizzata e modifica il tipo di cella da Python a Q#.
  • Non è possibile inserire un'istruzione Python prima o dopo %%qsharp.
  • Q# il codice seguente %%qsharp deve essere conforme alla Q# sintassi. Ad esempio, usare // anziché # per indicare i commenti e ; per terminare le righe di codice.

Stimare le risorse

Prima di eseguire su hardware quantistico reale, è necessario determinare se il programma può essere eseguito su hardware esistente e quante risorse utilizzeranno.

Azure Quantum Resource Estimator consente di valutare le decisioni dell'architettura, confrontare le tecnologie qubit e determinare le risorse necessarie per eseguire un determinato algoritmo quantistico. È possibile scegliere tra protocolli a tolleranza di errore predefiniti e specificare presupposti del modello qubit fisico sottostante.

Per altre informazioni, vedere Eseguire la prima stima delle risorse.

Nota

Lo strumento di stima delle risorse di Azure Quantum è gratuito e non richiede un account Azure.

Eseguire il programma nella simulazione

Quando si compila ed esegue un programma quantistico, QDK crea un'istanza del simulatore quantistico e vi passa il Q# codice. Il simulatore usa il codice Q# per creare i qubit (simulazioni di particelle quantistiche) e applicare le trasformazioni per modificarne lo stato. I risultati delle operazioni quantistiche nel simulatore vengono quindi restituiti al programma. L'isolamento del codice Q# nel simulatore garantisce che gli algoritmi seguano le leggi della fisica quantistica e possano essere eseguiti correttamente nei computer quantistici.

Invia il tuo programma all'hardware quantistico reale

Dopo aver testato il programma nella simulazione, è possibile eseguirlo su hardware quantistico reale. Quando si esegue un programma quantistico in Azure Quantum, si crea ed esegue un processo . Per inviare un'attività ai provider di Azure Quantum, è necessario un account Azure e uno spazio di lavoro quantistico. Se non si ha un'area di lavoro quantistica, vedere Creare un'area di lavoro di Azure Quantum.

Azure Quantum offre alcuni degli hardware quantistici più interessanti e diversificati. Vedere Provider di calcolo quantistico per l'elenco corrente dei provider hardware supportati.

Dopo aver inviato il lavoro, Azure Quantum gestisce il ciclo di vita del lavoro, inclusi la pianificazione, l'esecuzione e il monitoraggio. È possibile tenere traccia dello stato del processo e visualizzare i risultati nel portale di Azure Quantum.