Einführung in die Quantenprogrammiersprache Q#
Q# ist eine allgemeine, Open Source- Programmiersprache, die von Microsoft zum Schreiben von Quantenprogrammen entwickelt wurde. Q# ist im Quantum Development Kit (QDK) enthalten. Weitere Informationen finden Sie unter Einrichten des Quantum Development Kit.
Als Quantenprogrammiersprache erfüllt Q# die folgenden Anforderungen für Sprache, Compiler und Laufzeit:
- Hardwareagnostisch: Qubits in Quantenalgorithmen sind nicht an eine bestimmte Quantenhardware oder ein bestimmtes Layout gebunden. Der Q# Compiler und die Laufzeit verarbeiten die Zuordnung von Programmqubits zu physischen Qubits, sodass derselbe Code auf verschiedenen Quantenprozessoren ausgeführt werden kann.
- Integration von Quanten- und klassischem Computing:Q# ermöglicht die Integration von Quanten- und klassischen Berechnungen, die für die universelle Quantenberechnung unerlässlich sind.
- Qubit-Verwaltung:Q# bietet integrierte Vorgänge und Funktionen für die Verwaltung von Qubits, einschließlich der Erstellung von Superpositionszuständen, Verschränken von Qubits und Durchführung von Quantenmessungen.
- respektieren die Gesetze der Physik:Q# und Quantenalgorithmen müssen die Regeln der Quantenphysik einhalten. Sie können z. B. nicht direkt kopieren oder auf den Qubit-Zustand zugreifen.Q#
Weitere Informationen zu den Ursprüngen von Q#finden Sie im Blogbeitrag Warum brauchen wir Q#?.
Struktur eines Q# Programms
Bevor Sie mit dem Schreiben von Q# Programmen beginnen, ist es wichtig, ihre Struktur und Komponenten zu verstehen. Betrachten Sie das folgende Q#-Programm namens Superposition, das einen Superpositionszustand erstellt:
namespace Superposition {
@EntryPoint()
operation MeasureOneQubit() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure the qubit in the Z-basis.
let result = M(q);
// Reset the qubit before releasing it.
Reset(q);
// Return the result of the measurement.
return result;
}
}
Basierend auf den Kommentaren (//
), weist das Q# Programm zuerst ein Qubit zu, wendet einen Vorgang an, um den Qubit in Superposition zu setzen, misst den Qubit-Zustand, setzt den Qubit zurück und gibt schließlich das Ergebnis zurück.
Lassen Sie uns dieses Q#-Programm in seine Komponenten unterteilen.
Benutzernamespaces
Q# Programme können optional mit einem benutzerdefinierten Namespace beginnen, z. B.:
namespace Superposition {
// Your code goes here.
}
Namespaces können Ihnen beim Organisieren verwandter Funktionen helfen. Namespaces sind optionaL in Q# Programmen, was bedeutet, dass Sie ein Programm schreiben können, ohne einen Namespace zu definieren.
Beispielsweise könnte das Superposition-Programm des Beispiels auch ohne Namespace folgendermaßen geschrieben werden:
@EntryPoint()
operation MeasureOneQubit() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure the qubit in the Z-basis.
let result = M(q);
// Reset the qubit before releasing it.
Reset(q);
// Return the result of the measurement.
return result;
}
Hinweis
Jedes Q# Programm kann nur eine namespace
haben. Wenn Sie keinen Namespace angeben, verwendet der Q# Compiler den Dateinamen als Namespace.
Einstiegspunkte
Jedes Q# Programm muss über einen Einstiegspunkt verfügen, der den Ausgangspunkt des Programms darstellt. Standardmäßig startet der Q# Compiler die Ausführung eines Programms aus dem Main()
Vorgang, sofern verfügbar, das sich an einer beliebigen Stelle im Programm befinden kann. Optional können Sie das @EntryPoint()
Attribut verwenden, um einen beliebigen Vorgang im Programm als Ausführungspunkt anzugeben.
Beispielsweise ist im Superposition-Programm der MeasureOneQubit()
-Vorgang der Einstiegspunkt des Programms, da er das Attribut @EntryPoint()
vor der Definition des Vorgangs aufweist.
@EntryPoint()
operation MeasureOneQubit() : Result {
...
}
Das Programm kann jedoch auch ohne das attribut @EntryPoint()
geschrieben werden, indem der MeasureOneQubit()
Vorgang in Main()
umbenannt wird, z. B.:
// The Q# compiler automatically detects the Main() operation as the entry point.
operation Main() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure the qubit in the Z-basis.
let result = M(q);
// Reset the qubit before releasing it.
Reset(q);
// Return the result of the measurement.
return result;
}
Typen
Typen sind in jeder Programmiersprache unerlässlich, da sie die Daten definieren, mit denen ein Programm arbeiten kann. Q# bietet die integrierten Typen, die in den meisten Sprachen üblich sind, einschließlich Int
, Double
, Bool
und String
, sowie Typen zur Definition von Bereichen, Arrays und Tupeln.
Q# bietet auch Typen, die speziell für das Quantencomputing sind. Der typ Result
stellt z. B. das Ergebnis einer Qubitmessung dar und kann zwei Werte aufweisen: Zero
oder One
.
Im Superposition-Programm gibt der MeasureOneQubit()
-Vorgang einen Result
-Typ zurück, der dem Rückgabetyp des M
-Vorgangs entspricht. Das Messergebnis wird in einer neuen Variablen gespeichert, die mithilfe der let
Anweisung definiert wird:
// The operation definition returns a Result type.
operation MeasureOneQubit() : Result {
...
// Measure the qubit in the Z-basis, returning a Result type.
let result = M(q);
...
}
Ein weiteres Beispiel für einen quantenspezifischen Typ ist der Qubit
Typ, der ein Quantenbit darstellt.
Q# ermöglicht es Ihnen auch, eigene benutzerdefinierte Typen zu definieren. Weitere Informationen finden Sie unter Typdeklarationen.
Zuordnen von Qubits
In Q# weisen Sie Qubits mithilfe des Schlüsselworts use
und des Typs Qubit
zu. Qubits werden immer im $\ket{0}$ Zustand zugewiesen.
Beispielsweise definiert das Superposition Programm ein einzelnes Qubit und speichert es in der Variablen q
:
// Allocate a qubit.
use q = Qubit();
Sie können auch mehrere Qubits zuordnen und über ihren Index auf die einzelnen Zuweisen zugreifen:
use qubits = Qubit[2]; // Allocate two qubits.
H(qubits[0]); // Apply H to the first qubit.
X(qubits[1]); // Apply X to the second qubit.
Weitere Informationen finden Sie unter Use-Anweisung.
Quantenvorgänge
Nach dem Zuordnen eines Qubits können Sie ihn an Vorgänge und Funktionen übergeben. Vorgänge sind die Grundbausteine eines Q#-Programms. Eine Q# Operation ist eine Quantenunterroutine oder eine aufrufbare Routine, die Quantenvorgänge enthält, die den Zustand des Qubit-Registers ändern.
Zum Definieren eines Q# Vorgangs geben Sie einen Namen für den Vorgang, dessen Eingaben und die Ausgabe an. Im Superposition-Programm nimmt der MeasureOneQubit()
-Vorgang keine Parameter und gibt einen Result
-Typ zurück:
operation MeasureOneQubit() : Result {
...
}
Hier ist ein einfaches Beispiel, das keine Parameter akzeptiert und keinen Rückgabewert erwartet. Der Unit
Wert entspricht NULL
in anderen Sprachen:
operation SayHelloQ() : Unit {
Message("Hello quantum world!");
}
Die Q# Standardbibliothek bietet auch Vorgänge, die Sie in Quantenprogrammen verwenden können, z. B. den Hadamard-Vorgang, H
im Superposition
Programm. Bei einem Qubit auf der Z-Basis H
wird das Qubit in eine gleichmäßige Superposition versetzt, bei der es eine 50 %-Wahrscheinlichkeit hat, als Zero
oder One
.
Messen von Qubits
Während es viele Arten von Quantenmessungen gibt, Q# konzentriert sich der Schwerpunkt auf projektiven Messungen auf einzelnen Qubits, auch als Pauli-Messungen bezeichnet.
In Q#, misst der Measure
Vorgang eine oder mehrere Qubits in der angegebenen Pauli-Basis, die kann PauliX
, , PauliY
oder PauliZ
. Measure
gibt einen Result
Typ von entweder Zero
oder One
.
Um eine Messung in der Rechenbasis $\lbrace,\ket{0}\rbrace\ket{1}$ zu implementieren, können Sie auch den Vorgang verwenden, der M
ein Qubit in der Pauli Z-Basis misst. Dies entspricht M
Measure([PauliZ], [qubit])
.
Beispielsweise verwendet das Superposition-Programm den M
-Vorgang:
// Measure the qubit in the Z-basis.
let result = M(q);
Zurücksetzen von Qubits
In Q# müssen Qubits sich im $\ket{0}$ Zustand befinden, wenn sie freigegeben werden, um Fehler bei der Quantenhardware zu vermeiden. Sie können einen Qubit auf den $\ket{0}$ Zustand zurücksetzen, indem Sie den Reset
Vorgang am Ende des Programms verwenden. Das Zurücksetzen eines Qubits führt zu einem Laufzeitfehler.
// Reset a qubit.
Reset(q);
Namespaces der Standardbibliothek
Die Q# Standardbibliothek verfügt über integrierte Namespaces, die Funktionen und Vorgänge enthalten, die Sie in Quantenprogrammen verwenden können. Beispielsweise enthält der Microsoft.Quantum.Intrinsic
Namespace häufig verwendete Vorgänge und Funktionen, z M
. B. zum Messen von Ergebnissen und Message
zum Anzeigen von Benutzermeldungen an einer beliebigen Stelle im Programm.
Um eine Funktion oder einen Vorgang aufzurufen, können Sie den vollständigen Namespace angeben oder eine import
Anweisung verwenden, die alle Funktionen und Vorgänge für diesen Namespace verfügbar macht und den Code besser lesbar macht. In den folgenden Beispielen wird derselbe Vorgang aufgerufen:
Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
// imports all functions and operations from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.*;
Message("Hello quantum world!");
// imports just the `Message` function from the Microsoft.Quantum.Intrinsic namespace.
import Microsoft.Quantum.Intrinsic.Message;
Message("Hello quantum world!");
// namespaces in the standard library may be imported using `Std` instead of `Microsoft.Quantum`.
import Std.Intrinsic.*;
Message("Hello quantum world!");
Hinweis
Das Superposition-Programm hat keine import
-Anweisungen oder Aufrufe mit vollständigen Namespaces. Das liegt daran, dass die Q# Entwicklungsumgebung automatisch zwei Namespaces lädt: Microsoft.Quantum.Core
und Microsoft.Quantum.Intrinsic
, die häufig verwendete Funktionen und Vorgänge enthalten.
Sie können den Microsoft.Quantum.Measurement
-Namespace, indem Sie den MResetZ
-Vorgang verwenden, um das Superposition-Programm zu optimieren. MResetZ
kombiniert die Mess- und Rücksetzungsvorgänge in einem Schritt, wie im folgenden Beispiel gezeigt:
// Import the namespace for the MResetZ operation.
import Microsoft.Quantum.Measurement.*;
@EntryPoint()
operation MeasureOneQubit() : Result {
// Allocate a qubit. By default, it's in the 0 state.
use q = Qubit();
// Apply the Hadamard operation, H, to the state.
// It now has a 50% chance of being measured as 0 or 1.
H(q);
// Measure and reset the qubit, and then return the result value.
return MResetZ(q);
}
Lernen Sie, Quantenprogramme mit Q# und Azure Quantum zu entwickeln
Q# und Azure Quantum sind eine leistungsstarke Kombination für die Entwicklung und Ausführung von Quantenprogrammen. Mit Q# und Azure Quantum können Sie Quantenprogramme schreiben, ihr Verhalten simulieren, ressourcenanforderungen schätzen und auf realer Quantenhardware ausführen. Diese Integration ermöglicht es Ihnen, das Potenzial von Quantencomputing zu erkunden und innovative Lösungen für komplexe Probleme zu entwickeln. Ganz gleich, ob Sie Anfänger oder erfahrene Quantenentwickler sind, und Azure Quantum stellt die Tools und Ressourcen bereit, Q# die Sie benötigen, um die Leistungsfähigkeit von Quantum Computing zu entsperren.
Das folgende Diagramm zeigt die Phasen, durch die ein Quantenprogramm bei der Entwicklung mit Q# azure Quantum übergeben wird. Ihr Programm beginnt mit der Entwicklungsumgebung und endet mit der Übermittlung des Auftrags an echte Quantenhardware.
Lassen Sie uns die Schritte im Diagramm aufschlüsseln.
Auswählen Ihrer Entwicklungsumgebung
Führen Sie Ihre Quantenprogramme in Ihrer bevorzugten Entwicklungsumgebung aus. Sie können den Onlinecode-Editor auf der Azure Quantum-Website, die gehosteten Jupyter-Notizbücher in Ihrem Azure Quantum-Arbeitsbereich im Azure-Portal oder eine lokale Entwicklungsumgebung mit Visual Studio Code verwenden. Weitere Informationen finden Sie unter "Verschiedene Möglichkeiten zum Ausführen von Q# Programmen".
Schreiben Ihres Quantenprogramms
Sie können Quantenprogramme mit Q# dem Quantum Development Kit (QDK) schreiben. Informationen zu den ersten Schritten finden Sie unter "Schnellstart: Erstellen Ihres ersten Q# Programms".
Darüber hinaus Q#bietet der QDK Unterstützung für andere Sprachen für Quantencomputing, wie Qiskit und Cirq.
Integration in Python
Sie können selbst oder zusammen mit Python in verschiedenen IDEs verwenden Q# . Sie können beispielsweise ein Q#-Projekt mit einem Python-Hostprogramm nutzen, um Q#-Vorgänge aufzurufen oder Q# mit Python in Jupyter Notebooks zu integrieren. Weitere Informationen finden Sie unter Integration von Q# und Python.
Der Befehl %%qsharp
Q# Standardmäßig verwenden Programme in Jupyter-Notizbüchern das ipykernel
Python-Paket. Wenn Sie einer Notizbuchzelle Code hinzufügen möchten Q# , verwenden Sie den %%qsharp
Befehl, der mit dem qsharp
Python-Paket aktiviert ist, gefolgt von Ihrem Q# Code.
Beachten Sie bei der Verwendung %%qsharp
Folgendes:
- Sie müssen zuerst ausgeführt
import qsharp
werden, um dies zu aktivieren%%qsharp
. %%qsharp
bereichs to the notebook cell in which it appears and changes the cell type from Python to Q#.- Sie können eine Python-Anweisung nicht vor oder nach
%%qsharp
dem Einfügen einfügen. - Q# code that follows
%%qsharp
must adhere to Q# syntax. Verwenden Sie//
z. B. anstelle von#
Kommentaren und;
zum Beenden von Codezeilen.
Ressourcen schätzen
Bevor Ihr Programm auf realer Quantenhardware ausgeführt wird, müssen Sie herausfinden, ob es auf vorhandener Hardware laufen kann und wie viele Ressourcen es benötigt.
Mit dem Azure Quantum Resource Estimator können Sie Architekturentscheidungen bewerten, Qubit-Technologien vergleichen und die ressourcen ermitteln, die zum Ausführen eines bestimmten Quantenalgorithmus erforderlich sind. Sie können aus vordefinierten fehlertoleranten Protokollen wählen und Annahmen des zugrunde liegenden physischen Qubit-Modells angeben.
Weitere Informationen finden Sie unter Ausführen der ersten Ressourcenschätzung.
Hinweis
Der Azure Quantum Resources Estimator ist kostenlos und erfordert kein Azure-Konto.
Ausführen Ihres Programms in der Simulation
Wenn Sie ein Quantenprogramm kompilieren und ausführen, erstellt der QDK eine Instanz des Quantensimulators und übergibt den Q# Code an ihn. Der Simulator verwendet den Q#-Code, um Qubits (Simulationen von Quantenteilchen) zu erstellen und Transformationen anzuwenden, um deren Zustand zu ändern. Danach werden die Ergebnisse der Quantenoperationen im Simulator an das Programm zurückgegeben. Durch die Isolierung des Q#-Codes im Simulator wird sichergestellt, dass die Algorithmen den Gesetzen der Quantenphysik folgen und ordnungsgemäß auf Quantencomputern ausgeführt werden können.
Übermitteln Sie Ihr Programm an echte Quantenhardware
Sie können Ihre Q# Programme an Azure Quantum übermitteln, um auf echter Quantenhardware ausgeführt zu werden. Sie können auch Quantenschaltungen ausführen und übermitteln, die in Qiskit- und Cirq-Sprachen geschrieben wurden. Wenn Sie ein Quantenprogramm in Azure Quantum ausführen, erstellen und führen Sie einen Einzelvorgang aus. Weitere Informationen finden Sie unter Übermitteln von Q# Programmen an Azure Quantum.
xref:microsoft.quantum.work-with-jobs
Azure Quantum bietet einige der überzeugendsten und vielfältigen Quantenhardware, die heute von Branchenführern zur Verfügung steht. Die aktuelle Liste der unterstützten Hardwareanbieter finden Sie unter Quantencomputing-Anbieter in Azure Quantum.
Hinweis
Um einen Auftrag an die Azure Quantum-Anbieter zu übermitteln, benötigen Sie ein Azure-Konto und einen Quantenarbeitsbereich. Wenn Sie keinen Quantenarbeitsbereich haben, lesen Sie " Erstellen eines Azure Quantum"-Arbeitsbereichs.
Nachdem Sie Ihren Auftrag übermittelt haben, verwaltet Azure Quantum den Auftragslebenszyklus, einschließlich Auftragsplanung, Ausführung und Überwachung. Sie können den Status Ihrer Aufgabe nachverfolgen und die Ergebnisse im Azure Quantum-Portal anzeigen. Weitere Informationen finden Sie unter Arbeiten mit Azure Quantum-Aufträgen.