Delen via


Projecten en aangepaste bibliotheken maken en beheren Q#

In dit artikel leert u hoe u projecten maakt, beheert en deelt Q# . Een Q# project is een mapstructuur met meerdere Q# bestanden die toegang hebben tot elkaars bewerkingen en functies. Projecten helpen u uw broncode logisch te ordenen. U kunt projecten ook gebruiken als aangepaste bibliotheken die toegankelijk zijn vanuit externe bronnen.

Vereisten

  • Een Azure Quantum werkruimte in uw Azure-abonnement. Bekijk Een Azure Quantum werkruimte maken om een werkruimte te creëren.
  • Visual Studio Code (VS Code) waarop de Azure Quantum Development Kit en Python extensies zijn geïnstalleerd.
  • Een GitHub-account als u van plan bent uw externe project te publiceren naar een openbare GitHub-opslagplaats.

Als u programma's wilt uitvoeren Python , hebt u ook het volgende nodig:

  • Een Python omgeving met Python en Pip geïnstalleerd.

  • De qdkPython bibliotheek met de optionele azure extra.

    python -m pip install --upgrade "qdk[azure]"
    

Hoe Q# projecten werken

Een Q# project bevat een Q# manifestbestand met de naam qsharp.jsonen een of meer .qs bestanden in een opgegeven mapstructuur. U kunt een Q# project handmatig of rechtstreeks maken in VS Code.

Wanneer u een .qs bestand opent in VS Code, zoekt de compiler in de omringende maphiërarchie naar het manifestbestand en bepaalt het bereik van het project. Als er geen manifestbestand wordt gevonden, werkt de compiler in één bestandsmodus.

Wanneer u het project_root bestand in een Jupyter Notebook of Python bestand instelt, zoekt de compiler naar het manifestbestand in de project_root map.

Een extern Q# project is een standaardproject Q# dat zich in een andere map of in een openbare GitHub-opslagplaats bevindt en fungeert als een aangepaste bibliotheek. Een extern project maakt gebruik van export instructies voor het definiëren van de functies en bewerkingen die toegankelijk zijn voor externe programma's. Programma's definiëren het externe project als een afhankelijkheid in hun manifestbestand en gebruiken import instructies voor toegang tot de items in het externe project, zoals bewerkingen, functies, structs en naamruimten. Zie Projecten gebruiken als externe afhankelijkheden voor meer informatie.

Q# Een project definiëren

Een Q# project wordt gedefinieerd door de aanwezigheid van een manifestbestand met de naam qsharp.jsonen een src map, die beide zich in de hoofdmap van het project moeten bevinden. De src map bevat de Q# bronbestanden. Voor Q# programma's en externe projecten detecteert de Q# compiler de projectmap automatisch. Voor Python programma's en Jupyter Notebook bestanden moet u de Q# projectmap opgeven met een qsharp.init aanroep. De mapstructuur voor een Q# project is echter hetzelfde voor alle typen programma's.

De mapstructuur en -hiërarchie voor een Q# project.

