Papers
Topics
Authors
Recent
Search
2000 character limit reached

Fearless Concurrency on the GPU

Published 14 Jun 2026 in cs.PL | (2606.15991v1)

Abstract: Rust has made safe systems programming practical on the CPU, but writing custom GPU kernels in Rust still forces programmers outside the language's ownership guarantees. We present cuTile Rust, a tile-based system for safe, idiomatic GPU kernel authoring in Rust. cuTile Rust extends Rust's ownership discipline to tile-based GPU kernels: mutable outputs are split into disjoint pieces, kernel launches preserve the host-side ownership contract, and programmers can opt out locally when they need lower-level control. The system also provides a composable host execution model spanning synchronous launches, asynchronous pipelines, and CUDA graph replay. Our evaluation shows that these abstractions can preserve performance on high-end GPUs. On the NVIDIA B200 GPU, cuTile Rust achieves 7 TB/s for element-wise operations and 2 PFlop/s for GEMM (96% of cuBLAS), matching cuTile Python within measurement noise. Grout, a cuTile-Rust-based inference engine, exercises cuTile Rust across an end-to-end Qwen3 inference path. In batch-1 decode, Grout reaches 171 generated tokens/s for Qwen3-4B on the NVIDIA GeForce RTX 5090 and 82 generated tokens/s for Qwen3-32B on the B200, competitive with vLLM and SGLang and consistent with an HBM roofline sanity check.

Summary

  • The paper introduces cuTile Rust, which extends Rust's ownership model to GPU kernels using a tile-based execution model to ensure data-race freedom.
  • It establishes a safe host–device interface with macro-generated type checking, allowing zero-cost safety in high-throughput GPU computations.
  • Evaluation shows performance nearly identical to unsafe baselines, validated by benchmarks and LLM inference use in the Grout engine.

Fearless Concurrency on the GPU: Extending Safe Rust Programming to Tile-Based GPU Kernels

Introduction

"Fearless Concurrency on the GPU" (2606.15991) addresses the longstanding gap between static safety guarantees in CPU-side systems programming and custom GPU kernel development. The Rust language’s affine type system enforces zero-cost safety and aliasing invariants, which prevent data races in concurrent CPU applications. However, existing approaches to authoring GPU kernels in Rust (e.g., rust-gpu, rust-cuda, cuda-oxide) require pervasive unsafe code, particularly due to the mismatch between Rust’s ownership model and typical SPMD GPU execution, compromising the core tenet of fearless concurrency. This work proposes and evaluates cuTile Rust, a programmable tile-based system that preserves Rust’s safety properties for both host and device code in GPU-accelerated computations.

System Model and Programming Abstractions

Tile-Based Execution and Partitioned Ownership

cuTile Rust extends the notion of ownership and borrowing from Rust to the tile-based GPU programming model. The system operates by logically partitioning mutable outputs into disjoint sub-tensors (tiles), assigning exclusive access to each tile program within a SPMD kernel launch. Immutable tensors are broadcast as shared references. This mapping is enforced so that at any point, the borrow checker ensures the absence of aliasing between mutable and shared accesses, even across the host—device boundary.

Tile computation is described as a grid of sequential programs, each operating with single-threaded semantics over tiles. The correspondence between host-side tensor partitioning and device-side tile dispatching enables static partition invariants to be discharged at compile time, typically eliminating dynamic checks from the inner execution path, except in cases explicitly marked as unsafe.

Safe Host–Device Interface and Kernel Launch Protocol

The host-to-device type mapping is materialized through a macro-generated, type-checked launch boundary. Data transfer and ownership acquisition are encoded as part of the kernel parameter protocol, using traits to enforce the prepare–recover phase: arguments are relinquished before launch and restored after stream synchronization. Thus, the semantics of borrowing, moving, and referencing tensors are precisely maintained across the launch boundary, transparently to the kernel author.

The host execution model composes device operations as lazy, typed expressions (DeviceOp). These operations can be executed synchronously, through async Rust task scheduling, or captured as CUDA Graphs for efficient replay. The system provides mechanisms for monadic chaining (then), operation fusion, and parallelism over complex host-side pipelines, including CUDA Graph scoped composition with borrow checking to ensure correct lifetime management.

Token-Based Memory Ordering Semantics

cuTile Rust leverages Tile IR’s explicit token-based memory ordering to ensure correctness in device-side mutation. Token threading establishes a sequential happens-before relation between loads and stores to mutable tensor views within a tile program, reflecting Rust’s intra-thread ordering invariants. In contrast, loads from immutable (&Tensor) types are unconstrained and amenable to compiler reordering for throughput; thus, partitioned access guarantees and token ordering compositionally enforce data-race freedom per the Tile IR memory model.

