A circuit isn't a sequence of gates. It's a unitary. Compile it as one.
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
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
| Conventional | Legato | |
|---|---|---|
| Optimization unit | one gate | one block (or whole circuit) |
| Gate-boundary 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 |
|
min-time compressed against fidelity floor |
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.
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:
- Transpile to native gates:
to_native(circuit, device)— pure circuit rewriting, e.g.CNOT(c,t) → H(t)·CZ(c,t)·H(t). - Schedule the native gates serially (or with parallelization in v0.4+).
- Stitch catalog pulses into a single warm-start pulse for the whole block.
- Joint-solve the block as one optimization — eliminates gate-boundary errors, exploits the device drift.
- Min-time compress against a fidelity floor.
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.
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.
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__.
| 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) |
# 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- Piccolo.jl — the quantum optimal control engine Legato sits on top of.
"Some people stretto. Some people wait."
