call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = \"\"\"\n#include <torch/extension.h>\ntorch::Tensor add_relu_nchw(torch::Tensor x, torch::Tensor identity);\ntorch::Tensor bn_relu_nchw(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps);\ntorch::Tensor bn_add_relu_nchw(torch::Tensor x, torch::Tensor identity, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps);\ntorch::Tensor bn2_add_relu_nchw(torch::Tensor x, torch::Tensor id, torch::Tensor w1, torch::Tensor b1, torch::Tensor m1, torch::Tensor v1, torch::Tensor w2, torch::Tensor b2, torch::Tensor m2, torch::Tensor v2, double eps1, double eps2);\ntorch::Tensor avgpool_nchw(torch::Tensor x);\n\"\"\"\n_cuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void add_relu_kernel(const float* __restrict__ x, const float* __restrict__ id, float* __restrict__ y, int64_t total){\n int64_t idx=(int64_t)blockIdx.x*blockDim.x+threadIdx.x;\n if(idx<total){ float v=x[idx]+id[idx]; y[idx]=v>0.f?v:0.f; }\n}\n__global__ void bn_relu_kernel(const float* __restrict__ x, float* __restrict__ y,\n const float* __restrict__ w, const float* __restrict__ b,\n const float* __restrict__ mean, const float* __restrict__ var,\n int64_t total, int C, int HW, float eps) {\n int64_t idx = (int64_t)blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < total) {\n int c = (idx / HW) % C;\n float a = w[c] * rsqrtf(var[c] + eps);\n float val = (x[idx] - mean[c]) * a + b[c];\n y[idx] = val > 0.0f ? val : 0.0f;\n }\n}\n__global__ void bn_add_relu_kernel(const float* __restrict__ x, const float* __restrict__ id, float* __restrict__ y,\n const float* __restrict__ w, const float* __restrict__ b,\n const float* __restrict__ mean, const float* __restrict__ var,\n int64_t total, int C, int HW, float eps) {\n int64_t idx = (int64_t)blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < total) {\n int c = (idx / HW) % C;\n float a = w[c] * rsqrtf(var[c] + eps);\n float val = (x[idx] - mean[c]) * a + b[c] + id[idx];\n y[idx] = val > 0.0f ? val : 0.0f;\n }\n}\n__global__ void bn2_add_relu_kernel(const float* __restrict__ x, const float* __restrict__ id, float* __restrict__ y,\n const float* __restrict__ w1, const float* __restrict__ b1, const float* __restrict__ m1, const float* __restrict__ v1,\n const float* __restrict__ w2, const float* __restrict__ b2, const float* __restrict__ m2, const float* __restrict__ v2,\n int64_t total, int C, int HW, float eps1, float eps2) {\n int64_t idx = (int64_t)blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < total) {\n int c = (idx / HW) % C;\n float a1 = w1[c] * rsqrtf(v1[c] + eps1);\n float a2 = w2[c] * rsqrtf(v2[c] + eps2);\n float val = (x[idx] - m1[c]) * a1 + b1[c] + (id[idx] - m2[c]) * a2 + b2[c];\n y[idx] = val > 0.0f ? val : 0.0f;\n }\n}\n__global__ void avgpool_kernel(const float* __restrict__ x, float* __restrict__ y, int N, int C, int HW) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = N * C;\n if (idx < total) {\n float sum = 0.0f;\n const float* base = x + (int64_t)idx * HW;\n #pragma unroll\n for (int i = 0; i < 49; ++i) { if (i < HW) sum += base[i]; }\n y[idx] = sum / (float)HW;\n }\n}\ntorch::Tensor add_relu_nchw(torch::Tensor x, torch::Tensor identity){\n auto y=torch::empty_like(x); int64_t total=x.numel(); int threads=256; int blocks=(int)((total+threads-1)/threads);\n add_relu_kernel<<<blocks,threads,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),identity.data_ptr<float>(),y.data_ptr<float>(),total); return y;\n}\ntorch::Tensor bn_relu_nchw(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps) {\n auto y = torch::empty_like(x); int64_t total = x.numel(); int C = (int)x.size(1); int HW=(int)(x.size(2)*x.size(3)); int threads = 256; int blocks = (int)((total + threads - 1) / threads);\n bn_relu_kernel<<<blocks, threads, 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;\n}\ntorch::Tensor bn_add_relu_nchw(torch::Tensor x, torch::Tensor identity, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps) {\n auto y = torch::empty_like(x); int64_t total = x.numel(); int C = (int)x.size(1); int HW=(int)(x.size(2)*x.size(3)); int threads = 256; int blocks = (int)((total + threads - 1) / threads);\n bn_add_relu_kernel<<<blocks, threads, 0, at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(), identity.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;\n}\ntorch::Tensor bn2_add_relu_nchw(torch::Tensor x, torch::Tensor id, torch::Tensor w1, torch::Tensor b1, torch::Tensor m1, torch::Tensor v1, torch::Tensor w2, torch::Tensor b2, torch::Tensor m2, torch::Tensor v2, double eps1, double eps2) {\n auto y = torch::empty_like(x); int64_t total = x.numel(); int C = (int)x.size(1); int HW=(int)(x.size(2)*x.size(3)); int threads = 256; int blocks = (int)((total + threads - 1) / threads);\n bn2_add_relu_kernel<<<blocks, threads, 0, at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(), id.data_ptr<float>(), y.data_ptr<float>(), w1.data_ptr<float>(), b1.data_ptr<float>(), m1.data_ptr<float>(), v1.data_ptr<float>(), w2.data_ptr<float>(), b2.data_ptr<float>(), m2.data_ptr<float>(), v2.data_ptr<float>(), total, C, HW, (float)eps1, (float)eps2); return y;\n}\ntorch::Tensor avgpool_nchw(torch::Tensor x) {\n int N=(int)x.size(0), C=(int)x.size(1), HW=(int)(x.size(2)*x.size(3)); auto y=torch::empty({N,C},x.options()); int total=N*C; int threads=256; int blocks=(total+threads-1)/threads;\n avgpool_kernel<<<blocks,threads,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),N,C,HW); return y;\n}\n'''\n_ext=load_inline(name='resnet18_nchw_fused_v1',cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=['add_relu_nchw','bn_relu_nchw','bn_add_relu_nchw','bn2_add_relu_nchw','avgpool_nchw'],extra_cuda_cflags=['-O3'],extra_cflags=['-O3'],verbose=False)\n\nclass BasicBlock(nn.Module):\n expansion=1\n def __init__(self,in_channels,out_channels,stride=1,downsample=None):\n super(BasicBlock,self).__init__(); self.conv1=nn.Conv2d(in_channels,out_channels,3,stride,1,bias=False); self.bn1=nn.BatchNorm2d(out_channels); self.relu=nn.ReLU(inplace=True); self.conv2=nn.Conv2d(out_channels,out_channels,3,1,1,bias=False); self.bn2=nn.BatchNorm2d(out_channels); self.downsample=downsample; self.stride=stride\n def forward(self,x):\n identity=x; out=self.conv1(x); out=self.bn1(out); out=self.relu(out); out=self.conv2(out); out=self.bn2(out)\n if self.downsample is not None: identity=self.downsample(x)\n return _ext.add_relu_nchw(out, identity)\nclass ModelNew(nn.Module):\n def __init__(self,num_classes=1000):\n super(ModelNew,self).__init__(); self.in_channels=64; self.conv1=nn.Conv2d(3,64,7,2,3,bias=False); self.bn1=nn.BatchNorm2d(64); self.relu=nn.ReLU(inplace=True); self.maxpool=nn.MaxPool2d(3,2,1); self.layer1=self._make_layer(BasicBlock,64,2,1); self.layer2=self._make_layer(BasicBlock,128,2,2); self.layer3=self._make_layer(BasicBlock,256,2,2); self.layer4=self._make_layer(BasicBlock,512,2,2); self.avgpool=nn.AdaptiveAvgPool2d((1,1)); self.fc=nn.Linear(512*BasicBlock.expansion,num_classes)\n def _make_layer(self,block,out_channels,blocks,stride=1):\n downsample=None\n if stride!=1 or self.in_channels!=out_channels*block.expansion: downsample=nn.Sequential(nn.Conv2d(self.in_channels,out_channels*block.expansion,1,stride,bias=False),nn.BatchNorm2d(out_channels*block.expansion))\n layers=[block(self.in_channels,out_channels,stride,downsample)]; self.in_channels=out_channels*block.expansion\n for _ in range(1,blocks): layers.append(block(self.in_channels,out_channels))\n return nn.Sequential(*layers)\n def _block_eval(self,x,b):\n identity=x; out=b.conv1(x); out=_ext.bn_relu_nchw(out,b.bn1.weight,b.bn1.bias,b.bn1.running_mean,b.bn1.running_var,b.bn1.eps); out=b.conv2(out)\n if b.downsample is not None:\n ident=b.downsample[0](x); return _ext.bn2_add_relu_nchw(out,ident,b.bn2.weight,b.bn2.bias,b.bn2.running_mean,b.bn2.running_var,b.downsample[1].weight,b.downsample[1].bias,b.downsample[1].running_mean,b.downsample[1].running_var,b.bn2.eps,b.downsample[1].eps)\n return _ext.bn_add_relu_nchw(out,identity,b.bn2.weight,b.bn2.bias,b.bn2.running_mean,b.bn2.running_var,b.bn2.eps)\n def _forward_eval(self,x):\n x=self.conv1(x); x=_ext.bn_relu_nchw(x,self.bn1.weight,self.bn1.bias,self.bn1.running_mean,self.bn1.running_var,self.bn1.eps); x=self.maxpool(x)\n for b in self.layer1: x=self._block_eval(x,b)\n for b in self.layer2: x=self._block_eval(x,b)\n for b in self.layer3: x=self._block_eval(x,b)\n for b in self.layer4: x=self._block_eval(x,b)\n return self.fc(_ext.avgpool_nchw(x))\n def forward(self,x):\n if self.training:\n x=self.conv1(x); x=self.bn1(x); x=self.relu(x); x=self.maxpool(x); x=self.layer1(x); x=self.layer2(x); x=self.layer3(x); x=self.layer4(x); x=_ext.avgpool_nchw(x); x=self.fc(x); return x\n return self._forward_eval(x)\n"
}