Expressiveness and Escape Hatches

cuTile Rust introduces MappedPartitonMut types, extending tensor partitions to support scheduling where a kernel may need to mutate multiple output sub-tiles sequentially (e.g., persistent GEMM). Bounded dimension iterators and branded partition indices provide static proofs of access disjointness within each kernel launch. For cases where tile-based statically-checked access is insufficient or too restrictive for optimal performance (e.g., fused or highly specialized attention kernels), unchecked access and raw pointer-based APIs are admitted only inside explicit unsafe code sections.

Evaluation

Zero-Overhead Safety in High-Throughput Kernels

Empirical results on the NVIDIA B200 GPU demonstrate that cuTile Rust achieves nearly transparent performance compared to both cuTile Python and low-level unsafe Rust baselines. For memory-bound, element-wise operations, both safe and unsafe Rust implementations reach the device’s theoretical DRAM limit (7 TB/s for two reads, one write). For compute-bound kernels (e.g., GEMM with f16, M=N=K=8192M = N = K = 8192), safe cuTile Rust attains 2.07 PFlop/s, which is 96.4% of cuBLAS and indistinguishable from the raw-pointer, manual partitioning baseline.

Host Execution Models: Synchronous, Asynchronous, and CUDA Graph Replay

Host pipeline composition (chains of up to 1000 kernels) was profiled in sync, async, and CUDA graph replay execution, showing that the cost is amortized once pipelining is leveraged, with CUDA graph replay achieving near-optimal dispatch limits. Asynchronous execution naturally overlaps host work (e.g., I/O, pre-processing), enabling a single host thread to saturate device streams and minimizing CPU footprint compared to thread-per-stream models.

End-to-End LLM Inference: Grout Engine

cuTile Rust serves as the foundation for Grout, a Qwen3 LLM batch-1 inference engine. Across RTX 5090 and B200, Grout matches or surpasses the decode throughput and prompt latency of state-of-the-art inference systems like vLLM and SGLang. Notably, Qwen3-4B decode achieves 154.7 tok/s on the RTX 5090 (74.7% of HBM roofline), and Qwen3-32B reaches 80.1 tok/s on the B200 (66.7% of HBM roofline). Grout fuses key operations and relies on cuTile Rust’s composable, safe kernel path for the majority of non-GEMM operators, using explicit unsafe only where required by performance constraints.

Data-Race Freedom and Theoretical Properties

The safe tensor API construction and kernel launch protocol provide formal guarantees of data-race freedom under the Tile IR weakly ordered memory model. The mapped partition injectivity and intra-tile token chains, together with Rust’s affine types, structurally preclude race conditions. Data-race causing bugs (e.g., index swaps leading to overlapping writes) cannot be expressed in safe cuTile Rust code.

cuTile Rust crystallizes several advances in tile-based and safe GPU programming. Distinct from efforts like Rust-CUDA, rust-gpu, or cubecl, which focus primarily on enabling Rust codegen or multi-backend support, cuTile Rust targets a high-level kernel programming model enforcing host–device ownership contracts. Compared to existing tile systems (e.g., Triton, ThunderKittens, Pallas), cuTile Rust is unique in statically checking access disjointness and memory safety, rather than relying on post-hoc verification or runtime detection. It contrasts with DSLs like Descend or Mojo in that it leverages Rust’s existing type system, avoiding the need to develop or maintain additional language infrastructure.

Limitations and Future Directions

Tile-based programming abstracts over SIMT-level control, thus precluding some low-level warp- or shared-memory-specialized kernels. While GEMM and a significant class of tensor computations map cleanly, complete elimination of raw pointer escape hatches for all relevant patterns requires further API generalization. Quantifying the impact of async execution on CPU utilization and power for real-world workloads (especially in edge or server environments) remains open. Extending partitioning principles for cross-device, multi-GPU, and collective operation safety offers a promising avenue for future research.

Conclusion

cuTile Rust demonstrates that it is possible to achieve data-race-free, zero-cost, safe GPU kernel programming in Rust for a wide range of tensor computations by mapping the affine ownership model onto a tile-based abstraction. Systematic composition of safe tensor and partition APIs results in performance that is within the noise floor of equivalent unsafe or vendor-library code for practical workloads in modern deep learning, as evidenced by both microbenchmarks and LLM inference evaluation. The work conclusively shows that static safety guarantees, often presumed infeasible in high-performance device-side programming, can be realized without a compromise in expressiveness or efficiency for a critical subset of GPU workloads.

Whiteboard

Explain it Like I'm 14

