mirror of
https://github.com/luxfi/precompile.git
synced 2026-07-27 03:33:45 +00:00
Align to the latest GPU-dispatch substrate: accel v1.3.1 now resolves the luxgpu pkg-config, gpu v1.1.2 is the libluxgpu binding. Zero API-drift — go build ./... and the full 54-package test link are green. Add precompile/dispatch: the single authority for GPU-batch-vs-CPU dispatch of the crypto/PQ/ZK/curve primitives. It lives in its own package so libluxgpu linkage stays opt-in — the 54 families that do not use the GPU never link the substrate, which also keeps them clear of the crypto _sha256/slhdsa link. A GPU batch kernel may back a precompile only when a parity test here proves it byte-equal to that precompile's CPU oracle; until then the CPU oracle is the single source of truth (consensus determinism). parity_test.go runs the real Metal kernels against the oracles and proves the current divergence (Poseidon2 by construction, BLS12-381 MSM by wire encoding), guarding the wiring decision in one place. No family is wired to a GPU kernel: every signature family diverges by context-binding, host-prehash framing, or partial-vs-full operation, so the CPU oracles and their regression tests stand unchanged and green. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
63 lines
3.6 KiB
Go
63 lines
3.6 KiB
Go
// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Package dispatch is the single, canonical authority for GPU-batch-versus-CPU
|
|
// dispatch of the precompile crypto/PQ/ZK/curve primitives. It wraps the latest
|
|
// accelerated substrate — luxfi/accel (the batch kernel dispatch library) over
|
|
// luxfi/gpu (the libluxgpu bindings) — behind ONE policy surface, so no family
|
|
// carries its own ad-hoc cgo or its own "should we use the GPU?" decision.
|
|
//
|
|
// The invariant, and the reason this package is separate from contract:
|
|
//
|
|
// - A GPU batch kernel may back a precompile ONLY when a parity test in this
|
|
// package proves it byte-equal to that precompile's CPU oracle. Consensus
|
|
// determinism requires that GPU-equipped and CPU-only validators return the
|
|
// byte-identical verdict on every input, including adversarial ones. Until a
|
|
// kernel is proven byte-equal, the CPU oracle is the single source of truth.
|
|
//
|
|
// - Every precompile is, at the EVM call boundary, a batch-of-1 (one Run() per
|
|
// call). n=1 is always below MinBatch, so a precompile always resolves to its
|
|
// CPU oracle regardless of what kernels exist. The GPU path only earns its
|
|
// dispatch overhead for a genuine multi-item batch (block/consensus-level
|
|
// multi-signature or multi-hash verification), and only for a byte-equal
|
|
// primitive.
|
|
//
|
|
// - This package deliberately does NOT live in contract: linking libluxgpu
|
|
// pulls the GPU substrate (and its slhdsa/dilithium host archives) into the
|
|
// cgo link. Keeping that linkage in one opt-in package means the 54 families
|
|
// that do not use the GPU never link the substrate and stay CPU-lean.
|
|
//
|
|
// Current state (see parity_test.go, which runs the real kernels against the CPU
|
|
// oracles): NO precompile family has a libluxgpu batch kernel that is byte-equal
|
|
// to its consensus-pinned CPU oracle — the signature families diverge by
|
|
// context-binding / host-prehash framing / partial-vs-full operation, the
|
|
// Poseidon2 kernel diverges by construction, and BLS12-381 MSM diverges by wire
|
|
// encoding. Every family therefore resolves to its CPU oracle. The parity tests
|
|
// are the executable proof of that, and the guard that flips the day accel ships
|
|
// a byte-equal, framing-matched kernel: a parity test starts passing, and wiring
|
|
// that one primitive through here becomes a local change in exactly one place.
|
|
package dispatch
|
|
|
|
import luxgpu "github.com/luxfi/gpu"
|
|
|
|
// MinBatch is the batch size below which the CPU oracle always wins: GPU
|
|
// dispatch plus host<->device copy overhead exceeds the throughput gain. It
|
|
// tracks the luxgpu substrate's own built-in ZK thresholds (Poseidon2=64,
|
|
// Merkle=128). A single EVM precompile Run() is a batch-of-1 and so is always
|
|
// served by the CPU oracle.
|
|
const MinBatch = 64
|
|
|
|
// Available reports whether the accelerated luxgpu substrate is present and
|
|
// usable on this host. It is the one place a batch caller asks "is the GPU path
|
|
// even worth considering?" before assembling a batch; the answer never changes
|
|
// the verdict, only the path taken to it. Note the substrate ZK kernels can be
|
|
// live (this returns true) while accel's higher-level session backend registers
|
|
// none — the two are checked independently, and the parity gate makes the
|
|
// verdict backend-invariant regardless.
|
|
func Available() bool { return luxgpu.ZKGPUAvailable() }
|
|
|
|
// Backend names the active luxgpu backend (metal/cuda/cpu) for diagnostics and
|
|
// benchmarks. It carries no consensus meaning — the verdict is backend-invariant
|
|
// by the parity gate above.
|
|
func Backend() string { return luxgpu.ZKGetBackend() }
|