Skip to main content
IBM Quantum Platform

Bruchgatter

  • 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
    

Auf dieser Seite werden zwei neue Gattertypen vorgestellt, die von der IBM Quantum® QPU-Flotte unterstützt werden. Diese gebrochenen Gatter werden auf den Heron QPUs in Form von unterstützt:

  • RZZ(θ)R_{ZZ}(\theta) für 0<θ≤π/20 \lt \theta \leq \pi/2
  • RX(θ)R_X(\theta) für jede θ\theta

Auf dieser Seite werden die Anwendungsfälle erörtert, in denen die Implementierung von fraktionalen Gattern die Effizienz Ihrer Arbeitsabläufe verbessern kann, und es wird erläutert, wie diese Gatter auf IBM Quantum QPUs verwendet werden können.


Verwendung von Bruchteil-Gates

Intern funktionieren diese Bruchteilgatter, indem sie direkt eine RZZ(θ)R_{ZZ}(\theta) und RX(θ)R_X(\theta) Rotation für einen beliebigen Winkel ausführen. Die Verwendung des „ RX(θ)R_X(\theta) “-Gatters kann die Dauer und Fehlerquote bei Einzelqubit-Rotationen mit beliebigem Winkel um bis zu den Faktor zwei reduzieren. Die direkte Ausführung der Gate-Rotation „ RZZ(θ)R_{ZZ}(\theta) “ vermeidet die Zerlegung in mehrere CZGate Objekte und reduziert so ebenfalls die Dauer und Fehler einer Schaltung. Dies ist besonders nützlich für Schaltungen, die viele Einzel- und Zwei-Qubit-Rotationen enthalten, beispielsweise bei der Simulation der Dynamik eines Quantensystems oder bei der Verwendung eines Variationsansatzes mit vielen Parametern.

Diese Gattertypen sind zwar in der Bibliothek der Standardgatter enthalten, über die ein System verfügen QuantumCircuit kann, sie können jedoch nur auf bestimmten QPUs von IBM Quantum verwendet werden, die mit dem auf gesetzten use_fractional_gates Flag True geladen werden müssen (siehe unten). Dieses Flag sorgt dafür, dass Bruchteilsgatter in die Backend-Implementierung Target des Transpilers aufgenommen werden.

service = QiskitRuntimeService()
backend = service.backend('ibm_torino', use_fractional_gates=True)

Dieses Codebeispiel demonstriert die Verwendung von fraktionierten Gattern im Rahmen eines Arbeitsablaufs, der die Dynamik einer Ising-Kette mit Hilfe von fraktionierten Gattern simuliert. Die Dauer der Schaltung wird dann mit einem Backend verglichen, das keine gebrochenen Gatter verwendet.

Hinweis zu den gemeldeten Fehlerquoten

Der Fehlerwert, der in der Target eines Backends mit aktivierten fraktionalen Gattern gemeldet wird, ist lediglich eine Kopie des Gegenstücks des nicht-fraktionalen Gatters (das möglicherweise nicht dasselbe ist). Der Grund dafür ist, dass die Meldung von Fehlerquoten bei den fraktionierten Gates noch nicht unterstützt wird.

Da jedoch die Gatterzeit von fraktionierten und nicht-fraktionierten Gattern gleich ist, ist es eine vernünftige Annahme, dass ihre Fehlerraten vergleichbar sind - vor allem, wenn die dominierende Fehlerquelle in einer Schaltung auf Relaxation zurückzuführen ist.

from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization.timeline import draw as draw_timeline, IQXSimple

from qiskit_ibm_runtime import QiskitRuntimeService


num_qubits = 5
num_time_steps = 3
rx_angle = 0.1
rzz_angle = 0.1