Fearless Concurrency on the GPU — Explained Simply

What is this paper about?

This paper shows a new way to write fast and safe programs that run on graphics cards (GPUs) using the Rust programming language. The system is called “cuTile Rust.” Its main goal is to give programmers the strong safety guarantees Rust is famous for—now on the GPU—without slowing things down.

Think of it like organizing a big team project so that:

  • Everyone knows exactly which piece they own,
  • No two people accidentally write on the same page,
  • And the team still hits top speed.

What questions are the authors trying to answer?

The paper explores three big questions:

  1. Can we bring Rust’s safety rules (no data races, clear ownership) to GPU code?
  2. Can we do this without making programs slower?
  3. Can we make it easy to build and run GPU tasks in different ways (normal, async, or as reusable “graphs”) while staying safe?

How does their approach work?

The authors use a simple idea: tiles and ownership.

  • Tiles: Imagine a giant image you want to edit. Instead of dealing with every pixel one by one, you split the image into many fixed-size squares called tiles, and each tile is processed by one “worker.” This is how the GPU code is written: each worker operates on complete chunks (tiles) of data.
  • Ownership and partitions: Before the GPU starts, the output is cut into non-overlapping pieces (partitions). Each tile program gets exclusive access to its own piece, like giving each worker their own slice of the cake so they never bump into each other.
  • No mixed-up writes: Because each worker owns a different piece of the output, two workers never write to the same spot at the same time. That prevents data races (bad, unpredictable clashes).
  • Keeping order with “tokens”: Inside a worker’s tile, you still need steps to happen in the right order (e.g., load, then add, then store). The system uses “tokens” (think of a baton in a relay race) to make the compiler keep the memory operations in the right sequence—without the programmer micromanaging it.
  • Safety with escape hatches: Most code can stay safe and simple. But if you really need low-level control for performance tricks, you can locally opt out (marking code as unsafe) in tiny, focused spots.
  • Easy launching and running: On the CPU side (the “host”), they provide a simple way to:
    • Build up work without running it right away,
    • Run it synchronously (wait for it), asynchronously (don’t block the thread), or
    • Capture it as a CUDA graph (like recording a routine you can replay super fast).

Everyday analogy:

  • Host vs. device: The host (CPU) is like a chef planning the meal; the device (GPU) is the kitchen team doing the cooking. cuTile Rust lets the chef hand out recipes (kernels) and ingredients (tensors) with strict “who-owns-what” rules so cooks don’t fight over the same pan.
  • Tokens: A baton passed between steps so the kitchen doesn’t flip the order of “wash, chop, cook.”

What did they find?

  • Speed stays high. On a top-end NVIDIA B200 GPU:
    • Simple element-wise operations hit about 7 TB/s (near hardware limits).
    • Matrix multiply (GEMM) reaches about 2 PFlop/s—roughly 96% of cuBLAS (NVIDIA’s highly optimized library). That’s excellent.
    • Their safe Rust version is as fast as a carefully written unsafe version, and matches their Python version that uses the same GPU backend.
  • Real-world test: They built a small LLM engine called Grout using cuTile Rust and ran Qwen3 models end-to-end:
    • Qwen3-4B on an RTX 5090: about 171 tokens/second (batch size 1).
    • Qwen3-32B on a B200: about 82 tokens/second.
    • These numbers are competitive with popular systems like vLLM and SGLang, and they line up with a “roofline” check (a sanity test based on memory limits).
  • Flexible execution: The same code can be run in different modes:
    • sync: simple “run and wait,”
    • async: run without blocking the CPU thread,
    • graph: record a chain of GPU steps and replay it very quickly. Graph replay cuts per-kernel launch overhead dramatically, great for repeated sequences.

Why this matters:

  • You get Rust’s safety (fewer bugs, no data races) on GPUs—a place that is usually hard and error-prone—without paying a speed penalty.

What does this mean going forward?

  • Safer GPU programming: Programmers can write GPU kernels in a way that naturally prevents common bugs like two threads writing to the same place.
  • Fewer runtime checks: By proving safety up front (through Rust types, tiles, and branded indices), the system avoids costly checks inside hot loops, keeping performance high.
  • Practical for AI/ML: Since modern AI relies heavily on GPUs, having a safe and fast Rust pathway helps build reliable inference engines and other high-performance tools.
  • Gradual control: Most code stays safe and easy to reason about, but experts can drop down to lower-level access in small, controlled ways when necessary.

In short, cuTile Rust shows that “fearless concurrency” (Rust’s promise of safe parallel code) can work on GPUs too. It makes it easier to write correct, fast GPU programs—especially for AI workloads—without giving up performance.

