How gpuemu works
gpuemu turns kernel correctness into a hardware-free, reproducible pipeline. Below is the path a single validation run takes — from generating inputs to handing you a seed you can replay byte-for-byte.
generator
reference
compare
lint
report
The correctness path (input → kernel vs fp64 → tolerance) runs without a GPU. PTX/SASS lint is an optional artifact step.
- 1
Generate op-schema-aware inputs
P3For the operator under test, gpuemu builds boundary, regular, and adversarial inputs — deliberately including partial-tile shapes where dimensions are not multiples of the block size. Values and shapes come from a bit-identical xorshift128+ RNG, so every case is seeded and replayable.
- 2
Run your kernel and the fp64 reference
P1Your kernel runs wherever it runs (GPU or CPU); in parallel gpuemu evaluates a high-precision fp64 CPU implementation of the same op as ground truth. Comparing against double precision — rather than two low-precision results — is what exposes small, silent numerical errors.
- 3
Compare with per-op calibrated tolerances
P2Instead of one global atol/rtol, gpuemu fits a p95-of-controls × 1.5 tolerance envelope per operator and dtype. Tight ops are held tight; loose ops are not falsely failed. This raises bug recall from 65% to 82% over a fixed atol=1e-5, rtol=1e-2.
- 4
Lint the compiled artifacts (optional)
P4A static pass reads register pressure, spills, and instruction counts from PTX/SASS and gates on regressions vs a baseline. It catches performance regressions the oracle cannot — but semantic bugs compile to identical PTX, so it is paired with, never a substitute for, the correctness oracle.
- 5
Report a replayable failure
Every failing case reports its seed, dtype, and shape plus a snapshot of the input. Because the RNG is bit-identical across Rust and Python, gpuemu reproduce <seed> replays the exact failure byte-for-byte — on a laptop, with or without a GPU.
The five layers at a glance
fp64 reference oracle
P1Validates GPU-kernel output against a high-precision CPU reference, per dtype — not a single allclose on one shape.
Op-schema-aware fuzzing
P3A per-op shape generator with boundary, regular, and adversarial value distributions — built to hit the partial-tile and edge cases real kernels break on.
Per-op calibrated tolerances
P2A p95-of-controls × 1.5 envelope fit individually per op and dtype, instead of one hand-picked atol/rtol for everything.
Static PTX/SASS lint
P4Reads register pressure, spills, and instruction counts straight from compiled artifacts and gates on regressions vs a baseline.
Reproducible RNG
A bit-identical xorshift128+ generator in Rust and Python, with exact input snapshots on every failure.
Frequently Asked Questions
How can gpuemu check GPU kernels without a GPU?
Correctness is a numerical question — does the kernel compute the right values? gpuemu answers it by comparing your kernel output to a high-precision fp64 CPU reference across many inputs. You run your kernel wherever it runs; gpuemu validates the result. Only the optional PTX/SASS lint needs compiled GPU artifacts.
Why an fp64 reference instead of comparing two fp16/bf16 results?
Two low-precision implementations can be wrong in the same direction and still agree, hiding a bug. A double-precision reference is a precise ground truth, so a small deviation in the kernel shows up instead of being masked.
Why generate adversarial and partial-tile shapes?
Whole bug classes — tail-mask leaks, online-softmax rescale errors — only fire when a dimension is not a multiple of the block size. Sampling only regular shapes misses 100% of tail-mask bugs; adversarial shape and value sampling reaches 99% overall recall (P3).
Want the measured detail behind each layer? Read the P1–P4 evidence, browse the full feature list, or check why one-shape testing is blind.
Stop shipping silently-wrong kernels
Open source, dual-licensed MIT / Apache-2.0. Validate your first kernel in five minutes — or talk to us about an enterprise pilot.