call → run_correctness
callrun_correctness
{
"kernel_code": "import torch, math\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\ncpp_src=r'''\n#include <torch/extension.h>\n#include <vector>\ntorch::Tensor layernorm_forward(torch::Tensor x, torch::Tensor gamma, torch::Tensor beta);\nstd::vector<torch::Tensor> add_layernorm_forward(torch::Tensor a, torch::Tensor b, torch::Tensor gamma, torch::Tensor beta);\ntorch::Tensor gelu_forward(torch::Tensor x);\ntorch::Tensor add_forward(torch::Tensor a, torch::Tensor b);\n'''\ncuda_src=r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <vector>\n#include <algorithm>\n#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x \" must be CUDA\")\n__inline__ __device__ float warp_reduce_sum(float val){for(int o=16;o>0;o>>=1) val+=__shfl_down_sync(0xffffffff,val,o); return val;}\n__inline__ __device__ float block_reduce_sum(float val){__shared__ float shared[32]; int lane=threadIdx.x&31,wid=threadIdx.x>>5; val=warp_reduce_sum(val); if(lane==0) shared[wid]=val; __syncthreads(); val=(threadIdx.x<(blockDim.x>>5))?shared[lane]:0.0f; if(wid==0) val=warp_reduce_sum(val); if(threadIdx.x==0) shared[0]=val; __syncthreads(); return shared[0];}\n__global__ void layernorm_kernel(const float* __restrict__ x,const float* __restrict__ g,const float* __restrict__ be,float* __restrict__ out,int rows,int C){int row=blockIdx.x; const float* xr=x+(size_t)row*C; float sum=0.f; for(int i=threadIdx.x;i<C;i+=blockDim.x) sum+=xr[i]; sum=block_reduce_sum(sum); float mean=sum/(float)C; float vs=0.f; for(int i=threadIdx.x;i<C;i+=blockDim.x){float d=xr[i]-mean; vs+=d*d;} vs=block_reduce_sum(vs); float inv=rsqrtf(vs/(float)C+1.0e-5f); float* yr=out+(size_t)row*C; for(int i=threadIdx.x;i<C;i+=blockDim.x) yr[i]=(xr[i]-mean)*inv*g[i]+be[i];}\n__global__ void add_layernorm_kernel(const float* __restrict__ a,const float* __restrict__ b,const float* __restrict__ g,const float* __restrict__ be,float* __restrict__ add_out,float* __restrict__ ln_out,int rows,int C){int row=blockIdx.x; const float* ar=a+(size_t)row*C; const float* br=b+(size_t)row*C; float sum=0.f; for(int i=threadIdx.x;i<C;i+=blockDim.x){float v=ar[i]+br[i]; sum+=v;} sum=block_reduce_sum(sum); float mean=sum/(float)C; float vs=0.f; for(int i=threadIdx.x;i<C;i+=blockDim.x){float d=ar[i]+br[i]-mean; vs+=d*d;} vs=block_reduce_sum(vs); float inv=rsqrtf(vs/(float)C+1.0e-5f); float* ao=add_out+(size_t)row*C; float* lo=ln_out+(size_t)row*C; for(int i=threadIdx.x;i<C;i+=blockDim.x){float v=ar[i]+br[i]; ao[i]=v; lo[i]=(v-mean)*inv*g[i]+be[i];}}\n__global__ void gelu_kernel(const float* __restrict__ x,float* __restrict__ out,size_t n){size_t idx=(size_t)blockIdx.x*blockDim.x+threadIdx.x,str=(size_t)blockDim.x*gridDim.x; const float A=0.7978845608028654f,B=0.044715f; for(size_t i=idx;i<n;i+=str){float v=x[i]; out[i]=0.5f*v*(1.f+tanhf(A*(v+B*v*v*v)));}}\n__global__ void add_kernel(const float* __restrict__ a,const float* __restrict__ b,float* __restrict__ out,size_t n){size_t idx=(size_t)blockIdx.x*blockDim.x+threadIdx.x,str=(size_t)blockDim.x*gridDim.x; for(size_t i=idx;i<n;i+=str) out[i]=a[i]+b[i];}\ntorch::Tensor layernorm_forward(torch::Tensor x,torch::Tensor g,torch::Tensor b){CHECK_CUDA(x); auto out=torch::empty_like(x); int C=x.size(-1), rows=x.numel()/C; layernorm_kernel<<<rows,256>>>(x.data_ptr<float>(),g.data_ptr<float>(),b.data_ptr<float>(),out.data_ptr<float>(),rows,C); return out;}\nstd::vector<torch::Tensor> add_layernorm_forward(torch::Tensor a,torch::Tensor b,torch::Tensor g,torch::Tensor be){CHECK_CUDA(a); auto ao=torch::empty_like(a), lo=torch::empty_like(a); int C=a.size(-1), rows=a.numel()/C; add_layernorm_kernel<<<rows,256>>>(a.data_ptr<float>(),b.data_ptr<float>(),g.data_ptr<float>(),be.data_ptr<float>(),ao.data_ptr<float>(),lo.data_ptr<float>(),rows,C); return {ao,lo};}\ntorch::Tensor gelu_forward(torch::Tensor x){CHECK_CUDA(x); auto out=torch::empty_like(x); size_t n=x.numel(); int threads=256; int blocks=(int)std::min((size_t)65535,(n+threads-1)/threads); gelu_kernel<<<blocks,threads>>>(x.data_ptr<float>(),out.data_ptr<float>(),n); return out;}\ntorch::Tensor add_forward(torch::Tensor a,torch::Tensor b){CHECK_CUDA(a); auto out=torch::empty_like(a); size_t n=a.numel(); int threads=256; int blocks=(int)std::min((size_t)65535,(n+threads-1)/threads); add_kernel<<<blocks,threads>>>(a.data_ptr<float>(),b.data_ptr<float>(),out.data_ptr<float>(),n); return out;}\n'''\n_ext=load_inline(name='transformer_block_ext_v7', cpp_sources=cpp_src, cuda_sources=cuda_src, functions=['layernorm_forward','add_layernorm_forward','gelu_forward','add_forward'], extra_cuda_cflags=['-O3'], extra_cflags=['-O3'], verbose=False)\nclass NewGELU(nn.Module):\n def __init__(self): super().__init__()\n def forward(self,x): return _ext.gelu_forward(x.contiguous())\nclass CausalSelfAttention(nn.Module):\n def __init__(self,n_embd,n_head,attn_pdrop,resid_pdrop,max_seqlen):\n super().__init__(); assert n_embd%n_head==0; self.c_attn=nn.Linear(n_embd,3*n_embd); self.c_proj=nn.Linear(n_embd,n_embd); self.attn_dropout=nn.Dropout(attn_pdrop); self.resid_dropout=nn.Dropout(resid_pdrop); self.register_buffer('bias',torch.tril(torch.ones(max_seqlen,max_seqlen)).view(1,1,max_seqlen,max_seqlen)); self.n_head=n_head; self.n_embd=n_embd\n def forward(self,x):\n B,T,C=x.size(); q,k,v=F.linear(x,self.c_attn.weight,self.c_attn.bias).split(self.n_embd,dim=2); hs=C//self.n_head; k=k.view(B,T,self.n_head,hs).transpose(1,2); q=q.view(B,T,self.n_head,hs).transpose(1,2); v=v.view(B,T,self.n_head,hs).transpose(1,2); att=(q@k.transpose(-2,-1))*(1.0/math.sqrt(hs)); att=att.masked_fill(self.bias[:,:,:T,:T]==0,float('-inf')); att=F.softmax(att,dim=-1); y=att@v; y=y.transpose(1,2).contiguous().view(B,T,C); return F.linear(y,self.c_proj.weight,self.c_proj.bias)\nclass ModelNew(nn.Module):\n def __init__(self,n_embd,n_head,attn_pdrop,resid_pdrop,max_seqlen):\n super().__init__(); self.ln_1=nn.LayerNorm(n_embd); self.attn=CausalSelfAttention(n_embd,n_head,attn_pdrop,resid_pdrop,max_seqlen); self.ln_2=nn.LayerNorm(n_embd); self.mlp=nn.ModuleDict(dict(c_fc=nn.Linear(n_embd,4*n_embd),c_proj=nn.Linear(4*n_embd,n_embd),act=NewGELU(),dropout=nn.Dropout(resid_pdrop)))\n def forward(self,x):\n x=x.contiguous(); ln1=_ext.layernorm_forward(x,self.ln_1.weight,self.ln_1.bias); attn_out=self.attn(ln1); x1,ln2=_ext.add_layernorm_forward(x,attn_out,self.ln_2.weight,self.ln_2.bias); h=F.linear(ln2,self.mlp['c_fc'].weight,self.mlp['c_fc'].bias); h=_ext.gelu_forward(h); h=F.linear(h,self.mlp['c_proj'].weight,self.mlp['c_proj'].bias); return _ext.add_forward(x1,h)\n"
}