Metody kompilace pro obvody simulace Hamiltonovu
Odhadované využití QPU: v tomto tutoriálu nebylo provedeno žádné spuštění, protože se zaměřuje na proces transpilace.
Základy
Kompilace kvantových obvodů je klíčovým krokem v pracovním postupu kvantového výpočtu. Zahrnuje transformaci vysokoúrovňového kvantového algoritmu na fyzický kvantový Circuit, který respektuje omezení cílového kvantového hardwaru. Efektivní kompilace může výrazně ovlivnit výkon kvantových algoritmů snížením hloubky obvodu, počtu Gate a doby provádění. Tento tutoriál zkoumá tři odlišné přístupy ke kompilaci kvantových obvodů v Qiskitu a prostřednictvím praktických příkladů ukazuje jejich silné stránky a možnosti využití.
Cílem tohoto tutoriálu je naučit uživatele, jak v Qiskitu použít a vyhodnotit tři metody kompilace: transpiler SABRE, transpiler využívající umělou inteligenci a plugin Rustiq. Uživatelé se naučí, jak každou metodu efektivně používat a jak porovnávat jejich výkon na různých kvantových obvodech. Po absolvování tohoto tutoriálu budou uživatelé schopni vybírat a přizpůsobovat strategie kompilace na základě konkrétních optimalizačních cílů, jako je snížení hloubky obvodu, minimalizace počtu Gate nebo zlepšení doby provádění.
Co se naučíš
- Jak používat Qiskit transpiler se SABRE pro optimalizaci rozložení a směrování.
- Jak využít AI transpiler pro pokročilou, automatizovanou optimalizaci obvodů.
- Jak použít plugin Rustiq pro obvody vyžadující přesnou syntézu operací, zejména v úlohách simulace Hamiltonovu.
Tento tutoriál využívá tři ukázkové obvody podle pracovního postupu Qiskit patterns k ilustraci výkonu každé metody kompilace. Po absolvování tohoto tutoriálu budou uživatelé vybaveni k výběru vhodné strategie kompilace na základě svých konkrétních požadavků a omezení.
Přehled metod kompilace
1. Qiskit transpiler se SABRE
Qiskit transpiler používá algoritmus SABRE (SWAP-based BidiREctional heuristic search) k optimalizaci rozložení a směrování obvodů. SABRE se zaměřuje na minimalizaci SWAP Gate a jejich dopadu na hloubku obvodu při respektování omezení propojení hardwaru. Tato metoda je velmi všestranná a vhodná pro obecnou optimalizaci obvodů, přičemž poskytuje rovnováhu mezi výkonem a výpočetním časem. Chceš-li využít nejnovější vylepšení SABRE popsaná v [1], můžeš zvýšit počet pokusů (například layout_trials=400, swap_trials=400). Pro účely tohoto tutoriálu budeme používat výchozí hodnoty počtu pokusů, abychom mohli srovnávat s výchozím transpilerem Qiskitu. Výhody a průzkum parametrů SABRE jsou popsány v samostatném tutoriálu zaměřeném do hloubky.
2. AI transpiler
AI transpiler v Qiskitu využívá strojové učení k předpovídání optimálních strategií transpilace tím, že analyzuje vzory ve struktuře obvodů a omezení hardwaru a vybírá nejlepší posloupnost optimalizací pro daný vstup. Tato metoda je obzvláště účinná pro rozsáhlé kvantové obvody, nabízí vysoký stupeň automatizace a přizpůsobivosti různým typům problémů. Kromě obecné optimalizace obvodů lze AI transpiler použít s průchodem AIPauliNetworkSynthesis, který cílí na obvody Pauliho sítě — bloky složené z Gate H, S, SX, CX, RX, RY a RZ — a aplikuje syntetický přístup založený na zpětnovazebním učení. Více informací o AI transpileru a jeho syntézních strategiích najdeš v [2] a [3].
3. Plugin Rustiq
Plugin Rustiq zavádí pokročilé syntézní techniky speciálně pro operace PauliEvolutionGate, které reprezentují Pauliho rotace běžně používané v trotterizované dynamice. Tento plugin je cenný pro obvody implementující simulaci Hamiltonovu, jako jsou ty používané v problémech kvantové chemie a fyziky, kde jsou přesné Pauliho rotace nezbytné pro efektivní simulaci problémových Hamiltonianů. Rustiq nabízí přesnou syntézu obvodů s nízkou hloubkou pro tyto specializované operace. Více informací o implementaci a výkonu Rustiq najdeš v [4].
Hloubkovým prozkoumáním těchto metod kompilace tento tutoriál poskytuje uživatelům nástroje ke zvýšení výkonu jejich kvantových obvodů a připravuje cestu k efektivnějším a praktičtějším kvantovým výpočtům.
Požadavky
P řed zahájením tohoto tutoriálu se ujisti, že máš nainstalované následující:
- Qiskit SDK v1.3 nebo novější s podporou vizualizace
- Qiskit Runtime v0.28 nebo novější (
pip install qiskit-ibm-runtime) - Qiskit IBM Transpiler (
pip install qiskit-ibm-transpiler) - Qiskit AI Transpiler v lokálním režimu (
pip install qiskit_ibm_ai_local_transpiler) - Knihovna grafů Networkx (
pip install networkx)
Nastavení
# Added by doQumentation — required packages for this notebook
!pip install -q IPython matplotlib numpy pandas qiskit qiskit-ibm-runtime qiskit-ibm-transpiler requests
from qiskit.circuit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.circuit.library import (
efficient_su2,
PauliEvolutionGate,
)
from qiskit_ibm_transpiler import generate_ai_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig
from collections import Counter
from IPython.display import display
import time
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import json
import requests
import logging
# Suppress noisy loggers
logging.getLogger(
"qiskit_ibm_transpiler.wrappers.ai_local_synthesis"
).setLevel(logging.ERROR)
seed = 42 # Seed for reproducibility
Část 1: Circuit efficient SU2
Krok 1: Mapování klasických vstupů na kvantový problém
V této části zkoumáme Circuit efficient_su2, hardwarově efektivní ansatz běžně používaný ve variačních kvantových algoritmech (jako je VQE) a v úlohách kvantového strojového učení. Circuit se skládá ze střídajících se vrstev jednoQubitových rotací a provázacích Gate uspořádaných v kruhovém vzoru, který je navržen k efektivnímu prozkoumávání prostoru kvantových stavů při zachování zvládnutelné hloubky.
Začneme konstrukcí jednoho Circuit efficient_su2, abychom ukázali, jak porovnávat různé metody kompilace. Po části 1 rozšíříme naši analýzu na větší sadu obvodů, což umožní komplexní benchmark pro hodnocení výkonu různých technik kompilace.
qubit_size = list(range(10, 101, 10))
qc_su2_list = [
efficient_su2(n, entanglement="circular", reps=1)
.decompose()
.copy(name=f"SU2_{n}")
for n in qubit_size
]
# Draw the first circuit
qc_su2_list[0].draw(output="mpl")
Krok 2: Optimalizace problému pro spuštění na kvantovém hardwaru
Tento krok je hlavním zaměřením tutoriálu. Zde se snažíme optimalizovat kvantové obvody pro efektivní spuštění na reálném kvantovém hardwaru. Naším primárním cílem je snížit hloubku obvodu a počet Gate, což jsou klíčové faktory pro zlepšení věrnosti spuštění a zmírnění šumu hardwaru.
- Transpiler SABRE: Používá výchozí transpiler Qiskitu s algoritmem SABRE pro rozložení a směrování.
- AI transpiler (lokální režim): Standardní AI transpiler využívající lokální inference a výchozí syntézní strategii.
- Plugin Rustiq: Transpilerový plugin navržený pro kompilaci s nízkou hloubkou přizpůsobenou úlohám simulace Hamiltonovu.
Cílem tohoto kroku je porovnat výsledky těchto metod z hlediska hloubky transpilovaného Circuit a počtu Gate. Dalším důležitým měřítkem, které zvažujeme, je doba transpilace. Analýzou těchto metrik můžeme vyhodnotit relativní silné stránky každé metody a určit, která z nich vytváří nejefektivnější Circuit pro spuštění na vybraném hardwaru.
Poznámka: Pro úvodní příklad Circuit SU2 budeme porovnávat pouze transpiler SABRE a výchozí AI transpiler. V následném benchmarku využívajícím obvody Hamlib však porovnáme všechny tři metody transpilace.
# QiskitRuntimeService.save_account(channel="ibm_quantum_platform", token="<YOUR-API-KEY>", overwrite=True, set_as_default=True)
service = QiskitRuntimeService(channel="ibm_quantum_platform")
backend = service.backend("ibm_torino")
print(f"Using backend: {backend}")
qiskit_runtime_service._get_crn_from_instance_name:WARNING:2025-07-30 21:46:30,843: Multiple instances found. Using all matching instances.
Using backend: <IBMBackend('ibm_torino')>
Qiskit transpiler se SABRE:
pm_sabre = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=seed
)
AI transpiler:
# Standard AI transpiler pass manager, using the local mode
pm_ai = generate_ai_pass_manager(
backend=backend, optimization_level=3, ai_optimization_level=3
)
Plugin Rustiq:
hls_config = HLSConfig(
PauliEvolution=[
(
"rustiq",
{
"nshuffles": 400,
"upto_phase": True,
"fix_clifford": True,
"preserve_order": False,
"metric": "depth",
},
)
]
)
pm_rustiq = generate_preset_pass_manager(
optimization_level=3,
backend=backend,
hls_config=hls_config,
seed_transpiler=seed,
)
Transpilace a zachycení metrik
Pro porovnání výkonu metod kompilace definujeme funkci, která transpiluje vstupní Circuit a konzistentním způsobem zachycuje příslušné metriky. Zahrnuje to celkovou hloubku obvodu, celkový počet Gate a dobu transpilace.
Kromě těchto standardních metrik zaznamenáváme také hloubku 2-Qubitových Gate, což je obzvláště důležitá metrika pro hodnocení spuštění na kvantovém hardwaru. Na rozdíl od celkové hloubky, která zahrnuje všechny Gate, hloubka 2-Qubitových Gate přesněji odráží skutečnou dobu provádění Circuit na hardwaru. Je to proto, že 2-Qubitové Gate obvykle dominují časovému a chybovému rozpočtu ve většině kvantových zařízení. Proto je minimalizace hloubky 2-Qubitových Gate kritická pro zlepšení věrnosti a snížení efektů dekoherence během provádění.
Tuto funkci použijeme k analýze výkonu různých metod kompilace na více obvodech.
def capture_transpilation_metrics(
results, pass_manager, circuits, method_name
):
"""
Capture transpilation metrics for a list of circuits and stores the results in a DataFrame.
Args:
results (pd.DataFrame): DataFrame to store the results.
pass_manager: Pass manager used for transpilation.
circuits (list): List of quantum circuits to transpile.
method_name (str): Name of the transpilation method.
Returns:
list: List of transpiled circuits.
"""
transpiled_circuits = []
for i, qc in enumerate(circuits):
# Transpile the circuit
start_time = time.time()
transpiled_qc = pass_manager.run(qc)
end_time = time.time()
# Needed for AI transpiler to be consistent with other methods
transpiled_qc = transpiled_qc.decompose(gates_to_decompose=["swap"])
# Collect metrics
transpilation_time = end_time - start_time
circuit_depth = transpiled_qc.depth(
lambda x: x.operation.num_qubits == 2
)
circuit_size = transpiled_qc.size()
# Append results to DataFrame
results.loc[len(results)] = {
"method": method_name,
"qc_name": qc.name,
"qc_index": i,
"num_qubits": qc.num_qubits,
"ops": transpiled_qc.count_ops(),
"depth": circuit_depth,
"size": circuit_size,
"runtime": transpilation_time,
}
transpiled_circuits.append(transpiled_qc)
print(
f"Transpiled circuit index {i} ({qc.name}) in {transpilation_time:.2f} seconds with method {method_name}, "
f"depth {circuit_depth}, and size {circuit_size}."
)
return transpiled_circuits
results_su2 = pd.DataFrame(
columns=[
"method",
"qc_name",
"qc_index",
"num_qubits",
"ops",
"depth",
"size",
"runtime",
]
)
tqc_sabre = capture_transpilation_metrics(
results_su2, pm_sabre, qc_su2_list, "sabre"
)
tqc_ai = capture_transpilation_metrics(results_su2, pm_ai, qc_su2_list, "ai")
Transpiled circuit index 0 (SU2_10) in 0.06 seconds with method sabre, depth 13, and size 167.
Transpiled circuit index 1 (SU2_20) in 0.24 seconds with method sabre, depth 20, and size 299.
Transpiled circuit index 2 (SU2_30) in 10.72 seconds with method sabre, depth 72, and size 627.
Transpiled circuit index 3 (SU2_40) in 16.16 seconds with method sabre, depth 40, and size 599.
Transpiled circuit index 4 (SU2_50) in 76.89 seconds with method sabre, depth 77, and size 855.
Transpiled circuit index 5 (SU2_60) in 86.12 seconds with method sabre, depth 60, and size 899.
Transpiled circuit index 6 (SU2_70) in 94.46 seconds with method sabre, depth 79, and size 1085.
Transpiled circuit index 7 (SU2_80) in 69.05 seconds with method sabre, depth 80, and size 1199.
Transpiled circuit index 8 (SU2_90) in 88.25 seconds with method sabre, depth 105, and size 1420.
Transpiled circuit index 9 (SU2_100) in 83.80 seconds with method sabre, depth 100, and size 1499.
Transpiled circuit index 0 (SU2_10) in 0.17 seconds with method ai, depth 10, and size 168.
Transpiled circuit index 1 (SU2_20) in 0.29 seconds with method ai, depth 20, and size 299.
Transpiled circuit index 2 (SU2_30) in 13.56 seconds with method ai, depth 36, and size 548.
Transpiled circuit index 3 (SU2_40) in 15.95 seconds with method ai, depth 40, and size 599.
Transpiled circuit index 4 (SU2_50) in 80.70 seconds with method ai, depth 54, and size 823.
Transpiled circuit index 5 (SU2_60) in 75.99 seconds with method ai, depth 60, and size 899.
Transpiled circuit index 6 (SU2_70) in 64.96 seconds with method ai, depth 74, and size 1087.
Transpiled circuit index 7 (SU2_80) in 68.25 seconds with method ai, depth 80, and size 1199.
Transpiled circuit index 8 (SU2_90) in 75.07 seconds with method ai, depth 90, and size 1404.
Transpiled circuit index 9 (SU2_100) in 63.97 seconds with method ai, depth 100, and size 1499.
Zobrazení transpilovaných výsledků jednoho z obvodů.
print("Sabre transpilation")
display(tqc_sabre[0].draw("mpl", fold=-1, idle_wires=False))
print("AI transpilation")
display(tqc_ai[0].draw("mpl", fold=-1, idle_wires=False))
Sabre transpilation

