accel: One Dispatch Fabric for GPU, CUDA, Metal, and FPGA
LP-138 lands. accel is a capability-negotiated dispatch layer so accelerated crypto, ZK, and FHE are one codebase across runtimes.
For four years we wrote GPU code three times. Once for CUDA, once for Metal, once for everything that fell back to CPU. Three call paths through every consensus module, every ZK precompile, every FHE bootstrap. Every new operation was three implementations, three sets of bugs, three test matrices.
Today that ends. We ship accel — a capability-negotiated dispatch fabric that exposes one API for accelerated chain and crypto operations, and a backend plugin interface that lets any device (CUDA, Metal, WebGPU, FPGA, CPU) advertise what it can do. Accelerated EVM precompiles, accelerated BLS, accelerated FHE bootstrapping, accelerated ZK provers — all of it routes through the same fabric. One codebase.
LP-138 is the spec. This is the implementation.
The shape of the problem
A modern AI + chain runtime has dozens of compute kernels that benefit from accelerators:
- Crypto — batch ECDSA / Ed25519 / BLS verification, batched Keccak / SHA / Poseidon hashing, MSM, BLS aggregation.
- ZK — NTT / iNTT transforms, polynomial multiply, FFT, BN254 field arithmetic.
- FHE — BFV / CKKS encrypt / decrypt, homomorphic ops, bootstrapping, multi-GPU coordination.
- Lattice PQ — ML-KEM keygen / encap / decap, ML-DSA sign / verify, polynomial NTT for both.
- DEX — constant product swaps, order matching, TWAP computation, concentrated liquidity math.
- Consensus — batch signature verification, Merkle construction, block validation acceleration.
Every one of these is a candidate for a CUDA kernel, a Metal compute shader, a CPU SIMD path, and occasionally an FPGA pipeline. Without a dispatch layer, every call site has to make that choice. Every call site goes stale. Every call site is its own audit surface.
What accel is
accel is a Go package — github.com/luxfi/accel — with one public API surface and pluggable backends below it.
package main
import "github.com/luxfi/accel"
func main() {
if err := accel.Init(); err != nil {
panic(err)
}
defer accel.Shutdown()
if !accel.Available() {
// No accelerator: CPU fallback is built in.
}
results, err := accel.BLSBatchVerify(pubkeys, sigs, msgs)
if err == accel.ErrNotSupported {
// Backend doesn't have BLS. Caller falls back.
}
sess, _ := accel.NewSession()
defer sess.Close()
zk := sess.ZK()
_ = zk.NTT(input, output, roots, modulus)
}
That's the whole shape: top-level batch ops for the common path, sessions for stateful work (FHE, ZK), capability queries for the rare path.
Capability negotiation, not capability assumption
Every backend advertises which operations it implements. Application code asks; it does not assume. If the active backend cannot do BLS batch verification, the call returns ErrNotSupported and the caller falls back. That fallback path is in the library, not in each call site, so adding a new op to a backend is a one-line change everywhere downstream.
| Backend | Platform | Priority |
|---|---|---|
| CUDA | Linux / Windows | 1 |
| Metal | macOS / iOS | 2 |
| WebGPU (Dawn) | All | 3 |
| CPU | All | 4 |
Priority ordering is the default selection rule. Explicit selection is supported via session config for benchmarking, deterministic CI, and FPGA targets.
Build matrix
Three build configurations cover every use case:
# CPU only. Pure Go. Works everywhere.
CGO_ENABLED=0 go build ./...
# CGO. Routes through luxcpp/gpu when present.
CGO_ENABLED=1 go build ./...
# Full GPU ops in ops/* subpackages.
go build -tags=accel ./...
The build tags map to file suffixes: foo.go is the !cgo fallback, foo_c.go is the cgo GPU path, foo_types.go holds the shared types and interfaces. New backends slot in by adding files in the same shape. No core changes required.
Operations, organized
Specialized operations live in subpackages under ops/:
ops/crypto— batch signatures, batch hashes, MSM, BLS aggregation.ops/zk— NTT / iNTT, polynomial ops, FFT, BN254 arithmetic.ops/fhe— BFV / CKKS, homomorphic operations, bootstrapping, multi-GPU.ops/lattice— ML-KEM, ML-DSA, polynomial NTT for PQ.ops/dex— constant product, order matching, TWAP, concentrated liquidity.ops/consensus— batch verification, Merkle construction, block validation.
Each subpackage exposes an interface; each backend can implement any subset. The single dispatch layer routes a call to the right kernel on the right device, or falls back to CPU. That is the only routing decision in the system.
Why this matters for Hanzo
The Hanzo stack benefits from accel in three concrete places.
Inference plane crypto stops being CPU-bound. Every Hanzo Node verifies signatures on incoming requests, validates attestations on agent transcripts, and exchanges PQ-secure session keys. Batched on GPU, these stop being a per-request tax.
FHE-backed confidential inference becomes practical. BFV and CKKS bootstrapping are too slow on CPU to be useful at session-level latencies. Multi-GPU bootstrapping via Metal MLX or CUDA — through accel.ops/fhe — moves confidential agent compute into the practical envelope for AI subnets and private inference endpoints.
ZK attestations track the device, not the codebase. Provers attesting to model outputs, agent actions, or training-data inclusion spend almost all of their time on NTT and MSM. accel makes both first-class ops. Replacing a CPU prover with a GPU prover is a configuration change, not a code rewrite.
What is in flight
accel ships today with CUDA, Metal, and CPU backends and the operation interfaces above. Active work:
- WebGPU backend via Dawn for browser-side acceleration of lightweight ops.
- FPGA backend for fixed-pipeline crypto in datacenter deployments.
- Multi-GPU coordination layer for FHE bootstrapping at chain-realistic throughput.
- Tighter integration with the
luxcpp/gpuC++ backend so kernels written in C++/CUDA appear as accel ops without glue code.
Get accel
- Source: github.com/luxfi/accel
- Low-level GPU arrays: github.com/luxfi/gpu
- C++ backend: github.com/luxfi/luxcpp
- LP-138: the spec lives in the Lux Proposals repo
One dispatch API. Backends pluggable. Accelerated crypto, accelerated ZK, accelerated FHE — one codebase rather than three.
Capability-negotiated, backend-pluggable, CPU-fallback-default. The accelerator is a detail of deployment, not a fork of the runtime.
Read more
Hanzo Notebooks: Managed Jupyter with GPU Access
Introducing Hanzo Notebooks — managed Jupyter workspaces with on-demand GPU access and pre-installed ML frameworks.
Introducing Enso — one API, routed to the best frontier intelligence
Enso is Hanzo's learned router: no single frontier model leads every benchmark, so Enso routes each request to the model most likely to win it — and learns from your feedback as it goes. Microsecond routing on a CPU, a transparent per-request meter, and a 1% fee that pays for itself. Here is how it works, the measured results, and the cost-transparency angle a monolith cannot offer.
Introducing Hanzo Datastore: a post-quantum-ready OLAP engine
A ClickHouse-derived columnar warehouse, rebuilt around storage/compute separation on Hanzo S3, profile-guided and link-time optimized to roughly half the memory, with gRPC stripped out and a path to leaderless post-quantum coordination.