Kompilierungsmethoden für Hamilton-Simulationsschaltungen
Gschätzte QPU-Nutzung: koa Ausführung is in dem Tutorial gmacht worn, weil's si auf'n Transpilationsprozess konzentriert.
Hintergrund
De Quanteschaltungskompilierung is a entscheidender Schritt im Quantencomputing-Workflow. Se umfasst de Transformation von an hochrangigen Quantenalgorithmus in a physische Quanteschaltung, de de Einschränkungen von da Ziel-Quantehardware entspricht. Effektive Kompilierung ka de Leistung von Quantenalgorithmen erheblich beeinflussen, indem se Schaltungstiefe, Gate-Anzahl und Ausführungszeit reduziert. Des Tutorial untersuacht drei unterschiedliche Ansätz zur Quanteschaltungskompilierung in Qiskit und zeigt ihre Stärken und Anwendungen durch praktische Beispiele auf.
S Ziel von dem Tutorial is es, de Benutzern beizubringen, wie mia drei Kompilierungsmethoden in Qiskit anwenden und bewerten: den SABRE-Transpiler, den AI-gstützten Transpiler und des Rustiq-Plugin. De Benutzer werdn lerna, wie se jede Methode effektiv einsetzen und wie se ihre Leistung über verschiedene Quanteschaltungen hinweg benchmarken. Am End von dem Tutorial werdn de Benutzer in da Lag sei, Kompilierungsstrategien basierend auf spezifische Optimierungsziele – wia de Reduzierung von da Schaltungstiefe, de Minimierung von da Gate-Anzahl oder de Verbesserung von da Laufzeit – z wählen und anzupassen.
Was mia lerna werdn
- Wia mia den Qiskit-Transpiler mit SABRE für Layout- und Routing-Optimierung verwenden.
- Wia mia den AI-Transpiler für fortgschrittene, automatisierte Schaltungsoptimierung nutzen.
- Wia mia des Rustiq-Plugin für Schaltungen einsetzen, de a präzise Synthese von Operationen erfordern, insbesondere bei Hamilton-Simulationsaufgaben.
Des Tutorial verwendet drei Beispielschaltungen nach dem Qiskit Patterns-Workflow, um de Leistung von jeder Kompilierungsmethode zu veranschaulichen. Am End von dem Tutorial werdn de Benutzer in da Lag sei, de geeignete Kompilierungsstrategie basierend auf ihre spezifischen Anforderungen und Einschränkungen zu wählen.
Überblick über Kompilierungsmethoden
1. Qiskit-Transpiler mit SABRE
Da Qiskit-Transpiler verwendet den SABRE (SWAP-based BidiREctional heuristic search)-Algorithmus zur Optimierung von Schaltungslayout und -routing. SABRE konzentriert si auf de Minimierung von SWAP-Gates und deren Auswirkungen auf de Schaltungstiefe, während Hardware-Konnektivitätsbeschränkungen einghaten werdn. De Methode is hoch vielseitig und für allgemeine Schaltungsoptimierung geeignet und bietet a Gleichgewicht zwischen Leistung und Rechenzeit. Um de neuesten Verbesserungen in SABRE zu nutzen, de in [1] detailliert beschrieben san, ka mr de Anzahl von de Versuache erhöhen (zum Beispiel layout_trials=400, swap_trials=400). Für de Zwecke von dem Tutorial verwenden mia de Standardwerte für de Anzahl von de Versuache, um mit dem Standard-Transpiler von Qiskit zu vergleichen. De Vorteile und Parameter-Exploration von SABRE werdn in an separaten Deep-Dive-Tutorial behandelt.
2. AI-Transpiler
Da AI-gstützte Transpiler in Qiskit verwendet maschinelles Lernen, um optimale Transpilationsstrategien vorherzusagen, indem er Muster in da Schaltungsstruktur und Hardware-Einschränkungen analysiert, um de beste Sequenz von Optimierungen für a gegebene Eingabe auszuwählen. De Methode is besonders effektiv für groß angelegte Quanteschaltungen und bietet a hohes Maß an Automatisierung und Anpassungsfähigkeit an diverse Problemtypen. Zusätzlich zur allgemeinen Schaltungsoptimierung ka da AI-Transpiler mit dem AIPauliNetworkSynthesis-Pass verwendet werd, da Pauli-Netzwerkschaltungen – Blöcke, de aus H-, S-, SX-, CX-, RX-, RY- und RZ-Gates bestehnd – anvisiert und an auf Reinforcement Learning basierenden Syntheseansatz anwendet. Weitere Informationen zum AI-Transpiler und seine Synthese-Strategien findet mr in [2] und [3].
3. Rustiq-Plugin
Des Rustiq-Plugin führt fortgschrittene Synthesetechniken speziell für PauliEvolutionGate-Operationen ei, de Pauli-Rotationen repräsentieren, de häufig in trotterisierter Dynamik verwendet werdn. Des Plugin is wertvoll für Schaltungen, de Hamilton-Simulation implementieren, wia se in Quantenchemie- und Physikproblemen verwendet werdn, bei denen genaue Pauli-Rotationen für de effektive Simulation von Problem-Hamiltonians wesentlich san. Rustiq bietet präzise, niedrig-tife Schaltungssynthese für de spezialisierten Operationen. Weitere Details zur Implementierung und Leistung von Rustiq findet mr in [4].
Durch de eingehende Untersuchung von dene Kompilierungsmethoden bietet des Tutorial de Benutzern de Werkzeug, um de Leistung von ihre Quanteschaltungen zu verbessern und den Weg für effizientere und praktischere Quanteberechnungen zu ebnen.
Anforderungen
Stellt vor dem Beginn von dem Tutorial sicher, dass folgendes installiert is:
- Qiskit SDK v1.3 oder höher, mit Unterstützung für Visualisierung
- Qiskit Runtime v0.28 oder höher (
pip install qiskit-ibm-runtime) - Qiskit IBM Transpiler (
pip install qiskit-ibm-transpiler) - Qiskit AI Transpiler Lokalmodus (
pip install qiskit_ibm_ai_local_transpiler) - Networkx-Graphenbibliothek (
pip install networkx)
Setup
# Added by doQumentation — installs packages not in the Binder environment
!pip install -q qiskit-ibm-transpiler
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
Teil 1: Efficient SU2-Schaltung
Schritt 1: Klassische Eingaben auf a Quantenproblem abbilden
In dem Abschnitt untersuachen mia de efficient_su2-Schaltung, an hardwareeffizienten Ansatz, da häufig in variationellen Quantenalgorithmen (wia VQE) und Quantum-Machine-Learning-Aufgaben verwendet wird. De Schaltung besteht aus wechselnden Schichten von Ein-Qubit-Rotationen und verschränkenden Gates, de in an kreisförmigen Muster angeordnet san und dazu konzipiert san, den Quantezustandsraum effektiv zu erkunden, während a überschaubare Tiefe beibehalten wird.
Mia fangen mit da Konstruktion von ana efficient_su2-Schaltung an, um zu demonstrieren, wia verschiedene Kompilierungsmethoden verglichen werdn. Nach Teil 1 werdn mia onsere Analyse auf an größeren Satz von Schaltungen erweitern, um an umfassenden Benchmark zur Bewertung von da Leistung verschiedener Kompilierungstechniken zu ermöglichen.
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")
Schritt 2: Problem für de Ausführung auf Quantehardware optimieren
Des Schritt is da Hauptfokus von dem Tutorial. Do wollen mia Quanteschaltungen für de effiziente Ausführung auf echter Quantehardware optimieren. Onsers primäres Ziel is es, Schaltungstiefe und Gate-Anzahl zu reduzieren, de Schlüsselfaktoren zur Verbesserung von da Ausführungstreue und zur Minderung von Hardware-Rauschen san.
- SABRE-Transpiler: Verwendet den Standard-Transpiler von Qiskit mit dem SABRE-Layout- und Routing-Algorithmus.
- AI-Transpiler (Lokalmodus): Da Standard-AI-gstützte Transpiler mit lokaler Inferenz und da Standard-Synthesestrategie.
- Rustiq-Plugin: A Transpiler-Plugin für niedrig-tife Kompilierung, des auf Hamilton-Simulationsaufgaben zuagschnitten is.
S Ziel von dem Schritt is es, de Ergebnisse von dene Methoden hinsichtlich Tiefe und Gate-Anzahl von da transpilierten Schaltung zu vergleichen. A weitere wichtige Metrik, de mia berücksichtigen, is de Transpilationslaufzeit. Durch de Analyse von dene Metriken kenna mia de relativen Stärken von jeder Methode bewerten und bestimmen, welche de effizienteste Schaltung für de Ausführung auf da ausgwählten Hardware produziert.
Hinweis: Für des anfängliche SU2-Schaltungsbeispiel werdn mia nur den SABRE-Transpiler mit dem Standard-AI-Transpiler vergleichen. Im anschließenden Benchmark mit Hamlib-Schaltungen werdn mia jedoch alle drei Transpilationsmethoden vergleichen.
# 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 mit 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
)
Rustiq-Plugin:
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,
)
Transpilieren und Metriken erfassen
Um de Leistung von de Kompilierungsmethoden zu vergleichen, definieren mia a Funktion, de de Eingabeschaltung transpiliert und relevante Metriken auf konsistente Weise erfasst. Des umfasst de Gsamtschaltungstiefe, de Gsamt-Gate-Anzahl und de Transpilationszeit.
Zusätzlich zu dene Standardmetriken zeichnen mia a de 2-Qubit-Gate-Tiefe auf, de a besonders wichtige Metrik zur Bewertung von da Ausführung auf Quantehardware is. Im Gegensatz zur Gsamttiefe, de alle Gates einschließt, spiegelt de 2-Qubit-Tiefe de tatsächliche Ausführungsdauer von da Schaltung auf Hardware genauer wider. Des liegt daran, dass 2-Qubit-Gates typischerweise des Zeit- und Fehlerbudget in de meisten Quantegeräten dominieren. Daher is de Minimierung von da 2-Qubit-Tiefe entscheidend für de Verbesserung von da Fidelität und de Reduzierung von Dekohärenzeffekten während da Ausführung.
Mia werdn de Funktion verwenden, um de Leistung von de verschiedenen Kompilierungsmethoden über mehrere Schaltungen hinweg zu analysieren.
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.
Zeigt de transpilierten Ergebnisse von einer von de Schaltungen an.
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