AI transpilation

Tabulka výsledků:
summary_su2 = (
results_su2.groupby("method")[["depth", "size", "runtime"]]
.mean()
.round(2)
)
print(summary_su2)
results_su2
depth size runtime
method
ai 56.4 852.5 45.89
sabre 64.6 864.9 52.57
method qc_name qc_index num_qubits ops \
0 sabre SU2_10 0 10 {'rz': 81, 'sx': 70, 'cz': 16}
1 sabre SU2_20 1 20 {'rz': 160, 'sx': 119, 'cz': 20}
2 sabre SU2_30 2 30 {'sx': 295, 'rz': 242, 'cz': 90}
3 sabre SU2_40 3 40 {'rz': 320, 'sx': 239, 'cz': 40}
4 sabre SU2_50 4 50 {'rz': 402, 'sx': 367, 'cz': 86}
5 sabre SU2_60 5 60 {'rz': 480, 'sx': 359, 'cz': 60}
6 sabre SU2_70 6 70 {'rz': 562, 'sx': 441, 'cz': 82}
7 sabre SU2_80 7 80 {'rz': 640, 'sx': 479, 'cz': 80}
8 sabre SU2_90 8 90 {'rz': 721, 'sx': 585, 'cz': 114}
9 sabre SU2_100 9 100 {'rz': 800, 'sx': 599, 'cz': 100}
10 ai SU2_10 0 10 {'rz': 81, 'sx': 71, 'cz': 16}
11 ai SU2_20 1 20 {'rz': 160, 'sx': 119, 'cz': 20}
12 ai SU2_30 2 30 {'sx': 243, 'rz': 242, 'cz': 63}
13 ai SU2_40 3 40 {'rz': 320, 'sx': 239, 'cz': 40}
14 ai SU2_50 4 50 {'rz': 403, 'sx': 346, 'cz': 74}
15 ai SU2_60 5 60 {'rz': 480, 'sx': 359, 'cz': 60}
16 ai SU2_70 6 70 {'rz': 563, 'sx': 442, 'cz': 82}
17 ai SU2_80 7 80 {'rz': 640, 'sx': 479, 'cz': 80}
18 ai SU2_90 8 90 {'rz': 721, 'sx': 575, 'cz': 108}
19 ai SU2_100 9 100 {'rz': 800, 'sx': 599, 'cz': 100}
depth size runtime
0 13 167 0.058845
1 20 299 0.238217
2 72 627 10.723922
3 40 599 16.159262
4 77 855 76.886604
5 60 899 86.118255
6 79 1085 94.458287
7 80 1199 69.048184
8 105 1420 88.254809
9 100 1499 83.795482
10 10 168 0.171532
11 20 299 0.291691
12 36 548 13.555931
13 40 599 15.952733
14 54 823 80.702141
15 60 899 75.993404
16 74 1087 64.960162
17 80 1199 68.253280
18 90 1404 75.072412
19 100 1499 63.967446
Graf výsledků
Stejně jako jsme definovali funkci pro konzistentní zachycení metrik, definujeme i funkci pro jejich grafické znázornění. Zde zobrazíme hloubku 2-Qubitových Gate, počet Gate a dobu provádění pro každou metodu kompilace napříč obvody.
def plot_transpilation_metrics(results, overall_title, x_axis="qc_index"):
"""
Plots transpilation metrics (depth, size, runtime) for different transpilation methods.
Parameters:
results (DataFrame): Data containing columns ['num_qubits', 'method', 'depth', 'size', 'runtime']
overall_title (str): The title of the overall figure.
x_axis (str): The x-axis label, either 'num_qubits' or 'qc_index'.
"""
fig, axs = plt.subplots(1, 3, figsize=(24, 6))
metrics = ["depth", "size", "runtime"]
titles = ["Circuit Depth", "Circuit Size", "Transpilation Runtime"]
y_labels = ["Depth", "Size (Gate Count)", "Runtime (s)"]
methods = results["method"].unique()
colors = plt.colormaps["tab10"]
markers = ["o", "^", "s", "D", "P", "*", "X", "v"]
color_list = [colors(i % colors.N) for i in range(len(methods))]
color_map = {method: color_list[i] for i, method in enumerate(methods)}
marker_map = {
method: markers[i % len(markers)] for i, method in enumerate(methods)
}
jitter_factor = 0.1 # Small x-axis jitter for visibility
handles, labels = [], [] # Unique handles for legend
# Plot each metric
for i, metric in enumerate(metrics):
for method in methods:
method_data = results[results["method"] == method]
# Introduce slight jitter to avoid exact overlap
jitter = np.random.uniform(
-jitter_factor, jitter_factor, len(method_data)
)
scatter = axs[i].scatter(
method_data[x_axis] + jitter,
method_data[metric],
color=color_map[method],
label=method,
marker=marker_map[method],
alpha=0.7,
edgecolors="black",
s=80,
)
if method not in labels:
handles.append(scatter)
labels.append(method)
axs[i].set_title(titles[i])
axs[i].set_xlabel(x_axis)
axs[i].set_ylabel(y_labels[i])
axs[i].grid(axis="y", linestyle="--", alpha=0.7)
axs[i].tick_params(axis="x", rotation=45)
axs[i].set_xticks(sorted(results[x_axis].unique()))
fig.suptitle(overall_title, fontsize=16)
fig.legend(
handles=handles,
labels=labels,
loc="upper right",
bbox_to_anchor=(1.05, 1),
)
plt.tight_layout()
plt.show()
plot_transpilation_metrics(
results_su2, "Transpilation Metrics for SU2 Circuits", x_axis="num_qubits"
)

