Přeskočit na hlavní obsah

Nastavení úrovně optimalizace transpilátoru

Package versions

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.5.2
qiskit-ibm-runtime~=0.47.0

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

poznámka

Mock Backend FakeSherbrooke z qiskit_ibm_runtime je použit v těchto příkladech, ale můžeš to vyzkoušet na libovolném skutečném nebo fiktivním Backendu kompatibilním s Qiskitem. Tvé výsledky se mohou lišit.

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 obvod 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í