Skip to content
KernelIndex
Search⌘K

submission 830792

nathangong · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

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

submission.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-qr-v2-830792?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
18.5ms
#339 of 515
2026-06-23

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:2b1777284310102fe4f644811c141ce8736a43dce29dbfb58a04207a9f4e370d
license declaredunknown
license concludedunknown
authorsnathangong
imported2026-08-26

Techniques

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

shared-memoryextern __shared__ float sm[];

Kernel source

submission.py206 lines
"""Hybrid QR v4: shared-memory panel kernel (coalesced) + fp32 trailing.

v3 profiling: warp-parallel panel is memory-bound for n>=512 (panel ~76% of time)
because column access A[:,c] is strided (uncoalesced) in row-major. v4 loads the
whole panel A[j:n, j:j+b] into shared memory with COALESCED row-slice loads
(A[r, j:j+b] is contiguous), factors entirely in smem (the arithmetic is tiny;
the cost was memory stalls), and writes back coalesced. nb chosen so the panel
fits in B200's 228KB smem: 64 for n<=512, 32 for n=1024. n<=32 / n>=2048 -> geqrf.
"""
import torch

torch.backends.cuda.matmul.allow_tf32 = False
torch.backends.cudnn.allow_tf32 = False

_EXT = None


def _nb_for(n):
    return 32


def _load_ext():
    global _EXT
    if _EXT is not None:
        return _EXT
    from torch.utils.cpp_extension import load_inline
    cuda_src = r'''
#include <torch/extension.h>
#include <cuda_runtime.h>
#define FULL 0xffffffffu

__global__ void panel_kernel(float* __restrict__ H, float* __restrict__ tau,
                             int B, int n, int j, int b, int ntau, int L) {
    int mat = blockIdx.x;
    float* A = H + (long long)mat * n * n;
    float* tv = tau + (long long)mat * ntau;
    extern __shared__ float sm[];
    float* sp  = sm;          // [L*b] panel (row-major: sp[r*b+c])
    float* wsc = sm + L * b;  // [nwarps]
    int tid = threadIdx.x, nt = blockDim.x;
    int lane = tid & 31, wid = tid >> 5, nwarps = nt >> 5;

    // coalesced load of panel into smem
    for (int e = tid; e < L * b; e += nt) {
        int r = e / b, c = e - r * b;
        sp[e] = A[(long long)(j + r) * n + (j + c)];
    }
    __syncthreads();

    for (int k = 0; k < b; ++k) {
        float alpha = sp[k * b + k];
        float part = 0.f;
        for (int r = k + 1 + tid; r < L; r += nt) { float v = sp[r * b + k]; part += v * v; }
        for (int o = 16; o > 0; o >>= 1) part += __shfl_down_sync(FULL, part, o);
        if (lane == 0) wsc[wid] = part;
        __syncthreads();
        float sumsq = 0.f;
        for (int i = 0; i < nwarps; ++i) sumsq += wsc[i];
        float normx = sqrtf(alpha * alpha + sumsq);
        int safe = normx > 0.f;
        float beta, tau_k, denom;
        if (safe) {
            float sign = (alpha >= 0.f) ? 1.f : -1.f;
            beta = -sign * normx; tau_k = (beta - alpha) / beta; denom = alpha - beta;
        } else { beta = alpha; tau_k = 0.f; denom = 1.f; }
        for (int r = k + 1 + tid; r < L; r += nt) {
            float val = sp[r * b + k];
            sp[r * b + k] = safe ? (val / denom) : val;
        }
        __syncthreads();
        if (tid == 0) { sp[k * b + k] = beta; tv[j + k] = tau_k; }
        __syncthreads();
        // apply reflector to remaining panel cols; warp wid owns column c
        for (int c = k + 1 + wid; c < b; c += nwarps) {
            float wp = 0.f;
            for (int r = k + lane; r < L; r += 32) {
                float vr = (r == k) ? 1.f : sp[r * b + k];
                wp += vr * sp[r * b + c];
            }
            for (int o = 16; o > 0; o >>= 1) wp += __shfl_xor_sync(FULL, wp, o);
            float w = wp * tau_k;
            for (int r = k + lane; r < L; r += 32) {
                float vr = (r == k) ? 1.f : sp[r * b + k];
                sp[r * b + c] -= vr * w;
            }
        }
        __syncthreads();
    }
    // write back (coalesced)
    for (int e = tid; e < L * b; e += nt) {
        int r = e / b, c = e - r * b;
        A[(long long)(j + r) * n + (j + c)] = sp[e];
    }
}

void panel_factor(torch::Tensor H, torch::Tensor tau, int j, int b) {
    int B = H.size(0); int n = H.size(1); int ntau = tau.size(1);
    int L = n - j;
    int threads = 512;
    size_t smem = (size_t)(L * b + threads / 32) * sizeof(float);
    cudaFuncSetAttribute(panel_kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, (int)smem);
    panel_kernel<<<B, threads, smem>>>(
        H.data_ptr<float>(), tau.data_ptr<float>(), B, n, j, b, ntau, L);
}
'''
    cpp_src = "void panel_factor(torch::Tensor H, torch::Tensor tau, int j, int b);"
    _EXT = load_inline(
        name="qr_panel_v5",
        cpp_sources=cpp_src,
        cuda_sources=cuda_src,
        functions=["panel_factor"],
        extra_cuda_cflags=["-O3"],
        verbose=False,
    )
    return _EXT


