COOLJAPAN
← All posts

OxiCUDA 0.5.2 Released — PTX Portability Fixes for CUDA 12.9+, Windows, and a DMRG Correctness Bug

OxiCUDA 0.5.2 fixes a class of PTX portability bugs that CUDA 11.x silently tolerated and CUDA 12.9+ toolchains reject outright (non-ASCII bytes in generated comments), closes several Windows-specific test and lock-contention bugs, and fixes a numerical-correctness bug in the tensor-network DMRG excited-states solver. 38,675 tests, ~1.30M SLoC, 74 crates.

release oxicuda cuda gpu pure-rust ptx windows portability bugfix

A // comment is supposed to be invisible to the compiler. On CUDA 12.9+, one typographic character inside a generated PTX comment is enough to fail the entire kernel load with an opaque CUDA_ERROR_INVALID_PTX — and it had been silently fine on CUDA 11.x for years.

Today we released OxiCUDA 0.5.2 — a portability release that fixes a class of PTX bugs CUDA 11.x tolerated silently and CUDA 12.9+ toolchains reject outright, closes several Windows-specific test and lock-contention bugs, and fixes a numerical-correctness bug in the tensor-network DMRG excited-states solver.

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 74 crates and ~1.30M lines of safe Rust. libcuda.so/nvcuda.dll is loaded dynamically at runtime via libloading; nothing about building or running OxiCUDA requires the CUDA SDK, headers, or a C/C++ compiler. The result compiles to a single static binary and runs everywhere the driver is present.

Why OxiCUDA 0.5.2 is a game changer

Portability bugs are the worst kind precisely because they don’t show up where you’re looking:

OxiCUDA 0.5.2 ends all of that.

Technical Deep Dive

  1. Foundation — oxicuda-driver, oxicuda-memory. Module::from_ptx’s new ascii_only() scrubber and FileLockGuard’s Windows contention fix both live in this layer, underneath everything else that loads a module or takes a lock.
  2. PTX codegen — oxicuda-ptx, oxicuda-fft, oxicuda-launch, oxicuda-signal. Every generator that emitted a typographic Unicode character in a kernel comment is fixed at the source, so the non-ASCII rejection is closed both defensively (the driver scrubber) and at generation time (the templates themselves).
  3. Tensor networks — oxicuda-tn. The DMRG excited-states basis-rotation fix lives here, alongside the existing MPS/MPO/TEBD/PEPS machinery from Vol.50.
  4. Test infrastructure across the workspace. oxicuda-blas, oxicuda-dnn, oxicuda-solver, and oxicuda-sparse all picked up the same ptxas.exe/throwaway-file/stdout-capture fix, so Windows CI runs get the same signal Linux/macOS runs already had.

Getting Started

cargo add oxicuda --features blas

Default features remain driver, memory, and launch; every subsystem — ptx, autotune, blas, dnn, fft, sparse, solver, rand, nvrtc, primitives, vulkan, metal, webgpu, rocm, level-zero, and full for everything — is its own opt-in flag.

A complete GEMM, end to end — unchanged by this release, and now assembling cleanly on CUDA 12.9+ regardless of what characters ended up in the generated comments:

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’s fixes were checked against:

cargo test --features gpu-tests

What’s New in 0.5.2

Tips

This is the foundation

OxiCUDA is the GPU layer beneath the rest of the COOLJAPAN ecosystem. Its own architecture diagram puts SciRS2, OxiONNX, TrustformeRS, and ToRSh directly on top of it, with OxiBLAS and OxiFFT rounding out the list of projects that lean on this stack — and the oxicuda crate itself is an umbrella re-export over all 74 crates, so a single cargo add oxicuda pulls in whichever subsystem a dependent project needs. Every one of them inherits 0.5.2’s portability fixes today, without a single line of their own code changing.

Repository: https://github.com/cool-japan/oxicuda

Star the repo if you believe a stray character in a comment should never be the reason a GPU kernel fails to load. Every star tells us to keep building.

The era of “works on my toolchain” is over. Pure Rust GPU computing is here — and as of 0.5.2, it’s a little more portable than it was yesterday.

KitaSan at COOLJAPAN OÜ July 27, 2026

↑ Back to all posts