Day 93

GPU Kernels Learning Journey

Description

### Files: `RMS_Normalization.cu` I implemented a code that performs the RMS (Root Mean Square) Normalization on a 2D tensor.

Code Files

RMS_Normalization.cu

#include <cuda_runtime.h>
#include <math.h>

#define EPSILON 1e-5f

__global__ void compute_rms(const float* X, float* rms, size_t B, size_t N) {
    extern __shared__ float sdata[];
    size_t row = blockIdx.x;
    size_t tid = threadIdx.x;
    const float* row_ptr = X + row * N;

    float sum = 0.0f;
    for (size_t i = tid; i < N; i += blockDim.x) {
        float v = row_ptr[i];
        sum += v * v;
    }
    sdata[tid] = sum;
    __syncthreads();

    for (unsigned int s = blockDim.x / 2; s > 0; s >>= 1) {
        if (tid < s) {
            sdata[tid] += sdata[tid + s];
        }
        __syncthreads();
    }

    if (tid == 0) {
        float mean_sq = sdata[0] / static_cast<float>(N);
        rms[row] = sqrtf(mean_sq + EPSILON);
    }
}

__global__ void normalize_rms(const float* X, float* Y, const float* rms, size_t B, size_t N) {
    size_t row = blockIdx.x;
    size_t tid = threadIdx.x;
    float r = rms[row];
    const float* row_in = X + row * N;
    float* row_out = Y + row * N;

    for (size_t i = tid; i < N; i += blockDim.x) {
        row_out[i] = row_in[i] / r;
    }
}

extern "C" void solution(const float* X, float* Y, size_t B, size_t N) {
    int threads = (N < 256) ? int(N) : 256;
    size_t shared_mem_size = threads * sizeof(float);

    float* d_rms = nullptr;
    cudaMalloc(&d_rms, B * sizeof(float));

    compute_rms<<<B, threads, shared_mem_size>>>(X, d_rms, B, N);

    normalize_rms<<<B, threads>>>(X, Y, d_rms, B, N);

    cudaFree(d_rms);
}