Přeskočit na hlavní obsah

Nastavení úrovně optimalizace transpilátoru

Verze balíčků

Kód na této stránce byl vyvinut s použitím následujících požadavků. Doporučujeme používat tyto verze nebo novější.

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

Skutečná kvantová zařízení jsou náchylná na šum a chyby Gate, takže optimalizace obvodů za účelem snížení jejich hloubky a počtu Gate může výrazně zlepšit výsledky získané spuštěním těchto obvodů. Funkce generate_preset_pass_manager má jeden povinný poziční argument, optimization_level, který řídí, kolik úsilí Transpiler věnuje optimalizaci obvodů. Tento argument může být celé číslo nabývající jedné z hodnot 0, 1, 2 nebo 3. Vyšší úrovně optimalizace generují více optimalizované obvody na úkor delší doby kompilace. Následující tabulka vysvětluje optimalizace prováděné při každém nastavení.

Úroveň optimalizacePopis
0

Bez optimalizace: typicky se používá pro charakterizaci hardwaru

  • Základní překlad
  • Layout/Routing: TrivialLayout, kde jsou jako fyzické vybrána stejná čísla Qubit jako virtuální a jsou vloženy SWAPy, aby to fungovalo (pomocí SabreSwap)
1

Lehká optimalizace:

  • Layout/Routing: Layout se nejprve pokusí použít TrivialLayout. Jsou-li potřeba další SWAPy, je nalezen layout s minimálním počtem SWAPů pomocí SabreSwap, poté se použije VF2LayoutPostLayout k výběru nejlepších Qubit v grafu.
  • InverseCancellation
  • Optimalizace 1Q Gate
2

Střední optimalizace:

  • Layout/Routing: Úroveň optimalizace 1 (bez triviální) + heuristická optimalizace s větší hloubkou prohledávání a počtem pokusů optimalizační funkce. Protože TrivialLayout se nepoužívá, není žádná snaha o použití stejných čísel fyzických a virtuálních Qubit.
  • CommutativeCancellation
3

Vysoká optimalizace:

  • Úroveň optimalizace 2 + heuristická optimalizace layoutu/routingu s větším úsilím a počtem pokusů
  • Resyntéza dvouqubitových bloků pomocí Cartanovy KAK dekompozice.
  • Průchody porušující unitaritu:
    • OptimizeSwapBeforeMeasure: Přesouvá měření, aby se předešlo SWAPům
    • RemoveDiagonalGatesBeforeMeasure: Odstraňuje Gate před měřeními, která by měření neovlivnila

Úroveň optimalizace v praxi

Protože dvouqubitové Gate jsou typicky nejvýznamnějším zdrojem chyb, můžeme přibližně kvantifikovat „hardwarovou efektivitu" transpilace počítáním počtu dvouqubitových Gate ve výsledném Circuit. Zde vyzkoušíme různé úrovně optimalizace na vstupním Circuit sestávajícím z náhodné unitární matice následované Gate SWAP.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
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 of the previous code cell

V příkladech budeme používat mock Backend FakeSherbrooke. Nejprve transpilujme s úrovní optimalizace 0.

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

Transpilovaný Circuit má šest dvouqubitových Gate ECR.

Zopakujeme pro úroveň optimalizace 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 of the previous code cell

Transpilovaný Circuit stále obsahuje šest Gate ECR, ale počet jednoqubitových Gate se snížil.

Zopakujeme pro úroveň optimalizace 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 of the previous code cell

Tím se dosáhne stejných výsledků jako u úrovně optimalizace 1. Všimni si, že zvýšení úrovně optimalizace ne vždy přináší rozdíl.

Zopakujeme ještě jednou, s úrovní optimalizace 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 of the previous code cell

Nyní jsou zde pouze tři Gate ECR. Tento výsledek získáme proto, že při úrovni optimalizace 3 se Qiskit pokouší znovu syntetizovat dvouqubitové bloky Gate a jakýkoli dvouqubitový Gate lze implementovat pomocí nejvýše tří Gate ECR. Ještě méně Gate ECR můžeme získat, nastavíme-li approximation_degree na hodnotu menší než 1, čímž umožníme Transpilátoru provádět aproximace, které mohou do dekompozice Gate vnést určitou chybu (viz Běžně používané parametry pro transpilaci):

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

Tento Circuit má pouze dvě Gate ECR, ale jedná se o aproximovaný Circuit. Abychom pochopili, jak se jeho efekt liší od přesného Circuit, můžeme vypočítat věrnost (fidelitu) mezi unitárním operátorem, který tento Circuit implementuje, a přesnou unitární maticí. Před provedením výpočtu nejprve zredukujeme transpilovaný Circuit, který obsahuje 127 Qubit, na Circuit obsahující pouze aktivní Qubit, kterých je dva.

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}"
)
Synthesis fidelity
Exact: 1.000+0.000j
Approximate: 0.992+0.000j

Úprava úrovně optimalizace může změnit i jiné aspekty Circuit, nejen počet Gate ECR. Příklady toho, jak nastavení úrovně optimalizace mění layout, najdeš v části Reprezentace kvantových počítačů.

Další kroky

Doporučení