Dela via


Skapa och hantera Q# projekt och anpassade bibliotek

I den här artikeln får du lära dig hur du skapar, hanterar och delar Q# projekt. Q# projekt är mappstrukturer med flera Q# filer som kan komma åt varandras åtgärder och funktioner. Projekt är användbara för att logiskt organisera källkoden. Du kan också använda projekt som anpassade bibliotek som kan nås från externa källor.

Förutsättningar

  • En Azure Quantum-arbetsyta i din Azure-prenumeration. Information om hur du skapar en arbetsyta finns i Skapa en Azure Quantum-arbetsyta.
  • Visual Studio Code med AzureQuantum Development Kit- och Python-tillägget installerat.
  • Ett GitHub-konto om du planerar att publicera ditt externa projekt till en offentlig GitHub-lagringsplats.

För att köra Python-program behöver du också:

  • En Python-miljö med Python och Pip installerade.
  • Azure Quantum qsharp och azure-quantum paket.

Så Q# här fungerar projekt

Ett Q# projekt innehåller en Q# manifestfil med namnet qsharp.json och en eller flera *.qs-filer i en angiven mappstruktur. När en användare öppnar en *.qs-fil i VS Code, eller anger project_root i en Jupyter Notebook- eller Python-fil, söker kompilatorn i den omgivande mapphierarkin efter manifestfilen och avgör projektets omfång. Om ingen manifestfil hittas fungerar kompilatorn i ett enda filläge. Du kan skapa ett Q# projekt manuellt eller direkt i VS Code.

Ett externt Q# projekt är ett standardprojekt Q# som finns i en annan katalog eller på en offentlig GitHub-lagringsplats och fungerar som ett anpassat bibliotek. Ett externt projekt använder export instruktioner för att definiera vilka funktioner och åtgärder som kan nås av externa program. Program definierar det externa projektet som ett beroende i manifestfilen och använder import instruktioner för att komma åt objekten (åtgärder, funktioner, structs och namnområden) i det externa projektet. Mer information finns i Använda projekt som externa beroenden.

Definiera ett Q# projekt

Ett Q# projekt definieras av förekomsten av en manifestfil med namnet qsharp.json och en src-mapp (som innehåller källfilerna Q# ), som båda måste finnas i projektets rotmapp. För Q# program och externa projekt Q# identifierar kompilatorn projektmappen automatiskt. För Python-program och Jupyter Notebooks måste du ange projektmappen Q# med ett qsharp.init anrop. Mappstrukturen för ett Q# projekt är dock densamma för alla typer av program.

Mappstrukturen och hierarkin för ett Q# projekt.

