Skip to main content
← [ ABORT TO HUD ]
SEQ. 1
SEQ. 2

Launching 3D Grid/Block Kernels from Safe Rust

⚡ Writing & Launching Custom GPU Kernels in Rust (PTX & NVVM)⏱ 22 min⭐ 160 BASE XP⌨ HANDS-ON LAB

Embedding & Dynamic Launching via cudarc

Once compiled, the PTX can be embedded into the host binary using include_str! or dynamically compiled at runtime using NVRTC (NVIDIA Runtime Compilation):

use cudarc::driver::CudaContext;

use cudarc::driver::{LaunchConfig, PushKernelArg};
use cudarc::nvrtc::Ptx;

const KERNEL_PTX: &str = include_str!("../kernels/vector_add.ptx");

pub fn execute_gpu_pipeline() -> Result<(), Box> {
    let ctx = CudaContext::new(0)?;
    let stream = ctx.default_stream();
    println!("Initialized CUDA Context on GPU: {}", ctx.name()?);

    // Load PTX module into GPU context
    let module = ctx.load_module(Ptx::from_src(KERNEL_PTX))?;
    let f = module.load_function("vector_add_kernel")?;
    // Kernel symbol resolved from loaded PTX module

    let n = 1_048_576; // 1M elements
    let a_dev = stream.clone_htod(&vec![2.0f32; n])?;
    let b_dev = stream.clone_htod(&vec![3.0f32; n])?;
    let mut c_dev = stream.alloc_zeros::(n)?;
    // Buffers allocated asynchronously on CudaStream
    // Zero-initialized output CudaSlice ready

    // Configure 3D Grid & Block Topology
    let threads_per_block = 256;
    let blocks = (n as u32 + threads_per_block - 1) / threads_per_block;
    let cfg = LaunchConfig {
        grid_dim: (blocks, 1, 1),
        block_dim: (threads_per_block, 1, 1),
        shared_mem_bytes: 0,
    };

    // Launch kernel asynchronously!
    let mut builder = stream.launch_builder(&f);
    builder.arg(&a_dev).arg(&b_dev).arg(&mut c_dev).arg(&n);
    unsafe { builder.launch(cfg) }?;

    // Copy result back to CPU
    let c_host = stream.clone_dtoh(&c_dev)?;
    assert_eq!(c_host[0], 5.0);
    println!("Successfully verified 1M GPU vector additions!");
    Ok(())
}
⌨ HANDS-ON LABLaunch 3D Grid CUDA Kernel via Safe Rust
⭐ +200 XP

Launch an elementwise matrix addition PTX kernel with 3D thread blocks using cudarc.

1Compile and launch 3D grid kernel using cudarc.
lab-sandbox — simulated environment
INFINITY LAB SANDBOX v2.6 — simulated shell
Type the command for the current objective. Helpers: "hint", "solution", "clear".
$
OBJECTIVE 1 / 1 — type "hint" if stuck
SYNAPSE VERIFICATION
QUERY 1 // 1
How does the host thread coordinate with the GPU to ensure asynchronous kernel computation has finished before reading results?
By synchronizing the stream (stream.synchronize()) or calling a blocking device-to-host copy (stream.clone_dtoh / memcpy_dtov)
By inserting a thread::sleep(100) call on the CPU
By executing an x86 mfence instruction
The GPU automatically halts the CPU clock until the kernel completes