Entwurf und Implementierung von Quantenalgorithmen mit Programmierung auf funktionaler Ebene
Einführung
Die Modellierung auf funktionaler Ebene ist der Hauptunterschied zwischen den bestehenden Methoden zur Konstruktion von Quantenschaltungen auf der Basis von Gates.
In dieser Application Note erfahren wir, wie einfach es ist, Algorithmen mit der Classiq-Plattform zu entwerfen. Beginnen wir mit einem der grundlegendsten Bausteine beim Entwurf von Quantenalgorithmen: der Zustandsvorbereitung. Der Zustand, den wir erzeugen wollen, ist die folgende Verteilung der Wahrscheinlichkeiten über 8 mögliche Zustände:
Da der Wahrscheinlichkeitsvektor über 8 mögliche Zustände geht, wissen wir, dass das Register, das die Werte speichert, 3 Qubits enthält (23=8).
Letzter Kreislauf
Beginnen wir am Ende, mit der endgültigen Schaltung, die wir erstellen werden, und gehen wir dann durch den Prozess des Aufbaus. Auf der hohen Ebene, der Ebene, auf der wir sie entwerfen werden, wird die Schaltung einfach dadurch dargestellt, was sie tun soll - einen Zustand mit 3 Qubits vorbereiten.
Dieser Block wird durch einige zugrundeliegende Gatter implementiert, die von der Classiq-Plattform automatisch entsprechend der von uns definierten Funktionalität synthetisiert werden. Die zugrundeliegende Schaltung ist unten zu sehen, wobei weitere Blöcke der Funktionsebene sichtbar sind.
Wir können diese Schaltung besser verstehen, wenn wir einen weiteren Block erweitern. Das Kernkonzept hinter der Programmierung auf Funktionsebene besteht darin, auf der abstraktesten Ebene zu entwerfen und die Classiq-Plattform die beste Implementierung eines solchen Entwurfs auf den unteren, gatterbasierten Ebenen berechnen zu lassen.
Wie man ein Funktionsmodell erstellt
Mit der Classiq-Plattform erstellen wir funktionale Modelle des Quantenalgorithmus, und dann lassen wir die Plattform die optimierte Schaltung für die gegebenen Modelle synthetisieren.
Für jeden Algorithmus, sei es der einfachste oder der komplexeste, wird das Modell in der Classiq IDE in drei einfachen Schritten erstellt:
- Definition der Funktionsblöcke - in unserem Beispiel haben wir nur 1 Funktionsblock, die Zustandsvorbereitung.
- Definition eines High-Level-Funktionsmodells, das die Funktionsblöcke enthalten wird.
- Verdrahtung der Blöcke innerhalb des High-Level-Funktionsmodells.
Zunächst sollten wir sicherstellen, dass wir die richtige Classiq-Version haben und uns in der richtigen Arbeitsumgebung befinden. Obwohl die Funktionalität mit dem Classiq Python SDK gleichwertig ist, wird in dieser Application Note unsere Classiq Integrated Development Environment (IDE) verwendet.
0. Einstieg in die Classiq-Plattform
Die Classiq-IDE ist unter platform.classiq.io verfügbar, wobei der Zugang auf authentifizierte akademische und Unternehmensnutzer beschränkt ist.
Sobald der Zugang bestätigt ist, melden Sie sich an, indem Sie auf das Symbol in der oberen rechten Ecke klicken. Daraufhin wird ein Anmeldebildschirm angezeigt, in dem die eingegebenen Anmeldedaten mit den für die Authentifizierung angegebenen Daten übereinstimmen müssen.
Nach erfolgreicher Anmeldung zeigt der IDE-Bildschirm vier Hauptbereiche an.
- Die Seitenleiste auf der linken Seite (grau) zeigt die Synthese, die Schaltungsansicht und -analyse sowie die Ausführung an - derzeit wird die Synthese angezeigt, in der wir unsere Algorithmen entwerfen.
- Der Upload-Bereich (gelb) ermöglicht es Benutzern, bereits erstellte Modelle in die Classiq-Plattform einzubringen.
- Der Modellbereich (rosa) ist der Bereich, in dem wir unsere Entwürfe erstellen, wobei die Modelle aus Einschränkungen bestehen, die die Größe, Genauigkeit usw. unserer Schaltungen begrenzen, sowie aus dem logischen Fluss, der angibt, welche Funktionen unsere Schaltungen haben werden oder welche Probleme sie lösen.
- Das Bedienfeld für Anwendungssuiten und Anpassungen (blau) enthält Beispiele und Parameter, mit denen die Benutzer ihre Algorithmen anpassen können.
1. Definition des Funktionsblocks - Logikfluss
Der Funktionsblock, den wir haben, ist die Zustandsvorbereitung. Wir werden ein StatePreparation-Objekt definieren, das die Funktionalität kapselt, die wir im logischen Fluss unseres Modells benötigen. Dieses Objekt erhält Parameter, wie z. B. die gewünschte Wahrscheinlichkeitsverteilung und eine Obergrenze für einen Fehler der Implementierung (da es normalerweise einen Kompromiss zwischen der Genauigkeit der Implementierung und der Anzahl der Qubits und/oder der Tiefe der Schaltung gibt).
Die endgültige Schaltung implementiert die gewünschte Wahrscheinlichkeitsverteilung mit einem Fehler, in diesem Fall die Kullback-Leibler-Divergenz, die durch die angegebene Obergrenze von 0,1 begrenzt ist. Dies ist ein Maß dafür, wie nahe die aus unserer Schaltung resultierenden Wahrscheinlichkeiten an den von uns definierten liegen.
2. Definition des High-Level-Funktionsmodells - Hardware-Beschränkungen
Das High-Level-Funktionsmodell kapselt die Funktionalität unseres Algorithmus - insbesondere den StatePreparation-Block, den wir definiert haben. Das Modell wird in dem .json-Codeblock gespeichert, der aus dem bereits definierten Logikfluss sowie allen Hardware-Einschränkungen besteht. In diesem Fall verhindern wir, dass Schaltungen mit mehr als 12 Qubits oder mehr als 200 Gattern auf dem am häufigsten verwendeten Qubit synthetisiert werden.
Wir können diese Beschränkungen hinzufügen, indem wir den folgenden Code eingeben oder indem wir die Werte in den Abschnitt zur Anpassung der Beschränkungen auf der rechten Seite eingeben, der den Code des Modells automatisch anpasst.
3. Verdrahtung der Blöcke innerhalb des High-Level-Funktionsmodells
In der IDE kombinieren oder verdrahten wir unsere Funktionsblöcke im Logikfluss miteinander, und da wir nur eine Funktion haben (unsere StatePreparation), ist unser Modell vollständig entworfen und bereit für die Synthese. In den kommenden Anwendungshinweisen werden wir anspruchsvollere Beispiele sehen, die die Verdrahtung von Funktionen miteinander zeigen, wobei viele Beispielprogramme in unserer Dokumentation verfügbar sind.
Um unsere Schaltung zu synthetisieren, klicken Sie einfach auf die Schaltfläche Synthesize in der unteren rechten Ecke.
Das war's! Wir haben unseren Schaltkreis und können die Funktionsebenen erkunden, indem wir mit den Plus-/Minus-Symbolen auf dem Schaltkreis interagieren oder die Symbolleiste auf der rechten Seite verwenden.
Ausführen eines Funktionsmodells
Jetzt können wir unsere Schaltung ausführen, um die Messergebnisse zu erhalten. Wenn wir zur Registerkarte "Ausführung" navigieren, sehen wir alle Hardware-Optionen mit Hersteller - IBM Quantum, Azure Quantum, AWS Braket, IonQ oder NVIDIA - und Typ - Simulator oder Hardware - Filter aufgelistet.
Wir wählen den ibm_qasm_simulator, verwenden 1000 Aufnahmen und klicken auf "Ausführen".
Während die Schaltung ausgeführt wird, wird ein Fortschrittsbalken angezeigt, und anschließend werden die Ergebnisse angezeigt.
Die Anzahl unserer Messungen wird im Histogramm angezeigt, und wir können unsere Ausführungsergebnisse auch als .json-Datei mit weiteren Informationen herunterladen.
Herzlichen Glückwunsch!
Mit wenig Aufwand oder Verständnis der gatterbasierten Ebene unseres Algorithmus konnten wir definieren, was wir auf der höchsten Ebene ausführen wollten, und die Classiq-Plattform nutzen, um die Schaltung für uns zu synthetisieren. In dieser Application Note haben wir gelernt, was Programmierung auf funktionaler Ebene ist, und einen einfachen Zustandsvorbereitungsalgorithmus mit der Classiq IDE entworfen. Weitere Informationen über die Classiq-Plattform finden Sie auf unserer Website, in unserer Dokumentation oder bei einem Demo-Termin.