Definiera projektmappen (Q# program)

När en *.qs-fil öppnas i VS Code Q# söker kompilatorn uppåt i mappstrukturen efter en manifestfil. Om den hittar en manifestfil innehåller kompilatorn sedan alla Q# filer i katalogen /src eller någon av dess underkataloger. Varje fils objekt görs tillgängliga för alla andra filer i projektet.

Till exempel med tanke på den här mappstrukturen:

  • Teleportation_project
    • qsharp.json
    • Src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

när du öppnar filen /src/TeleportOperation/PrepareState/PrepareStateLib.qs, Q# kompilatorn:

  1. Kontrollerar /src/TeleportOperation/PrepareState/ för qsharp.json.
  2. Kontrollerar /src/TeleportOperation för qsharp.json.
  3. Kontrollerar /src för qsharp.json.
  4. Söker efter / qsharp.json.
  5. Etablerar / som rotkatalogen för projektet och innehåller alla *.qs-filer under roten i projektet, enligt manifestfilens inställningar.

Skapa en manifestfil

En manifestfil är en enkel .json fil med namnet qsharp.json som kan innehålla fält för författare, licens och lints . Den minsta livskraftiga manifestfilen är strängen {}. När du skapar ett Q# projekt i VS Code skapas en minimal manifestfil åt dig.

{}

Exempel på manifestfil

Följande är några exempel på hur manifestfiler kan definiera projektets Q# omfattning.

  • I det här exemplet är författare det enda angivna fältet, och därför ingår alla *.qs-filer i den här katalogen och alla dess underkataloger i Q# projektet.

    {
        "author":"Microsoft",
        "license": "MIT"
    }
    
  • I ett Q# projekt kan du också använda manifestfilen för att finjustera VS Code Q# Linter-inställningarna. Som standard är de tre Linter-reglerna:

    • needlessParens: default = allow
    • divisionByZero: default = warn
    • redundantSemicolons: default = warn

    Med hjälp av manifestfilen kan du ställa in varje regel på antingen allow, warneller error, till exempel

    {
        "author":"Microsoft",
        "lints": [
            {
              "lint": "needlessParens",
              "level": "allow"
            },
            {
              "lint": "redundantSemicolons",
              "level": "warn"
            },
            {
              "lint": "divisionByZero",
              "level": "error"
            }
          ]
    }
    
  • Du kan också använda manifestfilen för att definiera ett externt Q# projekt som ett beroende och fjärråtkomst till åtgärder och funktioner i det externa projektet. Mer information finns i Använda projekt som externa beroenden.

Q# projektkrav och egenskaper

Följande krav och konfigurationer gäller för alla Q# projekt.

  • Alla *.qs-filer som du vill ska ingå i projektet måste finnas under en mapp med namnet src, som måste finnas under rotmappen i Q#. När du skapar ett Q# projekt i VS Code /src skapas mappen automatiskt.

  • Manifestfilen ska vara på samma nivå som src-mappen . När du skapar ett Q# projekt i VS Code skapas en minimal fil automatiskt.

  • Använd import instruktioner för att referera till åtgärder och funktioner från andra filer i projektet.

    import MyMathLib.*;  //imports all the callables in the MyMathLib namespace
    ...
        Multiply(x,y);
    

    eller refererar till dem individuellt med namnområdet

    MyMathLib.Multiply(x,y);  
    

Endast för Q# projekt

  • Endast en *.qs-fil i ett Q# projekt kan ha en startpunkt definierad, definierad av en enda Main() åtgärd.
  • Filen *.qs med startpunktsdefinitionen kan finnas på valfri nivå under manifestfilen.
  • Alla åtgärder eller funktioner som cachelagras från en *.qs-fil var som helst i Q# projektet visas i förutsägelsetext i VS Code.
  • Om namnområdet för en vald åtgärd eller funktion inte har importerats ännu lägger VS Code automatiskt till den nödvändiga import instruktionen.

Steg för att skapa ett Q# projekt

De här stegen gäller för alla Q# projekt.

  1. I VS Code-utforskaren högerklickar du på den mapp som du vill använda för rotmappen i Q# projektet och väljer Skapa Q# projekt, eller öppnar mappen och väljer Visa > kommandopalett >Q#: Skapa ett Q# projekt....

  2. VS Code skapar en minimal manifestfil i mappen och lägger till en /src mapp med en Main.qs mallfil.

  3. Redigera manifestfilen efter behov. Se Exempel på manifestfil.

  4. Lägg till och organisera källfilerna Q# /src under mappen .

  5. Om du kommer Q# åt projektet från ett Python-program eller Jupyter Notebook anger du sökvägen till rotmappen med hjälp av qsharp.init. Det här exemplet förutsätter att ditt program finns i mappen /src i Q# projektet:

    qsharp.init(project_root = '../Teleportation_project')
    
  6. Om du bara Q# använder filer i VS Code söker kompilatorn efter en manifestfil när du öppnar en Q# fil, fastställer rotmappen för projektet och söker sedan igenom undermappen efter *.qs-filer.

Kommentar

Du kan också skapa manifestfilen och /src mappen manuellt i steg 2.

Exempelprojekt

Det här kvantteleporteringsprogrammet är ett exempel på ett Q# projekt baserat på den enskilda mappstruktur som visades tidigare och körs på den lokala simulatorn i VS Code. Information om hur du kör programmet på Azure Quantum-maskinvara eller tredjepartssimulatorer finns i Kom igång med Q# program och VSCode för steg för att kompilera programmet och ansluta till din Azure-arbetsyta.

I exemplet används den här katalogstrukturen:

  • Teleportation_project
    • qsharp.json
    • Src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

Manifestfilen innehåller fälten författare och licenser :

{
    "author":"Microsoft",
    "license":"MIT"
}

Q# källfiler

Huvudfilen Main.qs innehåller startpunkten och refererar till TeleportOperations.TeleportLib namnområdet från 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 definierar Teleport() åtgärden och anropar PrepareBellPair() åtgärden från 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);
    }

Filen PrepareStateLib.qs innehåller en standardåtgärd som kan återanvändas för att skapa ett Bell-par.

    
    operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
        H(left);
        CNOT(left, right);
    }

Köra programmen

Välj fliken för den miljö där du kör programmet.

Om du vill köra det här programmet öppnar du filen Main.qs i VS Code och väljer Kör.

Konfigurera Q# projekt som externa beroenden

Ett Q# projekt kan också konfigureras som ett externt beroende för andra projekt, ungefär som ett bibliotek, där funktionerna och åtgärderna i det externa Q# projektet görs tillgängliga för flera Q# projekt. Ett externt beroende kan finnas på en enhetsresurs eller publiceras till en offentlig GitHub-lagringsplats.

Om du vill använda ett Q# projekt som ett externt beroende måste du:

  • Lägg till det externa projektet som ett beroende i manifestfilen för det anropande projektet.
  • Om det externa projektet publiceras på GitHub lägger du till egenskapen "files" i manifestfilen för det externa projektet.
  • Lägg till export instruktioner i det externa projektet.
  • Lägg till import instruktioner i det anropande projektet.

Konfigurera manifestfilerna

Externa Q# projekt kan finnas på en lokal resurs eller nätverksenhetsresurs eller publiceras till en offentlig GitHub-lagringsplats.

