Skip to content
harmoniqsPublic

About

Compile quantum circuits to single optimized pulses.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

124 Commits

Folders and files

Repository files navigation

Legato.jl

Documentation
Stable Dev
Build Status
Build Status Coverage
License
MIT License

A circuit isn't a sequence of gates. It's a unitary. Compile it as one.

Legato compiles a circuit into a single block unitary

Legato.jl is the circuit-to-pulse compilation layer of the Piccolo.jl ecosystem. Given a gate-level circuit and a hardware device profile, Legato synthesizes a single optimized control pulse that implements the whole circuit as one block unitary $U$ — skipping gate decomposition, scheduling, and gate-boundary error accumulation.

Why this is different

A conventional quantum compiler decomposes a circuit into native gates, schedules them, and lowers each gate to a precomputed pulse. That pipeline leaves pulse-level fidelity on the table — every gate boundary is a re-initialization, every idle qubit is accumulating decoherence, every decomposition hides joint optimization opportunities.

Legato treats the circuit as a unitary $U_\text{circ}$ and solves directly for a control pulse $u(t)$ on the device system $H_\text{sys}(u)$:

$$\begin{aligned} \min_{u(t),\,\varphi}\quad & 1 - \mathcal{F}\!\left(U_\text{circ},\, V_\varphi\, U(T;\,u)\right) \\\ \text{subject to}\quad & \dot{U}(t) = -i\,H_\text{sys}(u(t))\,U(t),\quad U(0) = I, \\\ & u_\text{min} \le u(t) \le u_\text{max}. \end{aligned}$$

$V_\varphi$ are per-qubit virtual-Z phases (free-phase). $\mathcal{F}$ is the Pedersen subspace fidelity on the computational levels.

Conventional Legato
Optimization unit one gate one block (or whole circuit)
Gate-boundary error $N$ × per-gate error one solve, no boundaries
Idle decoherence every non-active qubit at every layer actively driven through the block
Hardware coupling hidden in decomposition first-class — pulse uses the device's actual drift
Duration $\sum$ gate durations + scheduling slack min-time compressed against fidelity floor

Quick example

Cold-start a single-qubit X gate on a 2-level model of an IBM Heron r3 transmon:

using Random, Legato
Random.seed!(0xc0ffee)

device = HeronR3(n_levels = 2)         # qubit subspace; drop the kwarg for 3-level (with leakage)
circuit = GateCircuit([GateOp(:X, (1,))], 1)

report = compile(
    circuit, device;
    max_iter = 1500, T_ns = 60.0, N_knots = 21,
    Q = 100.0, R = 1e-4, ddu_bound = 10.0,
    free_phase = true,
)
Pulse fidelity  : 0.99283
Pulse duration  : 60.0 ns
Wall clock      : ~120 s on a workstation

The full runnable script is at scripts/x_heronr3_2level.jl.

For multi-qubit circuits or high-fidelity (≥ 5-nines) results, the substrate cold-start path isn't enough — install Legatissimo to enable parallel multistart, catalog warm-starts, and min-time compression. Public Legato lands you in the right basin; Legatissimo lands you at the bottom.

Compiling QEC blocks

The flagship use case: compile each block of a multi-block QEC circuit (e.g. surface-code syndrome extraction) once into a reusable pulse. Subsequent rounds reuse the cached pulse instead of re-decomposing.

report = compile(syndrome_circuit, device; strategy = :warm_stitch_transmon)

