Zum Hauptinhalt springen

Mit Pass Managern transpilieren

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

Der empfohlene Weg, einen Circuit zu transpilieren, besteht darin, einen gestuften Pass Manager zu erstellen und anschließend dessen run-Methode mit dem Circuit als Eingabe auszuführen. Diese Seite erklärt, wie du Quantum Circuits auf diese Weise transpilierst.

Was ist ein (gestufter) Pass Manager?

Im Kontext des Qiskit SDK bezeichnet Transpilierung den Prozess der Umwandlung eines Eingabe-Circuits in eine Form, die für die Ausführung auf einem Quantengerät geeignet ist. Die Transpilierung erfolgt typischerweise in einer Abfolge von Schritten, die als Transpiler-Passes bezeichnet werden. Der Circuit wird von jedem Transpiler-Pass der Reihe nach verarbeitet, wobei die Ausgabe eines Passes zur Eingabe des nächsten wird. Ein Pass könnte beispielsweise den Circuit durchlaufen und alle aufeinanderfolgenden Sequenzen von Einzel-Qubit-Gates zusammenführen, und der nächste Pass könnte diese Gates dann in den Basissatz des Zielgeräts synthetisieren. Die in Qiskit enthaltenen Transpiler-Passes befinden sich im Modul qiskit.transpiler.passes.

Ein Pass Manager ist ein Objekt, das eine Liste von Transpiler-Passes speichert und diese auf einem Circuit ausführen kann. Erstelle einen Pass Manager, indem du einen PassManager mit einer Liste von Transpiler-Passes initialisierst. Um die Transpilierung auf einem Circuit auszuführen, rufe die run-Methode mit einem Circuit als Eingabe auf.

Ein gestufter Pass Manager ist eine besondere Art von Pass Manager, der eine Abstraktionsebene über einem normalen Pass Manager darstellt. Während ein normaler Pass Manager aus mehreren Transpiler-Passes besteht, setzt sich ein gestufter Pass Manager aus mehreren Pass Managern zusammen. Dies ist eine nützliche Abstraktion, da die Transpilierung typischerweise in diskreten Stufen erfolgt, wie in Transpiler-Stufen beschrieben, wobei jede Stufe durch einen Pass Manager repräsentiert wird. Gestufte Pass Manager werden durch die Klasse StagedPassManager dargestellt. Der Rest dieser Seite beschreibt, wie du (gestufte) Pass Manager erstellst und anpasst.

Einen voreingestellten gestuften Pass Manager generieren

Um einen voreingestellten gestuften Pass Manager mit sinnvollen Standardwerten zu erstellen, verwende die Funktion generate_preset_pass_manager:

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend("ibm_fez")
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)

Um einen Circuit oder eine Liste von Circuits mit einem Pass Manager zu transpilieren, übergib den Circuit oder die Liste von Circuits an die run-Methode. Lass uns das an einem Zwei-Qubit-Circuit ausprobieren, der aus einem Hadamard gefolgt von zwei benachbarten CX-Gates besteht:

from qiskit import QuantumRegister, QuantumCircuit

# Create a circuit
qubits = QuantumRegister(2, name="q")
circuit = QuantumCircuit(qubits)
a, b = qubits
circuit.h(a)
circuit.cx(a, b)
circuit.cx(b, a)

# Transpile it by calling the run method of the pass manager
transpiled = pass_manager.run(circuit)

# Draw it, excluding idle qubits from the diagram
transpiled.draw("mpl", idle_wires=False)

Ausgabe der vorherigen Code-Zelle

Unter Transpilierungsstandards und Konfigurationsoptionen findest du eine Beschreibung der möglichen Argumente für die Funktion generate_preset_pass_manager. Die Argumente von generate_preset_pass_manager entsprechen den Argumenten der Funktion transpile.

Hast du Probleme, dir Pass-Manager-Details zu merken? Frag den Qiskit Code Assistant.

Wenn die voreingestellten Pass Manager deine Anforderungen nicht erfüllen, passe die Transpilierung an, indem du (gestufte) Pass Manager oder sogar Transpilierungs-Passes selbst erstellst. Der Rest dieser Seite beschreibt, wie du Pass Manager erstellst. Anleitungen zum Erstellen von Transpilierungs-Passes findest du unter Eigenen Transpiler-Pass schreiben.

