Day 40

GPU Kernels Learning Journey

Description

### Files: `softmax_triton.py` I implemented the softmax kernel in triton. I also implemented Native Sparse Attention in pure c and cuda! here : https://github.com/a-hamdi/native-sparse-attention

Code Files

softmax_triton.py

import triton
import triton.language as tl
import torch

@triton.jit
def softmax_kernel(
    output_ptr, input_ptr, stride_n, stride_f, N, F, BLOCK_SIZE: tl.constexpr
):
    row_idx = tl.program_id(0)  # Each row is processed by one program instance
    offsets = tl.arange(0, BLOCK_SIZE)  # Column offsets
    mask = offsets < F  # Mask to avoid out-of-bounds access

    # Load input row into shared memory
    row_start = input_ptr + row_idx * stride_n
    values = tl.load(row_start + offsets, mask=mask, other=-float("inf"))

    # Compute max for numerical stability
    row_max = tl.max(values, axis=0)
    values = values - row_max

    # Compute exp and sum
    exp_values = tl.exp(values)
    row_sum = tl.sum(exp_values, axis=0)

    # Normalize
    softmax_vals = exp_values / row_sum

    # Store result
    row_output_start = output_ptr + row_idx * stride_n
    tl.store(row_output_start + offsets, softmax_vals, mask=mask)

def softmax_triton(x):
    N, F = x.shape
    output = torch.empty_like(x)
    
    grid = (N,)
    BLOCK_SIZE = triton.next_power_of_2(F)
    
    softmax_kernel[grid](
        output,
        x,
        x.stride(0),
        x.stride(1),
        N,
        F,
        BLOCK_SIZE=BLOCK_SIZE
    )
    
    return output

# Example usage
x = torch.randn(4, 128, device="cuda")  # Batch of 4 vectors of size 128
y = softmax_triton(x)
print(y)