Knowledge Gaps

Knowledge gaps, limitations, and open questions

Below is a consolidated list of what remains missing, uncertain, or unexplored, framed to guide future research and engineering work:

  • Hardware and backend portability
    • Only NVIDIA GPUs and a Tile IR/PTX-based backend are supported; there is no path for AMD/Intel (HIP, SPIR-V, Level Zero), Metal, or Vulkan backends. What would a portable backend abstraction look like, and how would the token/partition model map to other GPU memory models?
    • Dependence on LLVM PTX and CUDA Graphs constrains portability; feasibility and performance of an alternative codegen path (e.g., NVVM, MLIR, SPIR-V) are not evaluated.
  • Scope and formalization of the safety model
    • The data-race-freedom argument relies on Tile IR token semantics; a fully mechanized proof that maps Rust references to GPU memory scopes and caches (e.g., CTA, GPU, system scopes; acquire/release) is not provided.
    • Interactions with atomics, barriers, and inter-program synchronization are unspecified; safe abstractions for atomics, reductions with cross-program dependencies, or custom synchronization protocols are missing.
    • Determinism is not discussed: shared reads may be reordered, potentially affecting floating-point associativity and result reproducibility. What guarantees (if any) can the model provide for deterministic execution?
  • Expressiveness limits of the safe tensor/partition API
    • Several performance-critical kernels in Grout (attention, fused norms) require unsafe escape hatches (unchecked accesses or raw pointers), indicating the current safe API cannot express some common high-performance patterns. What minimal safe primitives or iterator/index types would cover these cases without overhead?
    • Only intra-program ordering is guaranteed via tokens; the model does not offer safe cross-program communication (e.g., cooperative thread/block groups, warp-level collectives) or shared-memory protocols.
    • Reductions, scans, and segmented operations that require inter-tile coordination are not addressed; safe patterns and compilation strategies for these are open.
    • Mutable tensors are capped at rank 3 due to 3D launch grids; safe, zero-cost abstractions for higher-rank outputs (e.g., virtual tiling, multi-level partitioning) are not provided.
  • Partitioning and mapped partitions
    • The paper does not systematically characterize which partition maps are provably disjoint and what static information is required to eliminate dynamic checks for general schedules beyond GEMM-like patterns.
    • It is unclear how the system behaves with irregular, ragged, or sparse layouts; partitioning assumes regular tiles and strides.
    • Bounded iterator/brand-based proofs are demonstrated for select cases; a general framework for user-defined partition maps with compositional proofs (and diagnostics when proofs fail) is missing.
  • Shapes, indexing, and numerical types
    • Shapes use i32 dimensions and a -1 dynamic convention; support for 64-bit indexing (very large tensors) is not discussed and may be necessary for future models.
    • Type support is limited to “current upstream” GPU booleans/integers/floats; coverage of FP8 (E4M3/E5M2), BF16 variants, 4/8-bit quantization formats, and mixed-precision accumulation policies is unspecified.
    • Handling of misaligned/packed formats, interleaved layouts, or tensor core fragment-level abstractions within the safe API is unaddressed.
  • JIT compilation and deployment
    • JIT cold-start costs are measured but strategies for mitigation (AOT compilation, persistent kernel caches, fatbin embedding per-arch, cross-run caching, versioning) are not explored.
    • Stability of the JIT across driver versions, architectures, and library updates is not evaluated; reproducibility and cache invalidation policies remain open.
  • Execution model and concurrency
    • Safety across multiple streams and overlapping DeviceOps is not formally characterized beyond borrow exclusion; guidelines or static analyses to prevent cross-stream hazards with shared tensors (e.g., via Arc) are missing.
    • CUDA Graph capture is restricted to non-allocating operations; dynamic-shape changes across replays, graph specialization/parametrization, and multi-graph concurrency are not explored.
    • Interaction between host async task schedulers, Send/Sync constraints, and GPU stream semantics requires deeper analysis (e.g., preventing priority inversion or deadlocks in mixed async/graph pipelines).
  • Performance breadth and tuning
    • Evaluation focuses on GEMM and simple elementwise ops; broader kernels (reductions, softmax/attention variants, layer norms, convolutions, scatter/gather, sparse ops) are not benchmarked in safe form.
    • No automatic autotuning framework is provided; tile shapes are “tuned once per size.” How to integrate search/autotuning and ensure stability across architectures is open.
    • Small-problem regimes and micro-batched scenarios (common in interactive serving) are only partially addressed by graphs; profiling the break-even points and developing compile-time or runtime fusion strategies remain open.
  • Memory management and lifetime issues
    • The memory allocator/pool design, fragmentation behavior, and multi-tenant robustness are not evaluated; guarantees for OOM recovery and reuse policies are unspecified.
    • Unified memory, zero-copy pinned host buffers, and peer-to-peer memory semantics are not covered; safe abstractions for these memory models are missing.
  • Interoperability and ecosystem integration
    • Interop with cuBLAS/cuDNN/FlashAttention and zero-copy handoff between cuTile Rust and vendor libraries (including stream and event management) are not systematically described.
    • Integration with Rust-based ML stacks (candle, burn) beyond basic tensor exchange is not detailed; conversion, layout normalization, and error handling conventions remain open.
  • Tooling, debugging, and developer experience
    • Diagnostics for failed safety proofs (e.g., partition map disjointness), error messages from proc macros, and mapping of runtime faults back to source (kernel debug info, line mapping) are not discussed.
    • Profiling and observability (NVTX annotations, CUPTI integration, kernel timelines, token-chain visualization) are not covered; developer workflows for performance tuning need definition.
  • Distributed and multi-GPU execution
    • The model and runtime are single-GPU; abstractions for multi-GPU (tensor/model parallelism), NCCL collectives, and safe cross-device ownership/partitioning are not addressed.
  • Numerical and semantic guarantees
    • Mixed-precision and accumulation order policies are unspecified; impact of reordering reads on numerical stability is not analyzed.
    • No discussion of deterministic modes, reproducible RNG integration, or error bounds when reordering is permitted by the model.
  • Security and isolation
    • The implications of allowing raw-pointer escape hatches (e.g., sandboxing, capability-based restrictions) are not considered; safe composition with untrusted kernels is an open question.
  • API stability and maintainability
    • The proc-macro–driven codegen and embedded AST/JIT pipeline raise questions about long-term API stability, compile-time overhead, and version compatibility; migration and deprecation strategies are not provided.