Analýza výsledků kompilace Circuit SU2
V tomto experimentu porovnáváme dvě metody transpilace — Qiskit transpiler SABRE a AI transpiler — na sadě obvodů efficient_su2. Protože tyto obvody neobsahují žádné operace PauliEvolutionGate, plugin Rustiq není do tohoto porovnání zahrnut.
Průměrně si AI transpiler vede lépe z hlediska hloubky obvodu, s více než 10% zlepšením napříč celou sadou Circuit SU2. Pokud jde o počet Gate (velikost obvodu) a dobu transpilace, obě metody celkově přinášejí podobné výsledky.
Přezkoumání jednotlivých datových bodů však odhaluje hlubší poznatek:
- Pro většinu velikostí Qubitů dávají SABRE i AI téměř identické výsledky, což naznačuje, že v mnoha případech obě metody dospívají k podobně efektivním řešením.
- Pro určité velikosti obvodů, konkrétně při 30, 50, 70 a 90 Qubitech, nachází AI transpiler výrazně mělčí obvody než SABRE. To naznačuje, že přístup AI založený na učení je schopen objevit optimálnější rozložení nebo směrovací cesty v případech, kdy SABRE heuristika nestačí.
Toto chování poukazuje na důležitý závěr:
I když SABRE a AI často přinášejí srovnatelné výsledky, AI transpiler může občas nalézt mnohem lepší řešení, zejména z hlediska hloubky, což může vést k výrazně lepšímu výkonu na hardwaru.
Část 2: Circuit pro simulaci Hamiltoniánu
Krok 1: Zkoumání Circuitů s PauliEvolutionGate
V této části zkoumáme kvantové Circuity sestavené pomocí PauliEvolutionGate, který umožňuje efektivní simulaci Hamiltoniánů. Analyzujeme, jak různé metody kompilace optimalizují tyto Circuity pro různé Hamiltoniány.
Hamiltoniány použité v benchmarku
Hamiltoniány použité v tomto benchmarku popisují párové interakce mezi Qubity, včetně členů jako , a . Tyto Hamiltoniány se běžně používají v kvantové chemii, fyzice kondenzované hmoty a materiálové vědě, kde modelují systémy interagujících částic.
Pro referenci si můžeš prohlédnout širší sadu Hamiltoniánů v tomto článku: Efficient Hamiltonian Simulation on Noisy Quantum Devices.
Zdroj benchmarku: Hamlib a Benchpress
Circuity použité v tomto benchmarku pocházejí z repozitáře Hamlib, který obsahuje realistické úlohy simulace Hamiltoniánů.
Tyto samé Circuity byly dříve testovány pomocí Benchpress, open-source frameworku pro hodnocení výkonu kvantové transpilace. Díky použití této standardizované sady Circuitů můžeme přímo porovnat efektivitu různých kompilačních strategií na reprezentativních simulačních úlohách.
Simulace Hamiltoniánů je základní úlohou v kvantovém výpočetnictví s aplikacemi v molekulárních simulacích, optimalizačních problémech a kvantové fyzice mnohočásticových systémů. Pochopení toho, jak různé metody kompilace optimalizují tyto Circuity, může uživatelům pomoci zlepšit praktické spouštění takových Circuitů na near-term kvantových zařízeních.
# Obtain the Hamiltonian JSON from the benchpress repository
url = "https://raw.githubusercontent.com/Qiskit/benchpress/e7b29ef7be4cc0d70237b8fdc03edbd698908eff/benchpress/hamiltonian/hamlib/100_representative.json"
response = requests.get(url)
response.raise_for_status() # Raise an error if download failed
ham_records = json.loads(response.text)
# Remove circuits that are too large for the backend
ham_records = [
h for h in ham_records if h["ham_qubits"] <= backend.num_qubits
]
# Remove the circuits that are large to save transpilation time
ham_records = sorted(ham_records, key=lambda x: x["ham_terms"])[:35]
qc_ham_list = []
for h in ham_records:
terms = h["ham_hamlib_hamiltonian_terms"]
coeff = h["ham_hamlib_hamiltonian_coefficients"]
num_qubits = h["ham_qubits"]
name = h["ham_problem"]
evo_gate = PauliEvolutionGate(SparsePauliOp(terms, coeff))
qc_ham = QuantumCircuit(num_qubits)
qc_ham.name = name
qc_ham.append(evo_gate, range(num_qubits))
qc_ham_list.append(qc_ham)
print(f"Number of Hamiltonian circuits: {len(qc_ham_list)}")
# Draw the first Hamiltonian circuit
qc_ham_list[0].draw("mpl", fold=-1)
Number of Hamiltonian circuits: 35
Krok 2: Optimalizace problému pro spuštění na kvantovém hardwaru
Stejně jako v předchozím příkladu použijeme tentýž Backend pro zajištění konzistence ve srovnáních. Protože správci průchodů (pm_sabre, pm_ai a pm_rustiq) jsou již inicializovány, můžeme přímo přistoupit k transpilaci Hamiltonových Circuitů každou metodou.
Tento krok se soustředí výhradně na provedení transpilace a zaznamenání výsledných metrik Circuitu, včetně hloubky, počtu Gate a doby transpilace. Analýzou těchto výsledků chceme určit efektivitu každé metody transpilace pro tento typ Circuitu. Transpiluj a zachyť metriky:
results_ham = pd.DataFrame(
columns=[
"method",
"qc_name",
"qc_index",
"num_qubits",
"ops",
"depth",
"size",
"runtime",
]
)
tqc_sabre = capture_transpilation_metrics(
results_ham, pm_sabre, qc_ham_list, "sabre"
)
tqc_ai = capture_transpilation_metrics(results_ham, pm_ai, qc_ham_list, "ai")
tqc_rustiq = capture_transpilation_metrics(
results_ham, pm_rustiq, qc_ham_list, "rustiq"
)
Transpiled circuit index 0 (all-vib-o3) in 0.02 seconds with method sabre, depth 6, and size 58.
Transpiled circuit index 1 (all-vib-c2h) in 1.10 seconds with method sabre, depth 2, and size 39.
Transpiled circuit index 2 (all-vib-bh) in 0.01 seconds with method sabre, depth 3, and size 30.
Transpiled circuit index 3 (all-vib-c2h) in 0.03 seconds with method sabre, depth 18, and size 115.
Transpiled circuit index 4 (graph-gnp_k-2) in 0.02 seconds with method sabre, depth 24, and size 129.
Transpiled circuit index 5 (all-vib-fccf) in 0.05 seconds with method sabre, depth 14, and size 134.
Transpiled circuit index 6 (all-vib-hno) in 8.39 seconds with method sabre, depth 6, and size 174.
Transpiled circuit index 7 (all-vib-bhf2) in 3.92 seconds with method sabre, depth 22, and size 220.
Transpiled circuit index 8 (LiH) in 0.03 seconds with method sabre, depth 67, and size 290.
Transpiled circuit index 9 (uf20-ham) in 0.04 seconds with method sabre, depth 50, and size 340.
Transpiled circuit index 10 (all-vib-fccf) in 0.62 seconds with method sabre, depth 30, and size 286.
Transpiled circuit index 11 (all-vib-fccf) in 0.04 seconds with method sabre, depth 67, and size 339.
Transpiled circuit index 12 (all-vib-ch2) in 0.04 seconds with method sabre, depth 87, and size 421.
Transpiled circuit index 13 (tfim) in 0.05 seconds with method sabre, depth 36, and size 222.
Transpiled circuit index 14 (all-vib-cyclo_propene) in 9.51 seconds with method sabre, depth 22, and size 345.
Transpiled circuit index 15 (graph-gnp_k-4) in 0.05 seconds with method sabre, depth 128, and size 704.
Transpiled circuit index 16 (all-vib-hc3h2cn) in 13.83 seconds with method sabre, depth 2, and size 242.
Transpiled circuit index 17 (TSP_Ncity-4) in 0.05 seconds with method sabre, depth 106, and size 609.
Transpiled circuit index 18 (tfim) in 0.29 seconds with method sabre, depth 73, and size 399.
Transpiled circuit index 19 (all-vib-h2co) in 21.97 seconds with method sabre, depth 30, and size 572.
Transpiled circuit index 20 (Be2) in 0.09 seconds with method sabre, depth 324, and size 1555.
Transpiled circuit index 21 (graph-complete_bipart) in 0.12 seconds with method sabre, depth 250, and size 1394.
Transpiled circuit index 22 (all-vib-f2) in 0.07 seconds with method sabre, depth 215, and size 1027.
Transpiled circuit index 23 (all-vib-cyclo_propene) in 41.22 seconds with method sabre, depth 30, and size 1144.
Transpiled circuit index 24 (TSP_Ncity-5) in 1.89 seconds with method sabre, depth 175, and size 1933.
Transpiled circuit index 25 (H2) in 0.32 seconds with method sabre, depth 1237, and size 5502.
Transpiled circuit index 26 (uuf100-ham) in 0.20 seconds with method sabre, depth 385, and size 4303.
Transpiled circuit index 27 (ham-graph-gnp_k-5) in 0.20 seconds with method sabre, depth 311, and size 3654.
Transpiled circuit index 28 (tfim) in 0.15 seconds with method sabre, depth 276, and size 3213.
Transpiled circuit index 29 (uuf100-ham) in 0.21 seconds with method sabre, depth 520, and size 5250.
Transpiled circuit index 30 (flat100-ham) in 0.15 seconds with method sabre, depth 131, and size 3157.
Transpiled circuit index 31 (uf100-ham) in 0.24 seconds with method sabre, depth 624, and size 7378.
Transpiled circuit index 32 (OH) in 0.88 seconds with method sabre, depth 2175, and size 9808.
Transpiled circuit index 33 (HF) in 0.66 seconds with method sabre, depth 2206, and size 9417.
Transpiled circuit index 34 (BH) in 0.89 seconds with method sabre, depth 2177, and size 9802.
Transpiled circuit index 0 (all-vib-o3) in 0.02 seconds with method ai, depth 6, and size 58.
Transpiled circuit index 1 (all-vib-c2h) in 1.11 seconds with method ai, depth 2, and size 39.
Transpiled circuit index 2 (all-vib-bh) in 0.01 seconds with method ai, depth 3, and size 30.
Transpiled circuit index 3 (all-vib-c2h) in 0.11 seconds with method ai, depth 18, and size 94.
Transpiled circuit index 4 (graph-gnp_k-2) in 0.11 seconds with method ai, depth 22, and size 129.
Transpiled circuit index 5 (all-vib-fccf) in 0.06 seconds with method ai, depth 22, and size 177.
Transpiled circuit index 6 (all-vib-hno) in 8.62 seconds with method ai, depth 10, and size 198.
Transpiled circuit index 7 (all-vib-bhf2) in 3.71 seconds with method ai, depth 18, and size 195.
Transpiled circuit index 8 (LiH) in 0.19 seconds with method ai, depth 62, and size 267.
Transpiled circuit index 9 (uf20-ham) in 0.22 seconds with method ai, depth 47, and size 321.
Transpiled circuit index 10 (all-vib-fccf) in 0.71 seconds with method ai, depth 38, and size 369.
Transpiled circuit index 11 (all-vib-fccf) in 0.24 seconds with method ai, depth 65, and size 315.
Transpiled circuit index 12 (all-vib-ch2) in 0.24 seconds with method ai, depth 91, and size 430.
Transpiled circuit index 13 (tfim) in 0.15 seconds with method ai, depth 12, and size 251.
Transpiled circuit index 14 (all-vib-cyclo_propene) in 8.50 seconds with method ai, depth 18, and size 311.
Transpiled circuit index 15 (graph-gnp_k-4) in 0.25 seconds with method ai, depth 117, and size 659.
Transpiled circuit index 16 (all-vib-hc3h2cn) in 16.11 seconds with method ai, depth 2, and size 242.
Transpiled circuit index 17 (TSP_Ncity-4) in 0.39 seconds with method ai, depth 98, and size 564.
Transpiled circuit index 18 (tfim) in 0.38 seconds with method ai, depth 23, and size 437.
Transpiled circuit index 19 (all-vib-h2co) in 24.97 seconds with method ai, depth 38, and size 707.
Transpiled circuit index 20 (Be2) in 1.07 seconds with method ai, depth 293, and size 1392.
Transpiled circuit index 21 (graph-complete_bipart) in 0.61 seconds with method ai, depth 229, and size 1437.
Transpiled circuit index 22 (all-vib-f2) in 0.57 seconds with method ai, depth 178, and size 964.
Transpiled circuit index 23 (all-vib-cyclo_propene) in 50.89 seconds with method ai, depth 34, and size 1425.
Transpiled circuit index 24 (TSP_Ncity-5) in 1.61 seconds with method ai, depth 171, and size 2020.
Transpiled circuit index 25 (H2) in 6.39 seconds with method ai, depth 1148, and size 5208.
Transpiled circuit index 26 (uuf100-ham) in 3.97 seconds with method ai, depth 376, and size 5048.
Transpiled circuit index 27 (ham-graph-gnp_k-5) in 3.54 seconds with method ai, depth 357, and size 4451.
Transpiled circuit index 28 (tfim) in 1.72 seconds with method ai, depth 216, and size 3026.
Transpiled circuit index 29 (uuf100-ham) in 4.45 seconds with method ai, depth 426, and size 5399.
Transpiled circuit index 30 (flat100-ham) in 7.02 seconds with method ai, depth 86, and size 3108.
Transpiled circuit index 31 (uf100-ham) in 12.85 seconds with method ai, depth 623, and size 8354.
Transpiled circuit index 32 (OH) in 15.19 seconds with method ai, depth 2084, and size 9543.
Transpiled circuit index 33 (HF) in 17.51 seconds with method ai, depth 2063, and size 9446.
Transpiled circuit index 34 (BH) in 15.33 seconds with method ai, depth 2094, and size 9730.
Transpiled circuit index 0 (all-vib-o3) in 0.02 seconds with method rustiq, depth 13, and size 83.
Transpiled circuit index 1 (all-vib-c2h) in 1.11 seconds with method rustiq, depth 2, and size 39.
Transpiled circuit index 2 (all-vib-bh) in 0.01 seconds with method rustiq, depth 3, and size 30.
Transpiled circuit index 3 (all-vib-c2h) in 0.01 seconds with method rustiq, depth 13, and size 79.
Transpiled circuit index 4 (graph-gnp_k-2) in 0.02 seconds with method rustiq, depth 31, and size 131.
Transpiled circuit index 5 (all-vib-fccf) in 0.04 seconds with method rustiq, depth 50, and size 306.
Transpiled circuit index 6 (all-vib-hno) in 14.03 seconds with method rustiq, depth 22, and size 276.
Transpiled circuit index 7 (all-vib-bhf2) in 3.15 seconds with method rustiq, depth 13, and size 155.
Transpiled circuit index 8 (LiH) in 0.03 seconds with method rustiq, depth 54, and size 270.
Transpiled circuit index 9 (uf20-ham) in 0.04 seconds with method rustiq, depth 65, and size 398.
Transpiled circuit index 10 (all-vib-fccf) in 0.16 seconds with method rustiq, depth 41, and size 516.
Transpiled circuit index 11 (all-vib-fccf) in 0.02 seconds with method rustiq, depth 34, and size 189.
Transpiled circuit index 12 (all-vib-ch2) in 0.03 seconds with method rustiq, depth 49, and size 240.
Transpiled circuit index 13 (tfim) in 0.05 seconds with method rustiq, depth 20, and size 366.
Transpiled circuit index 14 (all-vib-cyclo_propene) in 9.08 seconds with method rustiq, depth 16, and size 277.
Transpiled circuit index 15 (graph-gnp_k-4) in 0.04 seconds with method rustiq, depth 116, and size 612.
Transpiled circuit index 16 (all-vib-hc3h2cn) in 13.89 seconds with method rustiq, depth 2, and size 257.
Transpiled circuit index 17 (TSP_Ncity-4) in 0.05 seconds with method rustiq, depth 133, and size 737.
Transpiled circuit index 18 (tfim) in 0.11 seconds with method rustiq, depth 25, and size 680.
Transpiled circuit index 19 (all-vib-h2co) in 27.19 seconds with method rustiq, depth 66, and size 983.
Transpiled circuit index 20 (Be2) in 0.07 seconds with method rustiq, depth 215, and size 1030.
Transpiled circuit index 21 (graph-complete_bipart) in 0.14 seconds with method rustiq, depth 328, and size 1918.
Transpiled circuit index 22 (all-vib-f2) in 0.05 seconds with method rustiq, depth 114, and size 692.
Transpiled circuit index 23 (all-vib-cyclo_propene) in 62.25 seconds with method rustiq, depth 74, and size 2348.
Transpiled circuit index 24 (TSP_Ncity-5) in 0.20 seconds with method rustiq, depth 436, and size 3605.
Transpiled circuit index 25 (H2) in 0.21 seconds with method rustiq, depth 643, and size 3476.
Transpiled circuit index 26 (uuf100-ham) in 0.24 seconds with method rustiq, depth 678, and size 6120.
Transpiled circuit index 27 (ham-graph-gnp_k-5) in 0.22 seconds with method rustiq, depth 588, and size 5241.
Transpiled circuit index 28 (tfim) in 0.34 seconds with method rustiq, depth 340, and size 5901.
Transpiled circuit index 29 (uuf100-ham) in 0.33 seconds with method rustiq, depth 881, and size 7667.
Transpiled circuit index 30 (flat100-ham) in 0.31 seconds with method rustiq, depth 279, and size 4910.
Transpiled circuit index 31 (uf100-ham) in 0.38 seconds with method rustiq, depth 1138, and size 10607.
Transpiled circuit index 32 (OH) in 0.38 seconds with method rustiq, depth 1148, and size 6512.
Transpiled circuit index 33 (HF) in 0.37 seconds with method rustiq, depth 1090, and size 6256.
Transpiled circuit index 34 (BH) in 0.37 seconds with method rustiq, depth 1148, and size 6501.
Tabulka výsledků (vizualizace je vynechána, protože výstupní Circuity jsou velmi velké):
summary_ham = (
results_ham.groupby("method")[["depth", "size", "runtime"]]
.mean()
.round(2)
)
print(summary_ham)
results_ham
depth size runtime
method
ai 316.86 2181.26 5.97
rustiq 281.94 2268.80 3.86
sabre 337.97 2120.14 3.07
method qc_name qc_index num_qubits \
0 sabre all-vib-o3 0 4
1 sabre all-vib-c2h 1 4
2 sabre all-vib-bh 2 2
3 sabre all-vib-c2h 3 3
4 sabre graph-gnp_k-2 4 4
.. ... ... ... ...
100 rustiq flat100-ham 30 90
101 rustiq uf100-ham 31 46
102 rustiq OH 32 10
103 rustiq HF 33 10
104 rustiq BH 34 10
ops depth size runtime
0 {'rz': 28, 'sx': 24, 'cz': 6} 6 58 0.016597
1 {'rz': 17, 'sx': 16, 'cz': 4, 'x': 2} 2 39 1.102089
2 {'sx': 14, 'rz': 13, 'cz': 3} 3 30 0.011042
3 {'sx': 46, 'rz': 45, 'cz': 18, 'x': 6} 18 115 0.025816
4 {'sx': 49, 'rz': 47, 'cz': 24, 'x': 9} 24 129 0.023077
.. ... ... ... ...
100 {'sx': 2709, 'cz': 1379, 'rz': 817, 'x': 5} 279 4910 0.309448
101 {'sx': 6180, 'cz': 3120, 'rz': 1303, 'x': 4} 1138 10607 0.380977
102 {'sx': 3330, 'cz': 1704, 'rz': 1455, 'x': 23} 1148 6512 0.383564
103 {'sx': 3213, 'cz': 1620, 'rz': 1406, 'x': 17} 1090 6256 0.368578
104 {'sx': 3331, 'cz': 1704, 'rz': 1447, 'x': 19} 1148 6501 0.374822
[105 rows x 8 columns]
Vizualizuj výkon podle indexu Circuit:
plot_transpilation_metrics(
results_ham, "Transpilation Metrics for Hamiltonian Circuits"
)

