Möglichkeiten zum Ausführen eines Q# Programms

Eine der größten Stärken des Quantum Development Kit ist die Flexibilität über Plattform- und Entwicklungsumgebungen hinweg. Dies bedeutet jedoch auch, dass neue Q# Benutzer möglicherweise durch die zahlreichen Optionen im Installationshandbuch verwirrt oder überfordert sind. Auf dieser Seite erläutern wir, was geschieht, wenn ein Q# Programm ausgeführt wird, und vergleichen die verschiedenen Möglichkeiten, wie Benutzer dies tun können.

Eine primäre Unterscheidung ist, dass Q# ausgeführt werden kann:

  • als eigenständige Anwendung, wobei Q# die einzige beteiligte Sprache ist und das Programm direkt aufgerufen wird. Zwei Methoden fallen tatsächlich in diese Kategorie:
    • die Befehlszeilenschnittstelle
    • Q# Jupyter Notebooks
  • mit einem zusätzlichen Hostprogramm, das in Python oder einer .NET-Sprache (z. B. C# oder F#) geschrieben ist, welches dann das Programm aufruft und zurückgegebene Ergebnisse weiter verarbeiten kann.

Um diese Prozesse und ihre Unterschiede am besten zu verstehen, betrachten wir ein einfaches Q# Programm und vergleichen die Möglichkeiten, wie es ausgeführt werden kann.

Grundlegendes Q# Programm

Ein grundlegendes Quantenprogramm kann aus der Vorbereitung eines Qubits in einer gleichen Superposition der Zustände $\ket{0}$ und $\ket{1}$, der Messung und der Rückgabe des Ergebnisses bestehen, bei dem es sich mit gleicher Wahrscheinlichkeit um einen dieser beiden Zustände handelt. Tatsächlich ist dieser Prozess der Kern des Schnellstarts zum Quanten-Zufallszahlengenerator.

In Q# wird dies mit dem folgenden Code ausgeführt:

        use q = Qubit();   // allocates qubit for use (automatically in |0>)
        H(q);                // puts qubit in superposition of |0> and |1>
        return MResetZ(q);   // measures qubit, returns result (and resets it to |0> before deallocation)
        

Dieser Code allein kann jedoch nicht von Q# ausgeführt werden. Dazu muss er den Text eines Vorgangs sein, der dann ausgeführt wird, wenn er aufgerufen wird – direkt oder durch einen anderen Vorgang. Daher können Sie einen Vorgang im folgenden Formular schreiben:

    operation MeasureSuperposition() : Result {
        use q = Qubit();
        H(q);
        return MResetZ(q);
        
    }

Sie haben einen Vorgang MeasureSuperposition definiert, der keine Eingaben annimmt und einen Wert vom Typ Result zurückgibt.

Neben Vorgängen ermöglicht Q# auch, deterministische Berechnungen in Funktionen zu kapseln. Abgesehen von der Determinismusgarantie, die impliziert, dass Berechnungen, die auf Qubits reagieren, in Vorgänge und nicht in Funktionen gekapselt werden müssen, gibt es nur wenige Unterschiede zwischen Vorgängen und Funktionen. Wir bezeichnen sie zusammen als aufrufbare Komponenten.

Aufrufbare Komponente in einer Q# Datei definiert

Die aufrufbare Komponente ist genau das, was von Q# aufgerufen und ausgeführt wird. Es sind jedoch einige weitere Ergänzungen erforderlich, um eine vollständige *.qs Q# Datei zu erstellen.

Alle Q# Typen und aufrufbaren Komponenten (sowohl die von Ihnen definierten als auch diejenigen, die für die Sprache intrinsisch sind) werden in Namespaces definiert, die jeweils einen vollständigen Namen bereitstellen, auf den dann verwiesen werden kann.

Beispielsweise befinden sich die H und MResetZ Vorgänge in den Microsoft.Quantum.Instrinsic und Microsoft.Quantum.Measurement Namespaces (Teil der Q# Standardbibliotheken). Daher können sie immer über ihren vollständigen Namen Microsoft.Quantum.Intrinsic.H(<qubit>) und Microsoft.Quantum.Measurement.MResetZ(<qubit>) aufgerufen werden, aber dies würde immer zu sehr überladenem Code führen.

Stattdessen ermöglichen open Anweisungen das Verweisen auf aufrufbare Komponenten mit einer präziseren Kurzform, wie wir dies im obigen Vorgangstext getan haben. Die vollständige Q# Datei, die unseren Vorgang enthält, besteht daher aus der Definition unseres eigenen Namespace, dem Öffnen der Namespaces für diese aufrufbaren Funktionen, die unser Vorgang verwendet, und dem anschließenden Vorgang:

namespace NamespaceName {
    open Microsoft.Quantum.Intrinsic;     // for the H operation
    open Microsoft.Quantum.Measurement;   // for MResetZ

    operation MeasureSuperposition() : Result {
        use q = Qubit();
        H(q);
        return MResetZ(q);
        
    }
}

Hinweis

Namespaces können beim Öffnen auch als Alias verwendet werden. Dies kann hilfreich sein, wenn Aufruf- bzw. Typnamen in zwei Namespaces in Konflikt stehen. Beispielsweise könnten wir stattdessen open Microsoft.Quantum.Instrinsic as NamespaceWithH; oben verwenden und dann H über NamespaceWithH.H(<qubit>) aufrufen.

Hinweis

Eine Ausnahme davon ist der Namespace Microsoft.Quantum.Core, der stets automatisch geöffnet wird. Daher können aufrufbare Funktionen wie Length stets direkt verwendet werden.

Wird auf dem Zielframework ausgeführt

Jetzt wird das allgemeine Ausführungsmodell eines Q# Programms deutlich.


Q# program execution diagram

Erstens hat die spezifische aufrufbare Komponente, die ausgeführt werden soll, Zugriff auf alle anderen Aufrufbaren und Typen, die im gleichen Namespace definiert sind. Es greift auch über eine der Q# Bibliotheken auf diese zu, aber auf diese muss entweder über ihren vollständigen Namen oder durch die Verwendung der oben beschriebenen open Anweisungen verwiesen werden.

Die aufrufbare Komponente selbst wird dann auf einem Zielcomputer ausgeführt. Bei solchen Zielcomputern kann es sich um tatsächliche Quantenhardware oder um die im QDK verfügbaren Simulatoren handeln. Für unsere Zwecke ist der nützlichste Zielcomputer eine Instanz des Vollzustandssimulators QuantumSimulator, der das Verhalten des Programms berechnet, als würde es auf einem rauschfreien Quantencomputer ausgeführt.

Bisher haben wir beschrieben, was geschieht, wenn eine bestimmte Q# aufrufbare Komponente ausgeführt wird. Unabhängig davon, ob Q# in einer eigenständigen Anwendung oder mit einem Hostprogramm verwendet wird, ist dieser allgemeine Prozess mehr oder weniger gleich – daher die Flexibilität des QDK. Die Unterschiede zwischen den Methoden zum Aufrufen des Quantum Development Kit zeigen sich daher in der Art und Weise, wie diese Q# aufrufbare Komponente zum Ausführen aufgerufen wird und in welcher Weise Ergebnisse zurückgegeben werden. Genauer gesagt drehen sich die Unterschiede um:

  • Gibt an, welche Q# aufrufbare Komponente ausgeführt werden soll
  • Wie potenzielle aufrufbare Argumente bereitgestellt werden
  • Angeben des Zielcomputers, auf dem er ausgeführt werden soll
  • Wie Ergebnisse zurückgegeben werden

Zunächst erläutern wir, wie dies mit der eigenständigen Anwendung Q# über die Eingabeaufforderung erfolgt, und fahren dann mit der Verwendung von Python- und C#-Hostprogrammen fort. Wir reservieren die eigenständige Anwendung von Q# Jupyter Notebooks für die letzte Zeit, da sie im Gegensatz zu den ersten drei Funktionen sich nicht um eine lokale Q# Datei zentriert.

Hinweis

Obwohl wir es in diesen Beispielen nicht veranschaulichen, besteht eine Gemeinsamkeit zwischen den Ausführungsmethoden darin, dass alle Nachrichten, die aus dem Q# Programm (z. B. über Message oder DumpMachine) ausgegeben werden, in der Regel immer in der jeweiligen Konsole ausgegeben werden.

Q# über die Eingabeaufforderung

Eine der einfachsten Möglichkeiten für den Einstieg in das Schreiben von Q# Programmen besteht darin, dass Sie sich keine Gedanken über separate Dateien und eine zweite Sprache machen müssen. Visual Studio Code oder Visual Studio mit QDK-Erweiterung ermöglicht einen nahtlosen Workflow, bei dem Q# aufrufbare Komponenten nur aus einer einzelnen Q# Datei ausgeführt werden.

Dazu führen wir das Programm letztendlich aus, indem wir Folgendes eingeben:

dotnet run

an der Eingabeaufforderung ein. Der einfachste Workflow ist, wenn der Verzeichnisspeicherort des Terminals mit der Q# Datei identisch ist, was beispielsweise mithilfe des integrierten Terminals in VS Code einfach zusammen mit der Bearbeitung der Q# Datei erfolgen kann. Der dotnet run Befehl akzeptiert jedoch zahlreiche Optionen und das Programm kann auch von einem anderen Speicherort aus ausgeführt werden, indem --project <PATH> einfach der Speicherort der Datei Q# zur Verfügung gestellt wird.

Hinzufügen eines Einstiegspunkts zur Q# Datei

Die meisten Q# Dateien enthalten mehr als eine aufrufbare Komponente. Daher müssen wir den Compiler darüber informieren, welche Komponente ausgeführt werden soll, wenn wir den Befehl dotnet run bereitstellen. Dies erfolgt mit einer einfachen Änderung an der Q# Datei selbst: - fügen Sie eine Zeile mit @EntryPoint() direkt vor der aufrufbaren Komponente hinzu.

Unsere Datei von oben würde daher zu

namespace NamespaceName {
    open Microsoft.Quantum.Intrinsic;     // for the H operation
    open Microsoft.Quantum.Measurement;   // for MResetZ

    @EntryPoint()
    operation MeasureSuperposition() : Result {
        use q = Qubit();
        H(q);
        return MResetZ(q);
        
    }
}

Nun führt ein Aufruf von dotnet run über die Eingabeaufforderung zur MeasureSuperposition Ausführung und der zurückgegebene Wert wird dann direkt im Terminal ausgegeben. Daher wird entweder One oder Zero angezeigt.

Beachten Sie, dass es keine Rolle spielt, ob mehr aufrufbare Komponenten darunter definiert sind – nur MeasureSuperposition wird ausgeführt. Darüber hinaus ist es kein Problem, wenn Ihr aufrufbares Attribut Dokumentationskommentare vor der Deklaration enthält, das @EntryPoint() Attribut kann einfach über diesen platziert werden.

Aufrufbare Argumente

Bisher haben wir nur einen Vorgang betrachtet, der keine Eingaben annimmt. Angenommen wir möchten einen ähnlichen Vorgang ausführen, aber für mehrere Qubits, deren Anzahl als Argument bereitgestellt wird. Ein solcher Vorgang könnte geschrieben werden als

    operation MeasureSuperpositionArray(n : Int) : Result[] {
        use qubits = Qubit[n];             // allocate a register of n qubits
        ApplyToEach(H, qubits);              // apply H to each qubit in the register
        return ForEach(MResetZ, qubits);     // perform MResetZ on each qubit, returns the resulting array
        }
    }

, wobei der zurückgegebene Wert ein Array der Messergebnisse ist. Beachten Sie, dass ApplyToEach und ForEach in den Namespaces Microsoft.Quantum.Canon und Microsoft.Quantum.Arrays enthalten sind, für die jeweils zusätzliche open Anweisungen erforderlich sind.

Wenn wir das @EntryPoint() Attribut vor diesen neuen Vorgang verschieben (beachten Sie, dass es nur eine solche Zeile in einer Datei geben kann), führt der Versuch, es mit dotnet run auszuführen, zu einer dotnet run Fehlermeldung, die angibt, welche zusätzlichen Befehlszeilenoptionen erforderlich sind und wie sie ausgedrückt werden.

Das allgemeine Format für die Befehlszeile ist tatsächlich dotnet run [options] und aufrufbare Argumente werden dort bereitgestellt. In diesem Fall fehlt das n Argument und es zeigt, dass wir die Option -n <n> bereitstellen müssen. Um MeasureSuperpositionArray für n=4 Qubits ausgeführt zu werden, verwenden wir daher

dotnet run -n 4

ergibt eine Ausgabe ähnlich zu

[Zero,One,One,One]

Dies gilt natürlich auch für mehrere Argumente.

Hinweis

Argumentnamen, die in camelCase definiert sind, werden vom Compiler leicht geändert, damit sie als Q# Eingaben akzeptiert werden. Wenn wir beispielsweise anstelle von n den oben genannten Namen numQubits verwendet haben, wird diese Eingabe in der Befehlszeile über --num-qubits 4 anstelle von -n 4 bereitgestellt.

Die Fehlermeldung enthält auch andere verwendbare Optionen, einschließlich der Änderung des Zielcomputers.

Verschiedene Zielcomputer

Da die Ausgaben unserer bisher durchgeführten Vorgänge die erwarteten Ergebnisse ihrer Aktion auf echte Qubits waren, ist klar, dass der Standardzielcomputer per Befehlszeile der Quantensimulator in vollständigem Zustand (QuantumSimulator) ist. Sie können aufrufbare Komponenten jedoch dazu anweisen, dass sie auf einem bestimmten Zielcomputer mit der Option --simulator (oder der Kurzsprache -s) ausgeführt werden.

Beispielsweise könnten wir sie unter ResourcesEstimator ausführen:

dotnet run -n 4 -s ResourcesEstimator

Die gedruckte Ausgabe ist dann

Metric          Sum
CNOT            0
QubitClifford   4
R               0
Measure         4
T               0
Depth           0
Width           4
BorrowedWidth   0

Weitere Informationen dazu, was diese Metriken angeben, finden Sie unter Ressourcenschätzung: gemeldete Metriken.

Zusammenfassung der Befehlszeilen-Ausführung


Q# program from command line

Nicht-Q# dotnet run Optionen

Wie wir oben kurz mit der Option --project erwähnt haben, akzeptiert der dotnet run Befehl auch Optionen, die nicht mit den Q# aufrufbaren Argumenten in Zusammenhang stehen. Wenn sie beide Arten von Optionen bereitstellen, müssen zuerst die dotnet-spezifischen Optionen bereitgestellt werden, gefolgt von einem Trennzeichen -- und dann den Q# -spezifischen Optionen. Die Angabe eines Pfads zusammen mit einer Anzahl von Qubits für den oben genannten Vorgang würde beispielsweise über dotnet run --project <PATH> -- -n <n> ausgeführt werden.

Q# mit Hostprogrammen

Mit unserer Q# Datei ist eine Alternative zum direkten Aufrufen eines Vorgangs oder einer Funktion über die Eingabeaufforderung die Verwendung eines Hostprogramms in einer anderen klassischen Sprache. Dies kann insbesondere mit Python oder einer .NET-Sprache wie C# oder F# erfolgen (aus Gründen der Kürze werden wir hier nur C# ausführlich beschreiben). Es ist etwas mehr Setup erforderlich, um die Interoperabilität zu ermöglichen. Diese Details finden Sie jedoch in den Installationshandbüchern.

Kurz gesagt enthält die Situation jetzt eine Hostprogrammdatei (z. B. *.py oder *.cs) am gleichen Speicherort wie unsere Q# Datei. Es ist jetzt das Hostprogramm, das ausgeführt wird, und während der Ausführung kann es bestimmte Q# Vorgänge und Funktionen aus der Datei Q# aufrufen. Der Kern der Interoperabilität basiert darauf, dass der Q# Compiler den Inhalt der Q# Datei für das Hostprogramm zugänglich macht, sodass sie aufgerufen werden können.

Einer der Hauptvorteile der Verwendung eines Hostprogramms besteht darin, dass die vom Q# Programm zurückgegebenen klassischen Daten dann in der Hostsprache weiter verarbeitet werden können. Dies kann aus einer erweiterten Datenverarbeitung bestehen (z. B. etwas, das nicht intern in Q# ausgeführt werden kann) und dann weitere Q# Aktionen auf der Grundlage dieser Ergebnisse aufrufen, oder etwas, das so einfach wie das Zeichnen der Q# Ergebnisse ist.

Das allgemeine Schema wird hier gezeigt und nachfolgend werden die spezifischen Implementierungen für Python und C# erläutert. Ein Beispiel mit einem F#-Hostprogramm finden Sie unter .NET-Interoperabilitätsbeispiele.


Q# program from a host program

Hinweis

Das für Anwendungen verwendete @EntryPoint() Attribut für Q# Anwendungen kann nicht mit Hostprogrammen verwendet werden. Ein Fehler wird ausgelöst, wenn er in der Q# Datei vorhanden ist, die von einem Host aufgerufen wird.

Für die Arbeit mit verschiedenen Hostprogrammen sind keine Änderungen an einer *.qs Q# Datei erforderlich. Die folgenden Hostprogrammimplementierungen funktionieren alle mit derselben Q# Datei:

namespace NamespaceName {
    open Microsoft.Quantum.Intrinsic;     // contains H
    open Microsoft.Quantum.Measurement;   // MResetZ
    open Microsoft.Quantum.Canon;         // ApplyToEach
    open Microsoft.Quantum.Arrays;        // ForEach

    operation MeasureSuperposition() : Result {
        use q = Qubit();
        H(q);
        return MResetZ(q);
        
    }

    operation MeasureSuperpositionArray(n : Int) : Result[] {
        use qubits = Qubit[n];
        ApplyToEach(H, qubits); 
        return ForEach(MResetZ, qubits);    
        
    }
}

Wählen Sie die Registerkarte aus, die Ihrer gewünschten Hostsprache entspricht.

Ein Python-Hostprogramm wird wie folgt erstellt:

  1. Zuerst importieren wir das qsharp Modul, das den Modullader für die Q# Interoperabilität registriert. Dadurch können Q# Namespaces als Python-Module angezeigt werden, aus denen aufrufbare Q# Objekte „importiert“ werden können. Beachten Sie, dass es technisch gesehen nicht die aufrufbaren Q# Objekte selbst sind, die importiert werden, sondern Python-Stubs, welche das Aufrufen ermöglichen. Diese verhalten sich wie Objekte von Python-Klassen. Wir verwenden Methoden für diese Objekte, um die Zielcomputer anzugeben, an die der Vorgang gesendet wird, wenn das Programm ausgeführt wird.

  2. Importieren Sie die aufrufbaren Q# Komponenten, die wir direkt aufrufen – in diesem Fall MeasureSuperposition und MeasureSuperpositionArray.

    import qsharp
    from NamespaceName import MeasureSuperposition, MeasureSuperpositionArray
    

    Wenn das qsharp Modul importiert wurde, können Sie aufrufbare Objekte auch direkt aus den Q# Bibliotheksnamespaces importieren.

  3. Neben jedem anderen Python-Code können Sie diese aufrufbaren Objekte jetzt auf bestimmten Zielcomputern aufrufen und ihre Rückgabe Variablen (wenn sie einen Wert zurückgeben) zur weiteren Verwendung zuweisen.

Angeben von Zielcomputern

Das Aufrufen eines Vorgangs, der auf einem bestimmten Zielcomputer ausgeführt werden soll, erfolgt über verschiedene Python-Methoden für das importierte Objekt. .simulate(<args>) verwendet bspw. QuantumSimulator, um den Vorgang zu ausführen, während .estimate_resources(<args>) dies auf ResourcesEstimator tut.

Übergeben von Eingaben an Q#

Argumente für die aufrufbaren Q# Objekte sollten in Form eines Schlüsselwortarguments bereitgestellt werden, wobei das Schlüsselwort der Argumentname in der Q# aufrufbaren Definition ist. Das heißt, MeasureSuperpositionArray.simulate(n=4) ist gültig, während MeasureSuperpositionArray.simulate(4) einen Fehler auslösen würde.

Daher führt das Python-Hostprogramm

import qsharp
from NamespaceName import MeasureSuperposition, MeasureSuperpositionArray

single_qubit_result = MeasureSuperposition.simulate()
single_qubit_resources = MeasureSuperposition.estimate_resources()

multi_qubit_result = MeasureSuperpositionArray.simulate(n=4)
multi_qubit_resources = MeasureSuperpositionArray.estimate_resources(n=4)

print('Single qubit:\n' + str(single_qubit_result))
print(single_qubit_resources)

print('\nMultiple qubits:\n' + str(multi_qubit_result))
print(multi_qubit_resources)

zu einer Ausgabe ähnlich der folgenden:

Single qubit:
1
{'CNOT': 0, 'QubitClifford': 1, 'R': 0, 'Measure': 1, 'T': 0, 'Depth': 0, 'Width': 1, 'BorrowedWidth': 0}

Multiple qubits:
[0, 1, 1, 1]
{'CNOT': 0, 'QubitClifford': 4, 'R': 0, 'Measure': 4, 'T': 0, 'Depth': 0, 'Width': 4, 'BorrowedWidth': 0}

Verwenden von Q# Code aus anderen Projekten oder Paketen

Standardmäßig lädt der import qsharp Befehl alle .qs Dateien im aktuellen Ordner und stellt ihre Q# Vorgänge und Funktionen für die Verwendung im Python-Skript zur Verfügung.

Um Q# Code aus einem anderen Ordner zu laden, kann mithilfe der qsharp.projects API ein Verweis auf eine .csproj Datei für ein Q# Projekt (d. h. ein Projekt, das auf Microsoft.Quantum.Sdk verweist) hinzugefügt werden. Mit diesem Befehl werden alle .qs Dateien in dem Ordner kompiliert, der .csproj und seine Unterordner enthält. Außerdem werden alle Pakete rekursiv geladen, auf die über PackageReference oder Q# Projekte verwiesen wird, auf die ProjectReference in dieser .csproj Datei verweist.

Beispielsweise importiert der folgende Python-Code ein externes Projekt, verweist auf seinen Pfad relativ zum aktuellen Ordner und ruft einen seiner Q# Vorgänge auf:

import qsharp
qsharp.projects.add("../qrng/Qrng.csproj")
from Qrng import SampleQuantumRandomNumberGenerator
print(f"Qrng result: {SampleQuantumRandomNumberGenerator.simulate()}")

Dies führt zu einer Ausgabe wie der folgenden:

Adding reference to project: ../qrng/Qrng.csproj
Qrng result: 0

Um externe Pakete mit Code Q# zu laden, verwenden Sie die qsharp.packages API.

Wenn der Q# Code im aktuellen Ordner von externen Projekten oder Paketen abhängt, werden beim Ausführen von import qsharp möglicherweise Fehler angezeigt, da die Abhängigkeiten noch nicht geladen wurden. Um erforderliche externe Pakete oder Q# Projekte während des import qsharp Befehls zu laden, stellen Sie sicher, dass der Ordner mit dem Python-Skript eine .csproj Datei enthält, die auf Microsoft.Quantum.Sdk verweist. Fügen Sie in .csproj diesem die Eigenschaft <IQSharpLoadAutomatically>true</IQSharpLoadAutomatically> der <PropertyGroup> hinzu. Dadurch wird IQ# angewiesen, während des import qsharp Befehls rekursiv alle ProjectReference oder PackageReference Elemente zu laden, die in diesem .csproj gefunden wurden.

Hier ist beispielsweise eine einfache .csproj Datei, die bewirkt, dass IQ# das Microsoft.Quantum.Chemistry Paket automatisch lädt:

<Project Sdk="Microsoft.Quantum.Sdk/0.12.20072031">
    <PropertyGroup>
        <OutputType>Library</OutputType>
        <TargetFramework>netstandard2.1</TargetFramework>
        <IQSharpLoadAutomatically>true</IQSharpLoadAutomatically>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Quantum.Chemistry" Version="0.12.20072031" />
    </ItemGroup>
</Project>

Hinweis

Derzeit ist diese benutzerdefinierte <IQSharpLoadAutomatically> Eigenschaft für Python-Hosts erforderlich, aber in Zukunft kann dies das Standardverhalten für eine .csproj Datei werden, die sich im selben Ordner wie das Python-Skript befindet.

Hinweis

Derzeit wird die <QsharpCompile> Einstellung in .csproj von Python-Hosts ignoriert und alle .qs Dateien im Ordner von .csproj (einschließlich Unterordner) werden geladen und kompiliert. Die Unterstützung für .csproj Einstellungen wird in Zukunft verbessert (weitere Informationen finden Sie unter iqsharp#277).

Q# Jupyter Notebooks

Q# Jupyter Notebooks verwenden den IQ# Kernel, mit dem Sie aufrufbare Q# Komponenten in einem einzelnen Notebook definieren, kompilieren und ausführen können – zusammen mit Anweisungen, Notizen und anderen Inhalten. Dies bedeutet, dass es zwar möglich ist, den Inhalt von *.qs Q# Dateien zu importieren und zu verwenden, sie im Ausführungsmodell jedoch nicht erforderlich sind.

Hier erläutern wir, wie die oben definierten Q# Vorgänge ausgeführt werden. Eine umfassendere Einführung in die Verwendung von Q# Jupyter Notebooks finden Sie unter Einführung in Q# und Jupyter Notebooks.

Definieren von Vorgängen

In einem Q# Jupyter Notebook geben Sie Q# Code genau wie im Namespace einer Q# Datei ein.

Daher können wir den Zugriff auf aufrufbare Komponenten aus den Q# Standardbibliotheken mit open Anweisungen für ihre jeweiligen Namespaces ermöglichen. Beim Ausführen einer Zelle mit einer solchen Anweisung sind die Definitionen aus diesen Namespaces im gesamten Arbeitsbereich verfügbar.

Hinweis

Aufrufbare Komponenten aus Microsoft.Quantum.Intrinsic und Microsoft.Quantum.Canon (z. B. H und ApplyToEach) sind automatisch für Vorgänge verfügbar, die in Zellen bei Q# Jupyter Notebooks definiert sind. Dies gilt jedoch nicht für Code, der aus externen Q# Quelldateien eingeführt wurde (ein Prozess, der unter Einführung in Q# und Jupyter Notebooks gezeigt wird).

Ebenso erfordert das Definieren von Vorgängen nur das Schreiben des Q# Codes und das Ausführen der Zelle.

Jupyter cell defining Q# operations

Die Ausgabe listet dann diese Vorgänge auf, die dann aus zukünftigen Zellen aufgerufen werden können.

Zielcomputer

Die Funktionalität zum Ausführen von Vorgängen auf bestimmten Zielcomputern wird über IQ# Magic Commands bereitgestellt. Beispielsweise verwendet %simulate die QuantumSimulator – und %estimate verwendet ResourcesEstimator:

Jupyter cell simulating a Q# operation and running resource estimation

Übergeben von Eingaben an Funktionen und Vorgänge

Um Eingaben an die Q# Vorgänge zu übergeben, können die Argumente als key=value Paare an den Befehl „run magic“ übergeben werden. Um also MeasureSuperpositionArray mit vier Qubits auszuführen, können wir %simulate MeasureSuperpositionArray n=4 ausführen:

Jupyter cell simulating a Q# operation with arguments

Dieses Muster kann auf ähnliche Weise mit %estimate und anderen Ausführungsbefehlen verwendet werden.

Verwenden von Q# Code aus anderen Projekten oder Paketen

Standardmäßig lädt ein Q# Jupyter Notebook alle .qs Dateien im aktuellen Ordner und stellt deren Q# Vorgänge und Funktionen zur Verwendung aus dem Notebook zur Verfügung. Der %who Magic-Befehl listet alle derzeit verfügbaren Q# Vorgänge und Funktionen auf.

Zum Laden von Q# Code aus einem anderen Ordner kann der %project Befehl „magic“ verwendet werden, um einen Verweis auf eine .csproj Datei für ein Q# Projekt (d. h. ein Projekt, das auf Microsoft.Quantum.Sdk verweist) hinzuzufügen. Mit diesem Befehl werden alle .qs Dateien in dem Ordner kompiliert, der .csproj und seine Unterordner enthält. Außerdem werden alle Pakete rekursiv geladen, auf die über PackageReference oder Q# Projekte verwiesen wird, auf die ProjectReference in dieser .csproj Datei verweist.

Beispielsweise simulieren die folgenden Zellen einen Q# Vorgang aus einem externen Projekt, bei dem relativ zum aktuellen Ordner auf den Projektpfad verwiesen wird:

Jupyter cell simulating a Q# operation from an external project

Um externe Pakete mit Code Q# zu laden, verwenden Sie die %package API. Beim Laden eines Pakets werden auch alle benutzerdefinierten Magic-Befehle oder Anzeigeencoder verfügbar, die in allen Assemblys enthalten sind, die Teil des Pakets sind.

Um externe Pakete oder Q# Projekte zur Initialisierungszeit des Notebooks zu laden, stellen Sie sicher, dass der Notebook-Ordner eine .csproj Datei enthält, die auf Microsoft.Quantum.Sdk verweist. Fügen Sie in .csproj diesem die Eigenschaft <IQSharpLoadAutomatically>true</IQSharpLoadAutomatically> der <PropertyGroup> hinzu. Dadurch wird IQ# angewiesen, rekursiv alle ProjectReference oder PackageReference Elemente zu laden, die in diesem .csproj bei Notebook-Ladezeit gefunden wurden.

Hier ist beispielsweise eine einfache .csproj Datei, die bewirkt, dass IQ# das Microsoft.Quantum.Chemistry Paket automatisch lädt:

<Project Sdk="Microsoft.Quantum.Sdk/0.12.20072031">
    <PropertyGroup>
        <OutputType>Library</OutputType>
        <TargetFramework>netstandard2.1</TargetFramework>
        <IQSharpLoadAutomatically>true</IQSharpLoadAutomatically>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Quantum.Chemistry" Version="0.12.20072031" />
    </ItemGroup>
</Project>

Hinweis

Derzeit ist diese benutzerdefinierte <IQSharpLoadAutomatically> Eigenschaft für Q# Jupyter Notebook-Hosts erforderlich, aber in Zukunft kann dies das Standardverhalten für eine .csproj Datei werden, die sich im selben Ordner wie die Notebook-Datei befindet.

Hinweis

Derzeit wird die <QsharpCompile> Einstellung in .csproj von Q# Jupyter Notebook-Hosts ignoriert und alle .qs Dateien im Ordner von .csproj (einschließlich Unterordner) werden geladen und kompiliert. Die Unterstützung für .csproj Einstellungen wird in Zukunft verbessert (weitere Informationen finden Sie unter iqsharp#277).