Przejdź do głównej treści
Ten projekt jest w wersji beta. Znalazłeś błąd? Otwórz zgłoszenie na GitHub. Masz pytanie lub pomysł? Zapytaj w Discussions — chętnie poznamy Twoją opinię!
Jak oceniasz jakość tłumaczenia tej strony?

Bramki ułamkowe

Wersje pakietów

Kod na tej stronie został opracowany przy użyciu następujących wymagań. Zalecamy korzystanie z tych lub nowszych wersji.

qiskit[all]~=2.6.1
qiskit-ibm-runtime~=0.50.0

Ta strona przedstawia dwa nowo obsługiwane typy Gate'ów dostępnych w sieci QPU IBM Quantum®. Te ułamkowe Gate'y są obsługiwane na QPU Heron w postaci:

  • RZZ(θ)R_{ZZ}(\theta) dla 0<θ≤π/20 \lt \theta \leq \pi/2
  • RX(θ)R_X(\theta) dla dowolnego θ\theta

Ta strona omawia przypadki użycia, w których zastosowanie bramek ułamkowych może zwiększyć efektywność twoich przepływów pracy, a także sposób korzystania z tych bramek na QPU IBM Quantum.

Jak używać bramek ułamkowych​

Wewnętrznie bramki ułamkowe działają poprzez bezpośrednie wykonanie rotacji RZZ(θ)R_{ZZ}(\theta) i RX(θ)R_X(\theta) dla dowolnego kąta. Użycie Gate'u RX(θ)R_X(\theta) może zmniejszyć czas trwania i błąd jednokubitowych rotacji o dowolnym kącie nawet dwukrotnie. Bezpośrednie wykonanie rotacji Gate'u RZZ(θ)R_{ZZ}(\theta) pozwala uniknąć dekompozycji na wiele obiektów CZGate, podobnie zmniejszając czas trwania Circuit'u i poziom błędów. Jest to szczególnie przydatne w przypadku Circuit'ów zawierających wiele jedno- i dwukubitowych rotacji, na przykład przy symulowaniu dynamiki układu kwantowego lub przy użyciu wariacyjnego ansatzu z wieloma parametrami.

Chociaż te typy Gate'ów znajdują się w bibliotece standardowych bramek, którą może posiadać QuantumCircuit, można je używać tylko na określonych QPU IBM Quantum, które muszą być załadowane z flagą use_fractional_gates ustawioną na True (jak pokazano poniżej). Ta flaga zapewni, że bramki ułamkowe zostaną uwzględnione w Target Backendu dla Transpilera.

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

Ten przykład kodu demonstruje, jak używać bramek ułamkowych w kontekście przepływu pracy, który symuluje dynamikę łańcucha Isinga przy użyciu bramek ułamkowych. Czas trwania Circuit'u jest następnie porównywany z Backendem, który nie używa bramek ułamkowych.

Uwaga dotycząca raportowanych współczynników błędów

Wartość błędu raportowana w Target Backendu z włączonymi bramkami ułamkowymi jest jedynie kopią wartości dla odpowiadającej bramki nieułamkowej (która może nie być taka sama). Wynika to z faktu, że raportowanie współczynników błędów dla bramek ułamkowych nie jest jeszcze obsługiwane.

Jednak ponieważ czas Gate'u dla bramek ułamkowych i niełamkowych jest taki sam, rozsądnym założeniem jest, że ich współczynniki błędów są porównywalne — zwłaszcza gdy dominującym źródłem błędów w Circuit'cie jest relaksacja.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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 of the previous code cell

Zdefiniuj dwa obiekty Backend: jeden z włączonymi bramkami ułamkowymi, a drugi z wyłączonymi, a następnie transpiluj oba.

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)

Wyświetl oś czasu Circuit'u przy użyciu dwóch rodzajów Gate'ów.

# 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 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 of the previous code cell

Ograniczenia kątów​

