Transpiler-Optimierungsstufe festlegen
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
Echte Quantenbauelemente sind mit Rauschen und Gatterfehlern behaftet, so dass eine Optimierung der Schaltungen zur Verringerung ihrer Tiefe und Gatteranzahl die Ergebnisse der Ausführung dieser Schaltungen erheblich verbessern kann.
Die Funktion generate_preset_pass_manager funktion hat ein erforderliches Positionsargument, optimization_level, das steuert, wie viel Aufwand der Transpiler für die Optimierung von Schaltungen betreibt. Dieses Argument kann eine ganze Zahl mit einem der Werte 0, 1, 2 oder 3 sein.
Höhere Optimierungsstufen erzeugen mehr optimierte Schaltungen auf Kosten einer längeren Kompilierzeit.
In der folgenden Tabelle wird erläutert, welche Optimierungen mit den einzelnen Einstellungen vorgenommen werden.
Optimier.- stufe | Beschreibung |
|---|---|
| 0 | Keine Optimierung: typischerweise für die Charakterisierung von Hardware verwendet
|
| 1 | Optimierung der Beleuchtung:
|
| 2 | Mittlere Optimierung:
|
| 3 | Hohe Optimierung:
|
Optimierungsstufe in Aktion
Da Zwei-Qubit-Gatter in der Regel die größte Fehlerquelle darstellen, können wir die "Hardware-Effizienz" der Transpilierung annähernd quantifizieren, indem wir die Anzahl der Zwei-Qubit-Gatter in der resultierenden Schaltung zählen. Hier werden wir die verschiedenen Optimierungsstufen an einer Eingangsschaltung ausprobieren, die aus einer zufälligen Unitary und einem SWAP-Gatter besteht.
from qiskit import QuantumCircuit
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import Operator, random_unitary
UU = random_unitary(4, seed=12345)
rand_U = UnitaryGate(UU)
qc = QuantumCircuit(2)
qc.append(rand_U, range(2))
qc.swap(0, 1)
qc.draw("mpl", style="iqp")Output:
In diesen Beispielen wird das FakeSherbrooke``qiskit_ibm_runtime Mock-Backend von verwendet, Sie können es jedoch mit jedem Qiskit-kompatiblen echten oder simulierten Backend ausprobieren. Ihre Ergebnisse können davon abweichen.
Zunächst führen wir die Transpilation mit der Optimierungsstufe 0 durch.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
pass_manager = generate_preset_pass_manager(
optimization_level=0, backend=backend, seed_transpiler=12345
)
qc_t1_exact = pass_manager.run(qc)
qc_t1_exact.draw("mpl", idle_wires=False)Output:
Die transpilierte Schaltung hat sechs Zwei-Qubit-ECR-Gatter.
Wiederholen Sie den Vorgang für Optimierungsstufe 1:
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, seed_transpiler=12345
)
qc_t1_exact = pass_manager.run(qc)
qc_t1_exact.draw("mpl", idle_wires=False)Output:
Die transpilierte Schaltung hat immer noch sechs ECR-Gatter, aber die Anzahl der Ein-Qubit-Gatter hat sich verringert.
Wiederholen Sie den Vorgang für Optimierungsstufe 2:
pass_manager = generate_preset_pass_manager(
optimization_level=2, backend=backend, seed_transpiler=12345
)
qc_t2_exact = pass_manager.run(qc)
qc_t2_exact.draw("mpl", idle_wires=False)Output:
Dies führt zu den gleichen Ergebnissen wie Optimierungsstufe 1. Beachten Sie, dass eine Erhöhung des Optimierungsgrades nicht immer einen Unterschied macht.
Wiederholen Sie den Vorgang mit der Optimierungsstufe 3:
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=12345
)
qc_t3_exact = pass_manager.run(qc)
qc_t3_exact.draw("mpl", idle_wires=False)Output:
Jetzt gibt es nur noch drei ECR-Tore. Wir erhalten dieses Ergebnis, weil Qiskit auf Optimierungsebene 3 versucht, Zwei-Qubit-Blöcke von Gattern zu re-synthetisieren, und jedes Zwei-Qubit-Gatter kann mit höchstens drei ECR-Gattern implementiert werden. Wir können sogar noch weniger ECR-Gatter erhalten, wenn wir approximation_degree auf einen Wert kleiner als 1 setzen, was dem Transpiler erlaubt, Annäherungen vorzunehmen, die einen gewissen Fehler in die Gatterzerlegung einbringen können (siehe Häufig verwendete Parameter für die Transpilation ):
pass_manager = generate_preset_pass_manager(
optimization_level=3,
approximation_degree=0.99,
backend=backend,
seed_transpiler=12345,
)
qc_t3_approx = pass_manager.run(qc)
qc_t3_approx.draw("mpl", idle_wires=False)Output:
Diese Schaltung hat nur zwei ECR-Gatter, aber es ist eine ungefähre Schaltung. Um zu verstehen, inwiefern sich die Wirkung von der exakten Schaltung unterscheidet, können wir die Treue zwischen dem unitären Operator, den diese Schaltung implementiert, und dem exakten unitären berechnen. Bevor wir die Berechnung durchführen, reduzieren wir zunächst die transpilierte Schaltung, die 127 Qubits enthält, auf eine Schaltung, die nur die aktiven Qubits enthält, von denen es zwei gibt.
import numpy as np
def trace_to_fidelity_2q(trace: float) -> float:
return (4.0 + trace * trace.conjugate()) / 20.0
# Reduce circuits down to 2 qubits so they are easy to simulate
qc_t3_exact_small = QuantumCircuit.from_instructions(qc_t3_exact)
qc_t3_approx_small = QuantumCircuit.from_instructions(qc_t3_approx)
# Compute the fidelity
exact_fid = trace_to_fidelity_2q(
np.trace(np.dot(Operator(qc_t3_exact_small).adjoint().data, UU))
)
approx_fid = trace_to_fidelity_2q(
np.trace(np.dot(Operator(qc_t3_approx_small).adjoint().data, UU))
)
print(
f"Synthesis fidelity\nExact: {exact_fid:.3f}\nApproximate: {approx_fid:.3f}"
)Output:
Synthesis fidelity
Exact: 1.000+0.000j
Approximate: 0.992+0.000j
Die Anpassung des Optimierungsgrades kann auch andere Aspekte der Schaltung beeinflussen, nicht nur die Anzahl der ECR-Gatter. Beispiele dafür, wie sich die Änderung der Optimierungsstufe auf das Layout auswirkt, finden Sie unter „Darstellung von Quantencomputern “.
Nächste Schritte
- Um mehr über die Funktion
generate_preset_passmanagerzu erfahren, beginnen Sie mit dem Thema Standardeinstellungen und Konfigurationsoptionen für die Transpilation. - Erfahren Sie mehr über die Transpilierung mit dem Thema Transpiler-Stufen.
- Probieren Sie die Anleitung zum Vergleichen der Transpiler-Einstellungen aus.
- Versuchen Sie das Tutorial Build repetition codes.
- Siehe die Transpile-API-Dokumentation.