Freigeben über


Erstellen und Verwalten von Projekten und benutzerdefinierten Bibliotheken

In diesem Artikel erfahren Sie, wie Sie Projekte erstellen, verwalten und freigeben . Ein Projekt ist eine Ordnerstruktur mit mehreren Dateien, die auf die Vorgänge und Funktionen der anderen zugreifen können. Projekte helfen Ihnen dabei, Den Quellcode logisch zu organisieren. Sie können Projekte auch als benutzerdefinierte Bibliotheken verwenden, auf die Sie aus externen Quellen zugreifen können.

Voraussetzungen

  • Ein Azure Quantum-Arbeitsbereich in Ihrem Azure-Abonnement. Informationen zum Erstellen eines Arbeitsbereichs finden Sie unter Create an Azure Quantum workspace.
  • Visual Studio Code (VS Code) mit den installierten Erweiterungen Microsoft Quantum Development Kit (QDK) und Python.
  • Um Ihr externes Projekt in einem öffentlichen GitHub Repository zu veröffentlichen, müssen Sie über ein GitHub Konto verfügen.

Zum Ausführen von Python-Programmen benötigen Sie außerdem Folgendes:

  • Eine Python-Umgebung, in der Python und Pip installiert ist.

  • Die qdkPython-Bibliothek mit dem azure-Zusatz.

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

Funktionsweise von Projekten

Ein Projekt enthält eine Manifestdatei mit einem bestimmten Namen sowie eine oder mehrere Dateien in einer angegebenen Ordnerstruktur. Sie können ein -Projekt manuell oder direkt in erstellen.

Wenn Sie eine Datei oder Datei in öffnen, durchsucht der Compiler die umgebende Ordnerhierarchie nach der Manifestdatei und bestimmt den Umfang des Projekts. Wenn der Compiler keine Manifestdatei findet, wird der Compiler in einem einzigen Dateimodus ausgeführt.

Wenn Sie die project_root in einer datei Jupyter Notebook oder Python festlegen, sucht der Compiler im Ordner project_root nach der Manifestdatei.

Ein externes Q#-Projekt ist ein Standardprojekt Q#, das sich in einem anderen Verzeichnis oder in einem öffentlichen GitHub-Repository befindet und als benutzerdefinierte Bibliothek fungiert. Ein externes Projekt verwendet Anweisungen, um die Funktionen und Vorgänge zu definieren, auf die externe Programme zugreifen können. Programme definieren das externe Projekt als Abhängigkeit in ihrer Manifestdatei und verwenden Anweisungen, um auf die Elemente im externen Projekt zuzugreifen, z. B. Vorgänge, Funktionen, Strukturen und Namespaces. Weitere Informationen finden Sie unter Verwenden von Projekten als externe Abhängigkeiten.

Definieren eines Projekts

Ein Projekt wird durch das Vorhandensein einer Manifestdatei und eines Ordners definiert, der sich beide im Stammordner des Projekts befinden müssen. Der Ordner enthält die Quelldateien. Bei Programmen und externen Projekten erkennt der Compiler automatisch den Projektordner. Für Python Programme und Jupyter Notebook-Dateien müssen Sie den Q# Projektordner mit einem qsharp.init-Aufruf angeben. Die Ordnerstruktur für ein Projekt ist jedoch für alle Arten von Programmen identisch.

Die Ordnerstruktur und -hierarchie für ein Projekt.

Definieren des Projektordners für Programme

Wenn Sie eine Datei in öffnen, sucht der Compiler in der Ordnerstruktur nach oben nach einer Manifestdatei. Wenn der Compiler eine Manifestdatei findet, enthält der Compiler alle Dateien im Verzeichnis und seinen Unterverzeichnissen. Die in jeder Datei definierten Elemente werden für alle anderen Dateien innerhalb des Projekts verfügbar.

Betrachten Sie beispielsweise die folgende Ordnerstruktur:

  • Teleportation-Projekt
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

Wenn Sie die Datei öffnen, führt der Compiler die folgenden Aktionen aus:

  1. Prüft auf .
  2. Prüft auf .
  3. Prüft auf .
  4. Sucht nach der Datei und findet sie.
  5. Legt das Root-Verzeichnis des Projekts fest und fügt alle Dateien und Dateitypen unter dem Verzeichnis in das Projekt ein. Wenn die Manifestdatei.

