Passmanager
qiskit.passmanager
Übersicht
Der Qiskit-Pass-Manager ist vom LLVM-Compiler inspiriert. Die Compiler-Infrastruktur unterteilt die Aufgaben in drei Hauptkomponenten: Aufgaben, Ablaufsteuerungen und Pass-Manager.
Eine Kompilierungspipeline führt eine Abfolge von Objekten Task aus, von denen jedes eine Zwischenrepräsentation (IR) als Eingabe entgegennimmt, eine Verarbeitung durchführt und eine – möglicherweise andere – IR als Ausgabe zurückgibt. Wobei die Schnittstelle definiert Task , ist eine atomare Aufgabe ein Pass, der eine Unterklasse von bildet und GenericPass dessen abstrakte run() Methode implementiert. Dies ist die Klasse, die als Basisklasse verwendet werden sollte, wenn ein benutzerdefinierter Compiler-Durchlauf implementiert wird.
Ablaufsteuerungen stellen Ausführungsmodelle für eine Reihe von Aufgaben bereit. Der einfachste Ablaufsteuerer ist ein FlowControllerLinear, der lediglich eine Reihe von Aufgaben in linearer Reihenfolge ausführt. Fortgeschrittenere Ablaufsteuerungen umfassen Schleifen oder bedingte Ausführung. Diese werden beispielsweise in den voreingestellten Transpiler-Pipelines von Qiskit für höhere Optimierungsstufen verwendet, bei denen Optimierungen so lange durchgeführt werden, bis ein Konvergenzkriterium erfüllt ist.
Pass-Manager sind für die Verwaltung der Aufgaben zuständig, einschließlich der Planung erforderlicher Analysen und der Ermöglichung von Änderungen an der Aufgabenabfolge durch den Benutzer. Qiskit stellt in diesem Modul zwei IR-generische Pass-Manager sowie einen Pass-Manager bereit, der speziell auf DAGCircuit als IR in ausgerichtet ist qiskit.transpiler. Die IR-generischen sind:
-
BasePassManager: ein Pass-Manager mit festem IR. Mit diesem Pass-Manager lassen sich die auszuführenden Aufgaben anpassen, und er unterstützt die parallele Ausführung mehrerer Eingaben mithilfe vonparallel_map(). Diese Klasse bietet Unterstützung für die weitere Konvertierung einer Eingabeprogrammdarstellung in das interne IR sowie für die Konvertierung in ein Ausgabeprogrammformat.Die ist
BasePassManagerdie Basisklasse für die voreingestellten Pass-Manager von Qiskit zurDAGCircuitTranspilation, wie sie beispielsweise von zurückgegeben werdengenerate_preset_pass_manager(). Dort werden implizite Konvertierungen in das bzw. ausQuantumCircuitdem Eingabe- und Ausgabeprogrammformat verwendet. -
MultiStagePassManager: ein gestufter Pass-Manager, bei dem jede Stufe den IR beibehalten oder verringern kann. Eine Stufe wird durch ein oderTaskein iterierbares Element davon definiert, das auch innerhalb eines gruppiert werden kannBasePassManager. Die Stufen müssen so eingerichtet werden, dass der Ausgangs-IR der aktuellen Stufe mit dem Eingangs-IR der nächsten Stufe übereinstimmt; es gibt (derzeit) keine automatischen Übersetzungen.
Pass-Manager stellen zudem eine Infrastruktur bereit, um ein PropertySet mit Kontextinformationen durch jede Aufgabe weiterzuleiten, sowie eine Callback-Funktion zur Introspektion. Das PropertySet ist ein frei definierbares Wörterbuch, das während der Ausführung durch einen Durchlauf gefüllt und gelesen werden kann oder von einem Ablaufsteuerer gelesen wird, um die Ausführung des Durchlaufs zu steuern. Die Eigenschaftsmenge ist übertragbar und wird bei der Ausführung von Durchlauf zu Durchlauf weitergegeben. Zusätzlich zu den Eigenschaften erhalten Aufgaben auch eine WorkflowStatus Datenstruktur. Dieses Objekt wird beim Start des Pass-Managers initialisiert und an die zugrunde liegenden Aufgaben übergeben. Der Status wird nach jedem Durchlauf aktualisiert und enthält Informationen zum Zustand der Pipeline (Anzahl der durchgeführten Durchläufe, Fehlerzustand usw.), im Gegensatz zum PropertySet, der Informationen zum zu optimierenden IR enthält.
Der Callback wird von Instanzen GenericPass aufgerufen, die die folgende Signatur erwarten:
def callback(
*,
task: Task[IR_IN, IR_OUT],
passmanager_ir: IR_OUT,
property_set: PropertySet,
running_time: float,
count: int
) -> None:
...Beachten Sie, dass sich diese Signatur bei Pässen und Pass-Managern, die im Modul qiskit.transpiler definiert sind, geringfügig unterscheidet.
Beispiele
Wir befassen uns mit einer einfachen Optimierungsaufgabe, bei der es darum geht, eine Zahlenreihe zu erstellen und eine Ziffer zu entfernen, wenn die Zahl „fünf“ lautet. Eine solche Aufgabe lässt sich leicht lösen, indem man die Eingabezahlen in Zeichenfolgen umwandelt. Wir nutzen hier das Pass-Manager-Framework und lassen die Effizienz einmal außer Acht, um zu lernen, wie man einen benutzerdefinierten Qiskit-Compiler erstellt.
from qiskit.passmanager import BasePassManager, GenericPass, ConditionalController
class ToyPassManager(BasePassManager):
def _passmanager_frontend(self, input_program: int, **kwargs) -> str:
return str(input_program)
def _passmanager_backend(self, passmanager_ir: str, in_program: int, **kwargs) -> int:
return int(passmanager_ir)Dieser Pass-Manager gibt eine ganze Zahl ein und aus, während er die Optimierungsaufgaben für eine Zeichenkette durchführt. Daher sind die Typen input, IR und output jeweils integer, string und integer. Die Methode _passmanager_frontend() definiert die Umwandlung von Eingangsdaten in IR, und _passmanager_backend() definiert die Umwandlung von IR in Ausgangsdaten. Das Backend des Pass-Managers erhält außerdem einen in_program -Parameter, der die ursprüngliche input_program für das Frontend enthält, um alle ursprünglichen Metadaten des Eingabeprogramms für die endgültige Konvertierung zu referenzieren.
Als Nächstes implementieren wir einen Pass, der eine Ziffer entfernt, wenn die Zahl fünf ist.
class RemoveFive(GenericPass):
def run(self, passmanager_ir: str):
return passmanager_ir.replace("5", "")
task = RemoveFive()Zuletzt instanziieren wir einen Pass-Manager und planen die Aufgabe damit. Wenn man den Pass-Manager mit einer zufälligen Zahlenreihe ausführt, erhält man neue Zahlen, die die 5 nicht enthalten.
pm = ToyPassManager()
pm.append(task)
pm.run([123456789, 45654, 36785554])Ausgabe:
[12346789, 464, 36784]Betrachten wir nun den Fall der bedingten Ausführung. Wir vermeiden die Ausführung der Aufgabe "Fünf entfernen", wenn die eingegebene Zahl sechs oder weniger Ziffern hat. Eine solche Steuerung kann durch einen Durchflussregler erfolgen. Wir beginnen mit einem Analysedurchlauf, der dem Flussregler Informationen über die Anzahl der Ziffern liefert.
class CountDigits(GenericPass):
def run(self, passmanager_ir: str):
self.property_set["ndigits"] = len(passmanager_ir)
analysis_task = CountDigits()Anschließend verpacken wir die Aufgabe „remove five“ in die ConditionalController , die die gespeicherten Aufgaben nur dann ausführt, wenn die Bedingung erfüllt ist.
def digit_condition(property_set):
# Return True when condition is met.
return property_set["ndigits"] > 6
conditional_task = ConditionalController(
tasks=[RemoveFive()],
condition=digit_condition,
)Wie zuvor planen wir diese Pässe mit dem Passmanager und führen sie aus.
pm = ToyPassManager()
pm.append(analysis_task)
pm.append(conditional_task)
pm.run([123456789, 45654, 36785554])Ausgabe:
[12346789, 45654, 36784]Die Aufgabe "Fünf entfernen" wird nur für den ersten und dritten Eingabewert ausgelöst, die mehr als sechs Ziffern haben.
Mit dem Pass-Manager-Framework kann ein Entwickler die Optimierungsaufgabe flexibel anpassen, indem er mehrere Durchläufe und Ablaufsteuerungen kombiniert. Weitere Informationen finden Sie in der folgenden API-Dokumentation zur Klasse.
Schnittstelle
Bestanden
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
GenericPass() | Basisklasse einer Einzelpassmanageraufgabe. |
Task() | Eine Schnittstelle der Pass-Manager-Aufgabe. |
Pass-Manager
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
BasePassManager( [Aufgaben, max_iteration] ) | Pass Manager Basisklasse. |
MultiStagePassManager(**Bühnen) | Ein Manager für gestaffelte Übergaben, der mehrere IRs unterstützt. |
Durchflussregler
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
BaseController( [Optionen] ) | Basisklasse des Controllers. |
FlowControllerLinear( [Aufgaben, Optionen] ) | Ein Standardflussregler, der Aufgaben nacheinander ausführt. |
ConditionalController( [Aufgaben, Bedingungen,...] ) | Ein Flusscontroller führt die Pipeline einmal aus, wenn die Bedingung wahr ist, oder tut nichts, wenn die Bedingung falsch ist. |
DoWhileController( [Aufgaben, do_while, Optionen] ) | Führen Sie die angegebenen Aufgaben in einer Schleife aus, bis die Bedingung do_while für den Eigenschaftssatz False lautet. |
Zusammenstellungsstatus
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
PropertySet | Ein standardmäßiges wörterbuchähnliches Objekt. |
WorkflowStatus( [Anzahl, abgeschlossene_Durchläufe,...] ) | Sammlung des Kompilierungsstatus des Workflows, d.h. Pass Manager Run. |
PassManagerState(workflow_status, property_set) | Ein tragbares Container-Objekt, das die Aufgaben des Pass-Managers über den Generator kommuniziert. |
Ausnahmen
PassManagerError
exception qiskit.passmanager.PassManagerError(*message)
Basen: QiskitError
Fehler des Passmanagers.
Legen Sie die Fehlermeldung fest.