Manifestfilen för det anropande projektet

Om du vill lägga till ett beroende i ett externt projekt på en enhetsresurs definierar du beroendet i manifestfilen för det anropande projektet.

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyDependency": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

där "MyDependency" är en användardefinierad sträng som identifierar namnområdet när en åtgärd anropas. Om du till exempel skapar ett beroende med namnet "MyMathFunctions" anropar du en funktion från det beroendet med MyMathFunctions.MyFunction().

Så här lägger du till ett beroende till ett projekt som publiceras till en offentlig GitHub-lagringsplats

{
    "author": "Microsoft",
    "dependencies": {
        "MyDependency": {
            "github": {
                "owner": "GitHubUser",
                "repo": "GitHubRepoName",
                "ref": "CommitHash",
                "path": "/path/to/dependency"
            }
        }
}

Kommentar

För GitHub-beroenden refererar "ref" till en GitHub refspec. Microsoft rekommenderar att du alltid använder en incheckningshash, så att du kan förlita dig på en viss version av ditt beroende.

Manifestfilen för det externa projektet

Om ditt externa Q# projekt publiceras på en offentlig GitHub-lagringsplats måste du lägga till filegenskapen i manifestfilen för det externa projektet, inklusive alla filer som används i projektet.

{
    "author": "Microsoft",
    "license": "MIT",
    "files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}

Egenskapen "files" är valfri för ett externt projekt som importeras via "path" (dvs. en lokal filsökvägsbaserad import). Det krävs endast för projekt som publicerats till GitHub.

Använda export-instruktionen

Om du vill göra funktioner och åtgärder i ett externt projekt tillgängliga för anropande projekt använder du -instruktionen export . Du kan exportera valfritt eller alla anropsbara filer i filen. Jokerteckensyntax stöds inte. Du måste ange varje anropsbar fil som ska exporteras.

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;             

Använda import-instruktionen

Från det anropande programmet använder import du instruktioner för att göra objekt från ett externt beroende tillgängligt. import -uttryck använder det namnområde som har definierats för beroendet i manifestfilen. Till exempel för det här beroendet

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyMathFunctions": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

du importerar anropsbara som

import MyMathFunctions.MyFunction;  // imports "MyFunction()" from the namespace
...

-instruktionen import stöder även jokerteckensyntax och 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; 

Kommentar

Den för närvarande använda open instruktionen i Q#, som används för att referera till bibliotek och namnområden, stöds fortfarande men kommer att bli inaktuell så småningom. Under tiden kan du uppdatera dina aktuella filer för att använda -instruktionen import . Kan till exempel open Microsoft.Quantum.Diagnostics; ersättas med import Microsoft.Quantum.Diagnostics.*;. Observera också att när du använder -instruktionen import med standardbiblioteken Q# kan du förkorta rotnamnområdet till Std. Kan till exempel import Microsoft.Quantum.Diagnostics.*; skrivas som import Std.Diagnostics.*;.

Exempel på externt projekt

I det här exemplet använder du samma teleporteringsprogram som i det tidigare exemplet, men separerar anropande program och anropsbara objekt i olika projekt.

  1. Skapa två mappar på den lokala enheten, till exempel "Project_A" och "Project_B".

  2. Skapa ett Q# projekt i varje mapp genom att följa stegen i Steg för att skapa ett Q# projekt.

  3. I Project_A kopierar du följande kod till manifestfilen och redigerar sökvägen efter behov för Project_B

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. I Project_A kopierar du följande kod till 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);
        }
    }   
    
  5. I Project_B kopierar du följande kod till 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
    

    Kommentar

    Observera att åtgärden PrepareBellPair inte behöver exporteras eftersom den inte anropas direkt från programmet i Project_A. Eftersom den finns i det lokala omfånget för Project_B är den redan tillgänglig för åtgärden Teleport .

  6. Om du vill köra programmet öppnar du /Project_A/Main.qs i VS Code och väljer Kör.

Projekt och implicita namnområden

Om Q# ett namnområde inte har angetts i ett *.qs-program i projekt använder kompilatorn filnamnet som namnområde. Om du refererar till ett anropsbart från ett externt beroende använder du sedan syntaxen <dependencyName>.<namnområde>.<anropsbar>. Men om filen heter "Main.qs" förutsätter kompilatorn namnområdet och den anropande syntaxen är <dependencyName>.<anropsbar>, som i föregående exempel, import MyTeleportLib.Teleport.

Eftersom det inte är ovanligt att ha flera projektfiler måste du ta hänsyn till rätt syntax när du refererar till anropsbara filer. Till exempel i ett projekt med följande filstruktur

  • /Src
    • Main.qs
    • MathFunctions.qs

samtal till det externa beroendet skulle vara

import MyTeleportLib.MyFunction;        // "Main" namespace is implied

import MyTeleportLib.MathFunctions.MyFunction;   // "Math" namespace must be explicit 

Mer information om namnområdesbeteende finns i Användarnamnrymder.