Hinweis

Wenn Sie explizite Verweise auf und Dateipfade in die Datei einfügen, lädt der Compiler diese Dateien und durchläuft nicht den automatischen Ermittlungsprozess. Explizite Dateipfadverweise sind nur erforderlich, wenn Sie eine Bibliothek definieren, die aus einem Git-Verweis geladen werden kann.

So erstellen Sie eine Manifestdatei

Eine Manifestdatei ist eine JSON-Datei, die optionale Felder und zusätzliche Elemente enthalten kann. Die mindestfähige Manifestdatei ist die Zeichenfolge . Wenn Sie ein Projekt in erstellen, wird eine minimale Manifestdatei für Sie erstellt.

{}

Manifestdateibeispiele

Die folgenden Beispiele zeigen, wie Manifestdateien den Umfang Ihres Projekts definieren.

  • In diesem Beispiel ist das einzige angegebene Feld, sodass alle Dateien in diesem Verzeichnis und deren Unterverzeichnisse im Projekt enthalten sind.

    {
        "author":"Microsoft"
    }
    
  • In einem Projekt können Sie auch die Manifestdatei verwenden, um die Linter-Einstellungen zu optimieren. Standardmäßig sind die drei Linter-Regeln:

    • : default =

    • : default =

    • : default =

      Sie können jede Regel in der Manifestdatei entweder auf , oder festlegen. Beispiel:

      {
          "author":"Microsoft",
          "lints": [
              {
                "lint": "needlessParens",
                "level": "allow"
              },
              {
                "lint": "redundantSemicolons",
                "level": "warn"
              },
              {
                "lint": "divisionByZero",
                "level": "error"
              }
            ]
      }
      
  • Sie können die Manifestdatei auch verwenden, um ein externes Projekt als Abhängigkeit zu definieren und Vorgänge und Funktionen in diesem externen Projekt aus der Ferne zuzugreifen. Weitere Informationen finden Sie unter Verwenden von Projekten als externe Abhängigkeiten.

Projektanforderungen und Eigenschaften

Die folgenden Anforderungen und Konfigurationen gelten für alle Projekte.

  • Alle Dateien, die Sie in das Projekt aufnehmen möchten, müssen sich unter einem Ordner namens befinden, der sich unter dem Stammordner des Projekts befinden muss. Wenn Sie ein -Projekt in erstellen, wird der -Ordner automatisch erstellt.

  • Die Manifestdatei sollte auf derselben Ebene wie der Ordner sein. Wenn Sie ein Projekt in erstellen, wird automatisch eine minimale Manifestdatei erstellt.

  • Verwenden Sie Anweisungen zum Verweisen auf Vorgänge und Funktionen aus anderen Dateien im Projekt.

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

    Oder verweisen Sie einzeln mit dem Namespace auf sie.

    MyMathLib.Multiply(x,y); 
    

Nur für Projekte

  • Sie können einen Einstiegspunktvorgang in nur einer Datei in einem Projekt definieren, bei dem es sich standardmäßig um den Vorgang handelt.
  • Sie müssen die Datei mit der Einstiegspunktdefinition auf einer Projektverzeichnisebene unter der Manifestdatei ablegen.
  • Alle Vorgänge und Funktionen im Projekt, die aus einem Anzeigenbildschirm im Vorhersagetext in zwischengespeichert werden.
  • Wenn der Namespace für einen ausgewählten Vorgang oder eine ausgewählte Funktion noch nicht importiert wird, wird automatisch die erforderliche Anweisung hinzugefügt.

Wie man ein -Projekt erstellt

