Skip to content
KernelIndex
Search⌘K

submission 800090

Pradheep P · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

No package. Vendor the mirrored source: 452 lines, June 9 Researcher Reciprocity License v1.0.

submission_spld_v2.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-qr-v2-800090?include=source"
interfacepython
Compatibility
measured onNVIDIA B200
declared hardwareNVIDIA B200
architecturessm_100
dtypesfp32

Benchmark evidence

1 measurement across 1 GPU, fastest first.

Operation / workload
Hardware
Latency
Rank
Observed
NVIDIA B200
14.0ms
#317 of 515
2026-06-15

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:f1b09a2a97b4a42ad87cbce9f20aa01ab076cbdc335f516f4a9a661fff87e7f8
license declaredunknown
license concludedunknown
authorsPradheep P
imported2026-08-26

Techniques

Extracted from the mirrored source by pattern, never inferred. Each row cites its line.

mmawmma::fragment<wmma::accumulator,16,16,8,float>& cf,
shared-memoryextern __shared__ float smem[];

Kernel source

submission_spld_v2.py452 lines
#!POPCORN leaderboard qr_v2
#!POPCORN gpu B200

# from-scratch batched blocked householder qr. panel+T fp32 (correct, from lmaf).
# heavy trailing gemms (W=V^T C, C-=V Y) on tf32x3 tensor cores via nvcuda::wmma,
# now BLOCK-TILED: 4 warps per block share one staged A operand (V) with lean
# single-buffer staging for higher resident CTA count on skinny updates.
# W is consumed inside its producer: each warp applies T^T to its 16x16 W tile
# and writes Y directly. the panel is staged row-wise in shared memory when it fits.

import torch
from torch.utils.cpp_extension import load_inline
from task import input_t, output_t