Practical Applications

Immediate Applications

The following applications can be deployed now, leveraging cuTile Rust’s safe tile-kernel model, typed host–device launches, and multi-mode execution (sync, async, CUDA Graphs), with performance validated near vendor libraries.

  • Software/AI Infrastructure — Rust LLM inference engines for low-latency, batch-1 serving
    • What: Build and deploy Rust-based inference backends that capture the decode step as CUDA graphs for rapid replay; use safe kernels for element-wise ops and GEMM, with escape hatches for fused attention where needed.
    • Tools/workflows: Grout (reference), DeviceOp pipelines, CudaGraph::scope, Partition/MappedPartitionMut, TensorView.
    • Dependencies/assumptions: NVIDIA GPUs with CUDA; shapes stable enough to benefit from graph replay; Rust runtime (e.g., tokio) for async integration; initial JIT cost amortized or pre-warmed.
  • ML Frameworks in Rust — Safe custom-kernel authoring inside Candle/Burn
    • What: Replace or augment CUDA C++ kernels with cuTile Rust kernels to gain borrow-checked host/device ownership, partitioned mutable outputs (no data races), and near-cuBLAS performance for GEMM.
    • Tools/workflows: #[cutile::module], generated typed launchers, KernelInput/KernelOutput, branded iterators (PartitionIndex, Dim) to avoid bounds checks in hot loops.
    • Dependencies/assumptions: Rust-based frameworks (Candle, Burn) integration; developers familiar with Rust generics and lifetimes; CUDA toolchain availability.
  • HPC/Scientific Computing — Memory- and compute-bound kernels with safety guarantees
    • What: Port tiled patterns (stencils, reductions, BLAS-3) to cuTile Rust to eliminate classes of race conditions (e.g., wrong-destination indices) while retaining performance.
    • Tools/workflows: Tile-level kernels (load_tile_like, mma, token-ordered mutable ops); sync/async modes for pipeline composition; CUDA Graphs for repeated sequences.
    • Dependencies/assumptions: NVIDIA hardware; kernel fits tile abstraction (most dense linear algebra does); initial tuning of tile sizes.
  • Healthcare/Medical Imaging — Safer GPU pipelines for reconstruction and denoising
    • What: Implement image processing and reconstruction kernels (element-wise transforms, convolution via GEMM) with stronger safety and DRF (data-race freedom) to ease audits and reduce nondeterminism.
    • Tools/workflows: Partitioned outputs (disjoint writes), token-ordered mutable sequences, zero-copy tensor views for in-place transforms.
    • Dependencies/assumptions: Regulatory acceptance still requires validation; numerics and precision (e.g., f16) must meet clinical requirements; CUDA-equipped workstations.
  • Robotics/Edge AI — Deterministic, low-latency inference on-device
    • What: Use CUDA Graphs for steady-state control/inference loops; safe borrowing prevents host–device aliasing bugs; tile model maps well to perception DNNs and post-processing.
    • Tools/workflows: CudaGraph::scope for capturing per-cycle sequences; async execution to overlap CPU I/O with GPU compute; mapped partitions for persistent kernels to improve cache reuse.
    • Dependencies/assumptions: NVIDIA Jetson/embedded GPUs; real-time determinism beyond intra-tile ordering still requires system-level scheduling.
  • Finance — Fast, reproducible Monte Carlo and linear-algebra pipelines
    • What: Implement element-wise paths and GEMMs with safe ownership semantics, aiding auditability and reducing production incidents from concurrency bugs.
    • Tools/workflows: DeviceOp.then chains for dependency-aware sequencing; CUDA Graphs for recurring pricing steps; shared tensors via Arc for multi-task reuse.
    • Dependencies/assumptions: GPU fleet with CUDA; acceptance of Rust in risk infrastructure; precision formats (f32/f64) as needed.
  • MLOps/Serving — Latency-optimized microservices with Rust async runtimes
    • What: Integrate GPU launches directly into async Rust services using .await on DeviceOp; amortize launch overhead with CUDA Graphs for repeated workloads.
    • Tools/workflows: Stream-scoped execution contexts, shared ops via shared() combinator, graph capture + replay as a DeviceOp.
    • Dependencies/assumptions: Consistent CUDA streams per request; careful graph-capture scoping around allocations; executor integration (tokio/async-std).
  • Education/Training — Teaching safe GPU parallelism
    • What: Use cuTile Rust in courses to illustrate ownership, data-race freedom, and tile-level GPU programming without unsafe code.
    • Tools/workflows: Small kernels (element-wise, reductions, GEMM) using #[cutile::entry]; experiments demonstrating elimination of index-race bugs.
    • Dependencies/assumptions: Access to NVIDIA-equipped labs; Rust toolchain familiarity.
  • Security/Compliance (Org Policy) — Internal guidelines to favor safe GPU kernels
    • What: Adopt team-wide policies preferring cuTile Rust kernels for new GPU work to reduce undefined behavior and ease code reviews.
    • Tools/workflows: Code templates with #[cutile::module]; CI checks that disallow unsafe escape hatches except in reviewed wrappers; DRF tests.
    • Dependencies/assumptions: Organizational buy-in; training for Rust + CUDA; exceptions documented for performance-critical hotspots.

