call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n#include <vector>\ntorch::Tensor cvit_forward_cuda(torch::Tensor x, torch::Tensor conv_w, torch::Tensor conv_b,\n torch::Tensor lp_w, torch::Tensor lp_b, torch::Tensor cls,\n std::vector<torch::Tensor> layer_tensors, torch::Tensor fc_w, torch::Tensor fc_b,\n int64_t num_heads);\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <vector>\n#include <math.h>\n\n__global__ void conv_patch_kernel(const float* __restrict__ x, const float* __restrict__ w, const float* __restrict__ bias, float* __restrict__ y, int B, int C, int H, int W, int E, int K, int OH, int OW) {\n int idx=blockIdx.x*blockDim.x+threadIdx.x; int total=B*E*OH*OW; if(idx>=total) return;\n int p=idx%(OH*OW), oc=(idx/(OH*OW))%E, b=idx/(E*OH*OW); int py=p/OW, px=p-py*OW; float sum=bias[oc];\n for(int c=0;c<3;++c) for(int dy=0;dy<4;++dy) for(int dx=0;dx<4;++dx) sum=fmaf(x[((b*C+c)*H+(py*K+dy))*W+(px*K+dx)], w[((oc*C+c)*K+dy)*K+dx], sum);\n y[idx]=sum;\n}\n__global__ void linear_kernel(const float* __restrict__ inp,const float* __restrict__ w,const float* __restrict__ bias,float* __restrict__ out,int rows,int K,int N,int do_relu){\n extern __shared__ float sdata[]; int row=blockIdx.x,n=blockIdx.y,tid=threadIdx.x; float sum=0.f; const float* inrow=inp+row*K; const float* wrow=w+n*K;\n for(int k=tid;k<K;k+=blockDim.x) sum=fmaf(inrow[k],wrow[k],sum); sdata[tid]=sum; __syncthreads();\n for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sdata[tid]+=sdata[tid+s]; __syncthreads();}\n if(tid==0){float v=sdata[0]+bias[n]; if(do_relu&&v<0.f)v=0.f; out[row*N+n]=v;}\n}\n__global__ void linear_strided_kernel(const float* __restrict__ inp,const float* __restrict__ w,const float* __restrict__ bias,float* __restrict__ out,int rows,int K,int N,int stride){\n extern __shared__ float sdata[]; int row=blockIdx.x,n=blockIdx.y,tid=threadIdx.x; float sum=0.f; const float* inrow=inp+row*stride; const float* wrow=w+n*K;\n for(int k=tid;k<K;k+=blockDim.x) sum=fmaf(inrow[k],wrow[k],sum); sdata[tid]=sum; __syncthreads();\n for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sdata[tid]+=sdata[tid+s]; __syncthreads();}\n if(tid==0) out[row*N+n]=sdata[0]+bias[n];\n}\n__global__ void make_seq_kernel(const float* __restrict__ z,const float* __restrict__ cls,float* __restrict__ seq,int B,int E){int idx=blockIdx.x*blockDim.x+threadIdx.x,total=B*2*E; if(idx>=total)return; int e=idx%E,t=(idx/E)%2,b=idx/(2*E); seq[(b*2+t)*E+e]=(t==0)?cls[e]:z[b*E+e];}\n__global__ void attn2_kernel(const float* __restrict__ qkv,float* __restrict__ ctx,int B,int E,int Hh){\n extern __shared__ float sh[]; int b=blockIdx.x,h=blockIdx.y,tid=threadIdx.x,D=E/Hh; int base0=(b*2)*3*E+h*D, base1=(b*2+1)*3*E+h*D; float p00=0,p01=0,p10=0,p11=0;\n for(int d=tid;d<D;d+=blockDim.x){float q0=qkv[base0+d],q1=qkv[base1+d],k0=qkv[base0+E+d],k1=qkv[base1+E+d]; p00=fmaf(q0,k0,p00); p01=fmaf(q0,k1,p01); p10=fmaf(q1,k0,p10); p11=fmaf(q1,k1,p11);} \n sh[tid]=p00; __syncthreads(); for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sh[tid]+=sh[tid+s]; __syncthreads();} p00=sh[0];\n sh[tid]=p01; __syncthreads(); for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sh[tid]+=sh[tid+s]; __syncthreads();} p01=sh[0];\n sh[tid]=p10; __syncthreads(); for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sh[tid]+=sh[tid+s]; __syncthreads();} p10=sh[0];\n sh[tid]=p11; __syncthreads(); for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sh[tid]+=sh[tid+s]; __syncthreads();} p11=sh[0];\n float scale=rsqrtf((float)D); float a=p00*scale,c=p01*scale,m=fmaxf(a,c),e0=expf(a-m),e1=expf(c-m),inv=1.f/(e0+e1),a00=e0*inv,a01=e1*inv; a=p10*scale;c=p11*scale;m=fmaxf(a,c);e0=expf(a-m);e1=expf(c-m);inv=1.f/(e0+e1);float a10=e0*inv,a11=e1*inv;\n for(int d=tid;d<D;d+=blockDim.x){float v0=qkv[base0+2*E+d],v1=qkv[base1+2*E+d]; ctx[(b*2)*E+h*D+d]=a00*v0+a01*v1; ctx[(b*2+1)*E+h*D+d]=a10*v0+a11*v1;}\n}\n__global__ void add_ln_kernel(const float* __restrict__ x,const float* __restrict__ add,const float* __restrict__ gamma,const float* __restrict__ beta,float* __restrict__ out,int rows,int E){\n extern __shared__ float sh[]; int row=blockIdx.x,tid=threadIdx.x; float sum=0.f; for(int e=tid;e<E;e+=blockDim.x) sum+=x[row*E+e]+add[row*E+e]; sh[tid]=sum; __syncthreads(); for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sh[tid]+=sh[tid+s]; __syncthreads();} float mean=sh[0]/(float)E; float ss=0.f; for(int e=tid;e<E;e+=blockDim.x){float v=x[row*E+e]+add[row*E+e]-mean; ss+=v*v;} sh[tid]=ss; __syncthreads(); for(int s=blockDim.x/2;s>0;s>>=1){if(tid<s)sh[tid]+=sh[tid+s]; __syncthreads();} float rstd=rsqrtf(sh[0]/(float)E+1e-5f); for(int e=tid;e<E;e+=blockDim.x){float v=x[row*E+e]+add[row*E+e]; out[row*E+e]=(v-mean)*rstd*gamma[e]+beta[e];}\n}\n\ntorch::Tensor cvit_forward_cuda(torch::Tensor x, torch::Tensor conv_w, torch::Tensor conv_b, torch::Tensor lp_w, torch::Tensor lp_b, torch::Tensor cls, std::vector<torch::Tensor> layer_tensors, torch::Tensor fc_w, torch::Tensor fc_b, int64_t num_heads){\n int B=x.size(0),C=x.size(1),IH=x.size(2),IW=x.size(3),E=conv_w.size(0),Kp=conv_w.size(2),OH=IH/Kp,OW=IW/Kp,P=OH*OW; auto opts=x.options(); cudaStream_t stream=at::cuda::getCurrentCUDAStream(); int threads=256;\n auto conv=torch::empty({B,E,P},opts); auto z=torch::empty({B,E},opts); auto seq=torch::empty({B*2,E},opts);\n conv_patch_kernel<<<(B*E*P+threads-1)/threads,threads,0,stream>>>(x.data_ptr<float>(),conv_w.data_ptr<float>(),conv_b.data_ptr<float>(),conv.data_ptr<float>(),B,C,IH,IW,E,Kp,OH,OW);\n linear_kernel<<<dim3(B,E),threads,threads*sizeof(float),stream>>>(conv.data_ptr<float>(),lp_w.data_ptr<float>(),lp_b.data_ptr<float>(),z.data_ptr<float>(),B,E*P,E,0);\n make_seq_kernel<<<(B*2*E+threads-1)/threads,threads,0,stream>>>(z.data_ptr<float>(),cls.data_ptr<float>(),seq.data_ptr<float>(),B,E);\n int rows=B*2; auto qkv=torch::empty({rows,3*E},opts),ctx=torch::empty({rows,E},opts),proj=torch::empty({rows,E},opts),ff1=torch::empty({rows,(int)layer_tensors[9].size(0)},opts),ff2=torch::empty({rows,E},opts); int L=layer_tensors.size()/12;\n for(int l=0;l<L;++l){auto inpw=layer_tensors[l*12],inpb=layer_tensors[l*12+1],outw=layer_tensors[l*12+2],outb=layer_tensors[l*12+3],n1w=layer_tensors[l*12+4],n1b=layer_tensors[l*12+5],n2w=layer_tensors[l*12+6],n2b=layer_tensors[l*12+7],l1w=layer_tensors[l*12+8],l1b=layer_tensors[l*12+9],l2w=layer_tensors[l*12+10],l2b=layer_tensors[l*12+11];\n linear_kernel<<<dim3(rows,3*E),threads,threads*sizeof(float),stream>>>(seq.data_ptr<float>(),inpw.data_ptr<float>(),inpb.data_ptr<float>(),qkv.data_ptr<float>(),rows,E,3*E,0);\n attn2_kernel<<<dim3(B,(int)num_heads),64,64*sizeof(float),stream>>>(qkv.data_ptr<float>(),ctx.data_ptr<float>(),B,E,(int)num_heads);\n linear_kernel<<<dim3(rows,E),threads,threads*sizeof(float),stream>>>(ctx.data_ptr<float>(),outw.data_ptr<float>(),outb.data_ptr<float>(),proj.data_ptr<float>(),rows,E,E,0);\n add_ln_kernel<<<rows,threads,threads*sizeof(float),stream>>>(seq.data_ptr<float>(),proj.data_ptr<float>(),n1w.data_ptr<float>(),n1b.data_ptr<float>(),seq.data_ptr<float>(),rows,E);\n int F=l1b.size(0); linear_kernel<<<dim3(rows,F),threads,threads*sizeof(float),stream>>>(seq.data_ptr<float>(),l1w.data_ptr<float>(),l1b.data_ptr<float>(),ff1.data_ptr<float>(),rows,E,F,1);\n linear_kernel<<<dim3(rows,E),threads,threads*sizeof(float),stream>>>(ff1.data_ptr<float>(),l2w.data_ptr<float>(),l2b.data_ptr<float>(),ff2.data_ptr<float>(),rows,F,E,0);\n add_ln_kernel<<<rows,threads,threads*sizeof(float),stream>>>(seq.data_ptr<float>(),ff2.data_ptr<float>(),n2w.data_ptr<float>(),n2b.data_ptr<float>(),seq.data_ptr<float>(),rows,E);\n }\n int classes=fc_b.size(0); auto out=torch::empty({B,classes},opts); linear_strided_kernel<<<dim3(B,classes),threads,threads*sizeof(float),stream>>>(seq.data_ptr<float>(),fc_w.data_ptr<float>(),fc_b.data_ptr<float>(),out.data_ptr<float>(),B,E,classes,2*E); return out;\n}\n'''\n_ext = load_inline(name='cvit_ext_v2', cpp_sources=cpp_src, cuda_sources=cuda_src, functions=['cvit_forward_cuda'], extra_cuda_cflags=['-O3', '--use_fast_math'], verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self, num_classes, embed_dim=512, num_heads=8, num_layers=6, mlp_ratio=4.0, patch_size=4, in_channels=3, image_size=32):\n super(ModelNew,self).__init__(); self.patch_size=patch_size; self.image_size=image_size; self.embed_dim=embed_dim; self.num_heads=num_heads\n self.conv1=nn.Conv2d(in_channels,embed_dim,kernel_size=patch_size,stride=patch_size); num_patches=(image_size//patch_size)**2; self.linear_proj=nn.Linear(embed_dim*num_patches,embed_dim)\n self.transformer_layers=nn.ModuleList([nn.TransformerEncoderLayer(d_model=embed_dim,nhead=num_heads,dim_feedforward=int(embed_dim*mlp_ratio),dropout=0.0,batch_first=True) for _ in range(num_layers)])\n self.cls_token=nn.Parameter(torch.zeros(1,1,embed_dim)); self.fc_out=nn.Linear(embed_dim,num_classes)\n def forward(self,x):\n lt=[]\n for layer in self.transformer_layers:\n lt.extend([layer.self_attn.in_proj_weight,layer.self_attn.in_proj_bias,layer.self_attn.out_proj.weight,layer.self_attn.out_proj.bias,layer.norm1.weight,layer.norm1.bias,layer.norm2.weight,layer.norm2.bias,layer.linear1.weight,layer.linear1.bias,layer.linear2.weight,layer.linear2.bias])\n return _ext.cvit_forward_cuda(x,self.conv1.weight,self.conv1.bias,self.linear_proj.weight,self.linear_proj.bias,self.cls_token,lt,self.fc_out.weight,self.fc_out.bias,self.num_heads)\n"
}