Freigeben über


Quantum Memory Management

Ein Programm beginnt immer ohne Qubits, was bedeutet, dass Sie keine Werte vom Typ Qubit als Einstiegspunktargumente übergeben können. Diese Einschränkung ist beabsichtigt, da der Zweck von Q# darin besteht, ein Programm in seiner Gesamtheit auszudrücken und zu begründen. Stattdessen ordnet ein Programm Qubits oder Quantenspeicher zu und gibt sie frei, wie es geht. In dieser Hinsicht modelliert Q# den Quantencomputer als Qubit-Heap.

Anstatt separate zuzuweisen, und Release Anweisungen für den Quantenspeicher freizugeben, unterstützt Q# die Quantenspeicherzuweisung in Form von Blockanweisungen, wo der Speicher nur im Rahmen dieser Blockausweisung zugänglich ist. Der Anweisungsblock kann implizit definiert werden, wenn Qubits für die Dauer des aktuellen Bereichs zuweisen, wie in den Abschnitten zu den use und borrow Anweisungen beschrieben. Der Versuch, auf die zugewiesenen Qubits zuzugreifen, nachdem die Anweisung beendet wurde, führt zu einer Laufzeitausnahme.

Q# hat zwei Anweisungen, use und borrow, die Qubitwerte instanziieren, Arrays von Qubits oder eine beliebige Kombination davon. Sie können diese Anweisungen nur innerhalb von Vorgängen verwenden. Sie sammeln die instanziierten Qubitwerte, binden sie an die variablen, die in der Anweisung angegeben sind, und führen dann einen Block von Anweisungen aus. Am Ende des Blocks gehen die gebundenen Variablen außerhalb des Gültigkeitsbereichs und werden nicht mehr definiert.

Q# unterscheidet zwischen der Zuordnung von sauberen und schmutzigen Qubits. Clean qubits are unentangled and are not used by another part of the computation. Schmutzige Qubits sind Qubits, deren Zustand unbekannt ist und sogar mit anderen Teilen des Speichers des Quantenprozessors verangt werden kann.

Use-Anweisung

Clean qubits are allocated by the use statement.

  • Die Anweisung besteht aus dem Schlüsselwort use gefolgt von einer Bindung und einem optionalen Anweisungsblock.
  • Wenn ein Anweisungsblock vorhanden ist, sind die Qubits nur innerhalb dieses Blocks verfügbar. Andernfalls sind die Qubits bis zum Ende des aktuellen Bereichs verfügbar.
  • Die Bindung folgt demselben Muster wie let Anweisungen: entweder ein einzelnes Symbol oder ein Tupel von Symbolen, gefolgt von einem Gleichheitszeichen =und entweder ein einzelnes Tupel oder ein übereinstimmende Tupel von Initialisierern.

Initialisierer sind entweder für einen einzelnen Qubit verfügbar, der als Qubit()angegeben ist, oder ein Array von Qubits, Qubit[n], wobei n ein Int Ausdruck ist. Zum Beispiel

use qubit = Qubit();
// ...

use (aux, register) = (Qubit(), Qubit[5]);
// ...

use qubit = Qubit() {
    // ...
}

use (aux, register) = (Qubit(), Qubit[5]) {
    // ...
}

Die Qubits sind bei der Zuordnung garantiert in einem |0⟩ Zustand. Sie werden am Ende des Bereichs freigegeben und müssen nach der Veröffentlichung in einem |0⟩-Zustand sein. Diese Anforderung wird nicht vom Compiler erzwungen, da dies eine symbolische Auswertung erfordern würde, die schnell unerschwinglich teuer wird. Bei der Ausführung auf Simulatoren kann die Anforderung erzwungen werden. Bei Quantenprozessoren kann die Anforderung nicht zur Laufzeit erzwungen werden; Ein nicht gemessenes Qubit kann über eine einheitliche Transformation auf |0⟩ zurückgesetzt werden. Wenn dies nicht erfolgt, führt dies zu einem falschen Verhalten.

Die use-Anweisung weist die Qubits aus dem freien Qubit-Heap des Quantenprozessors zu und gibt sie spätestens am Ende des Bereichs zurück, in dem die Qubits gebunden sind.

Kreditauszug

Die borrow-Anweisung gewährt Zugriff auf qubits, die bereits zugeordnet sind, aber derzeit nicht verwendet werden. Diese Qubits können sich in einem beliebigen Zustand befinden und müssen sich wieder in demselben Zustand befinden, wenn die Ausleiherklärung beendet wird. Einige Quantenalgorithmen können Qubits verwenden, ohne sich auf ihren genauen Zustand zu verlassen, und ohne dass sie mit dem Rest des Systems ungekoppelt sind. Das heißt, sie benötigen vorübergehend zusätzliche Qubits, aber sie können sicherstellen, dass diese Qubits genau in ihren ursprünglichen Zustand zurückgegeben werden, unabhängig davon, welchen Zustand es war.

Wenn qubits vorhanden sind, die in Teilen einer Subroutine verwendet, aber nicht berührt werden, können diese Qubits für die Verwendung durch einen solchen Algorithmus geliehen werden, anstatt zusätzlichen Quantenspeicher zuzuweisen. Die Kreditaufnahme kann die Gesamtanforderungen an den Quantenspeicher eines Algorithmus erheblich reduzieren und ist ein Quantenbeispiel für einen typischen Raum-Zeit-Kompromiss.

Eine borrow-Anweisung folgt dem muster, das zuvor für die use-Anweisungbeschrieben wurde, wobei dieselben Initialisierer verfügbar sind. Zum Beispiel

borrow qubit = Qubit();
// ...

borrow (aux, register) = (Qubit(), Qubit[5]);
// ...

borrow qubit = Qubit() {
    // ...
}

borrow (aux, register) = (Qubit(), Qubit[5]) {
    // ...
}

Die geliehenen Qubits befinden sich in einem unbekannten Zustand und gehen am Ende des Anweisungsblocks außerhalb des Gültigkeitsbereichs. Der Darlehensnehmer verpflichtet sich, die Qubits in demselben Zustand zu verlassen wie, als sie geliehen wurden; d. h. ihr Zustand am Anfang und am Ende des Anweisungsblocks wird erwartet, dass er identisch ist.

Die borrow-Anweisung ruft In-Use-Qubits ab, die garantiert nicht vom Programm verwendet werden, wenn der Qubit bis zur letzten Verwendung dieses Qubits gebunden ist. Wenn nicht genügend Qubits zum Ausleihen verfügbar sind, werden Qubits von dem Heap wie eine use Anweisung zugewiesen und an den Heap zurückgegeben.

Hinweis

Unter den bekannten Anwendungsfällen von schmutzigen Qubits sind Implementierungen von mehrgesteuerten CNOT-Toren, die sehr wenige Qubits erfordern, und Implementierungen von Incrementer. Dieses Papier zum Faktorieren mit Qubits bietet ein Beispiel für einen Algorithmus, der geliehene Qubits verwendet.