ising_circuit = QuantumCircuit(num_qubits)
for i in range(num_time_steps):
    # rx layer
    for q in range(num_qubits):
        ising_circuit.rx(rx_angle, q)
    for q in range(1, num_qubits - 1, 2):
        ising_circuit.rzz(rzz_angle, q, q + 1)
    # 2nd rzz layer
    for q in range(0, num_qubits - 1, 2):
        ising_circuit.rzz(rzz_angle, q, q + 1)
    ising_circuit.barrier()
ising_circuit.draw("mpl")

Output:

Output of the previous code cell

Geben Sie zwei Backend-Objekte an: eines mit aktivierten und eines mit deaktivierten Fractional Gates, und transpilieren Sie dann beide.

service = QiskitRuntimeService()
backend_name = service.least_busy(operational=True, simulator=False).name
backend_fractional = service.backend(backend_name, use_fractional_gates=True)
backend_conventional = service.backend(
    backend_name, use_fractional_gates=False
)

pm_fractional = generate_preset_pass_manager(
    optimization_level=3, backend=backend_fractional, scheduling_method="alap"
)
pm_conventional = generate_preset_pass_manager(
    optimization_level=3,
    backend=backend_conventional,
    scheduling_method="alap",
)

ising_circuit_fractional = pm_fractional.run(ising_circuit)
ising_circuit_conventional = pm_conventional.run(ising_circuit)

Zeigen Sie die Zeitachse der Schaltung mit den beiden Gattertypen an.

# Draw timeline of circuit with conventional gates
draw_timeline(
    ising_circuit_conventional,
    idle_wires=False,
    target=backend_conventional.target,
    time_range=(0, 500),
    style=IQXSimple(),
)

Output:

Output of the previous code cell
# Draw timeline of circuit with fractional gates
draw_timeline(
    ising_circuit_fractional,
    idle_wires=False,
    target=backend_fractional.target,
    time_range=(0, 500),
    style=IQXSimple(),
)

Output:

Output of the previous code cell

Winkelbeschränkungen

Für das Zwei-Qubit- RZZ(θ)R_{ZZ}(\theta) -Gatter können auf der Hardware von IBM Quantum nur Winkel zwischen 00 und π/2\pi/2 ausgeführt werden. Enthält eine Schaltung „ RZZ(θ)R_{ZZ}(\theta) “-Gatter mit einem Winkel außerhalb dieses Bereichs, wird dies von der Standard-Transpilations-Pipeline in der Regel durch eine entsprechende Schaltungstransformation (im Pass FoldRzzAngle ) korrigiert. Für jedes „ RZZ(θ)R_{ZZ}(\theta) “-Gatter, das ein oder mehrere Parameter„s“ enthält, geht der Transpiler jedoch davon aus, dass diesen Parametern zur Laufzeit Winkel innerhalb dieses Bereichs zugewiesen werden. Der Auftrag schlägt fehl, wenn einer der im „ PUB “ angegebenen Parameterwerte, der an den „ IBM Quantum Compute Service“ übermittelt wurde, außerhalb dieses Bereichs liegt.


Wo fraktionierte Gates verwendet werden sollten

In der Vergangenheit waren die auf IBM Quantum QPUs verfügbaren Basisgatter CZ, X, RZ, SX, und **ID**die nicht in der Lage sind, Schaltungen mit Ein- und Zwei-Qubit-Rotationen, die keine Vielfachen von π/2\pi / 2 sind, effizient darzustellen. Beispielsweise muss ein RX(θ)R_X(\theta) -Gatter, wenn es transpiliert wird, in eine Reihe von RZRZ - und X\sqrt{X} -Gattern zerlegt werden, wodurch eine Schaltung mit zwei Gattern von endlicher Dauer anstelle von einem entsteht.

Wenn Zwei-Qubit-Rotationen, wie z. B. ein RZZ(θ)R_{ZZ}(\theta) -Gatter, transponiert werden, erfordert die Zerlegung ebenfalls zwei CZ gatter und mehrere Ein-Qubit-Gatter, was die Schaltungstiefe erhöht. Diese Zerlegungen sind im folgenden Code dargestellt.