def _form_T(V, tau):
    b = V.shape[2]
    eye = torch.eye(b, dtype=V.dtype, device=V.device)
    G = torch.bmm(V.transpose(1, 2), V)
    U = torch.triu(G, diagonal=1)
    D = tau[:, :, None] * eye
    M = eye + torch.bmm(D, U)
    return torch.linalg.solve(M, D)


def _hybrid(A):
    B, n, _ = A.shape
    nb = _nb_for(n)
    ext = _load_ext()
    H = A.contiguous().clone()
    tau = torch.zeros(B, n, dtype=A.dtype, device=A.device)
    eye = torch.eye(nb, dtype=A.dtype, device=A.device)
    j = 0
    while j < n:
        b = min(nb, n - j)
        ext.panel_factor(H, tau, j, b)
        if j + b < n:
            panel = H[:, j:, j:j + b]
            V = torch.tril(panel, diagonal=-1)
            V[:, :b, :b] = V[:, :b, :b] + eye[:b, :b]
            T = _form_T(V, tau[:, j:j + b])
            C = H[:, j:, j + b:]
            W = torch.bmm(V.transpose(1, 2), C)
            W = torch.bmm(T.transpose(1, 2), W)
            C.sub_(torch.bmm(V, W))
        j += b
    return H, tau


def _blocked_cpu(A, nb=64):
    B, n, _ = A.shape
    H = A.clone()
    tau = torch.zeros(B, n, dtype=A.dtype, device=A.device)
    one = torch.ones(B, 1, dtype=A.dtype, device=A.device)
    eye = torch.eye(nb, dtype=A.dtype, device=A.device)
    j = 0
    while j < n:
        b = min(nb, n - j)
        for k in range(j, j + b):
            x = H[:, k:, k]
            alpha = x[:, 0]
            xnorm = torch.linalg.vector_norm(x[:, 1:], dim=1) if x.shape[1] > 1 else torch.zeros_like(alpha)
            normx = torch.sqrt(alpha * alpha + xnorm * xnorm)
            sign = torch.where(alpha >= 0, 1.0, -1.0).to(H.dtype)
            beta = -sign * normx
            safe = normx > 0
            betas = torch.where(safe, beta, torch.ones_like(beta))
            tau_k = torch.where(safe, (beta - alpha) / betas, torch.zeros_like(beta))
            denom = torch.where(safe, alpha - beta, torch.ones_like(beta))
            if x.shape[1] > 1:
                vt = x[:, 1:] / denom[:, None]
                H[:, k + 1:, k] = torch.where(safe[:, None], vt, torch.zeros_like(vt))
            H[:, k, k] = torch.where(safe, beta, alpha)
            tau[:, k] = tau_k
            if k + 1 < j + b:
                sub = H[:, k:, k + 1:j + b]
                v = torch.cat([one[:, :1], H[:, k + 1:, k]], dim=1)
                w = torch.einsum('bi,bij->bj', v, sub)
                sub.sub_((tau_k[:, None] * v)[:, :, None] * w[:, None, :])
        if j + b < n:
            panel = H[:, j:, j:j + b]
            V = torch.tril(panel, diagonal=-1)
            V[:, :b, :b] = V[:, :b, :b] + eye[:b, :b]
            T = _form_T(V, tau[:, j:j + b])
            C = H[:, j:, j + b:]
            W = torch.einsum('bik,bij->bkj', V, C)
            W = torch.bmm(T.transpose(1, 2), W)
            C.sub_(torch.einsum('bik,bkj->bij', V, W))
        j += b
    return H, tau


def custom_kernel(data):
    A = data
    B, n, _ = A.shape
    if not A.is_cuda:
        return _blocked_cpu(A)
    if n <= 32 or n >= 2048:
        return torch.geqrf(A)
    try:
        return _hybrid(A)
    except Exception:
        return torch.geqrf(A)
scrolls · 206 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