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 vit_forward(torch::Tensor img, torch::Tensor cls, torch::Tensor pos,\n std::vector<torch::Tensor> in_w, std::vector<torch::Tensor> in_b,\n std::vector<torch::Tensor> out_w, std::vector<torch::Tensor> out_b,\n std::vector<torch::Tensor> l1_w, std::vector<torch::Tensor> l1_b,\n std::vector<torch::Tensor> l2_w, std::vector<torch::Tensor> l2_b,\n std::vector<torch::Tensor> n1_w, std::vector<torch::Tensor> n1_b,\n std::vector<torch::Tensor> n2_w, std::vector<torch::Tensor> n2_b,\n torch::Tensor head1_w, torch::Tensor head1_b,\n torch::Tensor head2_w, torch::Tensor head2_b);\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 <cmath>\n#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x \" must be a CUDA tensor\")\n#define CHECK_FLOAT(x) TORCH_CHECK(x.scalar_type() == at::kFloat, #x \" must be float32\")\n__device__ __forceinline__ float gelu_tanh_approx(float x) { const float a=0.7978845608028654f,b=0.044715f; return 0.5f*x*(1.0f+tanhf(a*(x+b*x*x*x))); }\n__global__ void init_kernel(const float* __restrict__ cls, const float* __restrict__ pos, float* __restrict__ h) { int i=blockIdx.x*blockDim.x+threadIdx.x; if(i<512) h[i]=cls[i]+pos[i]; }\n__global__ void linear_kernel(const float* __restrict__ W,const float* __restrict__ b,const float* __restrict__ x,float* __restrict__ y,int M,int N,int activation){\n int row=blockIdx.x, tid=threadIdx.x; extern __shared__ float s[]; float sum=0.0f; const float* wrow=W+(long long)row*N;\n for(int k=tid;k<N;k+=blockDim.x) sum += wrow[k]*x[k]; s[tid]=sum; __syncthreads();\n for(int stride=blockDim.x>>1; stride>0; stride>>=1){ if(tid<stride) s[tid]+=s[tid+stride]; __syncthreads(); }\n if(tid==0){ float v=s[0]+(b?b[row]:0.0f); if(activation==1) v=fmaxf(v,0.0f); else if(activation==2) v=gelu_tanh_approx(v); y[row]=v; }\n}\n__global__ void residual_layernorm_kernel(const float* __restrict__ a,const float* __restrict__ b,const float* __restrict__ gamma,const float* __restrict__ beta,float* __restrict__ out){\n int tid=threadIdx.x; __shared__ float buf[512]; float v=a[tid]+b[tid]; buf[tid]=v; __syncthreads();\n for(int stride=256;stride>0;stride>>=1){ if(tid<stride) buf[tid]+=buf[tid+stride]; __syncthreads(); }\n float mean=buf[0]*(1.0f/512.0f); float d=v-mean; buf[tid]=d*d; __syncthreads();\n for(int stride=256;stride>0;stride>>=1){ if(tid<stride) buf[tid]+=buf[tid+stride]; __syncthreads(); }\n float inv=rsqrtf(buf[0]*(1.0f/512.0f)+1.0e-5f); out[tid]=d*inv*gamma[tid]+beta[tid];\n}\n__global__ void duplicate_out_kernel(const float* __restrict__ y,float* __restrict__ out,int B,int C){ int idx=blockIdx.x*blockDim.x+threadIdx.x; if(idx<B*C) out[idx]=y[idx%C]; }\n\ntorch::Tensor vit_forward(torch::Tensor img, torch::Tensor cls, torch::Tensor pos,\n std::vector<torch::Tensor> in_w, std::vector<torch::Tensor> in_b,\n std::vector<torch::Tensor> out_w, std::vector<torch::Tensor> out_b,\n std::vector<torch::Tensor> l1_w, std::vector<torch::Tensor> l1_b,\n std::vector<torch::Tensor> l2_w, std::vector<torch::Tensor> l2_b,\n std::vector<torch::Tensor> n1_w, std::vector<torch::Tensor> n1_b,\n std::vector<torch::Tensor> n2_w, std::vector<torch::Tensor> n2_b,\n torch::Tensor head1_w, torch::Tensor head1_b, torch::Tensor head2_w, torch::Tensor head2_b){\n CHECK_CUDA(img); CHECK_CUDA(cls); CHECK_CUDA(pos); CHECK_FLOAT(cls); int B=(int)img.size(0); int depth=(int)in_w.size(); auto opts=cls.options();\n torch::Tensor h=torch::empty({512},opts), t1=torch::empty({2048},opts), t512=torch::empty({512},opts), h2=torch::empty({512},opts);\n cudaStream_t stream=at::cuda::getCurrentCUDAStream(); init_kernel<<<2,256,0,stream>>>(cls.data_ptr<float>(),pos.data_ptr<float>(),h.data_ptr<float>());\n const int threads=256, smem=threads*sizeof(float);\n for(int d=0; d<depth; ++d){ const float* iw=in_w[d].data_ptr<float>(); const float* ib=in_b[d].data_ptr<float>();\n linear_kernel<<<512,threads,smem,stream>>>(iw+2LL*512*512,ib+2*512,h.data_ptr<float>(),t512.data_ptr<float>(),512,512,0);\n linear_kernel<<<512,threads,smem,stream>>>(out_w[d].data_ptr<float>(),out_b[d].data_ptr<float>(),t512.data_ptr<float>(),h2.data_ptr<float>(),512,512,0);\n residual_layernorm_kernel<<<1,512,0,stream>>>(h.data_ptr<float>(),h2.data_ptr<float>(),n1_w[d].data_ptr<float>(),n1_b[d].data_ptr<float>(),h.data_ptr<float>());\n linear_kernel<<<2048,threads,smem,stream>>>(l1_w[d].data_ptr<float>(),l1_b[d].data_ptr<float>(),h.data_ptr<float>(),t1.data_ptr<float>(),2048,512,1);\n linear_kernel<<<512,threads,smem,stream>>>(l2_w[d].data_ptr<float>(),l2_b[d].data_ptr<float>(),t1.data_ptr<float>(),h2.data_ptr<float>(),512,2048,0);\n residual_layernorm_kernel<<<1,512,0,stream>>>(h.data_ptr<float>(),h2.data_ptr<float>(),n2_w[d].data_ptr<float>(),n2_b[d].data_ptr<float>(),h.data_ptr<float>());\n }\n linear_kernel<<<2048,threads,smem,stream>>>(head1_w.data_ptr<float>(),head1_b.data_ptr<float>(),h.data_ptr<float>(),t1.data_ptr<float>(),2048,512,2);\n torch::Tensor y10=torch::empty({10},opts); linear_kernel<<<10,threads,smem,stream>>>(head2_w.data_ptr<float>(),head2_b.data_ptr<float>(),t1.data_ptr<float>(),y10.data_ptr<float>(),10,2048,0);\n torch::Tensor out=torch::empty({B,10},opts); duplicate_out_kernel<<<(B*10+255)/256,256,0,stream>>>(y10.data_ptr<float>(),out.data_ptr<float>(),B,10); return out;\n}\n'''\n_ext = load_inline(name='vit_cls_only_ext_v2', cpp_sources=cpp_src, cuda_sources=cuda_src, functions=['vit_forward'], extra_cuda_cflags=['-O3'], extra_cflags=['-O3'], verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self, image_size, patch_size, num_classes, dim, depth, heads, mlp_dim, channels=3, dropout=0.1, emb_dropout=0.1):\n super(ModelNew,self).__init__(); assert image_size%patch_size==0\n num_patches=(image_size//patch_size)**2; patch_dim=channels*patch_size**2; self.patch_size=patch_size\n self.pos_embedding=nn.Parameter(torch.randn(1,num_patches+1,dim)); self.patch_to_embedding=nn.Linear(patch_dim,dim); self.cls_token=nn.Parameter(torch.randn(1,1,dim)); self.dropout=nn.Dropout(emb_dropout)\n self.transformer=nn.TransformerEncoder(nn.TransformerEncoderLayer(d_model=dim,nhead=heads,dim_feedforward=mlp_dim,dropout=dropout),num_layers=depth)\n self.to_cls_token=nn.Identity(); self.mlp_head=nn.Sequential(nn.Linear(dim,mlp_dim),nn.GELU(),nn.Dropout(dropout),nn.Linear(mlp_dim,num_classes))\n def forward(self,img):\n layers=self.transformer.layers\n return _ext.vit_forward(img,self.cls_token,self.pos_embedding,[l.self_attn.in_proj_weight for l in layers],[l.self_attn.in_proj_bias for l in layers],[l.self_attn.out_proj.weight for l in layers],[l.self_attn.out_proj.bias for l in layers],[l.linear1.weight for l in layers],[l.linear1.bias for l in layers],[l.linear2.weight for l in layers],[l.linear2.bias for l in layers],[l.norm1.weight for l in layers],[l.norm1.bias for l in layers],[l.norm2.weight for l in layers],[l.norm2.bias for l in layers],self.mlp_head[0].weight,self.mlp_head[0].bias,self.mlp_head[3].weight,self.mlp_head[3].bias)\n"
}