qc = QuantumCircuit(1)
param = Parameter("θ")
qc.rx(param, 0)
qc.draw("mpl")

Output:

Output of the previous code cell
# Decomposition of an RX(θ) gate using the IBM Quantum QPU basis
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
optimization_level = 3
pm = generate_preset_pass_manager(optimization_level, backend=backend)
transpiled_circuit = pm.run(qc)
transpiled_circuit.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.transpiler import generate_preset_pass_manager

from qiskit_ibm_runtime import QiskitRuntimeService

qc = QuantumCircuit(2)
param = Parameter("θ")
qc.rzz(param, 0, 1)
qc.draw("mpl")

Output:

Output of the previous code cell
# Decomposition of an RZZ(θ) gate using the IBM Quantum QPU basis
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
optimization_level = 3
pm = generate_preset_pass_manager(optimization_level, backend=backend)
transpiled_circuit = pm.run(qc)
transpiled_circuit.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell

Bei Arbeitsabläufen, die viele Ein-Qubit- RX(θ)R_X(\theta) oder Zwei-Qubit-Rotationen erfordern (z. B. in einem Variationsansatz oder bei der Simulation der zeitlichen Entwicklung von Quantensystemen), führt diese Einschränkung dazu, dass die Schaltungstiefe schnell wächst. Mit fraktionierten Gattern entfällt diese Anforderung jedoch, da die Ein- und Zwei-Qubit-Drehungen direkt ausgeführt werden und eine effizientere (und damit fehlerunterdrückte) Quantenschaltung entsteht.


Wann man keine fraktionierten Gates verwenden sollte

Es ist wichtig zu beachten, dass „Fractional Gates“ eine experimentelle Funktion sind und sich das Verhalten des Flags use_fractional_gates in Zukunft ändern kann. Weitere Informationen finden Sie qiskit-ibm-runtime in den Versionshinweisen zu den neuen Versionen von. Siehe auch die API-Referenzdokumentation zu „ QiskitRuntimeService.backend“, in der dies beschrieben wird use_fractional_gates.

Außerdem kann der Qiskit-Transpiler in seinen Optimierungsläufen nur begrenzt RZZ(θ)R_{ZZ}(\theta) verwenden. Daher müssen Sie bei der Erstellung und Optimierung von Schaltungen, die diese Anweisungen enthalten, mehr Sorgfalt walten lassen.

Schließlich wird die Verwendung von Fractional Gates nicht unterstützt für:

Lesen Sie den Leitfaden zu den primitiven Optionen, um mehr über die Anpassung der Fehlerbegrenzungs- und -unterdrückungstechniken für eine bestimmte Quantenarbeitslast zu erfahren.


Welche Backends unterstützen fraktionierte Gates?

Nicht alle Backends unterstützen fraktionierte Gates. Lauf los, service.backends(use_fractional_gates=True) um diejenigen zu finden, die es tun. Mit der Veröffentlichung von „ v0.48qiskit-ibm-runtime “ können Sie außerdem den Befehl ausführen, um service.least_busy(fractional_gates=True) das am wenigsten ausgelastete Backend zu finden, das fraktionierte Gatter unterstützt. Ein simuliertes Backend unterstützt Bruchgates nur dann, wenn das zugehörige „echte“ Backend diese ebenfalls unterstützt.

Beachten Sie, dass gefälschte Backends standardmäßig keine Bruchgates unterstützen, da diese standardmäßig deaktiviert sind. Um Fractional Gates auf einem Fake-Backend zu aktivieren, das diese unterstützt, aktualisieren Sie dessen Konfiguration.

Beispiel:

service = QiskitRuntimeService()
fake_backend = FakeBoston()
fake_backend.refresh(service=service, use_fractional_gates=True)

Nächste Schritte

Empfehlungen
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.