Vizualizuj podíl Circuitů, pro které každá metoda dosáhla nejlepšího výsledku.
def analyze_and_plot_best_methods(results, metric):
"""
Analyze the best-performing methods for a given metric and plot a pie chart.
Parameters:
results (DataFrame): The input DataFrame containing method performance data.
metric (str): The metric to evaluate ("depth" or "size").
"""
method_counts = Counter()
for qc_idx, group in results.groupby("qc_index"):
min_value = group[metric].min()
# Find all methods that achieved this minimum value
best_methods = group[group[metric] == min_value]["method"]
# Update counts for all best methods (handling ties)
method_counts.update(best_methods)
best_method_counts = dict(
sorted(method_counts.items(), key=lambda x: x[1], reverse=True)
)
# Print summary
print(f"Best-performing methods based on {metric}:")
for method, count in best_method_counts.items():
print(f" {method}: {count} circuit(s)")
# Plot pie chart
num_methods = len(best_method_counts)
colors = plt.cm.viridis_r(range(0, 256, 256 // num_methods))
plt.figure(figsize=(5, 5))
plt.pie(
best_method_counts.values(),
labels=best_method_counts.keys(),
autopct="%1.1f%%",
startangle=140,
wedgeprops={"edgecolor": "black"},
textprops={"fontsize": 10},
colors=colors,
)
plt.title(
f"Percentage of Circuits Method Performed Best for {metric.capitalize()}",
fontsize=12,
fontweight="bold",
)
plt.show()
analyze_and_plot_best_methods(results_ham, "depth")
analyze_and_plot_best_methods(results_ham, "size")
Best-performing methods based on depth:
ai: 16 circuit(s)
rustiq: 16 circuit(s)
sabre: 10 circuit(s)
Best-performing methods based on size:
sabre: 18 circuit(s)
rustiq: 14 circuit(s)
ai: 10 circuit(s)
Analýza výsledků kompilace Hamiltonových Circuitů
V této části hodnotíme výkon tří metod transpilace — SABRE, AI transpilátoru a Rustiq — na kvantových Circuitech sestavených pomocí PauliEvolutionGate, které se běžně používají při simulaci Hamiltoniánů.
Rustiq dosáhl průměrně nejlepšího výsledku z hlediska hloubky Circuit**, přičemž dosáhl přibližně o 20 % nižší hloubky než SABRE. To je očekávané, protože Rustiq je speciálně navržen pro syntézu operací PauliEvolutionGate s optimalizovanými strategiemi rozkladu s nízkou hloubkou. Graf hloubky navíc ukazuje, že jak Circuity rostou co do velikosti a složitosti, Rustiq škáluje nejefektivněji a na větších Circuitech dosahuje výrazně nižší hloubky než AI i SABRE.
AI transpilátor vykázal silný a konzistentní výkon z hlediska hloubky Circuit, přičemž ve většině Circuitů trvale překonával SABRE. Byl však zatížen nejvyšší dobou běhu, zejména u větších Circuitů, což může omezit jeho praktičnost v časově citlivých úlohách. Škálovatelnost jeho doby běhu zůstává klíčovým omezením, přestože nabízí solidní zlepšení hloubky.
SABRE, přestože dosáhl nejvyšší průměrné hloubky, dosáhl nejnižšího průměrného počtu Gate, těsně následován AI transpilátorem. To odpovídá designu heuristiky SABRE, která přímo upřednostňuje minimalizaci počtu Gate. Rustiq, navzdory svým silným stránkám v snižování hloubky, dosáhl nejvyššího průměrného počtu Gate, což je výrazný kompromis, který je třeba zvážit v aplikacích, kde záleží více na velikosti Circuit než na době trvání Circuit.
Shrnutí
Ačkoli AI transpilátor obecně dosahuje lepších výsledků než SABRE, zejména z hlediska hloubky Circuit, závěr by neměl znít jednoduše „vždy používej AI transpilátor." Je třeba zvážit důležité nuance:
-
AI transpilátor je obvykle spolehlivý a poskytuje hloubkově optimalizované Circuity, ale přináší kompromisy z hlediska doby běhu a má i další omezení, včetně podporovaných coupling map a schopností syntézy. Tato omezení jsou podrobně popsána v dokumentaci ke službě Qiskit Transpiler Service.
-
V některých případech, zejména u velmi velkých nebo hardwarově specifických Circuitů, nemusí být AI transpilátor tak efektivní. V těchto případech zůstává výchozí transpilátor SABRE extrémně spolehlivý a lze ho dále optimalizovat úpravou parametrů (viz tutoriál o optimalizaci SABRE).
-
Při výběru metody je také důležité zvážit strukturu Circuit. Například
rustiqje přímo vytvořen pro Circuity obsahujícíPauliEvolutionGatea pro úlohy simulace Hamiltoniánů často dosahuje nejlepšího výkonu.
Doporučení:
Neexistuje žádná univerzální strategie transpilace. Doporučuje se, abys porozuměl struktuře svého Circuit a otestoval více metod transpilace — včetně AI, SABRE a specializovaných nástrojů jako Rustiq — a nalezl tak nejefektivnější řešení pro svůj konkrétní problém a hardwarová omezení.
Krok 3: Spuštění pomocí primitiv Qiskit
Protože se tento tutoriál zaměřuje na transpilaci, nejsou na kvantovém zařízení prováděny žádné experimenty. Cílem je využít optimalizace z kroku 2 k získání transpilovaného Circuit se sníženou hloubkou a počtem Gate.
Krok 4: Následné zpracování a vrácení výsledku v požadovaném klasickém formátu
Protože v tomto notebooku neprobíhá žádné spuštění, nejsou k dispozici žádné výsledky ke zpracování.
Reference
[1] "LightSABRE: A Lightweight and Enhanced SABRE Algorithm". H. Zou, M. Treinish, K. Hartman, A. Ivrii, J. Lishman et al. https://arxiv.org/abs/2409.08368
[2] "Practical and efficient quantum circuit synthesis and transpiling with Reinforcement Learning". D. Kremer, V. Villar, H. Paik, I. Duran, I. Faro, J. Cruz-Benito et al. https://arxiv.org/abs/2405.13196
[3] "Pauli Network Circuit Synthesis with Reinforcement Learning". A. Dubal, D. Kremer, S. Martiel, V. Villar, D. Wang, J. Cruz-Benito et al. https://arxiv.org/abs/2503.14448
[4] "Faster and shorter synthesis of Hamiltonian simulation circuits". T. Goubault de Brugière, S. Martiel et al. https://arxiv.org/abs/2404.03280