Ergebnistabelle:
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
Ergebnisgraph
Weil mia a Funktion definiert ham, um Metriken konsistent zu erfassen, werdn mia a eine definieren, um de Metriken grafisch darzustellen. Do werdn mia de Zwei-Qubit-Tiefe, de Gate-Anzahl und de Laufzeit für jede Kompilierungsmethode über de Schaltungen hinweg darstellen.
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"
)

Analyse von de SU2-Schaltungskompilierungsergebnisse
In dem Experiment vergleichen mia zwei Transpilationsmethoden – Qiskits SABRE-Transpiler und den AI-gstützten Transpiler – an an Satz von efficient_su2-Schaltungen. Weil dene Schaltungen koa PauliEvolutionGate-Operationen ham, is des Rustiq-Plugin in dem Vergleich ned enthalten.
Im Durchschnitt schneidet da AI-Transpiler hinsichtlich da Schaltungstiefe besser ab, mit ana Verbesserung von mehr als 10% über de gsamt Bandbreite von de SU2-Schaltungen hinweg. Für Gate-Anzahl (Schaltungsgröße) und Transpilationslaufzeit erzielen beide Methoden insgesamt ähnliche Ergebnisse.
De Inspektion von de einzelnen Datenpunkte offenbart jedoch a tiefere Einsicht:
- Für de meisten Qubit-Größen produzieren sowohl SABRE als a AI nahezu identische Ergebnisse, was drauf hindeutet, dass beide Methoden in vielen Fällen zu ähnlich effizienten Lösungen konvergieren.
- Für bestimmte Schaltungsgrößen, speziell bei 30, 50, 70 und 90 Qubits, findet da AI-Transpiler deutlich flachere Schaltungen als SABRE. Des zeigt, dass da lernbasierte Ansatz von AI in da Lag is, optimalere Layouts oder Routing-Pfade in Fällen zu entdecken, in denen de SABRE-Heuristik des ned tut.
Des Verhalten hebt a wichtige Erkenntnis hervor:
Während SABRE und AI oft vergleichbare Ergebnisse produzieren, ka da AI-Transpiler gelegentlich viel bessere Lösungen entdecken, insbesondere hinsichtlich da Tiefe, was zu deutlich verbesserter Leistung auf Hardware führen ka.
Teil 2: Hamilton-Simulationsschaltung
Schritt 1: Untersuchung von Schaltungen mit PauliEvolutionGate
In dem Abschnitt untersuachen mia Quanteschaltungen, de unter Verwendung von PauliEvolutionGate konstruiert worn san, des a effiziente Simulation von Hamiltonians ermöglicht. Mia werdn analysieren, wia verschiedene Kompilierungsmethoden dene Schaltungen über verschiedene Hamiltonians hinweg optimieren.
In dem Benchmark verwendete Hamiltonians
De in dem Benchmark verwendeten Hamiltonians beschreiben paarweise Interaktionen zwischen Qubits, einschließlich Terme wia , und . Dene Hamiltonians werdn häufig in Quantenchemie, Festkörperphysik und Materialwissenschaft verwendet, wo se Systeme von interagierenden Teilchen modellieren.
Als Referenz kenna Benutzer an breiteren Satz von Hamiltonians in dem Paper erkunden: Efficient Hamiltonian Simulation on Noisy Quantum Devices.
Benchmark-Quelle: Hamlib und Benchpress
De in dem Benchmark verwendeten Schaltungen stammen aus dem Hamlib-Benchmark-Repository, des realistische Hamilton-Simulations-Workloads enthält.
Dene gleichen Schaltungen san zuvor mit Benchpress benchmarked worn, an Open-Source-Framework zur Bewertung von da Quanten-Transpilationsleistung. Durch de Verwendung von dem standardisierten Satz von Schaltungen kenna mia de Effektivität verschiedener Kompilierungsstrategien bei repräsentativen Simulationsproblemen direkt vergleichen.
Hamilton-Simulation is a grundlegende Aufgabe im Quantencomputing mit Anwendungen in Molekülsimulationen, Optimierungsproblemen und Quanten-Vielteilchenphysik. S Verständnis, wia verschiedene Kompilierungsmethoden dene Schaltungen optimieren, ka de Benutzern helfen, de praktische Ausführung von solchen Schaltungen auf kurzfristigen Quantegeräten zu verbessern.
# 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
Schritt 2: Problem für de Ausführung auf Quantehardware optimieren
Wia im vorherigen Beispiel verwenden mia dasselbe Backend, um Konsistenz in onseren Vergleichen sicherzustellen. Da de Pass-Manager (pm_sabre, pm_ai und pm_rustiq) bereits initialisiert worn san, kenna mia direkt mit da Transpilation von de Hamilton-Schaltungen mit jeder Methode fortfahren.
Des Schritt konzentriert si ausschließlich auf de Durchführung von da Transpilation und de Aufzeichnung von de resultierenden Schaltungsmetriken, einschließlich Tiefe, Gate-Anzahl und Transpilationslaufzeit. Durch de Analyse von dene Ergebnissen wollen mia de Effizienz von jeder Transpilationsmethode für dene Schaltungstyp bestimmen.
Transpilieren und Metriken erfassen:
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.
Ergebnistabelle (Visualisierung wird übergangen, weil de Ausgabeschaltungen sehr groß san):
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]
Visualisiert de Leistung basierend auf dem Schaltungsindex:
plot_transpilation_metrics(
results_ham, "Transpilation Metrics for Hamiltonian Circuits"
)