Eigenen Pass Manager erstellen

Das Modul qiskit.transpiler.passes enthält viele Transpiler-Passes, die zur Erstellung von Pass Managern verwendet werden können. Um einen Pass Manager zu erstellen, initialisiere einen PassManager mit einer Liste von Passes. Der folgende Code erstellt beispielsweise einen Transpiler-Pass, der benachbarte Zwei-Qubit-Gates zusammenführt und sie dann in eine Basis aus RyR_y-, RzR_z- und RxxR_{xx}-Gates synthetisiert.

from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import (
Collect2qBlocks,
ConsolidateBlocks,
UnitarySynthesis,
)

basis_gates = ["rx", "ry", "rxx"]
translate = PassManager(
[
Collect2qBlocks(),
ConsolidateBlocks(basis_gates=basis_gates),
UnitarySynthesis(basis_gates),
]
)

Um diesen Pass Manager in Aktion zu demonstrieren, teste ihn an einem Zwei-Qubit-Circuit, der aus einem Hadamard gefolgt von zwei benachbarten CX-Gates besteht:

from qiskit import QuantumRegister, QuantumCircuit

qubits = QuantumRegister(2, name="q")
circuit = QuantumCircuit(qubits)

a, b = qubits
circuit.h(a)
circuit.cx(a, b)
circuit.cx(b, a)

circuit.draw("mpl")

Ausgabe der vorherigen Code-Zelle

Um den Pass Manager auf dem Circuit auszuführen, rufe die Methode run auf.

translated = translate.run(circuit)
translated.draw("mpl")

Ausgabe der vorherigen Code-Zelle

Ein fortgeschritteneres Beispiel, das zeigt, wie du einen Pass Manager für die Fehlersuppression durch dynamisches Entkoppeln erstellst, findest du unter Einen Pass Manager für dynamisches Entkoppeln erstellen.

Einen gestuften Pass Manager erstellen

Ein StagedPassManager ist ein Pass Manager, der aus einzelnen Stufen besteht, wobei jede Stufe durch eine PassManager-Instanz definiert wird. Du kannst einen StagedPassManager erstellen, indem du die gewünschten Stufen angibst. Der folgende Code erstellt beispielsweise einen gestuften Pass Manager mit zwei Stufen, init und translation. Die Stufe translation wird durch den zuvor erstellten Pass Manager definiert.

from qiskit.transpiler import PassManager, StagedPassManager
from qiskit.transpiler.passes import UnitarySynthesis, Unroll3qOrMore

basis_gates = ["rx", "ry", "rxx"]
init = PassManager(
[UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()]
)
staged_pm = StagedPassManager(
stages=["init", "translation"], init=init, translation=translate
)

Die Anzahl der Stufen, die du in einen gestuften Pass Manager einfügen kannst, ist unbegrenzt.

Eine weitere nützliche Möglichkeit, einen gestuften Pass Manager zu erstellen, besteht darin, mit einem voreingestellten gestuften Pass Manager zu beginnen und dann einige der Stufen auszutauschen. Der folgende Code generiert beispielsweise einen voreingestellten Pass Manager mit Optimierungsstufe 3 und gibt dann eine benutzerdefinierte pre_layout-Stufe an.

import numpy as np
from qiskit.circuit.library import HGate, PhaseGate, RXGate, TdgGate, TGate
from qiskit.transpiler.passes import InverseCancellation

pass_manager = generate_preset_pass_manager(3, backend)
inverse_gate_list = [
HGate(),
(RXGate(np.pi / 4), RXGate(-np.pi / 4)),
(PhaseGate(np.pi / 4), PhaseGate(-np.pi / 4)),
(TGate(), TdgGate()),
]
logical_opt = PassManager(
[
InverseCancellation(inverse_gate_list),
]
)

# Add pre-layout stage to run extra logical optimization
pass_manager.pre_layout = logical_opt

Die Stufengeneratorfunktionen können beim Aufbau benutzerdefinierter Pass Manager hilfreich sein. Sie erzeugen Stufen, die häufig verwendete Funktionalitäten in vielen Pass Managern bereitstellen. Beispielsweise kann generate_embed_passmanager verwendet werden, um eine Stufe zu generieren, die ein ausgewähltes initiales Layout aus einem Layout-Pass auf das angegebene Zielgerät „einbettet".

Nächste Schritte