Rust's SIMD API, now running on the GPU

4 min read 1 source explainer
├── "GPUs and CPUs share the same underlying SIMD hardware model, so Rust's std::simd is the natural unifying abstraction"
│  ├── Vectorware (vectorware.com) → read

Vectorware argues they aren't inventing a new abstraction — Rust already shipped one with std::simd, and GPU warps/wavefronts are structurally just SIMD lanes with a divergence stack. By lowering Simd<f32, N> to OpGroupNonUniform* SPIR-V instructions, the same source code compiles to AVX-512, NEON, or GPU subgroups without a separate shading language.

│  └── top10.dev editorial (top10.dev) → read below

The editorial reinforces that SIMT was always a branding choice rather than a hardware distinction — a warp is a 32-lane SIMD unit. Maintaining two parallel dialects (explicit CPU intrinsics vs. implicit shader languages) for fundamentally identical hardware has been wasteful, and Vectorware's approach exposes that.

└── "The approach is promising but driver and toolchain reality will be messy"
  └── @Hacker News discussion (Hacker News, 157 pts) → view

The editorial characterizes the HN reception as a mix of 'finally' enthusiasm and skeptical 'wait, does this actually work on my driver' concerns. That skepticism reflects the practical worry that portable_simd is still nightly-only in Rust and that SPIR-V subgroup support varies across vendor drivers.

What happened

Vectorware published a walk-through of running Rust's `std::simd` (the still-nightly `portable_simd` feature) on the GPU, compiling the same `Simd` types you'd use on a CPU into GPU subgroup operations. In their model, a warp on NVIDIA, a wavefront on AMD, or a subgroup in Vulkan-speak becomes the backing storage for a SIMD vector: 32 or 64 threads acting in lockstep are, structurally, the lanes.

The compilation path goes Rust → rustc MIR → SPIR-V (via the rust-gpu lineage of tooling), with the SIMD intrinsics lowered to `OpGroupNonUniform*` instructions instead of AVX-512 or NEON. From the source side, a dot-product kernel looks nearly identical to the CPU version — you import `std::simd::Simd`, you write `a * b`, you reduce with `.reduce_sum()`, and the compiler picks the target.

The trick is that Vectorware isn't inventing a new abstraction; they're pointing out that Rust already shipped one and that GPUs quietly implement it in hardware. The post lands on Hacker News with 157 points and the usual mix of "finally" and "wait, does this actually work on my driver."

Why it matters

Every serious GPU stack in the last fifteen years has been a variation on the same lie: you write code that looks scalar (`float x = a + b;` in CUDA, HLSL, WGSL, Metal Shading Language) and the compiler and hardware conspire to run 32 copies of it in parallel across a warp. Nvidia branded this SIMT to distinguish it from SIMD, but the distinction has always been a language choice, not a hardware one — a warp is a 32-lane SIMD unit with a divergence stack bolted on top.

That means the industry has been maintaining two entire dialects of parallel code — one where the vector is explicit (`_mm256_add_ps`, `vaddq_f32`, `std::simd`) and one where it's implicit (every shading language ever) — for hardware that's fundamentally the same shape. Every team that ships both a CPU and a GPU implementation of an algorithm — every physics engine, every image codec, every ML inference kernel — pays that tax twice: two source trees, two debugging stories, two sets of numerical-precision gotchas.

Vectorware's move is to collapse the two. Because Rust's `std::simd` is *explicitly* lane-aware — you know `N` at the type level, reductions are methods, masked loads are first-class — it maps directly onto subgroup ops that GPUs already expose. Compare that to trying to compile SIMT-style scalar-looking code back down to CPU vectors, which is what auto-vectorizers have been failing at for two decades. The direction of the abstraction matters: going from explicit lanes down to a warp is trivial; going from implicit warps up to `vpaddd` is a research problem.

Community reaction on the HN thread splits along predictable lines. GPU compute veterans want to know about divergence, memory coalescing, and whether the compiler emits `OpGroupNonUniformShuffle` correctly for a full reduction — the details that separate a demo from a shippable kernel. Rust folks are more interested in the fact that `portable_simd` finally has a compelling reason to stabilize beyond "AVX-512 wrapper." And the wgpu/rust-gpu crowd sees the obvious next step: if you can lower `std::simd` to SPIR-V, you can write compute shaders in normal Rust and call them from wgpu without ever touching WGSL.

The uncomfortable truth for CUDA is that if this pattern generalizes, the moat isn't the language — it's the driver, the profiler, and cuDNN. Nvidia has been protected for years by the fact that porting a nontrivial CUDA kernel to anything else is a rewrite. A path where the *same Rust source* targets AVX-512, Apple Silicon NEON, and Vulkan compute is not going to displace PyTorch tomorrow, but it changes the calculus for the next generation of libraries that haven't been written yet.

What this means for your stack

If you ship a compute-heavy library today with separate CPU and GPU backends, this is worth an afternoon of prototyping. The realistic near-term win isn't replacing your CUDA kernels — it's writing new algorithms once and getting a competent GPU path for free, especially for the long tail of workloads where hand-tuning a shader was never going to pay for itself. Image processing, signal processing, small-batch inference, procedural generation: all things where a portable-good implementation beats an absent hand-tuned one.

The caveats are real. `portable_simd` is still nightly and the API has churned; the rust-gpu ecosystem has historically been one maintainer away from stalling; SPIR-V drivers vary wildly in how well they handle subgroup ops; and you will hit codegen bugs before you hit performance ones. Treat this as "the abstraction we've been wanting for a decade, finally with a plausible implementation," not as production-ready today. If you're on Metal, the subgroup story is weaker and you'll want to check what actually lowers.

For teams already invested in wgpu or rust-gpu, the concrete play is to start writing new compute kernels against `std::simd` and see what the generated SPIR-V looks like in RenderDoc. For teams on CUDA, the interesting exercise is picking one kernel where you've been putting off the ROCm port and asking whether one Rust source is a better answer than two vendor-specific ones.

Looking ahead

The long arc here is that GPU programming has been stuck in a local maximum defined by shading languages designed for graphics pipelines, then retrofitted for compute. A world where the same explicit-SIMD Rust code targets CPU vectors and GPU subgroups is a world where the *language* stops being the interesting variable and the hardware differences — memory hierarchy, occupancy, tensor cores — get to be the actual thing you reason about. That's the world compute programming should have been in a decade ago. Whether Vectorware's specific implementation gets there or someone else does, the direction is clearly right.

Hacker News 169 pts 81 comments

Rust SIMD on the GPU

→ read on Hacker News

// share this

// get daily digest

Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.