KernelBench cuda · RTX PRO 6000
DeepSeek NSA GPT-6.1 Sol
0.280 msgeomean latency across six shapes · lower is better
manually audited: clean
Real per-token NSA in two CUDA kernels. Block key means are stored as three bf16 pieces (hi, lo, tail) so a bf16 mma.sync scores blocks at about fp32 precision; the diagonal block uses an exact causal prefix mean; top-8 selection runs per query row in registers; a 16-query tile gathers the union of selected and sliding-window blocks and runs online-softmax attention on tensor cores.
harnesscodexagent session32mtotal wall1h 2mcheck5mbenchmark1soutput tokens58,102gpu-lock wait0sgpu-lock held30mregimecompute
Per-shape latencymilliseconds are the measured result; the dense-equivalent roofline is not a useful ceiling
1×16×2048×640.134 ms
1×16×4127×640.351 ms
1×8×8192×640.512 ms
1×8×8191×1280.948 ms
4×8×1024×640.094 ms
2×8×3000×640.223 ms
geomean(0.134 ms · 0.351 ms · 0.512 ms · 0.948 ms · 0.094 ms · 0.223 ms) = 0.280 ms
Kernel source (redacted)
"""CUDA sparse attention with exact causal block means and warp MMA gather."""
import os
import torch
from torch import nn
from torch.utils.cpp_extension import load_inline
os.environ.setdefault('TORCH_CUDA_ARCH_LIST', '12.0')
_CPP = r'''
#include <torch/extension.h>
torch::Tensor nsa_cuda(torch::Tensor q, torch::Tensor k, torch::Tensor v);
'''
_CUDA = r'''
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <c10/cuda/CUDAGuard.h>
#include <cuda_bf16.h>
#include <cuda_runtime.h>
#include <math.h>
using bf16 = __nv_bfloat16;
__device__ __forceinline__ unsigned pack(float x, float y) {
__nv_bfloat162_raw raw = __floats2bfloat162_rn(x,y); return unsigned(raw.x) | (unsigned(raw.y)<<16);
}
__device__ __forceinline__ void mma(float &c0, float &c1, float &c2, float &c3,
unsigned a0,unsigned a1,unsigned a2,unsigned a3,unsigned b0,unsigned b1) {
asm volatile("mma.sync.aligned.m16n8k16.row.col.f32.bf16.bf16.f32 "
"{%0,%1,%2,%3}, {%4,%5,%6,%7}, {%8,%9}, {%0,%1,%2,%3};"
: "+f"(c0),"+f"(c1),"+f"(c2),"+f"(c3)
: "r"(a0),"r"(a1),"r"(a2),"r"(a3),"r"(b0),"r"(b1));
}
__device__ __forceinline__ float warpmax(float x) {
#pragma unroll
for(int i=16;i;i/=2) x=fmaxf(x,__shfl_xor_sync(0xffffffff,x,i));
return x;
}
template<int D> __global__ void means_kernel(const bf16* k, bf16* means, float* prefix,int S,int NB) {
int d=threadIdx.x, bi=blockIdx.x, bh=blockIdx.y;
float sum=0;
int lim=min(64,S-bi*64);
const bf16* ptr=k+(size_t(bh)*S+bi*64)*D;
#pragma unroll 1
for(int j=0;j<lim;j++) {
sum += __bfloat162float(ptr[j*D+d]);
prefix[(size_t(bh)*S+bi*64+j)*D+d]=sum/float(j+1);
}
float mean=sum/float(lim);
bf16 hi=__float2bfloat16(mean);
float rest=mean-__bfloat162float(hi);
bf16 lo=__float2bfloat16(rest);
bf16 tail=__float2bfloat16(rest-__bfloat162float(lo));
means[(size_t(bh)*3*NB+bi)*D+d]=hi;
means[(size_t(bh)*3*NB+NB+bi)*D+d]=lo;
means[(size_t(bh)*3*NB+2*NB+bi)*D+d]=tail;
}
template<int D,int MAXB> __device__ __forceinline__ void select_rows(
const bf16* q,const bf16* compressed,const float* prefix,int* selected,
bf16* tile,const unsigned (&qfrag)[D/16][4],int S,int NB,int tbase) {
int lane=threadIdx.x%32,g=lane/4,sub=lane%4;
int t0=tbase+g,t1=tbase+g+8,cb=tbase/64;
float partial0=0,partial1=0;
#pragma unroll
for(int d=0;d<D/4;d++) {
int col=4*d+sub;
if(t0<S) partial0=fmaf(__bfloat162float(q[size_t(t0)*D+col]),prefix[size_t(t0)*D+col],partial0);
if(t1<S) partial1=fmaf(__bfloat162float(q[size_t(t1)*D+col]),prefix[size_t(t1)*D+col],partial1);
}
#pragma unroll
for(int off=1;off<=2;off*=2) {
partial0+=__shfl_xor_sync(0xffffffff,partial0,off);
partial1+=__shfl_xor_sync(0xffffffff,partial1,off);
}
float scores[MAXB/8][4];
#pragma unroll
for(int i=0;i<MAXB/8;i++) {
float c0=0,c1=0,c2=0,c3=0;
if(i*8<cb) {
#pragma unroll
for(int j=0;j<3*8*D/8/32;j++) {
int ix=j*32+lane,part=ix/(8*D/8),row=(ix/(D/8))%8,col=(ix%(D/8))*8;
unsigned dst=__cvta_generic_to_shared(tile+(part*8+row)*(D+8)+col);
const bf16* src=compressed+(size_t(part)*NB+i*8+row)*D+col;
int valid=i*8+row<cb?16:0;
asm volatile("cp.async.ca.shared.global [%0], [%1], 16, %2;"::"r"(dst),"l"(src),"r"(valid));
}
asm volatile("cp.async.commit_group; cp.async.wait_group 0;":::"memory");
__syncwarp();
#pragma unroll
for(int kd=0;kd<D/16;kd++) {
#pragma unroll
for(int part=0;part<3;part++) {
unsigned b0,b1;
unsigned addr=__cvta_generic_to_shared(tile+(part*8+lane%8)*(D+8)+kd*16+((lane/8)%2)*8);
asm volatile("ldmatrix.sync.aligned.m8n8.x2.shared.b16 {%0,%1}, [%2];":"=r"(b0),"=r"(b1):"r"(addr));
mma(c0,c1,c2,c3,qfrag[kd][0],qfrag[kd][1],qfrag[kd][2],qfrag[kd][3],b0,b1);
}
}
__syncwarp();
}
int b0=i*8+sub*2,b1=b0+1;
scores[i][0]=t0>=S || b0>cb?-INFINITY:b0==cb?partial0:c0;
scores[i][1]=t0>=S || b1>cb?-INFINITY:b1==cb?partial0:c1;
scores[i][2]=t1>=S || b0>cb?-INFINITY:b0==cb?partial1:c2;
scores[i][3]=t1>=S || b1>cb?-INFINITY:b1==cb?partial1:c3;
}
#pragma unroll
for(int rank=0;rank<8;rank++) {
float best0=-INFINITY,best1=-INFINITY;int id0=-1,id1=-1;
#pragma unroll
for(int i=0;i<MAXB/8;i++) {
#pragma unroll
for(int j=0;j<2;j++) {
int b=i*8+sub*2+j;
float x0=scores[i][j],x1=scores[i][j+2];
if(x0>best0 || (x0==best0 && b>id0)) {best0=x0;id0=b;}
if(x1>best1 || (x1==best1 && b>id1)) {best1=x1;id1=b;}
}
}
#pragma unroll
for(int off=1;off<=2;off*=2) {
float x0=__shfl_xor_sync(0xffffffff,best0,off),x1=__shfl_xor_sync(0xffffffff,best1,off);
int b0=__shfl_xor_sync(0xffffffff,id0,off),b1=__shfl_xor_sync(0xffffffff,id1,off);
if(x0>best0 || (x0==best0 && b0>id0)) {best0=x0;id0=b0;}
if(x1>best1 || (x1==best1 && b1>id1)) {best1=x1;id1=b1;}
}
if(sub==0) {selected[g*8+rank]=best0==-INFINITY?-1:id0;selected[(g+8)*8+rank]=best1==-INFINITY?-1:id1;}
#pragma unroll
for(int i=0;i<MAXB/8;i++) {
#pragma unroll
for(int j=0;j<2;j++) {
int b=i*8+sub*2+j;
if(b==id0) scores[i][j]=-INFINITY;
if(b==id1) scores[i][j+2]=-INFINITY;
}
}
}
}
struct Mask { unsigned a,b,c,d; };
__device__ __forceinline__ void insert(Mask &m,int b) {
if(b<0) return;
unsigned bit=1u<<(b&31);
if(b<32) m.a|=bit;
else if(b<64) m.b|=bit;
else if(b<96) m.c|=bit;
else m.d|=bit;
}
__device__ __forceinline__ unsigned word(const Mask &x,int b) {
return b<32?x.a:b<64?x.b:b<96?x.c:x.d;
}
template<int D,int MAXB> __global__ void grouped_attention_kernel(const bf16* q,const bf16* k,const bf16* v,const bf16* compressed,const float* prefix,bf16* out,int S,int NB) {
int tid=threadIdx.x,lane=tid%32,warp=tid/32,g=lane/4,sub=lane%4;
int tbase=blockIdx.x*16,bh=blockIdx.y;
int t0=tbase+g,t1=tbase+g+8;
int last=min(S-1,tbase+15);
q+=size_t(bh)*S*D; k+=size_t(bh)*S*D;v+=size_t(bh)*S*D;
compressed+=size_t(bh)*3*NB*D;prefix+=size_t(bh)*S*D;
__shared__ int selected[16*8];
extern __shared__ bf16 staging[];
bf16* qtile=staging+(D==128?4*16*(D+8):0);
__shared__ unsigned active[4];
if(tid<4) active[tid]=0;
__syncthreads();
#pragma unroll
for(int i=0;i<16*D/8/128;i++) {
int ix=i*128+tid,row=ix/(D/8),col=(ix%(D/8))*8;
unsigned dst=__cvta_generic_to_shared(qtile+row*(D+8)+col);
const bf16* src=q+size_t(tbase+row)*D+col;
int valid=tbase+row<S?16:0;
asm volatile("cp.async.ca.shared.global [%0], [%1], 16, %2;"::"r"(dst),"l"(src),"r"(valid));
}
asm volatile("cp.async.commit_group; cp.async.wait_group 0;":::"memory");
__syncthreads();
unsigned qfrag[D/16][4];
#pragma unroll
for(int kd=0;kd<D/16;kd++) {
unsigned addr=__cvta_generic_to_shared(qtile+(lane%16)*(D+8)+kd*16+(lane/16)*8);
asm volatile("ldmatrix.sync.aligned.m8n8.x4.shared.b16 {%0,%1,%2,%3}, [%4];"
:"=r"(qfrag[kd][0]),"=r"(qfrag[kd][1]),"=r"(qfrag[kd][2]),"=r"(qfrag[kd][3]):"r"(addr));
}
if(warp==0) {
bf16* means_tile=staging+(D==64?16*(D+8):0);
select_rows<D,MAXB>(q,compressed,prefix,selected,means_tile,qfrag,S,NB,tbase);
}
__syncthreads();
if(tid<16 && tbase+tid<S) {
int t=tbase+tid;
#pragma unroll
for(int i=0;i<8;i++) {
int b=selected[tid*8+i];
if(b>=0) atomicOr(active+b/32,1u<<(b%32));
}
int b=t/64;
atomicOr(active+b/32,1u<<(b%32));
b=max(0,t-63)/64;
atomicOr(active+b/32,1u<<(b%32));
}
__syncthreads();
Mask bits0={},bits1={};
#pragma unroll
for(int i=0;i<8;i++) {
int id0=t0<S?selected[g*8+i]:-1,id1=t1<S?selected[(g+8)*8+i]:-1;
insert(bits0,id0);insert(bits1,id1);
}
__syncthreads();
bf16* tile=staging+warp*16*(D+8);
float accum[D/8][4]={};
float m0=-INFINITY,m1=-INFINITY,l0=0,l1=0;
constexpr float scale=D==64?0.125f:0.08838834764831844f;
for(int b=0;b<=last/64;b++) {
if(!(active[b/32] & (1u<<(b%32)))) continue;
int start=b*64+warp*16;
if(start>last) continue;
#pragma unroll
for(int i=0;i<16*D/8/32;i++) {
int ix=i*32+lane,row=ix/(D/8),col=(ix%(D/8))*8;
unsigned dst=__cvta_generic_to_shared(tile+row*(D+8)+col);
const bf16* src=k+size_t(start+row)*D+col;
int valid=start+row<S?16:0;
asm volatile("cp.async.ca.shared.global [%0], [%1], 16, %2;"::"r"(dst),"l"(src),"r"(valid));
}
asm volatile("cp.async.commit_group; cp.async.wait_group 0;":::"memory");
__syncwarp();
float s00=0,s01=0,s10=0,s11=0,s02=0,s03=0,s12=0,s13=0;
#pragma unroll
for(int kd=0;kd<D/16;kd++) {
if constexpr(D==128) {
unsigned addr=__cvta_generic_to_shared(qtile+(lane%16)*(D+8)+kd*16+(lane/16)*8);
asm volatile("ldmatrix.sync.aligned.m8n8.x4.shared.b16 {%0,%1,%2,%3}, [%4];"
:"=r"(qfrag[kd][0]),"=r"(qfrag[kd][1]),"=r"(qfrag[kd][2]),"=r"(qfrag[kd][3]):"r"(addr));
}
unsigned bk0,bk1,bk2,bk3;
unsigned addr0=__cvta_generic_to_shared(tile+(lane%8)*(D+8)+kd*16+((lane/8)%2)*8);
unsigned addr1=__cvta_generic_to_shared(tile+(lane%8+8)*(D+8)+kd*16+((lane/8)%2)*8);
asm volatile("ldmatrix.sync.aligned.m8n8.x2.shared.b16 {%0,%1}, [%2];": "=r"(bk0),"=r"(bk1):"r"(addr0));
asm volatile("ldmatrix.sync.aligned.m8n8.x2.shared.b16 {%0,%1}, [%2];": "=r"(bk2),"=r"(bk3):"r"(addr1));
mma(s00,s01,s10,s11,qfrag[kd][0],qfrag[kd][1],qfrag[kd][2],qfrag[kd][3],bk0,bk1);
mma(s02,s03,s12,s13,qfrag[kd][0],qfrag[kd][1],qfrag[kd][2],qfrag[kd][3],bk2,bk3);
}
__syncwarp();
#pragma unroll
for(int i=0;i<16*D/8/32;i++) {
int ix=i*32+lane,row=ix/(D/8),col=(ix%(D/8))*8;
unsigned dst=__cvta_generic_to_shared(tile+row*(D+8)+col);
const bf16* src=v+size_t(start+row)*D+col;
int valid=start+row<S?16:0;
asm volatile("cp.async.ca.shared.global [%0], [%1], 16, %2;"::"r"(dst),"l"(src),"r"(valid));
}
asm volatile("cp.async.commit_group;":::"memory");
bool sel0=(word(bits0,b)>>(b%32))&1u,sel1=(word(bits1,b)>>(b%32))&1u;
int j=start+2*sub;
s00=(t0<S && j<=t0 && (sel0 || j>=t0-63))?s00*scale:-INFINITY;
s01=(t0<S && j+1<=t0 && (sel0 || j+1>=t0-63))?s01*scale:-INFINITY;
s02=(t0<S && j+8<=t0 && (sel0 || j+8>=t0-63))?s02*scale:-INFINITY;
s03=(t0<S && j+9<=t0 && (sel0 || j+9>=t0-63))?s03*scale:-INFINITY;
s10=(t1<S && j<=t1 && (sel1 || j>=t1-63))?s10*scale:-INFINITY;
s11=(t1<S && j+1<=t1 && (sel1 || j+1>=t1-63))?s11*scale:-INFINITY;
s12=(t1<S && j+8<=t1 && (sel1 || j+8>=t1-63))?s12*scale:-INFINITY;
s13=(t1<S && j+9<=t1 && (sel1 || j+9>=t1-63))?s13*scale:-INFINITY;
float nm0=fmaxf(fmaxf(s00,s01),fmaxf(s02,s03));
float nm1=fmaxf(fmaxf(s10,s11),fmaxf(s12,s13));
#pragma unroll
for(int off=1;off<=2;off*=2) {
nm0=fmaxf(nm0,__shfl_xor_sync(0xffffffff,nm0,off));
nm1=fmaxf(nm1,__shfl_xor_sync(0xffffffff,nm1,off));
}
nm0=fmaxf(m0,nm0);nm1=fmaxf(m1,nm1);
float a0=nm0==-INFINITY?1.f:expf(m0-nm0),a1=nm1==-INFINITY?1.f:expf(m1-nm1);
s00=s00==-INFINITY?0.f:expf(s00-nm0);s01=s01==-INFINITY?0.f:expf(s01-nm0);
s02=s02==-INFINITY?0.f:expf(s02-nm0);s03=s03==-INFINITY?0.f:expf(s03-nm0);
s10=s10==-INFINITY?0.f:expf(s10-nm1);s11=s11==-INFINITY?0.f:expf(s11-nm1);
s12=s12==-INFINITY?0.f:expf(s12-nm1);s13=s13==-INFINITY?0.f:expf(s13-nm1);
float sum0=s00+s01+s02+s03,sum1=s10+s11+s12+s13;
#pragma unroll
for(int off=1;off<=2;off*=2) {
sum0+=__shfl_xor_sync(0xffffffff,sum0,off);
sum1+=__shfl_xor_sync(0xffffffff,sum1,off);
}
l0=l0*a0+sum0;l1=l1*a1+sum1;m0=nm0;m1=nm1;
unsigned ap0=pack(s00,s01),ap1=pack(s10,s11),ap2=pack(s02,s03),ap3=pack(s12,s13);
asm volatile("cp.async.wait_group 0;":::"memory");
__syncwarp();
#pragma unroll
for(int di=0;di<D/8;di++) {
unsigned bv0,bv1;
unsigned addr=__cvta_generic_to_shared(tile+(lane%16)*(D+8)+di*8);
asm volatile("ldmatrix.sync.aligned.m8n8.x2.trans.shared.b16 {%0,%1}, [%2];":"=r"(bv0),"=r"(bv1):"r"(addr));
float c0=accum[di][0]*a0,c1=accum[di][1]*a0,c2=accum[di][2]*a1,c3=accum[di][3]*a1;
mma(c0,c1,c2,c3,ap0,ap1,ap2,ap3,bv0,bv1);
accum[di][0]=c0;accum[di][1]=c1;accum[di][2]=c2;accum[di][3]=c3;
}
__syncwarp();
}
__syncthreads();
float* stats=reinterpret_cast<float*>(staging);
float* sums=stats+64;
float* partial=stats+128;
if(sub==0) {
stats[warp*16+g]=m0;stats[warp*16+g+8]=m1;
sums[warp*16+g]=l0;sums[warp*16+g+8]=l1;
}
__syncthreads();
float gm0=-INFINITY,gm1=-INFINITY;
#pragma unroll
for(int w=0;w<4;w++) {gm0=fmaxf(gm0,stats[w*16+g]);gm1=fmaxf(gm1,stats[w*16+g+8]);}
float norm0=0,norm1=0;
#pragma unroll
for(int w=0;w<4;w++) {
norm0+=gm0==-INFINITY?0.f:expf(stats[w*16+g]-gm0)*sums[w*16+g];
norm1+=gm1==-INFINITY?0.f:expf(stats[w*16+g+8]-gm1)*sums[w*16+g+8];
}
float factor0=gm0==-INFINITY?0.f:expf(m0-gm0)/norm0;
float factor1=gm1==-INFINITY?0.f:expf(m1-gm1)/norm1;
if(warp==0) {
#pragma unroll
for(int di=0;di<D/8;di++) {
int d=di*8+2*sub;
partial[g*(D+8)+d]=accum[di][0]*factor0;
partial[g*(D+8)+d+1]=accum[di][1]*factor0;
partial[(g+8)*(D+8)+d]=accum[di][2]*factor1;
partial[(g+8)*(D+8)+d+1]=accum[di][3]*factor1;
}
}
__syncthreads();
if(warp!=0) {
#pragma unroll
for(int di=0;di<D/8;di++) {
int d=di*8+2*sub;
atomicAdd(partial+g*(D+8)+d,accum[di][0]*factor0);
atomicAdd(partial+g*(D+8)+d+1,accum[di][1]*factor0);
atomicAdd(partial+(g+8)*(D+8)+d,accum[di][2]*factor1);
atomicAdd(partial+(g+8)*(D+8)+d+1,accum[di][3]*factor1);
}
}
__syncthreads();
for(int ix=tid;ix<16*D;ix+=128) {
int row=ix/D,d=ix%D;
if(tbase+row<S) out[(size_t(bh)*S+tbase+row)*D+d]=__float2bfloat16(partial[row*(D+8)+d]);
}
}
template<int D> void launch(const torch::Tensor& q,const torch::Tensor& k,const torch::Tensor& v,torch::Tensor& out,torch::Tensor& means,torch::Tensor& prefix,int S,int BH,cudaStream_t stream) {
int nb=(S+63)/64;
means_kernel<D><<<dim3(nb,BH),D,0,stream>>>((const bf16*)k.data_ptr(),(bf16*)means.data_ptr(),prefix.data_ptr<float>(),S,nb);
dim3 grid((S+15)/16,BH);
int smem=(4+(D==128?1:0))*16*(D+8)*sizeof(bf16);
if(nb<=32) grouped_attention_kernel<D,32><<<grid,128,smem,stream>>>((const bf16*)q.data_ptr(),(const bf16*)k.data_ptr(),(const bf16*)v.data_ptr(),(const bf16*)means.data_ptr(),prefix.data_ptr<float>(),(bf16*)out.data_ptr(),S,nb);
else if(nb<=64) grouped_attention_kernel<D,64><<<grid,128,smem,stream>>>((const bf16*)q.data_ptr(),(const bf16*)k.data_ptr(),(const bf16*)v.data_ptr(),(const bf16*)means.data_ptr(),prefix.data_ptr<float>(),(bf16*)out.data_ptr(),S,nb);
else grouped_attention_kernel<D,128><<<grid,128,smem,stream>>>((const bf16*)q.data_ptr(),(const bf16*)k.data_ptr(),(const bf16*)v.data_ptr(),(const bf16*)means.data_ptr(),prefix.data_ptr<float>(),(bf16*)out.data_ptr(),S,nb);
}
torch::Tensor nsa_cuda(torch::Tensor q,torch::Tensor k,torch::Tensor v) {
c10::cuda::CUDAGuard guard(q.device());
int S=q.size(2),D=q.size(3),BH=q.size(0)*q.size(1),nb=(S+63)/64;
TORCH_CHECK(q.is_cuda() && q.scalar_type()==torch::kBFloat16,"bf16 CUDA inputs required");
TORCH_CHECK(q.is_contiguous() && k.is_contiguous() && v.is_contiguous(),"contiguous inputs required");
TORCH_CHECK((D==64 || D==128) && nb<=128,"unsupported shape");
auto out=torch::empty_like(q);
auto means=torch::empty({BH,3,nb,D},q.options());
auto prefix=torch::empty({BH,S,D},q.options().dtype(torch::kFloat32));
auto stream=at::cuda::getCurrentCUDAStream();
if(D==64) launch<64>(q,k,v,out,means,prefix,S,BH,stream);
else launch<128>(q,k,v,out,means,prefix,S,BH,stream);
C10_CUDA_KERNEL_LAUNCH_CHECK();
return out;
}
'''
_ext = load_inline(name='nsa_bf16_cuda', cpp_sources=_CPP, cuda_sources=_CUDA,
functions=['nsa_cuda'], extra_cuda_cflags=['-O3', '--use_fast_math', '-lineinfo'],
extra_cflags=['-O3'], verbose=False)
class Model(nn.Module):
def __init__(self, B, H, S, D):
super().__init__()
self.B, self.H, self.S, self.D = B, H, S, D
self.register_buffer('_dummy', torch.zeros(1, dtype=torch.bfloat16))
def forward(self, q, k, v):
return _ext.nsa_cuda(q, k, v)
20260930_133144_codex_gpt-6.1-sol_02_deepseek_nsa