Führen Sie zum Erstellen eines Projekts die folgenden Schritte aus:

  1. Wechseln Sie im Datei-Explorer zu dem Ordner, den Sie als Stammordner für das Projekt verwenden möchten.

  2. Öffnen Sie das Menü "Ansicht" , und wählen Sie "Befehlspalette" aus.

  3. Drücken Sie die Eingabetaste: Projekt erstellen. erstellt eine minimale Manifestdatei im Ordner und fügt einen Ordner mit einer Vorlagendatei hinzu.

  4. Bearbeiten Sie die Manifestdatei für Ihr Projekt. Siehe Manifestdateibeispiele.

  5. Fügen Sie Ihre Quelldateien unter dem Ordner hinzu und organisieren Sie sie .

  6. Wenn Sie über ein Q#Programm oder Python auf das Jupyter Notebook-Projekt zugreifen, legen Sie den Pfad des ordners root mit qsharp.init fest. In diesem Beispiel wird davon ausgegangen, dass sich Ihr Programm im Ordner des Projekts befindet:

    qsharp.init(project_root = '../Teleportation_project')
    
  7. Wenn Sie nur Dateien in verwenden, sucht der Compiler beim Öffnen einer Datei nach einer Manifestdatei und bestimmt den Stammordner des Projekts. Anschließend überprüft der Compiler und seine Unterverzeichnisse und Dateien.

Hinweis

Sie können stattdessen die Manifestdatei und den Ordner manuell erstellen.

Beispielprojekt

Dieses Quantenteleportationsprogramm ist ein Beispiel für ein Projekt, das auf dem lokalen Simulator ausgeführt wird. Informationen zum Ausführen des Programms auf Azure Quantum Hardware oder Drittanbietersimulatoren finden Sie unter Loslegen mit Q# Programmen und VS Code für Schritte zum Kompilieren Ihres Programms und zur Verbindung mit Ihrem Azure Quantum Arbeitsbereich.

Dieses Beispiel weist die folgende Verzeichnisstruktur auf:

  • Teleportation-Projekt
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

Die Manifestdatei enthält die Autoren - und Lizenzfelder :

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

Quelldateien

Die Hauptdatei enthält den Einstiegspunkt und verweist auf den Namespace von .

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

Die Datei definiert den Vorgang und ruft den Vorgang aus der Datei auf.

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

Die Datei enthält einen standardmäßigen wiederverwendbaren Vorgang zum Erstellen eines Bell-Paares.

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

Ausführen der Programme

Wählen Sie die Registerkarte für die Umgebung aus, in der Sie Ihr Programm ausführen.

Um dieses Programm auszuführen, öffnen Sie die Datei in , und wählen Sie "Ausführen" aus.

Konfigurieren Sie -Projekte als externe Abhängigkeiten

Sie können Projekte als externe Abhängigkeit für andere Projekte konfigurieren , ähnlich einer Bibliothek, um Funktionen und Vorgänge im externen Projekt anderen Projekten zur Verfügung zu stellen. Eine externe Abhängigkeit kann sich auf einer Laufwerkfreigabe befinden oder in einem öffentlichen GitHub Repository veröffentlicht werden.

Um ein Projekt als externe Abhängigkeit zu verwenden, müssen Sie:

  • Fügen Sie das externe Projekt als Abhängigkeit in der Manifestdatei des aufrufenden Projekts hinzu.
  • Wenn das externe Projekt in GitHub veröffentlicht wird, fügen Sie der Manifestdatei des externen Projekts die Eigenschaft files hinzu.
  • Fügen Sie Anweisungen zum externen Projekt hinzu.
  • Fügen Sie Anweisungen zum aufrufenden Projekt hinzu.

Konfigurieren der Manifestdateien

Externe Q# Projekte können sich auf einer lokalen oder Netzwerklaufwerkfreigabe befinden, oder Sie können sie in einem öffentlichen GitHub Repository veröffentlichen.

Manifestdatei des aufrufenden Projekts

Um einem externen Projekt eine Abhängigkeit zu einer Laufwerkfreigabe hinzuzufügen, definieren Sie die Abhängigkeit in der Manifestdatei des aufrufenden Projekts.

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

In der vorherigen Manifestdatei handelt es sich um eine benutzerdefinierte Zeichenfolge, die den Namespace identifiziert, wenn Sie einen Vorgang aufrufen. Wenn Sie z. B. eine Abhängigkeit mit dem Namen erstellen, können Sie mit eine Funktion aus dieser Abhängigkeit aufrufen.