W przypadku dwukubitowej bramki RZZ(θ)R_{ZZ}(\theta) na sprzęcie IBM Quantum można wykonywać jedynie kąty z zakresu od 00 do π/2\pi/2. Jeśli Circuit zawiera jakiekolwiek Gate'y RZZ(θ)R_{ZZ}(\theta) z kątem spoza tego zakresu, standardowy potok transpilacji zazwyczaj skoryguje to za pomocą odpowiedniej transformacji Circuit'u (poprzez przebieg FoldRzzAngle). Jednak w przypadku Gate'ów RZZ(θ)R_{ZZ}(\theta) zawierających jeden lub więcej Parameterów, Transpiler zakłada, że parametrom tym zostaną w czasie wykonywania przypisane kąty z tego zakresu. Zadanie zakończy się niepowodzeniem, jeśli którakolwiek z wartości parametrów określonych w PUB przesłanym do IBM Quantum Compute Service znajdzie się poza tym zakresem.

Gdzie używać bramek ułamkowych​

Historycznie, podstawowe Gate'y dostępne na QPU IBM Quantum to CZ, X, RZ, SX i ID, które nie mogą efektywnie reprezentować Circuit'ów z jednobitowymi i dwubitowymi rotacjami, które nie są wielokrotnościami π/2\pi / 2. Na przykład Gate RX(θ)R_X(\theta), po transpilacji, musi zostać rozłożony na serię Gate'ów RZRZ i X\sqrt{X}, co tworzy Circuit z dwoma Gate'ami o skończonym czasie trwania zamiast jednego.

Podobnie, gdy dwukubitowe rotacje, takie jak Gate RZZ(θ)R_{ZZ}(\theta), są transpilowane, dekompozycja wymaga dwóch Gate'ów CZ i kilku Gate'ów jednokubitowych, co zwiększa głębokość Circuit'u. Dekompozycje te są pokazane w poniższym kodzie.

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

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 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 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 of the previous code cell

W przypadku przepływów pracy wymagających wielu jednokubitowych rotacji RX(θ)R_X(\theta) lub dwukubitowych rotacji (na przykład w wariacyjnym ansatzu lub przy symulowaniu ewolucji czasowej układów kwantowych), to ograniczenie powoduje szybki wzrost głębokości Circuit'u. Jednak bramki ułamkowe eliminują to wymaganie, ponieważ jedno- i dwukubitowe rotacje są wykonywane bezpośrednio, tworząc bardziej wydajny (a przez to odporniejszy na błędy) Circuit kwantowy.

Kiedy nie używać bramek ułamkowych​

Ważne jest, aby pamiętać, że bramki ułamkowe są funkcją eksperymentalną, a zachowanie flagi use_fractional_gates może ulec zmianie w przyszłości. Zajrzyj do informacji o wydaniu nowych wersji qiskit-ibm-runtime, aby uzyskać więcej informacji. Zapoznaj się również z dokumentacją referencyjną API dla QiskitRuntimeService.backend, która opisuje use_fractional_gates.

Ponadto Transpiler Qiskit ma ograniczone możliwości używania RZZ(θ)R_{ZZ}(\theta) w swoich przebiegach optymalizacji. Wymaga to od ciebie większej staranności przy tworzeniu i optymalizowaniu Circuit'ów zawierających te instrukcje.

Wreszcie, używanie bramek ułamkowych nie jest obsługiwane dla:

Przeczytaj przewodnik dotyczący opcji prymitywów, aby dowiedzieć się więcej o dostosowywaniu technik ograniczania i tłumienia błędów dla danego obciążenia kwantowego.

Które backendy obsługują bramki ułamkowe?​

Nie wszystkie backendy obsługują bramki ułamkowe. Uruchom service.backends(use_fractional_gates=True), aby znaleźć te, które je obsługują. Wraz z wydaniem qiskit-ibm-runtime w wersji 0.48 możesz również uruchomić service.least_busy(fractional_gates=True), aby znaleźć najmniej obciążony backend obsługujący bramki ułamkowe. Fałszywy backend obsługuje bramki ułamkowe tylko wtedy, gdy powiązany „prawdziwy” backend je obsługuje.

Zauważ, że fałszywe backendy domyślnie nie obsługują bramek ułamkowych, ponieważ bramki ułamkowe są domyślnie wyłączone. Aby włączyć bramki ułamkowe na fałszywym backendzie, który je obsługuje, odśwież jego konfigurację.

Example:

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

Następne kroki​

Zalecenia