Long-Term Applications

The following applications require maturation of the ecosystem, broader backend support, or further research on verification, portability, and tooling.

  • Cross-Vendor Portability — SPIR-V/ROCm backends for safe Rust kernels
    • What: Extend cuTile Rust to AMD (ROCm) and Vulkan/SPIR-V, enabling the same ownership and partition guarantees across vendors.
    • Potential products: Cross-platform Rust GPU compute SDK; unified tile IR lowering to multiple backends.
    • Dependencies/assumptions: Stable backends beyond PTX; feature parity (token-like memory ordering) in other ecosystems.
  • Verified GPU Libraries — Formally proven DRF for core ops
    • What: Develop a standard library of safe, high-performance kernels (GEMM, convolution, attention, norms) with machine-checked proofs linking Rust types to IR memory models.
    • Potential products: Certified math kernels for regulated sectors (healthcare, automotive).
    • Dependencies/assumptions: Formal methods integration with Tile IR; stable specs; proof engineering investment.
  • Deep Framework Integration — Rust kernels as first-class ops in PyTorch/JAX
    • What: Build adapters so Python frameworks can invoke cuTile Rust kernels via FFI with minimal overhead, broadening adoption while keeping safety for kernel authors.
    • Potential products: PyTorch extension packages with cuTile Rust ops; op fusion pipelines driven by Rust backends.
    • Dependencies/assumptions: ABI stability, packaging/distribution (wheels), shape-specialization strategies to manage JIT costs.
  • Safety-Critical Systems — Automotive/Avionics perception in safe GPU Rust
    • What: Use typed ownership and token-ordered semantics to reduce certification burden of GPU code in ADAS/robotics perception stacks.
    • Potential products: Safety profiles (restricted APIs, disallowing escape hatches), deterministic kernels for key stages.
    • Dependencies/assumptions: Domain standards compliance (ISO 26262/DO-178C), deterministic execution beyond intra-tile semantics, toolchain qualification.
  • Multi-GPU and Distributed Runtime — Borrow- and partition-aware scaling
    • What: Extend partitioning and ownership across devices/nodes for safe multi-GPU kernels and pipelines (e.g., tensor-parallel attention).
    • Potential products: Distributed DeviceOp graphs with safe cross-device lifetimes; partition mappers that encode collective semantics.
    • Dependencies/assumptions: NCCL/collectives integration; inter-device memory models; scheduler support.
  • Hardware/Compiler Co-Design — First-class token ordering in GPU ISAs
    • What: Influence future GPU designs/compilers to better support tokenized memory ordering, lowering the cost of preserving Rust’s semantics.
    • Potential products: Compiler passes mapping Rust ownership to efficient hardware barriers; ISA hints for tile-level ordering.
    • Dependencies/assumptions: Vendor engagement; empirical evidence of performance gains.
  • On-Device Consumer AI — Private, offline assistants and media tools
    • What: Package Rust-based inference engines for laptops/phones with discrete or embedded NVIDIA GPUs for privacy-preserving, low-latency AI features.
    • Potential products: Desktop apps for transcription, summarization, image enhancement using safe GPU kernels.
    • Dependencies/assumptions: Model compression/quantization; memory footprint constraints; sustained power/thermal budgets.
  • Energy/Grid Optimization — Safer GPU solvers for planning and control
    • What: Implement linear algebra-heavy solvers and iterative methods with cuTile Rust to improve reliability of control loops and planning.
    • Potential products: Grid analytics microservices with CUDA Graph replay for periodic workloads.
    • Dependencies/assumptions: Domain validation of numerics; integration with legacy systems; GPU availability in control centers.
  • Governance and Standards — Guidance for safe GPU programming practices
    • What: Incorporate DRF-by-construction GPU approaches into governmental and industry guidance for AI/HPCC software (procurement, grants, curricula).
    • Potential products: Best-practice documents, compliance checklists referencing ownership/partitioning models.
    • Dependencies/assumptions: Community consensus; stable, maintained toolchains.
  • Auto-Fusion and Kernel Synthesis — Higher-level optimizers targeting safe tiles
    • What: Build compilers that fuse complex operator graphs to cuTile Rust kernels while preserving type-based safety and disjointness proofs.
    • Potential products: Graph compilers generating Rust tile code with verified partition maps.
    • Dependencies/assumptions: Cost models for fusion; integration with IRs (MLIR/XLA); robust codegen for multiple shapes/dtypes.