Wenn Sie einem Projekt, das in einem öffentlichen GitHub Repository veröffentlicht wird, eine Abhängigkeit hinzufügen möchten, verwenden Sie die folgende Beispielmanifestdatei:

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

Hinweis

Bei GitHub Abhängigkeiten bezieht sich ref auf eine GitHub refspec. empfiehlt, immer einen Commit-Hash zu verwenden, damit Sie sich auf eine bestimmte Version Ihrer Abhängigkeit verlassen können.

Die Manifestdatei des externen Projekts

Wenn Ihr externes Q#-Projekt in einem öffentlichen GitHub Repository veröffentlicht wird, müssen Sie der Manifestdatei des externen Projekts die Eigenschaft files hinzufügen, einschließlich aller Dateien, die das Projekt verwendet.

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

Die Eigenschaft ist optional für ein externes Projekt, das Sie über einen lokalen Dateipfad-basierten Import einbringen. Die eigenschaft files ist nur für Projekte erforderlich, die in GitHub veröffentlicht werden.

Verwenden Sie die Anweisung

Verwenden Sie die Anweisung, um Funktionen und Vorgänge in einem externen Projekt für das Aufrufen von Projekten zugänglich zu machen. Sie können alle aufrufbaren Elemente in der Datei exportieren. Sie können keine Wildcardsyntax verwenden, daher müssen Sie die einzelnen aufrufbaren Elemente angeben, die Sie exportieren möchten.

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;

Verwenden Sie die Anweisung

Verwenden Sie Anweisungen aus dem aufrufenden Programm, um Elemente aus einer externen Abhängigkeit verfügbar zu machen. Die Anweisung verwendet den Namespace, den Sie für die Abhängigkeit in der Manifestdatei definieren.

Betrachten Sie beispielsweise die Abhängigkeit in der folgenden Manifestdatei:

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

Importieren Sie die aufrufbaren Elemente mit dem folgenden Code:

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

...

Die Anweisung unterstützt auch die Syntax und Aliase von Wildcards.

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

Beispiel für ein externes Projekt

Verwenden Sie in diesem Beispiel das gleiche Teleportierungsprogramm wie im vorherigen Beispiel, trennen Sie jedoch das Aufrufprogramm und die aufzurufenden Funktionen in verschiedene Projekte.

  1. Erstellen Sie zwei Ordner auf Ihrem lokalen Laufwerk, z. B . und .

  2. Erstellen Sie ein Projekt in jedem Ordner. Ausführliche Informationen finden Sie in den Schritten zum Erstellen eines Projekts.

  3. Kopieren Sie im aufrufenden Programm den folgenden Code in die Manifestdatei, aber bearbeiten Sie den Pfad nach Bedarf für:

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. In kopieren Sie den folgenden Code nach :

    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. In kopieren Sie den folgenden Code nach :

        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
    

    Hinweis

    Sie müssen den Vorgang nicht exportieren, den Ihr Programm nicht direkt aufruft. Auf den Vorgang kann bereits durch den Vorgang zugegriffen werden, da sich im lokalen Bereich von befindet.

  6. Um das Programm auszuführen, öffnen Sie in und wählen Sie Ausführen aus.

Projekte und implizite Namespaces

Wenn Sie in Projekten keinen Namespace in einem Programm angeben, verwendet der Compiler den Dateinamen als Namespace. Wenn Sie dann auf ein aufrufbares Element aus einer externen Abhängigkeit verweisen, verwenden Sie die Syntax . Wenn die Datei jedoch den Namen trägt, geht der Compiler davon aus, dass der Namespace und die aufrufende Syntax lautet. Beispiel: .

Da möglicherweise mehrere Projektdateien vorhanden sind, müssen Sie die richtige Syntax berücksichtigen, wenn Sie auf aufrufbare Elemente verweisen. Betrachten Sie z. B. ein Projekt mit der folgenden Dateistruktur:

  • /Src
    • Main.qs
    • MathFunctions.qs

Der folgende Code ruft die externe Abhängigkeit auf:

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

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

Weitere Informationen zum Verhalten von Namensräumen finden Sie unter Benutzernamensräume.