Darstellung von Quantencomputern für den Transpiler
Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.
qiskit[all]~=2.5.2 qiskit-ibm-runtime~=0.47.0
Um eine abstrakte Schaltung in eine ISA-Schaltung umzuwandeln, die auf einer bestimmten QPU (Quantum Processing Unit) laufen kann, benötigt der Transpiler bestimmte Informationen über die QPU. Diese Informationen sind an zwei Stellen zu finden: dem BackendV2 (oder legacy BackendV1) Objekt, an das Sie Aufträge übermitteln wollen, und dem Target Attribut des Backends.
- Der
Targetenthält alle relevanten Einschränkungen eines Geräts, wie beispielsweise den unterstützten Befehlssatz, die Qubit-Konnektivität sowie Informationen zu Impulsen oder Zeitabläufen. - Das
Backendverfügt standardmäßig überTargetein, enthält zusätzliche Informationen – wie beispielsweise dasInstructionScheduleMap– und stellt die Schnittstelle für die Übermittlung von Quanten-Schaltkreis-Aufträgen bereit.
Sie können dem Transpiler auch explizit Informationen zur Verfügung stellen, z. B. wenn Sie einen bestimmten Anwendungsfall haben oder wenn Sie glauben, dass diese Informationen dem Transpiler helfen, eine optimierte Schaltung zu erstellen.
Die Genauigkeit, mit der der Transpiler die am besten geeignete Schaltung für eine bestimmte Hardware erzeugt, hängt davon ab, wie viele Informationen Target oder Backend über die Beschränkungen hat.
Da viele der zugrundeliegenden Umsetzungsalgorithmen stochastisch sind, gibt es keine Garantie, dass eine bessere Schaltung gefunden wird.
Auf dieser Seite finden Sie mehrere Beispiele für die Übergabe von QPU-Informationen an den Transpiler.
Standardkonfiguration
Die einfachste Verwendung des Transpilers ist die Bereitstellung aller QPU-Informationen durch die Bereitstellung der Backend oder Target. Um die Funktionsweise des Transpilers besser zu verstehen, konstruieren Sie eine Schaltung und transpilieren Sie sie mit verschiedenen Informationen, wie folgt.
Importieren Sie die erforderlichen Bibliotheken und instanziieren Sie die QPU: Um eine abstrakte Schaltung in eine ISA-Schaltung umzuwandeln, die auf einem bestimmten Prozessor laufen kann, benötigt der Transpiler bestimmte Informationen über den Prozessor. Normalerweise werden diese Informationen in der Datei Backend oder Target gespeichert, das dem Transpiler zur Verfügung gestellt wird, und es werden keine weiteren Informationen benötigt. Sie können dem Transpiler jedoch auch explizit Informationen zur Verfügung stellen, z. B. wenn Sie einen bestimmten Anwendungsfall haben oder wenn Sie glauben, dass diese Informationen dem Transpiler helfen, eine optimierte Schaltung zu erstellen.
In diesem Abschnitt werden mehrere Beispiele für die Übergabe von Informationen an den Transpiler vorgestellt.
In diesen Beispielen wird das Ziel aus dem qiskit_ibm_runtimeFakeSherbrooke Mock-Backend verwendet. Sie können es jedoch auf jedem Qiskit-kompatiblen echten oder simulierten Backend ausprobieren. Ihre Ergebnisse können davon abweichen.
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.targetDie Beispielschaltung verwendet eine Instanz von efficient_su2 aus der Schaltkreisbibliothek von Qiskit.
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
qc.draw("mpl")Output:
In diesem Beispiel werden die Standardeinstellungen für die Übertragung auf die Website backend's target verwendet, die alle erforderlichen Informationen für die Konvertierung der Schaltung in eine für das Backend geeignete Schaltung liefert.
from qiskit.transpiler import generate_preset_pass_manager
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)Output:
Dieses Beispiel wird in späteren Abschnitten dieses Themas verwendet, um zu veranschaulichen, dass die Kopplungskarte und der unterstützte Befehlssatz die wesentlichen Informationen sind, die an den Transpiler übergeben werden müssen, um eine optimale Schaltungserstellung zu erreichen. Die QPU kann in der Regel Standardeinstellungen für andere Informationen auswählen, die nicht übergeben werden, wie z. B. Zeitplanung und Terminierung.
Kopplungskarte
Die Kopplungskarte ist ein Diagramm, das zeigt, welche Qubits miteinander verbunden sind und somit Zwei-Qubit-Tore zwischen ihnen haben. Manchmal ist dieser Graph richtungsabhängig, was bedeutet, dass die Zwei-Qubit-Tore nur in eine Richtung gehen können. Der Transpiler kann jedoch jederzeit die Richtung eines Gatters umkehren, indem er zusätzliche Ein-Qubit-Gatter hinzufügt. Ein abstrakter Quantenschaltkreis kann immer auf diesem Graphen dargestellt werden, selbst wenn seine Konnektivität begrenzt ist, indem man SWAP-Gatter einführt, um die Quanteninformation zu verschieben.
Die Qubits unserer abstrakten Schaltkreise werden als virtuelle Qubits bezeichnet und die auf der Kopplungskarte als physikalische Qubits. Der Transpiler sorgt für ein Mapping zwischen virtuellen und physikalischen Qubits. Einer der ersten Schritte bei der Transpilierung, die Layout-Phase, führt dieses Mapping durch.
Obwohl die Routing-Phase standardmäßig mit der Layout-Phase - die die eigentlichen Qubits auswählt - verflochten ist, werden sie in diesem Thema der Einfachheit halber als separate Phasen behandelt. Die Kombination von Routing und Layout wird als Qubit-Mapping bezeichnet. Weitere Informationen zu diesen Stufen finden Sie im Thema Transpiler-Stufen.
Übergeben Sie das Schlüsselwortargument coupling_map , um seine Auswirkungen auf den Transpiler zu sehen:
coupling_map = target.build_coupling_map()
pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)Output:
Wie oben gezeigt, wurden mehrere SWAP-Gatter eingefügt (die jeweils aus drei CX-Gattern bestehen), was bei aktuellen Geräten eine Menge Fehler verursacht. Um zu sehen, welche Qubits in der tatsächlichen Qubit-Topologie ausgewählt sind, verwenden Sie plot_circuit_layout von Qiskit Visualizations:
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")Output:
Dies zeigt, dass unsere virtuellen Qubits 0-11 trivialerweise auf die Linie der physikalischen Qubits 0-11 abgebildet wurden. Kehren wir zur Standardeinstellung (optimization_level=1) zurück, die VF2Layout verwendet, wenn ein Routing erforderlich ist.
pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)Output:
Jetzt werden keine SWAP-Gates eingefügt, und die ausgewählten physikalischen Qubits sind bei Verwendung der Klasse target dieselben.
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")Output:
Jetzt befindet sich das Layout in einem Ring. Da bei diesem Layout die Konnektivität der Schaltung berücksichtigt wird, gibt es keine SWAP-Gates, was die Ausführung der Schaltung erheblich verbessert.
Unterstützte Anweisungen
Jeder Quantencomputer unterstützt einen begrenzten Befehlssatz. Jedes Gatter im Schaltkreis muss in die Elemente dieser Menge übersetzt werden. Dieses Set sollte aus Ein- und Zwei-Qubit-Gates bestehen, die ein universelles Gate-Set bilden, d. h. jede Quantenoperation kann in diese Gates zerlegt werden. Dies wird vom BasisTranslator durchgeführt und basis_gates kann als Schlüsselwortargument für den Transpiler angegeben werden, um diese Informationen bereitzustellen.
basis_gates = list(target.operation_names)
print(basis_gates)Output:
['id', 'delay', 'reset', 'if_else', 'for_loop', 'x', 'rz', 'ecr', 'switch_case', 'measure', 'sx']
Die Standard-Ein-Qubit-Gatter auf FakeSherbrooke sind rz, x, und sx, und das Standard-Zwei-Qubit-Gatter ist ecr (Echoed Cross-Resonance). CX-Gatter bestehen aus ecr Gattern, daher wird auf einigen ecr QPUs als Basisgatter für zwei Qubits festgelegt, während auf anderen cx als Standard gilt. Das ecr Tor ist der verwickelnde Teil des cx Tors. Neben den Steuerlogikgattern gibt es auch delay und measurement Befehle.
QPUs verfügen über Standard-Basistore, aber Sie können beliebige Tore auswählen, solange Sie die Anweisung bereitstellen oder Impulstore hinzufügen (siehe „Transpiler-Durchläufe erstellen “) Die Standard-Basisgatter sind diejenigen, für die Kalibrierungen auf der QPU durchgeführt wurden, sodass keine weiteren Befehls-/Impulsgatter bereitgestellt werden müssen. Beispielsweise ist bei einigen cx QPUs das Standard-Zwei-Qubit-Gatter und ecr bei anderen. Weitere Informationen finden Sie in der Liste der möglichen nativen Gatter und Operationen.
pass_manager = generate_preset_pass_manager(
optimization_level=1,
coupling_map=coupling_map,
basis_gates=basis_gates,
seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)Output:
Beachten Sie, dass die CXGate Objekte in ecr Gatter und Einzelqubit-Basissgatter zerlegt wurden.
Gerätefehlerraten
Die Klasse Target kann Informationen über die Fehlerquoten für Operationen auf dem Gerät enthalten.
Der folgende Code ruft zum Beispiel die Eigenschaften des ECR-Gatters (echoed cross-resonance) zwischen Qubit 1 und 0 ab (beachten Sie, dass das ECR-Gatter gerichtet ist):
target["ecr"][(1, 0)]Output:
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)
Die Ausgabe zeigt die Dauer des Gates (in Sekunden) und seine Fehlerquote an. Um Fehlerinformationen an den Transpiler weiterzugeben, erstellen Sie ein Zielmodell mit dem basis_gates und coupling_map von oben und füllen es mit Fehlerwerten aus dem Backend FakeSherbrooke.
from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp
err_targ = Target.from_configuration(
basis_gates=basis_gates,
coupling_map=coupling_map,
num_qubits=target.num_qubits,
custom_name_mapping={
"if_else": IfElseOp,
"switch_case": SwitchCaseOp,
"for_loop": ForLoopOp,
},
)
for i, (op, qargs) in enumerate(target.instructions):
if op.name in basis_gates:
err_targ[op.name][qargs] = target.instruction_properties(i)Transpile mit unserem neuen Ziel err_targ als Ziel:
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)Output:
Da das Ziel Fehlerinformationen enthält, versucht der VF2PostLayout Durchgang, die optimalen Qubits zu finden, was zu der gleichen Schaltung führt, die ursprünglich mit den gleichen physikalischen Qubits gefunden wurde.
Nächste Schritte
- Verstehen Sie die Standardeinstellungen und Konfigurationsoptionen von Transpilation.
- Lesen Sie das Thema Häufig verwendete Parameter für die Transpilation.
- Probieren Sie die Anleitung zum Vergleichen der Transpiler-Einstellungen aus.
- Siehe die Transpile-API-Dokumentation.