Come creare e gestire Q# progetti e librerie personalizzate
Questo articolo illustra come creare, gestire e condividere Q# progetti. Q# i progetti sono strutture di cartelle con più Q# file che possono accedere tra loro operazioni e funzioni. I progetti sono utili per organizzare logicamente il codice sorgente. È anche possibile usare progetti come librerie personalizzate a cui è possibile accedere da origini esterne.
Prerequisiti
- Un'area di lavoro di Azure Quantum nella sottoscrizione di Azure. Per creare un'area di lavoro, vedere Creare un'area di lavoro di Azure Quantum.
- Visual Studio Code con l'estensione Azure Quantum Development Kit e Python installata.
- Un account GitHub, se si prevede di pubblicare il progetto esterno in un repository GitHub pubblico.
Per l'esecuzione di programmi Python, è anche necessario:
- Un ambiente Python con Python e Pip installati.
- Azure Quantum
qsharp
eazure-quantum
i pacchetti.
Funzionamento Q# dei progetti
Un Q# progetto contiene un Q# file manifesto, denominato qsharp.json e uno o più file *.qs in una struttura di cartelle specificata. Quando un utente apre un file *.qs in VS Code o imposta project_root
in un file Jupyter Notebook o Python, il compilatore cerca il file manifesto nella gerarchia di cartelle circostanti e determina l'ambito del progetto. Se non viene trovato alcun file manifesto, il compilatore opera in una singola modalità file. È possibile creare un Q# progetto manualmente o direttamente in VS Code.
Un progetto esterno Q# è un progetto standard Q# che risiede in un'altra directory o in un repository GitHub pubblico e funge da libreria personalizzata. Un progetto esterno usa istruzioni export
per definire quali funzioni e operazioni possono essere accessibili da programmi esterni. I programmi definiscono il progetto esterno come dipendenza nel file manifesto e usano import
istruzioni per accedere agli elementi (operazioni, funzioni, struct e spazi dei nomi) nel progetto esterno. Per altre informazioni, vedere Uso di progetti come dipendenze esterne.
Definire un Q# progetto
Un Q# progetto è definito dalla presenza di un file manifesto, denominato qsharp.json, e una cartella src (che contiene i Q# file di origine), entrambi devono trovarsi nella cartella radice del progetto. Per Q# i programmi e i progetti esterni, il Q# compilatore rileva automaticamente la cartella del progetto. Per i programmi Python e Jupyter Notebook, è necessario specificare la cartella del Q# progetto con una qsharp.init
chiamata. La struttura di cartelle per un Q# progetto rimane tuttavia la stessa per tutti i tipi di programmi.
Definizione della cartella del progetto (Q# programmi)
Quando un file *.qs viene aperto in VS Code, il Q# compilatore cerca verso l'alto nella struttura di cartelle un file manifesto. Se trova un file manifesto, il compilatore include tutti i Q# file nella directory /src o in una delle relative sottodirectory. Gli elementi di ogni file vengono resi disponibili per tutti gli altri file all'interno del progetto.
Ad esempio, data questa struttura di cartelle:
- Teleportation_project
- qsharp.json
- src
- Main.qs
- TeleportOperations
- TeleportLib.qs
- PrepareState
- PrepareStateLib.qs
quando si apre il file /src/TeleportOperation/PrepareState/PrepareStateLib.qs, il Q# compilatore:
- Controlla /src/TeleportOperation/PrepareState/ per qsharp.json.
- Controlla /src/TeleportOperation per qsharp.json.
- Controlla /src per qsharp.json.
- Verifica la presenza di / qsharp.json.
- / Stabilisce come directory radice del progetto e include tutti i file *.qs nella radice del progetto, in base alle impostazioni del file manifesto.
Creare un file manifesto
Un file manifesto è un semplice file .json denominato qsharp.json che può includere facoltativamente campi autore, licenza e lints . Il file manifesto minimo praticabile è la stringa {}
. Quando si crea un Q# progetto in VS Code, viene creato automaticamente un file manifesto minimo.
{}
Esempi di file manifesto
Di seguito sono riportati alcuni esempi di come i file manifesto possono definire l'ambito del Q# progetto.
In questo esempio, author è l'unico campo specificato e quindi tutti i file *.qs in questa directory e tutte le relative sottodirectory sono incluse nel Q# progetto.
{ "author":"Microsoft", "license": "MIT" }
All'interno di un Q# progetto, è anche possibile usare il file manifesto per ottimizzare le impostazioni Linter di VS Code Q# . Per impostazione predefinita, le tre regole Linter sono:
needlessParens
: default =allow
divisionByZero
: default =warn
redundantSemicolons
: default =warn
Usando il file manifesto, è possibile impostare ogni regola su
allow
,warn
oerror
, ad esempio{ "author":"Microsoft", "lints": [ { "lint": "needlessParens", "level": "allow" }, { "lint": "redundantSemicolons", "level": "warn" }, { "lint": "divisionByZero", "level": "error" } ] }
È anche possibile usare il file manifesto per definire un progetto esterno Q# come dipendenza e accedere in remoto a operazioni e funzioni in tale progetto esterno. Per altre informazioni, vedere Uso di progetti come dipendenze esterne.
Q# requisiti e proprietà del progetto
I requisiti e le configurazioni seguenti si applicano a tutti i Q# progetti.
Tutti i file *.qs che si desidera includere nel progetto devono trovarsi in una cartella denominata src, che deve trovarsi nella cartella radice di Q#. Quando si crea un Q# progetto in VS Code, la
/src
cartella viene creata automaticamente.Il file manifesto deve essere allo stesso livello della cartella src . Quando si crea un Q# progetto in VS Code, viene creato automaticamente un file minimo.
Usare
import
istruzioni per fare riferimento a operazioni e funzioni di altri file nel progetto.import MyMathLib.*; //imports all the callables in the MyMathLib namespace ... Multiply(x,y);
o farvi riferimento singolarmente con lo spazio dei nomi
MyMathLib.Multiply(x,y);
Solo per Q# i progetti
- Un solo file *.qs in un Q# progetto può avere un punto di ingresso definito, definito da una singola
Main()
operazione. - Il file *.qs con la definizione del punto di ingresso può trovarsi a qualsiasi livello al di sotto del file manifesto.
- Qualsiasi operazione o funzione memorizzata nella cache da un file *.qs in qualsiasi punto del Q# progetto viene visualizzata nel testo predittivo in VS Code.
- Se lo spazio dei nomi per un'operazione o una funzione selezionata non è ancora importato, VS Code aggiunge automaticamente l'istruzione necessaria
import
.
Passaggi per la creazione di un Q# progetto
Questi passaggi si applicano a tutti i Q# progetti.
In Esplora file di VS Code fare clic con il pulsante destro del mouse sulla cartella che si vuole usare per la cartella radice del Q# progetto e selezionare Crea Q# progetto oppure aprire la cartella e selezionare Visualizza > riquadro comandi >Q#: Crea un Q# progetto....
VS Code crea un file manifesto minimo nella cartella e aggiunge una
/src
cartella con unMain.qs
file modello.Modificare il file manifesto in base alle esigenze. Vedere Esempi di file manifesto.
Aggiungere e organizzare i Q# file di origine nella
/src
cartella .Se si accede al Q# progetto da un programma Python o da Jupyter Notebook, impostare il percorso della cartella radice usando
qsharp.init
. Questo esempio presuppone che il programma si trova nella cartella /src del Q# progetto:qsharp.init(project_root = '../Teleportation_project')
Se si usano solo Q# file in VS Code, quando si apre un Q# file, il compilatore cerca un file manifesto, determina la cartella radice del progetto e quindi analizza la sottocartella per i file *.qs.
Nota
È anche possibile creare manualmente il file manifesto e la /src
cartella nel passaggio 2.
Progetto di esempio
Questo programma di teletrasportazione quantistica è un esempio di progetto Q# basato sulla struttura a cartella singola illustrata in precedenza e viene eseguito nel simulatore locale in VS Code. Per eseguire il programma su hardware Azure Quantum o simulatori di terze parti, vedere Introduzione ai Q# programmi e VSCode per la procedura per compilare il programma e connettersi all'area di lavoro di Azure.
L'esempio usa questa struttura di directory:
- Teleportation_project
- qsharp.json
- src
- Main.qs
- TeleportOperations
- TeleportLib.qs
- PrepareState
- PrepareStateLib.qs
Il file manifesto contiene i campi autore e licenza :
{
"author":"Microsoft",
"license":"MIT"
}
Q# file di origine
Il file principale Main.qs contiene il punto di ingresso e fa riferimento allo TeleportOperations.TeleportLib
spazio dei nomi da TeleportLib.qs.
import TeleportOperations.TeleportLib.Teleport; // references the Teleport operation from TeleportLib.qs
operation Main() : Unit {
use msg = Qubit();
use target = Qubit();
H(msg);
Teleport(msg, target); // calls the Teleport() operation from TeleportLib.qs
H(target);
if M(target) == Zero {
Message("Teleported successfully!");
Reset(msg);
Reset(target);
}
}
TeleportLib.qs definisce l'operazione Teleport()
e chiama l'operazione PrepareBellPair()
da PrepareStateLib.qs.
import TeleportOperations.PrepareState.PrepareStateLib.*; // references the namespace in PrepareStateLib.qs
operation Teleport(msg : Qubit, target : Qubit) : Unit {
use here = Qubit();
PrepareBellPair(here, target); // calls the PrepareBellPair() operation from PrepareStateLib.qs
Adjoint PrepareBellPair(msg, here);
if M(msg) == One { Z(target); }
if M(here) == One { X(target); }
Reset(here);
}
Il file PrepareStateLib.qs contiene un'operazione riutilizzabile standard per creare una coppia Bell.
operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
H(left);
CNOT(left, right);
}
Esecuzione dei programmi
Selezionare la scheda per l'ambiente in cui si esegue il programma.
- Esecuzione di un Q# programma
- Esecuzione di un notebook di Jupyter
- Esecuzione di un programma Python
Per eseguire questo programma, aprire il file Main.qs in VS Code e selezionare Esegui.
Configurazione di Q# progetti come dipendenze esterne
Un Q# progetto può anche essere configurato come dipendenza esterna per altri progetti, come una libreria, in cui le funzioni e le operazioni nel progetto esterno Q# vengono rese disponibili a più Q# progetti. Una dipendenza esterna può risiedere in una condivisione di unità o pubblicata in un repository GitHub pubblico.
Per usare un Q# progetto come dipendenza esterna, è necessario:
- Aggiungere il progetto esterno come dipendenza nel file manifesto del progetto chiamante.
- Se il progetto esterno viene pubblicato in GitHub, aggiungere la proprietà "files" al file manifesto del progetto esterno.
- Aggiungere
export
istruzioni al progetto esterno. - Aggiungere
import
istruzioni al progetto chiamante.
Configurazione dei file manifesto
I progetti esterni Q# possono risiedere in una condivisione di unità di rete o locale o pubblicata in un repository GitHub pubblico.
File manifesto del progetto chiamante
Per aggiungere una dipendenza a un progetto esterno in una condivisione di unità, definire la dipendenza nel file manifesto del progetto chiamante.
{
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"MyDependency": {
"path": "/path/to/project/folder/on/disk"
}
}
}
dove "MyDependency" è una stringa definita dall'utente che identifica lo spazio dei nomi quando si chiama un'operazione. Ad esempio, se si crea una dipendenza denominata "MyMathFunctions", si chiamerebbe una funzione da tale dipendenza con MyMathFunctions.MyFunction()
.
Per aggiungere una dipendenza a un progetto pubblicato in un repository GitHub pubblico
{
"author": "Microsoft",
"dependencies": {
"MyDependency": {
"github": {
"owner": "GitHubUser",
"repo": "GitHubRepoName",
"ref": "CommitHash",
"path": "/path/to/dependency"
}
}
}
Nota
Per le dipendenze di GitHub, "ref" fa riferimento a un refspec di GitHub. Microsoft consiglia di usare sempre un hash di commit, in modo da poter fare affidamento su una versione specifica della dipendenza.
File manifesto del progetto esterno
Se il progetto esterno Q# viene pubblicato in un repository GitHub pubblico, è necessario aggiungere la proprietà files al file manifesto del progetto esterno, inclusi tutti i file usati nel progetto.
{
"author": "Microsoft",
"license": "MIT",
"files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}
La proprietà "files" è facoltativa per un progetto esterno importato tramite "path"
(ovvero un'importazione basata su filepath locale). È necessario solo per i progetti pubblicati in GitHub.
Uso dell'istruzione export
Per rendere accessibili funzioni e operazioni in un progetto esterno per chiamare i progetti, usare l'istruzione export
. È possibile esportare uno o tutti i chiamabili nel file. La sintassi con caratteri jolly non è supportata, è necessario specificare ogni chiamata da esportare.
operation Operation_A() : Unit {
...
}
operation Operation_B() : Unit {
...
}
// makes just Operation_A available to calling programs
export Operation_A;
// makes Operation_A and Operation_B available to calling programs
export Operation_A, Operation_B, etc.;
// makes Operation_A available as 'OpA'
export Operation_A as OpA;
Uso dell'istruzione import
Dal programma chiamante si usano import
istruzioni per rendere disponibili gli elementi da una dipendenza esterna. import
Le istruzioni usano lo spazio dei nomi definito per la dipendenza nel file manifesto. Ad esempio, per questa dipendenza
{
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"MyMathFunctions": {
"path": "/path/to/project/folder/on/disk"
}
}
}
si importano callable come
import MyMathFunctions.MyFunction; // imports "MyFunction()" from the namespace
...
L'istruzione import
supporta anche la sintassi con caratteri jolly e gli alias
// imports all items from the "MyMathFunctions" namespace
import MyMathFunctions.*;
// imports the namespace as "Math", all items are accessible via "Math.<callable>"
import MyMathFunctions as Math;
// imports a single item, available in the local scope as "Add"
import MyMathFunctions.MyFunction as Add;
// imports can be combined on one line
import MyMathFunctions.MyFunction, MyMathFunctions.AnotherFunction as Multiply;
Nota
L'istruzione attualmente usata in Q#, che viene usata open
per fare riferimento a librerie e spazi dei nomi, è ancora supportata, ma verrà deprecata alla fine. Nel frattempo, è possibile aggiornare facoltativamente i file correnti per usare l'istruzione import
. Ad esempio, open Microsoft.Quantum.Diagnostics;
può essere sostituito da import Microsoft.Quantum.Diagnostics.*;
.
Si noti anche che quando si usa l'istruzione import
con le librerie standard Q# , è possibile abbreviare lo spazio dei nomi radice in Std
. Ad esempio, è possibile scrivere import Microsoft.Quantum.Diagnostics.*;
nel formato import Std.Diagnostics.*;
.
Esempio di progetto esterno
Per questo esempio si userà lo stesso programma di teletrasporto dell'esempio precedente, ma separare il programma chiamante e i chiamabili in progetti diversi.
Creare due cartelle nell'unità locale, ad esempio "Project_A" e "Project_B".
Creare un Q# progetto in ogni cartella seguendo i passaggi descritti in Passaggi per la creazione di un Q# progetto.
In Project_A, il programma chiamante copiare il codice seguente nel file manifesto, modificando il percorso in base alle esigenze per Project_B
{ "author": "Microsoft", "license": "MIT", "dependencies": { "MyTeleportLib": { "path": "/Project_B" } } }
In Project_A copiare il codice seguente in Main.qs
import MyTeleportLib.Teleport; // imports the Teleport operation from the MyTeleportLib namespace defined in the manifest file operation Main() : Unit { use msg = Qubit(); use target = Qubit(); H(msg); Teleport(msg, target); // calls the Teleport() operation from the MyTeleportLib namespace H(target); if M(target) == Zero { Message("Teleported successfully!"); Reset(msg); Reset(target); } }
In Project_B copiare il codice seguente in Main.qs
operation Teleport(msg : Qubit, target : Qubit) : Unit { use here = Qubit(); PrepareBellPair(here, target); Adjoint PrepareBellPair(msg, here); if M(msg) == One { Z(target); } if M(here) == One { X(target); } Reset(here); } operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl { H(left); CNOT(left, right); } export Teleport; // makes the Teleport operation available to external programs
Nota
Si noti che l'operazione
PrepareBellPair
non deve essere esportata perché non viene chiamata direttamente dal programma in Project_A. Poiché si trova nell'ambito locale di Project_B, è già accessibile dall'operazioneTeleport
.Per eseguire il programma, aprire /Project_A/Main.qs in VS Code e selezionare Esegui.
Progetti e spazi dei nomi impliciti
Nei Q# progetti, se uno spazio dei nomi non è specificato in un programma *.qs, il compilatore usa il nome file come spazio dei nomi. Facendo riferimento a un oggetto chiamabile da una dipendenza esterna, viene quindi usata la sintassi <dependencyName>.<spazio dei nomi>.<chiamabile>. Tuttavia, se il file è denominato "Main.qs", il compilatore presuppone lo spazio dei nomi e la sintassi chiamante è <dependencyName>.<chiamabile>, come nell'esempio precedente, import MyTeleportLib.Teleport
.
Poiché non è insolito avere più file di progetto, è necessario tenere conto della sintassi corretta quando si fa riferimento a callables. Ad esempio, in un progetto con la struttura di file seguente
- /Src
- Main.qs
- MathFunctions.qs
le chiamate alla dipendenza esterna sarebbero
import MyTeleportLib.MyFunction; // "Main" namespace is implied
import MyTeleportLib.MathFunctions.MyFunction; // "Math" namespace must be explicit
Per altre informazioni sul comportamento dello spazio dei nomi, vedere Spazi dei nomi utente.