:warm_stitch_transmon (in Legatissimo, Harmoniqs' private competitive layer) does the full pipeline:

  1. Transpile to native gates: to_native(circuit, device) — pure circuit rewriting, e.g. CNOT(c,t) → H(t)·CZ(c,t)·H(t).
  2. Schedule the native gates serially (or with parallelization in v0.4+).
  3. Stitch catalog pulses into a single warm-start pulse for the whole block.
  4. Joint-solve the block as one optimization — eliminates gate-boundary errors, exploits the device drift.
  5. Min-time compress against a fidelity floor.

What's where

Legato is a substrate that runs productively on small problems with no proprietary dependencies. Harmoniqs' competitive compilation intelligence lives in a private overlay package, Legatissimo.jl, which plugs in via Legato's strategy-registry seam:

Feature Legato (public, MIT) Legatissimo (private)
Circuit IR (GateCircuit, GateOp, circuit_unitary) ✅ —
Gate library (qft, toffoli, ccz, ...) ✅ —
Device profiles (HeronR3, HeronR2, IQMEmerald) ✅ —
to_native transpile pass ✅ —
compile_block substrate pipeline ✅ —
Basis-aware integrator + problem (ZOH → HermitianExponentialIntegrator + SmoothPulseProblem; splines → SplineIntegrator + SplinePulseProblem) ✅ substrate —
Multi-qubit scaling overrides — ✅
Pulse catalog warm-starts — ✅
Graph-based partitioning — ✅
Parallel multistart solver — ✅
QEC kernel compilation thin entry point ✅ implementation
Stagnation / landscape diagnostics — ✅

Legato users get a working substrate. Harmoniqs collaborators and NDA partners get the competitive layer.

Pulse library

Legato bundles a reference library of verified pulses (data/pulses/) — the public tier of the catalog format this package defines:

  • Solved + verified entries — the transmon single-qubit gate set (X, Y, √X, H) on generic device parameters. Each carries a verification record: an independently re-rolled, free-phase-aware fidelity (never the optimizer's claim), the verifier's identity, and the date. The query API ranks verified entries strictly above unverified ones at any recorded fidelity.
  • Analytic seed entries (tagged analytic-seed) — first-order DRAG seeds with no fidelity claim: seeds are initial guesses, and the empty verification record is the distinction.

The bundle is a standard catalog partition: bundled_catalog() returns it, find_pulses(bundled_catalog(); ...) queries it, and the warm-start fallback chain consumes it with hash-validated loading via set_default_catalog!(bundled_catalog()).

The IP rule is lint-enforced: every entry's device parameters must match a profile in data/pulses/allowlist.toml (generic or published parameterizations only) — partner-device parameters never enter the public repository.

To rebuild from source: julia --project=. scripts/seed_bundle.jl — it solves, independently re-verifies every pulse at build time, and refuses to bank anything below the quality bar.

Installation

using Pkg
Pkg.add("Legato")

Legato's default integrator follows the seed pulse's basis, so the optimizer integrates exactly the waveform the pulse describes (a ZeroOrderPulse with the exact exponential integrator, a spline pulse with SplineIntegrator of the pulse's order). Exact piecewise-constant integration can exhaust memory on 3+ qubit problems; Harmoniqs collaborators can load Legatissimo, which installs its own builder via set_default_integrator! on __init__.

Status

Version What ships
v0.2 Circuit IR, device profiles, compile_block, four substrate seams
v0.3 CompilationStrategy registry, select_strategy, :default strategy
v0.4 to_native(circuit, device) transpile pass
v0.5 Rename Stretto → Legato (re-registered under a new UUID)
v0.6 QASM import — from_qasm on main (single-register, common-gate subset; multi-register + parametric gates in progress)
v0.7+ Framework adapters (Qiskit / Cirq via PythonCall)

Contributing

# Run substrate tests (no private deps)
julia --project=. test/runtests.jl

# Run with Piccolissimo for multi-qubit smoke tests
julia --project=. -e 'using Pkg; Pkg.develop(path="../Piccolissimo.jl")'
LEGATO_FULL_TESTS=1 julia --project=. test/runtests.jl

# Build docs
./docs/get_docs_utils.sh
julia --project=docs docs/make.jl

See also

  • Piccolo.jl — the quantum optimal control engine Legato sits on top of.

"Some people stretto. Some people wait."

About

Compile quantum circuits to single optimized pulses.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages