call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = r'''\n#include <torch/extension.h>\ntorch::Tensor bn_relu_eval_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps);\ntorch::Tensor bn_eval_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps);\ntorch::Tensor bn_shuffle_eval_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, int64_t groups, double eps);\ntorch::Tensor add_cuda(torch::Tensor a, torch::Tensor b);\ntorch::Tensor bn_relu_avg_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps);\ntorch::Tensor bn_relu_train_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, double eps);\ntorch::Tensor bn_train_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, double eps);\ntorch::Tensor bn_shuffle_train_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, int64_t groups, double eps);\ntorch::Tensor bn_relu_avg_train_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, double eps);\n'''\n\n_cuda_src = r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <ATen/cuda/CUDAContext.h>\n\n__global__ void bn_relu_kernel(const float* __restrict__ x, float* __restrict__ y,const float* __restrict__ w,const float* __restrict__ b,const float* __restrict__ m,const float* __restrict__ v,int total,int C,int HW,float eps){int idx=blockIdx.x*blockDim.x+threadIdx.x; if(idx<total){int c=(idx/HW)%C; float val=(x[idx]-m[c])*(w[c]*rsqrtf(v[c]+eps))+b[c]; y[idx]=val>0.f?val:0.f;}}\n__global__ void bn_kernel(const float* __restrict__ x, float* __restrict__ y,const float* __restrict__ w,const float* __restrict__ b,const float* __restrict__ m,const float* __restrict__ v,int total,int C,int HW,float eps){int idx=blockIdx.x*blockDim.x+threadIdx.x; if(idx<total){int c=(idx/HW)%C; y[idx]=(x[idx]-m[c])*(w[c]*rsqrtf(v[c]+eps))+b[c];}}\n__global__ void bn_shuffle_kernel(const float* __restrict__ x,float* __restrict__ y,const float* __restrict__ w,const float* __restrict__ b,const float* __restrict__ m,const float* __restrict__ v,int total,int C,int HW,int groups,float eps){int out_idx=blockIdx.x*blockDim.x+threadIdx.x; if(out_idx<total){int hw=out_idx%HW; int tmp=out_idx/HW; int oc=tmp%C; int n=tmp/C; int cpg=C/groups; int cp=oc/groups; int gr=oc-cp*groups; int ic=gr*cpg+cp; int ii=(n*C+ic)*HW+hw; y[out_idx]=(x[ii]-m[ic])*(w[ic]*rsqrtf(v[ic]+eps))+b[ic];}}\n__global__ void add_kernel(const float* __restrict__ a,const float* __restrict__ b,float* __restrict__ y,int total){int idx=blockIdx.x*blockDim.x+threadIdx.x; if(idx<total)y[idx]=a[idx]+b[idx];}\n__global__ void bn_relu_avg_kernel(const float* __restrict__ x,float* __restrict__ y,const float* __restrict__ w,const float* __restrict__ b,const float* __restrict__ m,const float* __restrict__ v,int N,int C,int HW,float eps){int nc=blockIdx.x; int c=nc%C; int n=nc/C; const float* base=x+(n*C+c)*HW; float sc=w[c]*rsqrtf(v[c]+eps), sum=0.f; for(int i=threadIdx.x;i<HW;i+=blockDim.x){float val=(base[i]-m[c])*sc+b[c]; sum+=val>0.f?val:0.f;} __shared__ float sm[256]; sm[threadIdx.x]=sum; __syncthreads(); for(int s=128;s>0;s>>=1){if(threadIdx.x<s)sm[threadIdx.x]+=sm[threadIdx.x+s]; __syncthreads();} if(threadIdx.x==0)y[n*C+c]=sm[0]/(float)HW;}\n\ntemplate<int RELU, int SHUFFLE>\n__global__ void bn_train_ch_kernel(const float* __restrict__ x,float* __restrict__ y,const float* __restrict__ w,const float* __restrict__ b,int N,int C,int HW,int groups,float eps){\n int c=blockIdx.x; int M=N*HW; float sum=0.f, ss=0.f;\n for(int j=threadIdx.x;j<M;j+=blockDim.x){int n=j/HW; int hw=j-n*HW; float val=x[(n*C+c)*HW+hw]; sum+=val; ss+=val*val;}\n __shared__ float sm[512]; sm[threadIdx.x]=sum; sm[threadIdx.x+blockDim.x]=ss; __syncthreads();\n for(int s=blockDim.x/2;s>0;s>>=1){if(threadIdx.x<s){sm[threadIdx.x]+=sm[threadIdx.x+s]; sm[threadIdx.x+blockDim.x]+=sm[threadIdx.x+blockDim.x+s];} __syncthreads();}\n float mean=sm[0]/(float)M; float var=sm[blockDim.x]/(float)M - mean*mean; if(var<0.f) var=0.f; float sc=w[c]*rsqrtf(var+eps); float bb=b[c];\n int oc=c; if(SHUFFLE){int cpg=C/groups; int gr=c/cpg; int cp=c-gr*cpg; oc=cp*groups+gr;}\n for(int j=threadIdx.x;j<M;j+=blockDim.x){int n=j/HW; int hw=j-n*HW; float val=(x[(n*C+c)*HW+hw]-mean)*sc+bb; if(RELU) val=val>0.f?val:0.f; y[(n*C+oc)*HW+hw]=val;}\n}\n\n__global__ void bn_relu_avg_train_kernel(const float* __restrict__ x,float* __restrict__ y,const float* __restrict__ w,const float* __restrict__ b,int N,int C,int HW,float eps){\n int c=blockIdx.x; int M=N*HW; float sum=0.f, ss=0.f;\n for(int j=threadIdx.x;j<M;j+=blockDim.x){int n=j/HW; int hw=j-n*HW; float val=x[(n*C+c)*HW+hw]; sum+=val; ss+=val*val;}\n __shared__ float sm[512]; sm[threadIdx.x]=sum; sm[threadIdx.x+blockDim.x]=ss; __syncthreads();\n for(int s=blockDim.x/2;s>0;s>>=1){if(threadIdx.x<s){sm[threadIdx.x]+=sm[threadIdx.x+s]; sm[threadIdx.x+blockDim.x]+=sm[threadIdx.x+blockDim.x+s];} __syncthreads();}\n float mean=sm[0]/(float)M; float var=sm[blockDim.x]/(float)M - mean*mean; if(var<0.f) var=0.f; float sc=w[c]*rsqrtf(var+eps); float bb=b[c];\n for(int n=0;n<N;n++){float s=0.f; const float* base=x+(n*C+c)*HW; for(int i=threadIdx.x;i<HW;i+=blockDim.x){float val=(base[i]-mean)*sc+bb; s+=val>0.f?val:0.f;} sm[threadIdx.x]=s; __syncthreads(); for(int stride=blockDim.x/2;stride>0;stride>>=1){if(threadIdx.x<stride)sm[threadIdx.x]+=sm[threadIdx.x+stride]; __syncthreads();} if(threadIdx.x==0)y[n*C+c]=sm[0]/(float)HW; __syncthreads();}\n}\n\ntorch::Tensor bn_relu_eval_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,torch::Tensor mean,torch::Tensor var,double eps){auto y=torch::empty_like(x); int total=x.numel(),C=x.size(1),HW=x.size(2)*x.size(3); int th=256, bl=(total+th-1)/th; bn_relu_kernel<<<bl,th,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),mean.data_ptr<float>(),var.data_ptr<float>(),total,C,HW,(float)eps); return y;}\ntorch::Tensor bn_eval_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,torch::Tensor mean,torch::Tensor var,double eps){auto y=torch::empty_like(x); int total=x.numel(),C=x.size(1),HW=x.size(2)*x.size(3); int th=256, bl=(total+th-1)/th; bn_kernel<<<bl,th,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),mean.data_ptr<float>(),var.data_ptr<float>(),total,C,HW,(float)eps); return y;}\ntorch::Tensor bn_shuffle_eval_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,torch::Tensor mean,torch::Tensor var,int64_t groups,double eps){auto y=torch::empty_like(x); int total=x.numel(),C=x.size(1),HW=x.size(2)*x.size(3); int th=256, bl=(total+th-1)/th; bn_shuffle_kernel<<<bl,th,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),mean.data_ptr<float>(),var.data_ptr<float>(),total,C,HW,(int)groups,(float)eps); return y;}\ntorch::Tensor add_cuda(torch::Tensor a,torch::Tensor b){auto y=torch::empty_like(a); int total=a.numel(), th=256, bl=(total+th-1)/th; add_kernel<<<bl,th,0,at::cuda::getCurrentCUDAStream()>>>(a.data_ptr<float>(),b.data_ptr<float>(),y.data_ptr<float>(),total); return y;}\ntorch::Tensor bn_relu_avg_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,torch::Tensor mean,torch::Tensor var,double eps){int N=x.size(0),C=x.size(1),HW=x.size(2)*x.size(3); auto y=torch::empty({N,C},x.options()); bn_relu_avg_kernel<<<N*C,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),mean.data_ptr<float>(),var.data_ptr<float>(),N,C,HW,(float)eps); return y;}\ntorch::Tensor bn_relu_train_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,double eps){auto y=torch::empty_like(x); int N=x.size(0),C=x.size(1),HW=x.size(2)*x.size(3); bn_train_ch_kernel<1,0><<<C,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),N,C,HW,1,(float)eps); return y;}\ntorch::Tensor bn_train_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,double eps){auto y=torch::empty_like(x); int N=x.size(0),C=x.size(1),HW=x.size(2)*x.size(3); bn_train_ch_kernel<0,0><<<C,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),N,C,HW,1,(float)eps); return y;}\ntorch::Tensor bn_shuffle_train_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,int64_t groups,double eps){auto y=torch::empty_like(x); int N=x.size(0),C=x.size(1),HW=x.size(2)*x.size(3); bn_train_ch_kernel<0,1><<<C,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),N,C,HW,(int)groups,(float)eps); return y;}\ntorch::Tensor bn_relu_avg_train_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,double eps){int N=x.size(0),C=x.size(1),HW=x.size(2)*x.size(3); auto y=torch::empty({N,C},x.options()); bn_relu_avg_train_kernel<<<C,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),N,C,HW,(float)eps); return y;}\n'''\n\n_ext = load_inline(name='shufflenet_ext_v2', cpp_sources=[_cpp_src], cuda_sources=[_cuda_src], functions=['bn_relu_eval_cuda','bn_eval_cuda','bn_shuffle_eval_cuda','add_cuda','bn_relu_avg_cuda','bn_relu_train_cuda','bn_train_cuda','bn_shuffle_train_cuda','bn_relu_avg_train_cuda'], extra_cflags=['-O3'], extra_cuda_cflags=['-O3'], verbose=False)\n\nclass ChannelShuffle(nn.Module):\n def __init__(self, groups): super().__init__(); self.groups=groups\n def forward(self,x):\n n,c,h,w=x.size(); g=self.groups\n return x.view(n,g,c//g,h,w).transpose(1,2).contiguous().view(n,c,h,w)\n\nclass ShuffleNetUnitNew(nn.Module):\n def __init__(self,in_channels,out_channels,groups=3):\n super().__init__(); assert out_channels%4==0; mid=out_channels//4; self.groups=groups\n self.conv1=nn.Conv2d(in_channels,mid,1,1,0,groups=groups,bias=False); self.bn1=nn.BatchNorm2d(mid)\n self.conv2=nn.Conv2d(mid,mid,3,1,1,groups=mid,bias=False); self.bn2=nn.BatchNorm2d(mid)\n self.conv3=nn.Conv2d(mid,out_channels,1,1,0,groups=groups,bias=False); self.bn3=nn.BatchNorm2d(out_channels)\n self.shuffle=ChannelShuffle(groups)\n self.shortcut=nn.Sequential() if in_channels==out_channels else nn.Sequential(nn.Conv2d(in_channels,out_channels,1,1,0,bias=False),nn.BatchNorm2d(out_channels))\n def forward(self,x):\n if x.dtype!=torch.float32 or not x.is_cuda:\n out=F.relu(self.bn1(self.conv1(x))); out=self.shuffle(self.bn2(self.conv2(out))); out=F.relu(self.bn3(self.conv3(out))); return out+self.shortcut(x)\n out=F.conv2d(x,self.conv1.weight,None,1,0,1,self.conv1.groups)\n out=(_ext.bn_relu_train_cuda(out,self.bn1.weight,self.bn1.bias,self.bn1.eps) if self.training else _ext.bn_relu_eval_cuda(out,self.bn1.weight,self.bn1.bias,self.bn1.running_mean,self.bn1.running_var,self.bn1.eps))\n out=F.conv2d(out,self.conv2.weight,None,1,1,1,self.conv2.groups)\n out=(_ext.bn_shuffle_train_cuda(out,self.bn2.weight,self.bn2.bias,self.groups,self.bn2.eps) if self.training else _ext.bn_shuffle_eval_cuda(out,self.bn2.weight,self.bn2.bias,self.bn2.running_mean,self.bn2.running_var,self.groups,self.bn2.eps))\n out=F.conv2d(out,self.conv3.weight,None,1,0,1,self.conv3.groups)\n out=(_ext.bn_relu_train_cuda(out,self.bn3.weight,self.bn3.bias,self.bn3.eps) if self.training else _ext.bn_relu_eval_cuda(out,self.bn3.weight,self.bn3.bias,self.bn3.running_mean,self.bn3.running_var,self.bn3.eps))\n if len(self.shortcut)==0: sc=x\n else:\n sc=F.conv2d(x,self.shortcut[0].weight,None,1,0,1,1)\n sc=(_ext.bn_train_cuda(sc,self.shortcut[1].weight,self.shortcut[1].bias,self.shortcut[1].eps) if self.training else _ext.bn_eval_cuda(sc,self.shortcut[1].weight,self.shortcut[1].bias,self.shortcut[1].running_mean,self.shortcut[1].running_var,self.shortcut[1].eps))\n return _ext.add_cuda(out,sc)\n\nclass ModelNew(nn.Module):\n def __init__(self,num_classes=1000,groups=3,stages_repeats=[3,7,3],stages_out_channels=[24,240,480,960]):\n super().__init__(); self.conv1=nn.Conv2d(3,stages_out_channels[0],3,2,1,bias=False); self.bn1=nn.BatchNorm2d(stages_out_channels[0]); self.maxpool=nn.MaxPool2d(3,2,1)\n self.stage2=self._make_stage(stages_out_channels[0],stages_out_channels[1],stages_repeats[0],groups); self.stage3=self._make_stage(stages_out_channels[1],stages_out_channels[2],stages_repeats[1],groups); self.stage4=self._make_stage(stages_out_channels[2],stages_out_channels[3],stages_repeats[2],groups)\n self.conv5=nn.Conv2d(stages_out_channels[3],1024,1,1,0,bias=False); self.bn5=nn.BatchNorm2d(1024); self.fc=nn.Linear(1024,num_classes)\n def _make_stage(self,ic,oc,repeats,groups): return nn.Sequential(*([ShuffleNetUnitNew(ic,oc,groups)]+[ShuffleNetUnitNew(oc,oc,groups) for _ in range(1,repeats)]))\n def forward(self,x):\n if x.dtype!=torch.float32 or not x.is_cuda:\n x=F.relu(self.bn1(self.conv1(x))); x=self.maxpool(x); x=self.stage2(x); x=self.stage3(x); x=self.stage4(x); x=F.relu(self.bn5(self.conv5(x))); x=F.adaptive_avg_pool2d(x,(1,1)); return self.fc(x.view(x.size(0),-1))\n x=F.conv2d(x,self.conv1.weight,None,2,1,1,1)\n x=(_ext.bn_relu_train_cuda(x,self.bn1.weight,self.bn1.bias,self.bn1.eps) if self.training else _ext.bn_relu_eval_cuda(x,self.bn1.weight,self.bn1.bias,self.bn1.running_mean,self.bn1.running_var,self.bn1.eps))\n x=F.max_pool2d(x,3,2,1); x=self.stage2(x); x=self.stage3(x); x=self.stage4(x); x=F.conv2d(x,self.conv5.weight,None,1,0,1,1)\n x=(_ext.bn_relu_avg_train_cuda(x,self.bn5.weight,self.bn5.bias,self.bn5.eps) if self.training else _ext.bn_relu_avg_cuda(x,self.bn5.weight,self.bn5.bias,self.bn5.running_mean,self.bn5.running_var,self.bn5.eps))\n return F.linear(x,self.fc.weight,self.fc.bias)\n"
}