CUDA_SRC = r"""
#include <torch/extension.h>
#include <cuda_runtime.h>
#include <mma.h>
#include <math.h>
#include <stdexcept>
#include <vector>

using namespace nvcuda;

#define NB 16
#define NWARP 4                 // warps per gemm block
#define NTILE (NWARP * 16)      // cols handled per block

__device__ float block_sum(float x, float* scratch) {
    int tid = threadIdx.x;
    int lane = tid & 31;
    int wid = tid >> 5;
    #pragma unroll
    for (int o = 16; o > 0; o >>= 1) x += __shfl_down_sync(0xffffffff, x, o);
    if (lane == 0) scratch[wid] = x;
    __syncthreads();
    int nw = (blockDim.x + 31) >> 5;
    x = (tid < nw) ? scratch[tid] : 0.0f;
    if (wid == 0) {
        #pragma unroll
        for (int o = 16; o > 0; o >>= 1) x += __shfl_down_sync(0xffffffff, x, o);
    }
    if (tid == 0) scratch[0] = x;
    __syncthreads();
    return scratch[0];
}

template<int N>
__device__ void block_sums(float (&x)[N], int count, float* scratch, float* out) {
    int tid = threadIdx.x;
    int lane = tid & 31;
    int wid = tid >> 5;
    int nw = (blockDim.x + 31) >> 5;

    for (int p = 0; p < count; ++p) {
        float v = x[p];
        #pragma unroll
        for (int o = 16; o > 0; o >>= 1) v += __shfl_down_sync(0xffffffff, v, o);
        if (lane == 0) scratch[wid * N + p] = v;
    }
    __syncthreads();

    if (wid == 0) {
        for (int p = lane; p < count; p += 32) {
            float v = 0.0f;
            for (int w = 0; w < nw; ++w) v += scratch[w * N + p];
            out[p] = v;
        }
    }
    __syncthreads();
}

__global__ void panel_kernel_lwoc(float* __restrict__ A, float* __restrict__ tau,
                                  float* __restrict__ V, float* __restrict__ T,
                                  int n, int j0, int ib) {
    int b = blockIdx.x;
    float* M = A + (size_t)b * n * n;
    float* Tb = T + (size_t)b * NB * NB;
    float* Vb = V + (size_t)b * n * NB;
    float* taub = tau + (size_t)b * n;
    int tid = threadIdx.x, nt = blockDim.x;

    extern __shared__ float smem[];
    float* col = smem;
    float* scratch = col + n;
    float* ds = scratch + 32 * NB;
    float* bc = ds + NB;
    float* tmp = bc + 4;

    int m = n - j0;
    for (int idx = tid; idx < m * ib; idx += nt) Vb[idx] = 0.0f;
    for (int idx = tid; idx < NB * NB; idx += nt) Tb[idx] = 0.0f;
    __syncthreads();

    for (int kk = 0; kk < ib; ++kk) {
        int k = j0 + kk;
        float local = 0.0f;
        for (int i = k + tid; i < n; i += nt) { float x = M[(size_t)i * n + k]; col[i] = x; local += x * x; }
        float sumsq = block_sum(local, scratch);
        float alpha = col[k];
        if (tid == 0) {
            float norm = sqrtf(sumsq);
            float beta = (alpha >= 0.0f) ? -norm : norm;
            float below = sumsq - alpha * alpha;
            float tauk, scale;
            if (norm == 0.0f || below <= 0.0f) { tauk = 0.0f; scale = 1.0f; beta = alpha; }
            else { tauk = (beta - alpha) / beta; scale = alpha - beta; }
            bc[0] = tauk; bc[1] = beta; bc[2] = scale; taub[k] = tauk;
        }
        __syncthreads();
        float tauk = bc[0], beta = bc[1], scale = bc[2];
        float inv = 1.0f / scale;

        for (int i = k + 1 + tid; i < n; i += nt) {
            float vi = (tauk == 0.0f) ? 0.0f : col[i] * inv;
            col[i] = vi; M[(size_t)i * n + k] = vi; Vb[(size_t)(i - j0) * NB + kk] = vi;
        }
        if (tid == 0) { col[k] = 1.0f; M[(size_t)k * n + k] = beta; Vb[(size_t)kk * NB + kk] = 1.0f; }
        __syncthreads();

        if (tauk != 0.0f) {
            int lane = tid & 31, wid = tid >> 5, nwarps = nt >> 5;
            for (int jj = kk + 1 + wid; jj < ib; jj += nwarps) {
                int j = j0 + jj;
                float w = 0.0f;
                for (int i = k + lane; i < n; i += 32) w += col[i] * M[(size_t)i * n + j];
                #pragma unroll
                for (int o = 16; o > 0; o >>= 1) w += __shfl_down_sync(0xffffffff, w, o);
                w = __shfl_sync(0xffffffff, w, 0);
                float tw = tauk * w;
                for (int i = k + lane; i < n; i += 32) M[(size_t)i * n + j] -= col[i] * tw;
            }
        }
        __syncthreads();

        if (tid == 0) Tb[kk * NB + kk] = tauk;
        float dlocal[NB];
        #pragma unroll
        for (int p = 0; p < NB; ++p) dlocal[p] = 0.0f;
        for (int i = k + tid; i < n; i += nt) {
            float ci = col[i];
            #pragma unroll
            for (int p = 0; p < NB; ++p) {
                if (p < kk) dlocal[p] += Vb[(size_t)(i - j0) * NB + p] * ci;
            }
        }
        if (kk > 0) {
            block_sums<NB>(dlocal, kk, scratch, ds);
            for (int p = tid; p < kk; p += nt) {
                tmp[p] = -tauk * ds[p];
            }
            __syncthreads();
            for (int p = tid; p < kk; p += nt) {
                float s = 0.0f;
                for (int q = 0; q < kk; ++q) s += Tb[p * NB + q] * tmp[q];
                Tb[p * NB + kk] = s;
            }
        }
        __syncthreads();
    }
}

__global__ void panel_kernel(float* __restrict__ A, float* __restrict__ tau,
                             float* __restrict__ V, float* __restrict__ T,
                             int n, int j0, int ib) {
    int b = blockIdx.x;
    float* M = A + (size_t)b * n * n;
    float* Tb = T + (size_t)b * NB * NB;
    float* Vb = V + (size_t)b * n * NB;
    float* taub = tau + (size_t)b * n;
    int tid = threadIdx.x, nt = blockDim.x;
    int m = n - j0;

    extern __shared__ float smem[];
    float* sP = smem;
    float* scratch = sP + (size_t)m * ib;
    float* ds = scratch + 32 * NB;
    float* bc = ds + NB;
    float* tmp = bc + 4;

    for (int idx = tid; idx < m * ib; idx += nt) {
        int r = idx / ib;
        int c = idx - r * ib;
        sP[idx] = M[(size_t)(j0 + r) * n + (j0 + c)];
        Vb[(size_t)r * NB + c] = 0.0f;
    }
    for (int idx = tid; idx < NB * NB; idx += nt) Tb[idx] = 0.0f;
    __syncthreads();

    for (int kk = 0; kk < ib; ++kk) {
        float local = 0.0f;
        for (int r = kk + tid; r < m; r += nt) {
            float x = sP[(size_t)r * ib + kk];
            local += x * x;
        }
        float sumsq = block_sum(local, scratch);
        float alpha = sP[(size_t)kk * ib + kk];
        if (tid == 0) {
            float norm = sqrtf(sumsq);
            float beta = (alpha >= 0.0f) ? -norm : norm;
            float below = sumsq - alpha * alpha;
            float tauk, scale;
            if (norm == 0.0f || below <= 0.0f) { tauk = 0.0f; scale = 1.0f; beta = alpha; }
            else { tauk = (beta - alpha) / beta; scale = alpha - beta; }
            bc[0] = tauk; bc[1] = beta; bc[2] = scale; taub[j0 + kk] = tauk;
        }
        __syncthreads();
        float tauk = bc[0], beta = bc[1], scale = bc[2];
        float inv = 1.0f / scale;

        for (int r = kk + 1 + tid; r < m; r += nt) {
            float vi = (tauk == 0.0f) ? 0.0f : sP[(size_t)r * ib + kk] * inv;
            sP[(size_t)r * ib + kk] = vi;
            Vb[(size_t)r * NB + kk] = vi;
        }
        if (tid == 0) {
            sP[(size_t)kk * ib + kk] = beta;
            Vb[(size_t)kk * NB + kk] = 1.0f;
        }
        __syncthreads();

        if (tauk != 0.0f) {
            int lane = tid & 31, wid = tid >> 5, nwarps = nt >> 5;
            for (int jj = kk + 1 + wid; jj < ib; jj += nwarps) {
                float w = 0.0f;
                for (int r = kk + lane; r < m; r += 32) {
                    float v = (r == kk) ? 1.0f : sP[(size_t)r * ib + kk];
                    w += v * sP[(size_t)r * ib + jj];
                }
                #pragma unroll
                for (int o = 16; o > 0; o >>= 1) w += __shfl_down_sync(0xffffffff, w, o);
                w = __shfl_sync(0xffffffff, w, 0);
                float tw = tauk * w;
                for (int r = kk + lane; r < m; r += 32) {
                    float v = (r == kk) ? 1.0f : sP[(size_t)r * ib + kk];
                    sP[(size_t)r * ib + jj] -= v * tw;
                }
            }
        }
        __syncthreads();

        if (tid == 0) Tb[kk * NB + kk] = tauk;
        float dlocal[NB];
        #pragma unroll
        for (int p = 0; p < NB; ++p) dlocal[p] = 0.0f;
        for (int r = kk + tid; r < m; r += nt) {
            float ci = (r == kk) ? 1.0f : sP[(size_t)r * ib + kk];
            #pragma unroll
            for (int p = 0; p < NB; ++p) {
                if (p < kk) dlocal[p] += Vb[(size_t)r * NB + p] * ci;
            }
        }
        if (kk > 0) {
            block_sums<NB>(dlocal, kk, scratch, ds);
            for (int p = tid; p < kk; p += nt) tmp[p] = -tauk * ds[p];
            __syncthreads();
            for (int p = tid; p < kk; p += nt) {
                float s = 0.0f;
                for (int q = 0; q < kk; ++q) s += Tb[p * NB + q] * tmp[q];
                Tb[p * NB + kk] = s;
            }
        }
        __syncthreads();
    }

    for (int idx = tid; idx < m * ib; idx += nt) {
        int r = idx / ib;
        int c = idx - r * ib;
        M[(size_t)(j0 + r) * n + (j0 + c)] = sP[idx];
    }
}

// load+split+3mma helper: As is 16x8 (ld8), Bs slice is 8x16 inside an 8xNTILE (ld NTILE).
__device__ __forceinline__ void mma3(
    wmma::fragment<wmma::accumulator,16,16,8,float>& cf,
    const float* As, const float* Bslice) {
    wmma::fragment<wmma::matrix_a,16,16,8,wmma::precision::tf32,wmma::row_major> af, af_lo;
    wmma::fragment<wmma::matrix_b,16,16,8,wmma::precision::tf32,wmma::row_major> bf, bf_lo;
    wmma::load_matrix_sync(af, As, 8);
    wmma::load_matrix_sync(bf, Bslice, NTILE);
    #pragma unroll
    for (int t = 0; t < af.num_elements; t++) { float hi = wmma::__float_to_tf32(af.x[t]); af_lo.x[t] = wmma::__float_to_tf32(af.x[t]-hi); af.x[t]=hi; }
    #pragma unroll
    for (int t = 0; t < bf.num_elements; t++) { float hi = wmma::__float_to_tf32(bf.x[t]); bf_lo.x[t] = wmma::__float_to_tf32(bf.x[t]-hi); bf.x[t]=hi; }
    wmma::mma_sync(cf, af, bf, cf);
    wmma::mma_sync(cf, af_lo, bf, cf);
    wmma::mma_sync(cf, af, bf_lo, cf);
}

// Y = T^T @ (V^T @ C). block does 16 rows x NTILE cols; 4 warps share staged V^T tile.
__global__ void wmma_wy_kernel(const float* __restrict__ A, const float* __restrict__ V,
                               const float* __restrict__ T, float* __restrict__ Y,
                               int n, int j0, int ib, int m, int cols) {
    int tn = blockIdx.x, tm = blockIdx.y, b = blockIdx.z;
    int row0 = tm * 16, col0 = tn * NTILE;
    const float* Ab = A + (size_t)b * n * n + (size_t)j0 * n + (j0 + ib);
    const float* Vb = V + (size_t)b * n * NB;
    const float* Tb = T + (size_t)b * NB * NB;
    float* Yb = Y + (size_t)b * NB * n;

    __shared__ float As[16 * 8];
    __shared__ float Bs[8 * NTILE];
    __shared__ float Cs[NWARP * 256];
    int tid = threadIdx.x, w = tid >> 5;

    wmma::fragment<wmma::accumulator,16,16,8,float> cf;
    wmma::fill_fragment(cf, 0.0f);

    for (int k0 = 0; k0 < m; k0 += 8) {
        for (int idx = tid; idx < 16 * 8; idx += blockDim.x) {
            int r = idx >> 3, c = idx & 7, p = row0 + r, kk = k0 + c;
            As[idx] = (p < ib && kk < m) ? Vb[(size_t)kk * NB + p] : 0.0f;   // V^T[p,kk]=V[kk,p]
        }
        for (int idx = tid; idx < 8 * NTILE; idx += blockDim.x) {
            int c = idx / NTILE, r = idx % NTILE, kk = k0 + c, col = col0 + r;
            Bs[idx] = (kk < m && col < cols) ? Ab[(size_t)kk * n + col] : 0.0f;  // C[kk,col]
        }
        __syncthreads();
        mma3(cf, As, Bs + w * 16);
        __syncthreads();
    }
    wmma::store_matrix_sync(Cs + w * 256, cf, 16, wmma::mem_row_major);
    __syncwarp();
    for (int idx = (tid & 31); idx < 256; idx += 32) {
        int r = idx >> 4, c = idx & 15, p = row0 + r, col = col0 + w * 16 + c;
        if (p < ib && col < cols) {
            float y = 0.0f;
            #pragma unroll
            for (int q = 0; q < NB; ++q) {
                if (q < ib) y += Tb[(size_t)q * NB + p] * Cs[w * 256 + q * 16 + c];
            }
            Yb[(size_t)p * n + col] = y;
        }
    }
}

// C -= V @ Y. block does 16 rows x NTILE cols; 4 warps share staged V tile. K=ib.
__global__ void wmma_c_kernel(float* __restrict__ A, const float* __restrict__ V,
                              const float* __restrict__ Y, int n, int j0, int ib, int m, int cols) {
    int tn = blockIdx.x, tm = blockIdx.y, b = blockIdx.z;
    int row0 = tm * 16, col0 = tn * NTILE;
    float* Ab = A + (size_t)b * n * n + (size_t)j0 * n + (j0 + ib);
    const float* Vb = V + (size_t)b * n * NB;
    const float* Yb = Y + (size_t)b * NB * n;

    __shared__ float As[16 * 8];
    __shared__ float Bs[8 * NTILE];
    __shared__ float Cs[NWARP * 256];
    int tid = threadIdx.x, w = tid >> 5;

    wmma::fragment<wmma::accumulator,16,16,8,float> cf;
    wmma::fill_fragment(cf, 0.0f);

    for (int k0 = 0; k0 < ib; k0 += 8) {
        for (int idx = tid; idx < 16 * 8; idx += blockDim.x) {
            int r = idx >> 3, c = idx & 7, row = row0 + r, p = k0 + c;
            As[idx] = (row < m && p < ib) ? Vb[(size_t)row * NB + p] : 0.0f;   // V[row,p]
        }
        for (int idx = tid; idx < 8 * NTILE; idx += blockDim.x) {
            int c = idx / NTILE, r = idx % NTILE, p = k0 + c, col = col0 + r;
            Bs[idx] = (p < ib && col < cols) ? Yb[(size_t)p * n + col] : 0.0f;  // Y[p,col]
        }
        __syncthreads();
        mma3(cf, As, Bs + w * 16);
        __syncthreads();
    }
    wmma::store_matrix_sync(Cs + w * 256, cf, 16, wmma::mem_row_major);
    for (int idx = (tid & 31); idx < 256; idx += 32) {
        int r = idx >> 4, c = idx & 15, row = row0 + r, col = col0 + w * 16 + c;
        if (row < m && col < cols) Ab[(size_t)row * n + col] -= Cs[w * 256 + idx];
    }
}

std::vector<torch::Tensor> qr_forward(torch::Tensor A) {
    TORCH_CHECK(A.is_cuda(), "A must be cuda");
    TORCH_CHECK(A.scalar_type() == torch::kFloat32, "A must be fp32");
    auto Ac = A.contiguous();
    int64_t batch, n;
    bool was2 = (Ac.dim() == 2);
    if (Ac.dim() == 3) { batch = Ac.size(0); n = Ac.size(1); }
    else { batch = 1; n = Ac.size(0); Ac = Ac.reshape({1, n, n}); }

    auto a = Ac.clone();
    auto tau = torch::empty({batch, n}, A.options());
    auto V = torch::empty({batch, n, NB}, A.options());
    auto T = torch::empty({batch, NB, NB}, A.options());
    auto Y = torch::empty({batch, NB, n}, A.options());

    int threads = 256;
    size_t aux = 32 * NB + NB + 4 + NB;
    size_t cap = 200 * 1024;
    static bool attr_set = false;
    if (!attr_set) {
        cudaError_t attr = cudaFuncSetAttribute(
            panel_kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, (int)cap);
        TORCH_CHECK(attr == cudaSuccess, "panel attr");
        attr_set = true;
    }

    for (int j0 = 0; j0 < (int)n; j0 += NB) {
        int ib = ((int)n - j0 < NB) ? ((int)n - j0) : NB;
        int m = (int)n - j0;
        size_t panel_shmem = ((size_t)m * ib + aux) * sizeof(float);
        if (panel_shmem <= cap) {
            panel_kernel<<<(int)batch, threads, panel_shmem>>>(
                a.data_ptr<float>(), tau.data_ptr<float>(), V.data_ptr<float>(),
                T.data_ptr<float>(), (int)n, j0, ib);
        } else {
            size_t old_shmem = ((size_t)n + aux) * sizeof(float);
            panel_kernel_lwoc<<<(int)batch, threads, old_shmem>>>(
                a.data_ptr<float>(), tau.data_ptr<float>(), V.data_ptr<float>(),
                T.data_ptr<float>(), (int)n, j0, ib);
        }
        TORCH_CHECK(cudaGetLastError() == cudaSuccess, "panel");

        int cols = (int)n - j0 - ib;
        if (cols <= 0) continue;

        dim3 wg((cols + NTILE - 1) / NTILE, (ib + 15) / 16, (int)batch);
        wmma_wy_kernel<<<wg, NWARP * 32>>>(a.data_ptr<float>(), V.data_ptr<float>(),
                                           T.data_ptr<float>(), Y.data_ptr<float>(),
                                           (int)n, j0, ib, m, cols);
        TORCH_CHECK(cudaGetLastError() == cudaSuccess, "wy");

        dim3 cg((cols + NTILE - 1) / NTILE, (m + 15) / 16, (int)batch);
        wmma_c_kernel<<<cg, NWARP * 32>>>(a.data_ptr<float>(), V.data_ptr<float>(),
                                          Y.data_ptr<float>(), (int)n, j0, ib, m, cols);
        TORCH_CHECK(cudaGetLastError() == cudaSuccess, "c");
    }
    if (was2) return {a.squeeze(0), tau.squeeze(0)};
    return {a, tau};
}
"""

CPP_SRC = r"""
std::vector<torch::Tensor> qr_forward(torch::Tensor A);
"""

_mod = load_inline(
    name="qr_spld_v1",
    cpp_sources=[CPP_SRC],
    cuda_sources=[CUDA_SRC],
    functions=["qr_forward"],
    verbose=False,
    extra_cuda_cflags=["-O3"],
)


def custom_kernel(data: input_t) -> output_t:
    a, tau = _mod.qr_forward(data)
    return a, tau
scrolls · 452 lines total

Source code from GPU Mode and the KernelBot dataset · June 9 Researcher Reciprocity License v1.0

Best evidence level for this revision: reported

JSON