A kernel that passes validation running alone on the GPU can still be wrong the moment two streams touch it at the same time.
Today we released OxiCUDA 0.4.1 — a release that pushes the on-device validation sweep started in 0.4.0 into new territory. It’s no longer just “does this kernel compute the right numbers on real silicon” — it’s “does this still hold up under real concurrent execution, and does it hold up on hardware that was never CUDA’s to begin with.”
No CUDA SDK. No nvcc. No C/C++ toolchain. OxiCUDA is a type-safe, memory-safe, pure-Rust replacement for the entire NVIDIA CUDA Toolkit software stack — cuBLAS, cuDNN, cuFFT, cuSPARSE, cuSOLVER, cuRAND and more, across 73 crates and ~1.28M lines of safe Rust. libcuda.so / nvcuda.dll is loaded dynamically at runtime via libloading; nothing about building OxiCUDA requires the CUDA SDK or a C/C++ compiler. The result compiles to a single static binary and runs everywhere the driver is present — from Turing through Blackwell, and, through OxiCUDA’s own Vulkan, Metal, WebGPU, ROCm, and Level Zero backends, on GPUs that were never NVIDIA’s to begin with.
Why OxiCUDA 0.4.1 is a game changer
NVIDIA’s official stack still asks you to accept, on faith:
- A proprietary CUDA Toolkit installing gigabytes of SDK, headers, and compiler toolchain before a single kernel builds
- cuBLAS and cuDNN as closed-source black boxes — you cannot read, patch, or independently verify the kernel that’s about to run on your data
- C/C++ as the only implementation language, with no borrow checker — races and use-after-free are the default failure mode, not the exception
- A GPU compute path that’s validated once, upstream, at release time — nothing stops it from silently regressing on your exact hardware, driver version, or concurrency pattern
OxiCUDA 0.4.1 ends all of that.
- Concurrency bugs that only a real device under real load can catch. This sweep targeted context/stream/graph lifetime, peer access, and pooled-buffer reuse under actual concurrent execution — and found real races.
PooledBuffer::drophanded a device pointer straight back to the free list for immediate reuse with zero synchronization, so a second allocation could receive a pointer the GPU was still writing through.async_launch’s background poller woke its storedWakerexactly once, so a park-based async executor waiting on GPU work that outlived that single wake would hang forever. - Five GPU backends, checked against a real compiler for the first time ever. Vulkan/SPIR-V, WebGPU/WGSL, Metal/MSL, ROCm/HIP, and Level Zero/SPIR-V had never been run through a real backend compiler or validator before this release. The pass turned up dozens of invalid-shader-module and wrong-ISA-encoding bugs — SPIR-V instructions emitted in the wrong logical-layout order, a
GLSL_F_MINextended-instruction ID that was actually integerSMin, cooperative-matrix operands passed as raw struct pointers instead of the element pointers the ISA requires — plus several silently-wrong GEMM, attention, and quantization computations. - Real driver-backed CUDA Graph capture, landing for the first time.
StreamGraphCapture::begin/endnow drives the actualcuStreamBeginCapture_v2/cuStreamEndCapturecalls and finalizes a genuinely launchableGraphExec— verified end to end by capturing an async memset, ending capture, launching the resulting graph, and confirming the replayed memset actually wrote the pattern to device memory. - The BLAS and DNN validation gap closes. 144+ new BLAS device-vs-CPU-oracle tests (every Level-1/Level-2 op, reductions, elementwise ops, batched GEMM) and roughly 9,900 new lines of DNN on-device validation caught bugs that had been shipping silently — five Level-2 BLAS kernels that failed every launch because a hand-written branch was missing PTX’s required
$sigil, and a fused GRU/LSTM gate reduction that silently discarded every term of its dot product except the last. - Three security issues, broken out honestly instead of buried. A predictable, world-writable PTX cache fallback path (a symlink/cache-poisoning vector), plus two untrusted-length-prefix allocation issues in device-printf parsing and index/adapter deserializers — all fixed and called out under their own heading.
Technical Deep Dive: what 0.4.1 actually validates
- Foundation correctness — driver, runtime, memory, launch. The sweep reached the layer everything else stands on:
oxicuda-driver’s context/stream/event/module lifetime (a new live-context registry stops a child handle like aStreamorModulefrom double-freeing the driver when it outlives theContextit was created from),oxicuda-runtime’s error propagation (device_synchronizewas silently swallowing real driver errors instead of returning them), andoxicuda-memory’s pool/peer/managed-memory paths (cross-device allocation, peer-access context restoration, and uninitializedPinnedBuffer/UnifiedBuffer/MappedBuffermemory now zeroed before it ever reaches safe code). - PTX codegen hardening —
oxicuda-ptx. New validators (RegisterAllocator::validate_named(),validate_branch_labels(), tensor-core operand-consistency checks) catch illegal or colliding register declarations and mismatched branch targets before a single instruction is emitted, layered on top of ISA-level fixes to SM90+ warp/TMA primitives (mbarrier,elect.sync,fence.proxy,cp.async.bulk.tensor) and tensor-core MMA/WGMMA encoding. - Scientific and deep-learning kernels —
oxicuda-blas,oxicuda-dnn,oxicuda-sparse,oxicuda-solver,oxicuda-autotune. Each crate now carries its owngpu-testson-device validation suite, JIT-compiling the crate’s actual production PTX viaModule::from_ptxand diffing device output against an independent CPU oracle — the pattern that caughtoxicuda-solver’s batched LU/Cholesky kernels being literalret;stub bodies, now rewritten as real barrier-staged Doolittle LU and Cholesky factorizations. - Multi-vendor backends —
oxicuda-vulkan,oxicuda-webgpu,oxicuda-metal,oxicuda-rocm,oxicuda-levelzero. Each backend’s SPIR-V, WGSL, MSL, or HIP generation now gets checked by that backend’s own real compiler or validator, and every backend’s GEMM entry point now rejects transpose/leading-dimension configurations it can’t actually honor instead of silently computing the wrong answer.
Getting Started
Add OxiCUDA and opt into the subsystems you need:
cargo add oxicuda --features blas
Default features are driver, memory, and launch. Every subsystem is its own flag (ptx, autotune, blas, dnn, fft, sparse, solver, rand, primitives, vulkan, metal, webgpu, rocm, level-zero, and full for everything) — plus gpu-tests if you have real GPU hardware and want to run the same on-device validation this release relies on.
A complete GEMM, end to end:
use oxicuda::prelude::*;
fn main() -> Result<(), oxicuda::Error> {
// Initialize driver and select GPU device
let device = Device::get(0)?;
let ctx = Context::new(device)?;
let stream = Stream::new(&ctx)?;
// Allocate device memory
let mut d_a = DeviceBuffer::<f32>::zeroed(1024)?;
let mut d_b = DeviceBuffer::<f32>::zeroed(1024)?;
let mut d_c = DeviceBuffer::<f32>::zeroed(1024)?;
// Copy host data to device
d_a.copy_from_host(&host_a)?;
d_b.copy_from_host(&host_b)?;
// Launch a GEMM: C = alpha * A @ B + beta * C
let handle = BlasHandle::new(&stream)?;
handle.gemm(
Transpose::None, Transpose::None,
m, n, k,
1.0f32, // alpha
&d_a, lda,
&d_b, ldb,
0.0f32, // beta
&mut d_c, ldc,
)?;
stream.synchronize()?;
// Copy result back to host
let mut result = vec![0.0f32; m * n];
d_c.copy_to_host(&mut result)?;
Ok(())
}
On a machine with an NVIDIA GPU, run the same validation this release depends on:
cargo test --features gpu-tests
No nvcc invocation, no .cu files, no linker flags chasing a CUDA install. cargo build, and you ship.
What’s New in 0.4.1
- On-device validation sweep continues into
oxicuda-blas(Level-1/Level-2/GEMM/reduction kernels plus Amperemma.synctensor-core paths),oxicuda-dnn(attention, RNN, convolution, normalization, pooling, quantization), and theoxicuda-driver/oxicuda-runtime/oxicuda-memory/oxicuda-launchstack — this time targeting context/stream/graph lifetime, peer access, and pooled-buffer reuse races under real concurrent execution, not just single-kernel numeric correctness. - First-ever correctness pass across five non-CUDA backends — Vulkan/SPIR-V, WebGPU/WGSL, Metal/MSL, ROCm/HIP, Level Zero/SPIR-V — against real backend compilers and validators, finding dozens of invalid-shader-module and wrong-ISA-encoding bugs plus several silently-wrong GEMM, attention, and quantization computations.
- Real driver-backed CUDA Graph stream capture lands —
StreamGraphCapture::begin/enddrives realcuStreamBeginCapture_v2/cuStreamEndCaptureand finalizes a genuinely launchable graph, verified end to end on hardware. oxicuda-sparseandoxicuda-solverget their on-device validation debut — 34 device-vs-CPU-oracle sparse tests catch 3 real bugs (an SpMM tile-width bug, CSR5’s hardcodedbeta, a missing pre-download synchronize);BatchedSolver::lu/choleskygo from literalret;stub bodies to real barrier-staged factorizations.- Serious concurrency and lifetime fixes — a
PooledBufferreuse race with no synchronization, anasync_launchwaker that fires only once, aDevicePoolcontext leak, and a driver double-free/use-after-free acrossContext/Event/Module/GraphExec, all closed via a new live-context registry. CUdevice_attributeandCuLaunchAttributeIddiscriminant realignment — dozens of device-attribute and extended-launch-attribute values had drifted out of sync withcuda.h, so many “modern capability” queries and launch attributes were silently reading or setting the wrong thing.CudaBackendnow caches everything expensive — BLAS/DNN handles, JIT-compiled kernels, the on-disk PTX cache, and the launch stream are all built once and reused instead of rebuilt on every call.- Security fixes broken out separately — a predictable, world-writable PTX cache fallback path, plus untrusted-length-prefix allocation issues in device-printf parsing and two deserializers (
oxicuda-ann,oxicuda-peft). - Test suite grew to 38,612 passing tests (
--all-features; 37,288 with default features), up from 38,093/37,166 at 0.4.0.
Tips
- Run
cargo test --features gpu-testson your own hardware. BLAS, DNN, sparse, driver, and memory all now carry real device-vs-CPU-oracle suites — pointing them at your own card (anything Turing through Blackwell) extends this release’s coverage to configurations we haven’t tried yet. - If you’re on a non-CUDA backend, re-run your GEMM, attention, and quantization paths. Vulkan, WebGPU, Metal, ROCm, and Level Zero all had silent correctness bugs fixed this release — a workload that “worked” before may have been quietly computing the wrong answer.
ZeroOptimizer::newis no longer infallible. It now returnsTrainResult<Self>instead of panicking on an invalidZeroConfig(e.g.rank >= world_size) — handle theResultor propagate with?.- Pass an explicit
seq_lentocausal_softmaxif you batch multiple attention matrices in one buffer. The signature gained aseq_lenparameter because the old version silently un-masked every stacked matrix after the first — passseq_len == rowsfor a single, non-batched matrix. - Try real CUDA Graph capture for repeated launch patterns.
StreamGraphCapture::begin/endaround a sequence of stream-ordered work now produces a genuinely replayableGraphExecbacked by the real driver, not a topology-only stand-in. - You don’t need to clear your PTX cache after upgrading.
PtxCachenow mixesCARGO_PKG_VERSIONinto its cache key, so this upgrade automatically invalidates stale cached PTX from older, possibly-buggy generator code.
This is the foundation
OxiCUDA is the GPU layer beneath the rest of the COOLJAPAN ecosystem, and 0.4.1 is already the version every sibling project depends on. SciRS2 pulls in oxicuda-driver/-memory/-fft/-ptx/-launch/-blas/-solver/-sparse/-dnn; ToRSh routes its CudaBackend through oxicuda-backend/-driver/-launch/-ptx; sklears carries oxicuda-backend/-memory/-blas/-solver/-manifold/-dnn/-driver/-ptx/-primitives; OxiONNX executes graphs through oxicuda-driver/-memory/-blas/-dnn/-ptx/-launch. OxiFFT, OxiML, OxiProj, QuantRS2, and TensorLogic — which builds its own tensorlogic-oxicuda-* sparse/solver/rng bridge crates on top — round out the list. Every one of them is already pinned to oxicuda* = "0.4.1": the concurrency, cross-backend, and CUDA Graph fixes in this release are live under all of them today.
Repository: https://github.com/cool-japan/oxicuda
Star the repo if you believe GPU correctness should be proven under real concurrency and on real hardware, not assumed from a CPU stand-in or a single-threaded test run once. Every star tells us to keep building.
Pure Rust GPU computing is here — fast, safe, sovereign, and now proven under the conditions it actually has to survive.
— KitaSan at COOLJAPAN OÜ
July 7, 2026