De projectmap (Q# programma's) definiëren

Wanneer u een .qs-bestand opent in VS Code, zoekt de Q#-compiler omhoog in de mapstructuur naar een manifestbestand. Als de compiler een manifestbestand vindt, bevat de compiler alle Q# bestanden in de /src map en alle submappen. De items die in elk bestand zijn gedefinieerd, worden beschikbaar voor alle andere bestanden in het project.

Denk bijvoorbeeld aan de volgende mapstructuur:

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

Wanneer u het bestand /src/TeleportOperation/PrepareState/PrepareStateLib.qsopent, doet de Q# compiler het volgende:

  1. /src/TeleportOperation/PrepareState/Controleert op qsharp.json .
  2. /src/TeleportOperationControleert op qsharp.json .
  3. /srcControleert op qsharp.json .
  4. /*Controleert op qsharp.json .
  5. / Wordt ingesteld als de hoofdmap van het project en bevat alle .qs bestanden onder de hoofdmap in het project, volgens de instellingen van het manifestbestand.

Een manifestbestand maken

Een manifestbestand is een JSON-bestand met de naam qsharp.json dat desgewenst auteurs-, licentie- en lintvelden kan bevatten. Het minimaal levensvatbare manifestbestand is de tekenreeks {}. Wanneer u een Q# project in VS Code maakt, wordt er een minimaal manifestbestand voor u gegenereerd.

{}

Voorbeelden van manifestbestanden

In de volgende voorbeelden ziet u hoe manifestbestanden het bereik van uw Q# project kunnen definiëren.

  • In dit voorbeeld is auteur het enige opgegeven veld, dus alle .qs bestanden in deze map en de bijbehorende submappen zijn opgenomen in het Q# project.

    {
        "author":"Microsoft",
        "license": "MIT"
    }
    
  • Binnen een Q# project kunt u ook het manifestbestand gebruiken om de VS CodeQ# Linter-instellingen af te stemmen. Standaard zijn de drie Linter-regels:

    • needlessParens: standaard = allow

    • divisionByZero: standaard = warn

    • redundantSemicolons: standaard = warn

      U kunt elke regel in het manifestbestand instellen op allow, warnof error. Voorbeeld:

      {
          "author":"Microsoft",
          "lints": [
              {
                "lint": "needlessParens",
                "level": "allow"
              },
              {
                "lint": "redundantSemicolons",
                "level": "warn"
              },
              {
                "lint": "divisionByZero",
                "level": "error"
              }
            ]
      }
      
  • U kunt het manifestbestand ook gebruiken om een extern Q# project te definiëren als een afhankelijkheid en externe toegang tot bewerkingen en functies in dat externe project. Zie Projecten gebruiken als externe afhankelijkheden voor meer informatie.

Q# projectvereisten en -eigenschappen

De volgende vereisten en configuraties zijn van toepassing op alle Q# projecten.

  • Alle .qs bestanden die u in het project wilt opnemen, moeten zich onder een map bevinden met de naam src, die zich in de hoofdmap van het Q# project moet bevinden. Wanneer u een Q# project in VS Code maakt, wordt de /src map automatisch gemaakt.

  • Het manifestbestand moet zich op hetzelfde niveau bevinden als de src map. Wanneer u een project maakt in VS Code, wordt er automatisch een minimaal bestand gemaakt.

  • Gebruik import instructies om te verwijzen naar bewerkingen en functies van andere bestanden in het project.

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

    U kunt ze ook afzonderlijk verwijzen naar de naamruimte.

    MyMathLib.Multiply(x,y); 
    

Alleen voor Q# projecten

  • U kunt een invoerpuntbewerking definiëren in slechts één .qs bestand in een Q# project. Dit is standaard de Main() bewerking.
  • U moet het bestand met de definitie van het .qs toegangspunt onder het manifestbestand plaatsen op projectmapniveau.
  • Alle bewerkingen en functies in het Q# project die vanuit een .qs weergave zijn opgeslagen in de cache, worden weergegeven in voorspellende tekst in VS Code.
  • Als de naamruimte voor een geselecteerde bewerking of functie nog niet is geïmporteerd, voegt VS Code automatisch de benodigde import instructie toe.

Hoe maak je een Q#-project

Voer de volgende stappen uit om een Q# project te maken:

  1. Ga in de VS Code Verkenner naar de map die u wilt gebruiken als hoofdmap voor het Q# project.

  2. Open het menu Beeld en kies Opdrachtpalet.

  3. Enter QDK: Maak een Q# project en druk op Enter. VS Code maakt een minimaal manifestbestand in de map en voegt een /src map toe met een Main.qs sjabloonbestand.

  4. Bewerk het manifestbestand voor uw project. Zie voorbeelden van manifestbestanden.

  5. Voeg uw Q# bronbestanden toe en organiseer deze onder de /src map.

  6. Als u het Q# project opent vanuit een Python programma of Jupyter Notebook, stelt u het pad naar de hoofdmap in met behulp van qsharp.init. In dit voorbeeld wordt ervan uitgegaan dat uw programma zich in de /src map van het Q# project bevindt:

    qsharp.init(project_root = '../Teleportation_project')
    
  7. Als u alleen Q# bestanden in VS Code gebruikt, dan zoekt de compiler naar een manifestbestand wanneer u een Q# bestand opent. Het bepaalt de hoofdmap van het project en scant vervolgens de submap op .qs bestanden.

Notitie

U kunt ook handmatig het manifestbestand en de /src map maken.

Voorbeeldproject

Dit kwantumteleportatieprogramma is een voorbeeld van een Q# project dat wordt uitgevoerd op de lokale simulator in VS Code. Als u het programma wilt uitvoeren op Azure Quantum hardware- of simulators van derden, raadpleegt u Aan de slag met Q# programma's en VS Code voor stappen om uw programma te compileren en verbinding te maken met uw Azure Quantum werkruimte.

Dit voorbeeld heeft de volgende mapstructuur:

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

Het manifestbestand bevat de auteurs - en licentievelden :

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

Q# bronbestanden

Het hoofdbestand met de naam Main.qs, bevat het toegangspunt en verwijst naar de TeleportOperations.TeleportLib naamruimte van 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);
        }
    }

De TeleportLib.qs bestanden definiëren de Teleport bewerking en roept de PrepareBellPair bewerking aan vanuit het PrepareStateLib.qs bestand.

    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);
    }

Het PrepareStateLib.qs bestand bevat een standaard herbruikbare operatie om een Bell-paar te maken.

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

De programma's uitvoeren

Kies het tabblad voor de omgeving waarin u uw programma uitvoert.

Als u dit programma wilt uitvoeren, opent u het Main.qs bestand in VS Code en kiest u Uitvoeren.

Projecten configureren Q# als externe afhankelijkheden

U kunt projecten configureren Q# als externe afhankelijkheden voor andere projecten, vergelijkbaar met een bibliotheek. De functies en bewerkingen in het externe Q# project worden beschikbaar gesteld voor meerdere Q# projecten. Een externe afhankelijkheid kan zich op een gedeelde schijf bevinden of worden gepubliceerd op een openbare GitHub-opslagplaats.

Als u een Q# project als een externe afhankelijkheid wilt gebruiken, moet u het volgende doen:

  • Voeg het externe project toe als een afhankelijkheid in het manifestbestand van het aanroepende project.
  • Als het externe project wordt gepubliceerd naar GitHub, voegt u de bestandseigenschap toe aan het manifestbestand van het externe project.
  • Voeg export statements toe aan het externe project.
  • Voeg import statements toe aan het aanroepende project.

De manifestbestanden configureren

Externe Q# projecten kunnen zich op een lokale of netwerkstationshare bevinden of worden gepubliceerd naar een openbare GitHub-opslagplaats.

Het manifestbestand van het aanroepende project

Als u een afhankelijkheid wilt toevoegen aan een extern project op een netwerkschijf, definieert u de afhankelijkheid in het manifest-bestand van het aanroepende project.

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

In het voorgaande manifestbestand is MyDependency een door de gebruiker gedefinieerde tekenreeks die de naamruimte identificeert wanneer u een bewerking aanroept. Als u bijvoorbeeld een afhankelijkheid met de naam MyMathFunctionsmaakt, kunt u een functie aanroepen vanuit die afhankelijkheid met MyMathFunctions.MyFunction().

Als u een afhankelijkheid wilt toevoegen aan een project dat is gepubliceerd naar een openbare GitHub-opslagplaats, gebruikt u het volgende voorbeeldmanifestbestand:

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

Notitie

Voor GitHub-afhankelijkheden verwijst ref naar een GitHub-refspec. Microsoft raadt u aan altijd een commit-hash te gebruiken, zodat u kunt vertrouwen op een specifieke versie van uw afhankelijkheid.

Het manifestbestand van het externe project

Als uw externe Q# project wordt gepubliceerd naar een openbare GitHub-opslagplaats, moet u de bestandseigenschap toevoegen aan het manifestbestand van het externe project, inclusief alle bestanden die in het project worden gebruikt.

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

De bestandseigenschap is optioneel voor een extern project dat wordt geïmporteerd via "path" (een lokaal importbestandspad). De bestandseigenschap is alleen vereist voor projecten die zijn gepubliceerd naar GitHub.

Gebruik de export instructie

Gebruik de export instructie om functies en bewerkingen in een extern project toegankelijk te maken voor het aanroepen van projecten. U kunt enkele of alle aanroepbare items in het bestand exporteren. Wildcard-syntaxis wordt niet ondersteund, dus u moet elke functie of taak opgeven die u wilt exporteren.

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;

Gebruik de import instructie

Als u items van een externe afhankelijkheid beschikbaar wilt maken, gebruikt u de statements import van het aanroepende programma. De import instructie maakt gebruik van de naamruimte die is gedefinieerd voor de afhankelijkheid in het manifestbestand.

Denk bijvoorbeeld aan de afhankelijkheid in het volgende manifestbestand:

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

Importeer de aanroepbare items met de volgende code:

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

...

De import instructie ondersteunt ook wildcardsyntaxis en aliassen.

// 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; 

Notitie

De momenteel gebruikte open instructie Q#, die wordt gebruikt om te verwijzen naar bibliotheken en naamruimtes, wordt nog steeds ondersteund, maar wordt uiteindelijk verouderd. Ondertussen kunt u eventueel uw huidige bestanden bijwerken om de import instructie te gebruiken. Kan bijvoorbeeld open Std.Diagnostics; worden vervangen door import Std.Diagnostics.*;.

Voorbeeld van extern project

In dit voorbeeld gebruikt u hetzelfde teleportatieprogramma als in het vorige voorbeeld, maar scheidt u het oproepprogramma en de aanroepbare bestanden in verschillende projecten.

  1. Maak twee mappen op uw lokale schijf, bijvoorbeeld Project_A en Project_B.

  2. Maak een Q# project in elke map. Zie de stappen in Een project maken Q#voor meer informatie.

  3. Kopieer Project_Ain het aanroepende programma de volgende code naar het manifestbestand, maar bewerk het pad indien nodig voor Project_B:

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. Kopieer Project_Ade volgende code 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);
        }
    }   
    
  5. Kopieer Project_Bde volgende code 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
    

    Notitie

    Houd er rekening mee dat de PrepareBellPair bewerking niet hoeft te worden geëxporteerd omdat deze niet rechtstreeks vanuit uw programma wordt aangeroepen.Project_A Omdat PrepareBellPair zich in het lokale bereik van Project_B bevindt, is deze al toegankelijk voor de Teleport bewerking.

  6. Open /Project_A/Main.qs in VS Code en kies Uitvoeren om het programma uit te voeren.

Projecten en impliciete naamruimten

Als er in Q# projecten geen namespace is opgegeven in een .qs programma, dan gebruikt de compiler de bestandsnaam als de namespace. Vervolgens, wanneer u naar een aanroepbare vanuit een externe afhankelijkheid verwijst, gebruikt u de syntaxis <dependencyName>.<namespace>.<callable>. Echter, als het bestand de naam Main.qs heeft, neemt de compiler aan dat de namespace en de syntaxis voor aanroepen <dependencyName>.<callable> zijn, zoals in het vorige voorbeeld import MyTeleportLib.Teleport.

Omdat u mogelijk meerdere projectbestanden hebt, moet u rekening houden met de juiste syntaxis wanneer u verwijst naar aanroepbare bestanden. Denk bijvoorbeeld aan een project met de volgende bestandsstructuur:

  • /Src
    • Main.qs
    • MathFunctions.qs

Met de volgende code worden aanroepen naar de externe afhankelijkheid uitgevoerd:

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

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

Zie Gebruikersnaamruimten voor meer informatie over het gedrag van de naamruimte.