In all cases, feasibility depends on the following shared assumptions and constraints:

  • Hardware/toolchain: NVIDIA GPUs and CUDA are required today; performance and semantics rely on Tile IR, LLVM PTX, and CUDA drivers. Portability work is in the long-term bucket.
  • Applicability of the tile model: Best fit for tile-friendly kernels (dense linear algebra, many tensor ops). Some advanced fused kernels may still require localized unsafe escape hatches.
  • Kernel limits and shapes: Mutable partitions are currently capped at rank 3 due to CUDA’s 3D launch grid; stable input shapes benefit graph replay most.
  • JIT and warm-up: First-use JIT costs should be amortized in long-running services or handled via pre-warming; short-lived jobs may see overhead unless addressed.
  • Numerical requirements: Performance results are demonstrated for f16; some domains require f32/f64 and careful validation.
  • Determinism scope: Token ordering ensures intra-tile happens-before for mutable operations; full-system determinism (thread-block scheduling, cross-kernel order) requires additional controls.

Glossary

Below is an alphabetical list of advanced domain-specific terms from the paper, each with a brief definition and a verbatim usage example.

  • ABI: The low-level contract that defines how data and calls are passed between components (here, between host and device). "add_entry establishes the host/device ABI for cuTile Rust's tensor types."
  • aliasing XOR mutability: A Rust rule ensuring safety by permitting either one mutable reference or multiple immutable references, but not both at once. "The relevant Rust rule is aliasing XOR mutability: A value may have either one mutable reference (\lstinline|&mut T|) or any number of immutable references (\lstinline|&T|), but not both simultaneously."
  • async executor: A runtime that drives asynchronous Rust tasks to completion without blocking threads. "can run synchronously, through any Rust async executor, or be captured as a CUDA graph."
  • bounded dimension iterator: An iterator whose indices are statically or dynamically known to be within fixed bounds along a tensor dimension. "branded partition indices and bounded dimension iterators, letting the front end prove that common partition accesses are bounded and disjoint."
  • borrow checker: The Rust compiler component that enforces ownership and borrowing rules to ensure memory safety. "The borrow checker can verify the entire launch-execute-return lifecycle because this protocol is expressed as traits."
  • cuBLAS: NVIDIA’s high-performance CUDA library for basic linear algebra routines. "which is within about 96\% of cuBLAS performance."
  • CUDA Graph: A CUDA feature that captures a sequence of GPU operations for efficient replay with reduced launch overhead. "or be captured as a CUDA graph, replayed for work launched repeatedly that needs low-latency execution."
  • cubin: A compiled GPU binary produced by NVIDIA’s toolchain that contains device code. "and loads the resulting cubin."
  • DeviceOp: A cuTile Rust trait representing lazy, typed GPU work that composes and executes on demand. "Host-side GPU work is built around \lstinline|DeviceOp|, a trait for lazy, typed GPU work."
  • Dim iterator: A specialized iterator that yields bounded indices along a specific tensor dimension. "Dim iterator produces bounded indices along the KK axis."
  • execution context: The environment encapsulating stream, device, and memory pool information for GPU execution. "which takes an execution context (the CUDA stream, device, and memory pool)."
  • GEMM: General Matrix-Matrix Multiply, a core linear algebra operation central to high-performance computing and ML. "GEMM (compute-bound)."
  • HBM roofline: A performance model that bounds throughput based on High Bandwidth Memory limits. "consistent with an HBM roofline sanity check."
  • happens-before: A memory-ordering relation ensuring one operation’s effects are visible to another. "This chain establishes a happens-before relation:"
  • JIT: Just-In-Time compilation, where code is compiled at runtime for specialization and performance. "For each source entry point, the JIT generates a device entry wrapper."
  • Mapped partition: A partitioning scheme where each program owns a (possibly multiple) mapped sequence of disjoint output sub-tensors. "\lstinline|MappedPartitionMut<T, S, M>| generalizes it: the partition map \lstinline|M| lets each program own a bounded sequence of output sub-tensors."
  • monadic composition: A compositional pattern where operations are chained using bind-like combinators to propagate dependencies. "Composition is monadic, with \lstinline|then| acting as bind to sequence a dependent operation onto a prior one."
  • PartitionIndex: A branded index identifying a specific, disjoint output sub-tensor within a partition map. "z.iter_indices() produces disjoint output PartitionIndex values, while the k_tiles Dim iterator produces bounded indices along the KK axis."
  • partition view: A device-side view exposing an exclusive mutable sub-tensor to a tile program. "exposed in Tile~IR as a partition view."
  • PTX: NVIDIA’s intermediate representation (Parallel Thread Execution) targeted by compilers for GPU devices. "NVIDIA GPU's via the LLVM PTX backend."
  • rank-polymorphic: A trait or API that abstracts over tensor rank (number of dimensions) without duplicating user code. "Rank-polymorphic traits hide the per-rank generated structs and operation impls from user code..."
  • SGLang: An LLM serving framework used as a baseline for performance comparison. "competitive with vLLM and SGLang"
  • SPMD/SIMT: Single Program, Multiple Data / Single Instruction, Multiple Threads; GPU execution paradigms for parallel kernels. "device kernels run many SPMD/SIMT threads whose varying integer coordinates, hierarchical memory, and explicit synchronization make address disjointness and visibility programmer-managed invariants."
  • stream (CUDA stream): A CUDA execution queue used to order and overlap GPU operations. "The safe \lstinline|sync| method restores Rust's usual boundary: it runs \lstinline|execute| on a stream, synchronizes, and only then returns the recovered output."
  • tensor cores: Specialized GPU units for high-throughput matrix math (e.g., mixed-precision). "It stresses tensor cores; we compare Rust, unsafe Rust, cuTile Python, and cuBLAS"
  • TensorView: A zero-copy view that reinterprets tensor metadata (shape/stride/slice) without moving data. "The view() call creates a zero-copy TensorView that borrows input without copying."
  • Tile IR: An intermediate representation that models tile-level computations and memory ordering via tokens. "Tile IR~\cite{cuda_tile} exposes it through tokens."
  • tile program: A logical unit of GPU work operating on a tile-sized region of data. "Kernels consist of a grid of tile programs, each of which is modeled as a single logical thread of execution over tiles of data."
  • token ordering: A mechanism in Tile IR where tokens serialize mutable operations to enforce memory order. "Tile~IR's token-ordered operations have no default program order"
  • vLLM: An LLM serving system used as a performance comparator. "competitive with vLLM and SGLang"

Open Problems

We haven't generated a list of open problems mentioned in this paper yet.

Collections

Sign up for free to add this paper to one or more collections.

Tweets

Sign up for free to view the 8 tweets with 718 likes about this paper.

HackerNews

  1. Fearless Concurrency on the GPU (1 point, 0 comments) 

Reddit

  1. Fearless Concurrency on the GPU (253 points, 17 comments) 
  2. Fearless Concurrency on the GPU (paper) (37 points, 2 comments)