submission 833216
bnz941 · python · License unknown
Use it
Vendorable · source mirrored · license unknownView source →
No package. Vendor the mirrored source: 225 lines, June 9 Researcher Reciprocity License v1.0.
_v24.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-qr-v2-833216?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
Reported · How evidence levels are derived →
Source and license
sourceavailable
revision digestsha256:49a2fb89c0b36774033cbf3e08ff0acbc851625a5e00224a62692db5d2cfe2f7
license declaredunknown
license concludedunknown
authorsbnz941
imported2026-08-26
Techniques
Extracted from the mirrored source by pattern, never inferred. Each row cites its line.
mma
return tl.dot(Ah, Bh, out_dtype=tl.float32) + tl.dot(Ah, Bl, out_dtype=tl.float32) + tl.dot(Al, Bh, out_dtype=tl.float32)num-warps = 4
n * n, n, 1, BH=BH, BN=BN, NBc=NBc, num_warps=4, num_stages=2)shared-memory
extern __shared__ float smem[]; float* sPan = smem; float* sred = sPan + h * bw;stages = 2
n * n, n, 1, BH=BH, BN=BN, NBc=NBc, num_warps=4, num_stages=2)tile-n = 64
BN = 64Kernel source
_v24.py225 lines
#!POPCORN leaderboard qr_v2
#!POPCORN gpu B200
"""qr_v2 v24: v18 structure + bf16x3 fused trailing (was tf32x3), extended to n=2048.
The far-trailing C -= V (T^T (V^T C)) is done in ONE Triton kernel per (matrix, N-tile):
load V(h,NB) and C_tile(h,BN) into SRAM, W=V^T C, W2=T^T W, C-=V W2, store C. No
intermediate W/W2 to HBM, one launch instead of 3 bmms. The MMAs use bf16x3 (3 bf16
products accumulated fp32 ~= FP32-accurate, relerr ~8e-6 << gate) which is ~1.3-1.4x
faster than cuBLAS/tf32x3 on these bandwidth-bound shapes (H100 measured). Fused path
now also covers n=2048 (NB=48), giving 26->22ms there. n=512/1024/2048 fused; n=4096 geqrf.
"""
import torch
from torch.utils.cpp_extension import load_inline
import triton
import triton.language as tl
try:
from task import input_t, output_t
except Exception:
input_t = torch.Tensor
output_t = tuple
_BW = 64
_BH = 64 # occupancy-bound: BH=64 (3 CTA/SM) beats BH=128 (1 CTA/SM) on B200
_CUDA_SRC = r'''
#include <torch/extension.h>
#include <cuda_runtime.h>
#define BW 64
#define BLK 512
__global__ void panel_kernel(float* __restrict__ H, float* __restrict__ tau,
float* __restrict__ Vout, int n, int k, int bw, int voff_r, int voff_c) {
const int m = blockIdx.x; const int tid = threadIdx.x;
float* Hm = H + (long long)m * n * n; float* taum = tau + (long long)m * n;
float* Vm = Vout + (long long)m * n * BW; const int h = n - k;
extern __shared__ float smem[]; float* sPan = smem; float* sred = sPan + h * bw;
__shared__ float sRdiag[BW]; __shared__ float sh_tau, sh_beta, sh_inv;
for (int idx = tid; idx < h * bw; idx += BLK) { int c = idx / h, r = idx % h;
sPan[c * h + r] = Hm[(long long)(k + r) * n + (k + c)]; }
__syncthreads();
for (int j = 0; j < bw; ++j) {
int lane0 = tid & 31, warp0 = tid >> 5; float loc = 0.f;
for (int r = j + tid; r < h; r += BLK) { float v = sPan[j * h + r]; loc += v * v; }
for (int o = 16; o > 0; o >>= 1) loc += __shfl_down_sync(0xffffffffu, loc, o);
if (lane0 == 0) sred[warp0] = loc; __syncthreads();
if (warp0 == 0) { float v = (lane0 < (BLK >> 5)) ? sred[lane0] : 0.f;
for (int o = (BLK >> 6); o > 0; o >>= 1) v += __shfl_down_sync(0xffffffffu, v, o);
if (lane0 == 0) sred[0] = v; } __syncthreads();
float normsq = sred[0]; float alpha = sPan[j * h + j];
if (tid == 0) { float tail2 = normsq - alpha * alpha;
if (!(tail2 > 1e-30f * normsq)) { sh_tau = 0.f; sh_beta = alpha; sh_inv = 0.f; }
else { float sg = (alpha >= 0.f) ? 1.f : -1.f; float bb = -sg * sqrtf(normsq);
sh_beta = bb; sh_tau = (bb - alpha) / bb; sh_inv = 1.f / (alpha - bb); } }
__syncthreads(); float tauj = sh_tau, inv = sh_inv;
for (int r = j + 1 + tid; r < h; r += BLK) sPan[j * h + r] *= inv; __syncthreads();
if (tid == 0) { sRdiag[j] = sh_beta; sPan[j * h + j] = 1.0f; taum[k + j] = tauj; } __syncthreads();
int lane = tid & 31, warp = tid >> 5;
for (int c = j + 1 + warp; c < bw; c += (BLK >> 5)) { float d = 0.f;
for (int r = j + lane; r < h; r += 32) d += sPan[j * h + r] * sPan[c * h + r];
for (int o = 16; o > 0; o >>= 1) d += __shfl_down_sync(0xffffffffu, d, o);
d = __shfl_sync(0xffffffffu, d, 0); float coef = tauj * d;
for (int r = j + lane; r < h; r += 32) sPan[c * h + r] -= coef * sPan[j * h + r]; }
__syncthreads();
}
for (int idx = tid; idx < h * bw; idx += BLK) { int c = idx / h, r = idx % h; float pv = sPan[c * h + r];
Hm[(long long)(k + r) * n + (k + c)] = (r == c) ? sRdiag[c] : pv;
Vm[(long long)(voff_r + r) * BW + (voff_c + c)] = (r < c) ? 0.0f : ((r == c) ? 1.0f : pv); }
}
__global__ void zerov_kernel(float* __restrict__ Vout, int n, int NB) {
const int m = blockIdx.x; float* Vm = Vout + (long long)m * n * BW;
for (int idx = threadIdx.x; idx < NB * BW; idx += blockDim.x) Vm[idx] = 0.0f; }
__global__ void tfromg_kernel(const float* __restrict__ G, const float* __restrict__ tau,
float* __restrict__ Tout, int bw, int k, int n, int ldg) {
const int m = blockIdx.x; const int tid = threadIdx.x;
const float* Gm = G + (long long)m * ldg * ldg; const float* taum = tau + (long long)m * n + k;
float* Tm = Tout + (long long)m * BW * BW; __shared__ float sT[BW * BW]; __shared__ float sz[BW];
for (int idx = tid; idx < BW * BW; idx += blockDim.x) sT[idx] = 0.f; __syncthreads();
if (tid == 0) sT[0] = taum[0]; __syncthreads();
for (int j = 1; j < bw; ++j) { float tj = taum[j];
if (tid < j) sz[tid] = -tj * Gm[(long long)tid * ldg + j]; __syncthreads();
if (tid < j) { float s = 0.f; for (int l = tid; l < j; ++l) s += sT[(long long)tid * BW + l] * sz[l];
sT[(long long)tid * BW + j] = s; }
if (tid == 0) sT[(long long)j * BW + j] = tj; __syncthreads(); }
for (int idx = tid; idx < BW * BW; idx += blockDim.x) Tm[idx] = sT[idx]; }
void panel_cuda(torch::Tensor H, torch::Tensor tau, torch::Tensor Vout, int k, int bw, int voff_r, int voff_c) {
int batch = (int)H.size(0), n = (int)H.size(1); int h = n - k;
size_t shbytes = ((size_t)h * bw + BLK) * sizeof(float);
cudaFuncSetAttribute(panel_kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, (int)shbytes);
panel_kernel<<<batch, BLK, shbytes>>>(H.data_ptr<float>(), tau.data_ptr<float>(), Vout.data_ptr<float>(), n, k, bw, voff_r, voff_c); }
void zerov_cuda(torch::Tensor Vout, int NB) { int batch = (int)Vout.size(0), n = (int)Vout.size(1);
zerov_kernel<<<batch, 256>>>(Vout.data_ptr<float>(), n, NB); }
void tfromg_cuda(torch::Tensor G, torch::Tensor tau, torch::Tensor Tout, int bw, int k) {
int batch = (int)G.size(0); int n = (int)tau.size(1); int ldg = (int)G.size(2);
tfromg_kernel<<<batch, 64>>>(G.data_ptr<float>(), tau.data_ptr<float>(), Tout.data_ptr<float>(), bw, k, n, ldg); }
'''
_CPP = ("void panel_cuda(torch::Tensor H, torch::Tensor tau, torch::Tensor Vout, int k, int bw, int voff_r, int voff_c);\n"
"void zerov_cuda(torch::Tensor Vout, int NB);\n"
"void tfromg_cuda(torch::Tensor G, torch::Tensor tau, torch::Tensor Tout, int bw, int k);")
_mod = load_inline(name="qr_v18", cpp_sources=_CPP, cuda_sources=_CUDA_SRC,
functions=["panel_cuda", "zerov_cuda", "tfromg_cuda"], extra_cuda_cflags=["-O3"], verbose=False)
@triton.jit
def _dot3(A, B):
# bf16x3: 3 bf16 MMAs accumulated in fp32 ~= FP32-accurate (relerr ~8e-6 << gate),
# ~1.3-1.4x faster than cuBLAS/tf32x3 on the (bandwidth-bound) QR trailing shapes (H100 measured).
Ah = A.to(tl.bfloat16); Al = (A - Ah.to(tl.float32)).to(tl.bfloat16)
Bh = B.to(tl.bfloat16); Bl = (B - Bh.to(tl.float32)).to(tl.bfloat16)
return tl.dot(Ah, Bh, out_dtype=tl.float32) + tl.dot(Ah, Bl, out_dtype=tl.float32) + tl.dot(Al, Bh, out_dtype=tl.float32)
@triton.jit
def _trail_kernel(V_ptr, T_ptr, C_ptr, h, NB, farN,
svb, svh, svc, stb, sti, stj, scb, sch, scn,
BH: tl.constexpr, BN: tl.constexpr, NBc: tl.constexpr):
# Fused trailing C -= V (T^T (V^T C)) for one (matrix pb, N-tile pn). h-tiled (BH) so
# shared stays small (high occupancy); only W (NBc x BN) is kept resident; C is re-read
# in the 2nd pass (cheap on B200 HBM) but W/W2 never touch HBM. tf32x3 = FP32-accurate.
pb = tl.program_id(0)
pn = tl.program_id(1)
offnb = tl.arange(0, NBc)
offn = pn * BN + tl.arange(0, BN)
mn = offn < farN
mnb = offnb < NB
vbase = V_ptr + pb * svb
cbase = C_ptr + pb * scb
# pass 1: W = V^T C (accumulate over h-tiles)
W = tl.zeros((NBc, BN), dtype=tl.float32)
for h0 in range(0, h, BH):
offh = h0 + tl.arange(0, BH)
mh = offh < h
V = tl.load(vbase + offh[:, None] * svh + offnb[None, :] * svc, mask=mh[:, None] & mnb[None, :], other=0.0)
C = tl.load(cbase + offh[:, None] * sch + offn[None, :] * scn, mask=mh[:, None] & mn[None, :], other=0.0)
W += _dot3(tl.trans(V), C)
# W2 = T^T W
T = tl.load(T_ptr + pb * stb + offnb[:, None] * sti + offnb[None, :] * stj,
mask=mnb[:, None] & mnb[None, :], other=0.0)
W2 = _dot3(tl.trans(T), W)
# pass 2: C -= V W2
for h0 in range(0, h, BH):
offh = h0 + tl.arange(0, BH)
mh = offh < h
V = tl.load(vbase + offh[:, None] * svh + offnb[None, :] * svc, mask=mh[:, None] & mnb[None, :], other=0.0)
C = tl.load(cbase + offh[:, None] * sch + offn[None, :] * scn, mask=mh[:, None] & mn[None, :], other=0.0)
C = C - _dot3(V, W2)
tl.store(cbase + offh[:, None] * sch + offn[None, :] * scn, C, mask=mh[:, None] & mn[None, :])
def _fused_trailing(Vbuf, Tbuf, H, kb, nbk, hb, n, B):
farN = n - kb - nbk
BH = triton.next_power_of_2(hb)
BN = 64
NBc = triton.next_power_of_2(nbk)
boff = kb * n + (kb + nbk)
grid = (B, triton.cdiv(farN, BN))
_trail_kernel[grid](
Vbuf, Tbuf, H, # base ptrs (H offset applied via scb base? use offset)
hb, nbk, farN,
n * _BW, _BW, 1, # V strides (Vbuf (B,n,BW)) — V starts at [:, :hb, :nbk]
_BW * _BW, _BW, 1, # T strides (Tbuf (B,BW,BW))
n * n, n, 1, # C strides (H (B,n,n)); base offset added below
BH=BH, BN=BN, NBc=NBc,
)
def _trailing(V, T, C):
W = torch.bmm(V.transpose(1, 2), C)
W = torch.bmm(T.transpose(1, 2), W)
C -= torch.bmm(V, W)
@torch.no_grad()
def _qr(A, sb=32, NB=32, fused=False):
B, n, _ = A.shape
H = A.clone()
tau = torch.zeros(B, n, device=A.device, dtype=A.dtype)
Vbuf = torch.empty(B, n, _BW, device=A.device, dtype=A.dtype)
Tbuf = torch.empty(B, _BW, _BW, device=A.device, dtype=A.dtype)
for kb in range(0, n, NB):
nbk = min(NB, n - kb)
hb = n - kb
if NB > sb:
_mod.zerov_cuda(Vbuf, nbk)
for ki in range(kb, kb + nbk, sb):
bw = min(sb, kb + nbk - ki)
vo = ki - kb
_mod.panel_cuda(H, tau, Vbuf, ki, bw, vo, vo)
if ki + bw < kb + nbk:
Vs = Vbuf[:, vo:hb, vo:vo + bw]
Gs = torch.bmm(Vs.transpose(1, 2), Vs)
_mod.tfromg_cuda(Gs, tau, Tbuf, bw, ki)
Ci = H[:, ki:, ki + bw:kb + nbk]
_trailing(Vs, Tbuf[:, :bw, :bw], Ci)
if kb + nbk < n:
Vblk = Vbuf[:, :hb, :nbk]
Gb = torch.bmm(Vblk.transpose(1, 2), Vblk)
_mod.tfromg_cuda(Gb, tau, Tbuf, nbk, kb)
if fused:
# Triton fused trailing on H[:, kb:, kb+nbk:] (h-tiled, W-resident, tf32x3)
farN = n - kb - nbk
BN = 64
BH = _BH
NBc = triton.next_power_of_2(nbk)
Hsub = H[:, kb:, kb + nbk:] # (B, hb, farN) view, strides (n*n, n, 1)
grid = (B, triton.cdiv(farN, BN))
_trail_kernel[grid](Vblk, Tbuf, Hsub, hb, nbk, farN,
n * _BW, _BW, 1, _BW * _BW, _BW, 1,
n * n, n, 1, BH=BH, BN=BN, NBc=NBc, num_warps=4, num_stages=2)
else:
Cf = H[:, kb:, kb + nbk:]
_trailing(Vblk, Tbuf[:, :nbk, :nbk], Cf)
return H, tau
def custom_kernel(data: input_t) -> output_t:
A = data
n = A.shape[-1]
if n in (512, 1024):
return _qr(A, sb=32, NB=64, fused=True)
if 64 < n < 1024:
return _qr(A, sb=32, NB=32, fused=False) # tiny cases: cuBLAS far-trailing
if n == 2048:
return _qr(A, sb=24, NB=48, fused=True) # TEST: fused bf16x3 far-trailing for n=2048
return torch.geqrf(A)
scrolls · 225 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