<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi" -->

---
title: Rust SIMD on the GPU | daily.dev
description: VectorWare has achieved a world first by running Rust's portable SIMD (core::simd) on the GPU. The key insight is that NVIDIA's SIMT execution model — where a...
canonical: https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Rust SIMD on the GPU | daily.dev
og:description: VectorWare has achieved a world first by running Rust's portable SIMD (core::simd) on the GPU. The key insight is that NVIDIA's SIMT execution model — where a...
og:url: https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi
og:image: https://api.daily.dev/og/posts/rdNRzI0mI.png
og:image:alt: Rust SIMD on the GPU
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust SIMD on the GPU

**[Hacker News](https://daily.dev/sources/hn)** · 9 min read · 0 upvotes · 0 comments

## Summary

VectorWare has achieved a world first by running Rust's portable SIMD (core::simd) on the GPU. The key insight is that NVIDIA's SIMT execution model — where a warp issues one instruction across 32 lanes — is structurally identical to SIMD. By mapping Simd<T, N> onto warp lanes, elementwise operations, reductions, cross-lane shuffles, and masks all have direct warp-level counterparts using shuffle instructions, vote/ballot primitives, and PTX instructions. The same source code runs unchanged on both CPU and GPU. VectorWare also built a type-system-encoded IR for warp-lane programming that enables differential testing via a CPU reference interpreter. Downsides include portable SIMD still being unstable (nightly only), zero-cost abstraction only when vector width matches warp width, and some cross-lane operations not mapping efficiently. Future work includes composing SIMD with threads and async, targeting tensor cores, and auto-vectorizing scalar loops.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.vectorware.com/blog/simd-on-gpu>

## Questions this post answers

### How does Rust's portable SIMD type map onto GPU warp execution?

A Simd<T, N> vector maps directly onto a GPU warp's lanes, since a warp issuing one instruction across 32 lanes (SIMT) is functionally SIMD. Elementwise operations like Add run natively per lane, reductions like reduce_sum use warp shuffle instructions, simd_swizzle! uses warp shuffle primitives, and Mask::select/any/all use GPU vote and ballot instructions. The mapping requires no new GPU-specific vector type.

_Developers weighing GPU-native Rust approaches can track advances like this on daily.dev._

### What lane width do I need to use for portable SIMD to be zero-cost on the GPU?

The vector width N must match the GPU's fixed warp width to be zero cost: 32 lanes on NVIDIA hardware, and either 32 or 64 lanes on AMD. A smaller N leaves lanes idle, while a larger N requires each lane to process more than one element, turning a single operation into multiple instructions.

_Engineers tuning GPU kernel performance can follow warp-width tradeoffs like these on daily.dev._

### Can I use Rust's portable SIMD feature on stable Rust today?

No, portable SIMD is still unstable and requires enabling the nightly feature flag #![feature(portable_simd)], meaning its API surface may still change before stabilization. This applies whether targeting the CPU or the GPU, since the same core::simd types are used on both.

_Rust developers deciding when to adopt unstable features can watch stabilization progress via daily.dev._

## Community take

How the wider developer community reacted, aggregated from 1 discussion and 88 comments across hackernews (as of 2026-09-14).

**TL;DR:** The community finds the SIMD-on-GPU mapping genuinely clever and technically interesting, especially the insight that SIMT warps are structurally identical to SIMD lanes, though several commenters raise practical concerns about portable SIMD's fixed-width limitations and the compiler not yet being publicly available.

**Sentiment:** 55% positive · 30% mixed · 15% skeptical

**The case for**

- The structural equivalence between NVIDIA's SIMT warp model and CPU SIMD lanes makes the mapping elegant and well-motivated.
- Running the same source code unchanged on both CPU and GPU is a compelling ergonomic win for Rust developers.
- The type-system-encoded IR that catches scope/barrier mismatches at compile time is praised as a strong safety feature.
- Portable SIMD, even with fixed widths, offers a useful middle ground between auto-vectorization and hand-written intrinsics.

**The pushback**

- The compiler fork enabling this is not yet publicly available, limiting immediate experimentation.
- Portable SIMD is still nightly-only, making it unsuitable for stable Rust crates.
- Fixed SIMD width means zero-cost abstraction only when vector width matches warp width, leaving performance on the table otherwise.
- Some commenters question the value over existing GPU-targeted ML frameworks (torch/jax/tensorflow) for array-programming workloads.
- Portable SIMD's fixed-width design is seen as fundamentally at odds with true performance portability across different hardware.

**By community**

- hackernews (mixed): Broadly impressed by the technical insight and Rust-GPU integration, but split on the practical value of portable SIMD's fixed-width design and frustrated that the compiler isn't yet open source.

**Hottest debate:** Whether portable SIMD's fixed-width approach is genuinely useful or fundamentally undermines the portability it promises.

**Open questions**

- When will the compiler fork be made publicly available?
- How does performance compare to hand-tuned CUDA or existing GPU frameworks for real workloads like radix sort?
- Can SIMD width be selected statically based on available GPU/CPU hardware info to avoid leaving performance on the table?
- How will tensor core targeting be composed with the current warp-lane SIMD model?

**Highlights**

> Didn't want to go into crazy detail in the post. Each family of operations is a trait parameterized by the operation itself:   pub trait EvaluateReduction<Operation, T>: LaneEvaluator {       /// Reduce one distributed definition to an ordinary uniform scalar.       fn evaluate_reduction(&self, value: LaneValue<Self, role::Distributed, T>) -> T;   } Call sites name the operation:   let one   = evaluator.splat::<Splat, _>(1_u32);   let two   = evaluator.splat::<Splat, _>(2_u32);   let three = evaluator.binary::<Add, _>(one, two);   let total   = evaluator.reduce::<Sum, u32>(three);   // a uniform u32   let running = <Executor as EvaluateScan<Scan<Sum, Exclusive>, u32>>::scan(&evaluator, three); Operations like Sum, Max, ReduceXor, Inclusive, and Exclusive are all distinct types. As mentioned in the post, execution shape is typed too. A static shuffle takes its control as a type-level constant, and the shuffle mode constrains which controls are expressible:   // Shift down one lane, keeping our own value where the source is inactive.   let down  = <Executor as EvaluateShuffle<Shuffle<Down>, DownOrSelf<1>, u32>>::shuffle(&ev, v);   // Broadcast from lane zero.   let bcast = <Executor as EvaluateShuffle<Shuffle<Broadcast>, WarpLane<0>, u32>>::shuffle(&ev, down);   // Butterfly exchange with the neighbor one bit away.   let bfly  = <Executor as EvaluateShuffle<Shuffle<Xor>, Butterfly<1>, u32>>::shuffle(&ev, bcast); For an example of errors caught, a warp-scoped executor for a device-scoped barrier is a compile error:   <ScopedWarpExecutor<'_, WarpUniform> as EvaluateBarrier<Barrier<Device>>>::barrier(evaluator)   // error[E0277]: the trait bound `Device: NvptxBarrierScope` is not satisfied   //               help: the trait `NvptxBarrierScope` is implemented for `Warp` Strip mining is typed on the amount of work and the lane capacity, and it hands back one chunk at a time along with the predicate saying which lanes live in that chunk:   // Six work items across four active lanes: two chunks, based at 0 and 4.   <Executor as EvaluateStripMine<StripMine, (WorkItems, ActiveLanes<StripMined<4>>), i32>>::       for_each_strip_mined(           &evaluator,           (WorkItems::new(6)?, ActiveLanes::new(4)?),           |index, active| {            // ...           },       ); Hopefully that gives the flavor of it.
> — [LegNeato on hackernews](https://news.ycombinator.com/item?id=49249222)

> The goal of this work is to run existing unmodified CPU libraries (which may use core::simd) on the GPU. If you are manually writing ML-shaped workloads, it doesn't add any value over writing with tech like torch/tensorflow/jax which are custom built for those use-cases (except maybe familiarity if you are a CPU programmer).
> — [LegNeato on hackernews](https://news.ycombinator.com/item?id=49251624)

> The major one is that there's one layer of indirection that exists on GPUs that doesn't on CPUs.  There's one giant vector register file per for each of these processing cores (that'll be something like 2048 rows x 32 lanes x 32 bits).  An individual shader invocation might only need say, 16 rows.  While there's hardware for issuing 4 hyperthreads at any given time, there can be a variable number of thread states in the register file.  So for the case of each invocation only needing 16 rows, you might be able to fit 128 hyperthread states into processing core.  Those four hyperthreads then hardware schedule those 128 states and will execute any that are ready, as well as allocate more from other scheduling hardware as gaps in the register file appear from shaders completing. Because of this massive amount thread state, you don't depend nearly as much on a cache hierarchy to deal with DRAM latency.  There's ostensibly some other thread state sitting around that can be serviced while others wait for the hundreds of cycles of latency to access DRAM. So the whole model of how you account for the discrepancy between ALU cycle time, and DRAM latency changes versus a CPU.  Where a modern CPU spends a lot of area on complex cache hierarchies, speculation, etc, to hide the latency to memory, a GPU focuses on having a lot of thread state around and a lot of ALUs, but balanced ideally, so there's always ALU work to do while other thread states are waiting on memory. Now, over time, GPUs have gotten more complex hardware, and more complex cache hierarchies to cover the cases that aren't handled well by extremely long access times.  But those tend to be very explicit.  Additionally, CPU vector files have gotten more similar to GPU cores as architectural features like lane masking/predicates have been added to have the equivalent of CUDA threads in the same warp that take different paths through control flow blocks.  That's a lot of what people mean when they say that AVX-512 adds a lot more than just 512-bit registers.  The K mask registers let you do a lot of GPU shader tricks to have effective partial residency, and not have to use all the lanes if the data doesn't line up with that.
> — [monocasa on hackernews](https://news.ycombinator.com/item?id=49253580)

> It's not really obvious unless you go in depth of the details on modern GPU architecture. GPUs aren't really SIMD, they're SIMT (single instruction multiple thread). The silicon looks a lot like SIMD, but the programming model is different. If you go look at AMD's ISA docs (they're public) you'll see you don't have the equivalent of a __mm256 register like on x86. Each 'thread' just deals with single scalar values like int32 of float32. The hardware, however, groups 32 or 64 threads together which all run the same program and runs them together. Each 'thread' loosely maps to a SIMD lane. The SIMD is implicit, not explicit. The main difference is that the 'SIMD' execution is somewhat opaque to the program. You just write plain scalar code and the hardware model dispatches it efficiently to SIMD execution units. It's not really an abstraction because to extract maximum performance you have to understand how it works. You can use this kind of programming model on a CPU too, Intel did it with [0] ISPC. It's a C-like language that has execution semantics similar to GPU shader languages but compiles to regular CPU code, and maps threads to your CPUs SIMD lanes like a GPU. [0] https://ispc.github.io/
> — [MindSpunk on hackernews · 1 comments](https://news.ycombinator.com/item?id=49252526)

> > They specifies a constant SIMD width so it's non-portable. This is incorrect, you can use vectors wider than native SIMD width and the compiler will break them down to register size of the target cpu. In fact it's sometimes better to used wider than native width, in some applications I see 20% better throughput with f32x16 (512 bits) on an AVX2 CPU (256 bits). It is kinda like loop unrolling it.
> — [exDM69 on hackernews · 1 comments](https://news.ycombinator.com/item?id=49254417)

**Source threads**

- [hackernews](https://news.ycombinator.com/item?id=49247477) · 177 points · 88 comments

## Similar posts on daily.dev

- [Rust threads on the GPU](https://daily.dev/posts/rust-threads-on-the-gpu-x6lzacsrq) · Hacker News · 3 upvotes · 1 comments
- [SIMD programming in pure Rust](https://daily.dev/posts/simd-programming-in-pure-rust-idnkdlsse) · Hacker News · 2 upvotes · 0 comments
- [Async/await on the GPU](https://daily.dev/posts/async-await-on-the-gpu-1psejdrce) · Hacker News · 3 upvotes · 0 comments

---

Tags: [#rust](https://daily.dev/tags/rust), [#gpu](https://daily.dev/tags/gpu), [#cuda](https://daily.dev/tags/cuda)

[View this post on daily.dev](https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Rust SIMD on the GPU","url":"https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi"},"datePublished":"2026-08-10T20:22:19.204Z","dateModified":"2026-09-14T08:32:28.189Z","description":"VectorWare has achieved a world first by running Rust's portable SIMD (core::simd) on the GPU. The key insight is that NVIDIA's SIMT execution model — where a...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d5a30c500175a9e9c28009b36e456240?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d5a30c500175a9e9c28009b36e456240?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Hacker News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Hacker News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/hn","url":"https://daily.dev/sources/hn"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"rust,gpu,cuda","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Hacker News","item":"https://daily.dev/sources/hn"},{"@type":"ListItem","position":3,"name":"Rust SIMD on the GPU"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/rust-simd-on-the-gpu-rdnrzi0mi#faq","mainEntity":[{"@type":"Question","name":"How does Rust's portable SIMD type map onto GPU warp execution?","acceptedAnswer":{"@type":"Answer","text":"A Simd<T, N> vector maps directly onto a GPU warp's lanes, since a warp issuing one instruction across 32 lanes (SIMT) is functionally SIMD. Elementwise operations like Add run natively per lane, reductions like reduce_sum use warp shuffle instructions, simd_swizzle! uses warp shuffle primitives, and Mask::select/any/all use GPU vote and ballot instructions. The mapping requires no new GPU-specific vector type. Developers weighing GPU-native Rust approaches can track advances like this on daily.dev."}},{"@type":"Question","name":"What lane width do I need to use for portable SIMD to be zero-cost on the GPU?","acceptedAnswer":{"@type":"Answer","text":"The vector width N must match the GPU's fixed warp width to be zero cost: 32 lanes on NVIDIA hardware, and either 32 or 64 lanes on AMD. A smaller N leaves lanes idle, while a larger N requires each lane to process more than one element, turning a single operation into multiple instructions. Engineers tuning GPU kernel performance can follow warp-width tradeoffs like these on daily.dev."}},{"@type":"Question","name":"Can I use Rust's portable SIMD feature on stable Rust today?","acceptedAnswer":{"@type":"Answer","text":"No, portable SIMD is still unstable and requires enabling the nightly feature flag #![feature(portable_simd)], meaning its API surface may still change before stabilization. This applies whether targeting the CPU or the GPU, since the same core::simd types are used on both. Rust developers deciding when to adopt unstable features can watch stabilization progress via daily.dev."}}]}
```