Visualisiert den Prozentsatz von de Schaltungen, für de jede Methode am besten abgschnitten hett.
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)
Analyse von de Hamilton-Schaltungskompilierungsergebnisse
In dem Abschnitt evaluieren mia de Leistung von drei Transpilationsmethoden – SABRE, dem AI-gstützten Transpiler und Rustiq – an Quanteschaltungen, de mit PauliEvolutionGate konstruiert worn san, de häufig in Hamilton-Simulationsaufgaben verwendet werdn.
Rustiq hett im Durchschnitt am besten hinsichtlich da Schaltungstiefe abgschnitten und hett a etwa 20% niedrigere Tiefe als SABRE erreicht. Des is zu erwarten, weil Rustiq speziell für de Synthese von PauliEvolutionGate-Operationen mit optimierten, niedrig-tife Zerlegungsstrategien entwickelt worn is. Darüber hinaus zeigt des Tiefediagramm, dass Rustiq am effektivsten skaliert, wenn de Schaltungen an Größe und Komplexität zunehmen, und a deutlich geringere Tiefe als sowohl AI als a SABRE bei größeren Schaltungen beibehält.
Da AI-Transpiler hett starke und konsistente Leistung für de Schaltungstiefe gzeigt und hett SABRE konsistent über de meisten Schaltungen hinweg übertroffen. Er hett jedoch de höchste Laufzeit verursacht, insbesondere bei größeren Schaltungen, was seine Praktikabilität in zeitkritischen Workloads einschränken ka. Seine Skalierbarkeit bei da Laufzeit bleibt a Schlüsselbeschränkung, obwohl er solide Verbesserungen bei da Tiefe bietet.
SABRE hett zwar de höchste durchschnittliche Tiefe erzielt, aber de niedrigste durchschnittliche Gate-Anzahl, dicht gefolgt von dem AI-Transpiler. Des is im Einklang mit dem Design von da SABRE-Heuristik, de de Minimierung von da Gate-Anzahl direkt priorisiert. Rustiq hett trotz seiner Stärke bei da Senkung von da Tiefe de höchste durchschnittliche Gate-Anzahl ghabt, was a bemerkenswerter Kompromiss is, den mr in Anwendungen berücksichtigen sollte, bei denen de Schaltungsgröße mehr zählt als de Schaltungsdauer.
Zusammenfassung
Während da AI-Transpiler im Allgemeinen bessere Ergebnisse als SABRE liefert, insbesondere bei da Schaltungstiefe, sollt de Schlussfolgerung ned einfach "immer den AI-Transpiler verwenden" sei. Es gibt wichtige Nuancen zu berücksichtigen:
-
AI-Transpiler is typischerweise zuverlässig und liefert tiefenoptimierte Schaltungen, bringt aber Kompromisse bei da Laufzeit mit si und hett a andere Einschränkungen, einschließlich unterstützter Coupling-Maps und Synthese-Fähigkeiten. Dene san in da Qiskit Transpiler Service-Dokumentation detailliert beschrieben.
-
In manchen Fällen, insbesondere bei sehr großen oder hardwarespezifischen Schaltungen, is da AI-Transpiler möglicherweise ned so effektiv. In dene Fällen bleibt da Standard-SABRE-Transpiler äußerst zuverlässig und ka durch Anpassung seiner Parameter weiter optimiert werd (gsehgts SABRE-Optimierungs-Tutorial).
-
Es is a wichtig, de Schaltungsstruktur bei da Wahl von ana Methode zu berücksichtigen. Zum Beispiel is
rustiqspeziell für Schaltungen mitPauliEvolutionGatekonzipiert und liefert oft de beste Leistung für Hamilton-Simulationsprobleme.
Empfehlung:
Es gibt koa Einheitslösung für de Transpilationsstrategie. De Benutzer werdn ermuntert, de Struktur von ihrer Schaltung zu verstehn und mehrere Transpilationsmethoden zu testen – einschließlich AI, SABRE und spezialisierte Tools wia Rustiq – um de effizienteste Lösung für ihr spezifisches Problem und ihre Hardware-Einschränkungen zu findn.
Schritt 3: Ausführung mit Qiskit Primitives
Weil si des Tutorial auf Transpilation konzentriert, werdn koa Experimente auf an Quantegerät ausgführt. S Ziel is es, de Optimierungen aus Schritt 2 zu nutzen, um a transpilierte Schaltung mit reduzierter Tiefe und Gate-Anzahl zu erhalten.
Schritt 4: Nachbearbeitung und Rückgabe von dem Ergebnis im gewünschten klassischen Format
Da es koa Ausführung für des Notebook gibt, gibt es a koa Ergebnisse zur Nachbearbeitung.
Referenzen
[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