call → submit_kernel
callsubmit_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>\n\ntorch::Tensor bn_act_(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor mean, torch::Tensor var, double eps, int act);\ntorch::Tensor bn_add_(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor mean, torch::Tensor var, torch::Tensor residual, double eps);\ntorch::Tensor avgpool2d(torch::Tensor x);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda_runtime.h>\n\n__global__ void bn_act_ch_kernel(float* __restrict__ x,\n const float* __restrict__ weight,\n const float* __restrict__ bias,\n const float* __restrict__ mean,\n const float* __restrict__ var,\n int C, int HW, float eps, int act) {\n int nc = blockIdx.x;\n int c = nc % C;\n long base = (long)nc * (long)HW;\n float scale = weight[c] * rsqrtf(var[c] + eps);\n float shift = bias[c] - mean[c] * scale;\n for (int i = threadIdx.x; i < HW; i += blockDim.x) {\n float v = fmaf(x[base + i], scale, shift);\n if (act == 1) {\n v = v > 0.0f ? v : 0.0f;\n } else if (act == 2) {\n v = v > 0.0f ? v : 0.0f;\n v = v < 6.0f ? v : 6.0f;\n }\n x[base + i] = v;\n }\n}\n\n__global__ void bn_add_ch_kernel(float* __restrict__ x,\n const float* __restrict__ weight,\n const float* __restrict__ bias,\n const float* __restrict__ mean,\n const float* __restrict__ var,\n const float* __restrict__ residual,\n int C, int HW, float eps) {\n int nc = blockIdx.x;\n int c = nc % C;\n long base = (long)nc * (long)HW;\n float scale = weight[c] * rsqrtf(var[c] + eps);\n float shift = bias[c] - mean[c] * scale;\n for (int i = threadIdx.x; i < HW; i += blockDim.x) {\n float v = fmaf(x[base + i], scale, shift);\n x[base + i] = v + residual[base + i];\n }\n}\n\n__global__ void avgpool_ch_kernel(const float* __restrict__ x,\n float* __restrict__ out,\n int C, int HW) {\n int nc = blockIdx.x;\n long base = (long)nc * (long)HW;\n float sum = 0.0f;\n for (int i = threadIdx.x; i < HW; i += blockDim.x) {\n sum += x[base + i];\n }\n __shared__ float smem[256];\n smem[threadIdx.x] = sum;\n __syncthreads();\n for (int stride = blockDim.x >> 1; stride > 0; stride >>= 1) {\n if (threadIdx.x < stride) smem[threadIdx.x] += smem[threadIdx.x + stride];\n __syncthreads();\n }\n if (threadIdx.x == 0) out[nc] = smem[0] / (float)HW;\n}\n\ntorch::Tensor bn_act_(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor mean, torch::Tensor var, double eps, int act) {\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int H = (int)x.size(2);\n const int W = (int)x.size(3);\n const int HW = H * W;\n const int blocks = N * C;\n bn_act_ch_kernel<<<blocks, 256, 0, at::cuda::getCurrentCUDAStream()>>>(\n x.data_ptr<float>(), weight.data_ptr<float>(), bias.data_ptr<float>(),\n mean.data_ptr<float>(), var.data_ptr<float>(), C, HW, (float)eps, act);\n return x;\n}\n\ntorch::Tensor bn_add_(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor mean, torch::Tensor var, torch::Tensor residual, double eps) {\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int H = (int)x.size(2);\n const int W = (int)x.size(3);\n const int HW = H * W;\n const int blocks = N * C;\n bn_add_ch_kernel<<<blocks, 256, 0, at::cuda::getCurrentCUDAStream()>>>(\n x.data_ptr<float>(), weight.data_ptr<float>(), bias.data_ptr<float>(),\n mean.data_ptr<float>(), var.data_ptr<float>(), residual.data_ptr<float>(),\n C, HW, (float)eps);\n return x;\n}\n\ntorch::Tensor avgpool2d(torch::Tensor x) {\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int H = (int)x.size(2);\n const int W = (int)x.size(3);\n const int HW = H * W;\n auto out = torch::empty({N, C}, x.options());\n avgpool_ch_kernel<<<N * C, 256, 0, at::cuda::getCurrentCUDAStream()>>>(\n x.data_ptr<float>(), out.data_ptr<float>(), C, HW);\n return out;\n}\n\"\"\"\n\n_effnet_fused = load_inline(\n name=\"effnet_b0_fused_bn_relu_ext\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"bn_act_\", \"bn_add_\", \"avgpool2d\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\"],\n verbose=False,\n)\n\n\nclass _MBConvNew(nn.Module):\n def __init__(self, in_channels, out_channels, kernel_size, stride, expand_ratio):\n super(_MBConvNew, self).__init__()\n self.use_residual = (stride == 1 and in_channels == out_channels)\n hidden_dim = in_channels * expand_ratio\n if expand_ratio != 1:\n self.expand_conv = nn.Sequential(\n nn.Conv2d(in_channels, hidden_dim, kernel_size=1, stride=1, padding=0, bias=False),\n nn.BatchNorm2d(hidden_dim),\n nn.ReLU6(inplace=True),\n )\n self.depthwise_conv = nn.Sequential(\n nn.Conv2d(hidden_dim, hidden_dim, kernel_size=kernel_size, stride=stride,\n padding=(kernel_size - 1) // 2, groups=hidden_dim, bias=False),\n nn.BatchNorm2d(hidden_dim),\n nn.ReLU6(inplace=True),\n )\n self.project_conv = nn.Sequential(\n nn.Conv2d(hidden_dim, out_channels, kernel_size=1, stride=1, padding=0, bias=False),\n nn.BatchNorm2d(out_channels),\n )\n\n\nclass ModelNew(nn.Module):\n def __init__(self, num_classes=1000):\n super(ModelNew, self).__init__()\n self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1, bias=False)\n self.bn1 = nn.BatchNorm2d(32)\n self.blocks = nn.Sequential(\n _MBConvNew(32, 16, kernel_size=3, stride=1, expand_ratio=1),\n _MBConvNew(16, 24, kernel_size=3, stride=2, expand_ratio=6),\n _MBConvNew(24, 24, kernel_size=3, stride=1, expand_ratio=6),\n _MBConvNew(24, 40, kernel_size=5, stride=2, expand_ratio=6),\n _MBConvNew(40, 40, kernel_size=5, stride=1, expand_ratio=6),\n _MBConvNew(40, 80, kernel_size=3, stride=2, expand_ratio=6),\n _MBConvNew(80, 80, kernel_size=3, stride=1, expand_ratio=6),\n _MBConvNew(80, 112, kernel_size=5, stride=1, expand_ratio=6),\n _MBConvNew(112, 112, kernel_size=5, stride=1, expand_ratio=6),\n _MBConvNew(112, 192, kernel_size=5, stride=2, expand_ratio=6),\n _MBConvNew(192, 192, kernel_size=5, stride=1, expand_ratio=6),\n _MBConvNew(192, 192, kernel_size=5, stride=1, expand_ratio=6),\n _MBConvNew(192, 320, kernel_size=3, stride=1, expand_ratio=6),\n )\n self.conv2 = nn.Conv2d(320, 1280, kernel_size=1, stride=1, padding=0, bias=False)\n self.bn2 = nn.BatchNorm2d(1280)\n self.fc = nn.Linear(1280, num_classes)\n\n @staticmethod\n def _bn_act_inplace(x, bn, act):\n return _effnet_fused.bn_act_(x, bn.weight, bn.bias, bn.running_mean, bn.running_var, float(bn.eps), int(act))\n\n @staticmethod\n def _bn_add_inplace(x, bn, residual):\n return _effnet_fused.bn_add_(x, bn.weight, bn.bias, bn.running_mean, bn.running_var, residual, float(bn.eps))\n\n def _forward_block(self, block, x):\n identity = x\n if hasattr(block, 'expand_conv'):\n conv = block.expand_conv[0]\n x = F.conv2d(x, conv.weight, None, conv.stride, conv.padding, conv.dilation, conv.groups)\n x = self._bn_act_inplace(x, block.expand_conv[1], 2) # ReLU6\n conv = block.depthwise_conv[0]\n x = F.conv2d(x, conv.weight, None, conv.stride, conv.padding, conv.dilation, conv.groups)\n x = self._bn_act_inplace(x, block.depthwise_conv[1], 2) # ReLU6\n conv = block.project_conv[0]\n x = F.conv2d(x, conv.weight, None, conv.stride, conv.padding, conv.dilation, conv.groups)\n if block.use_residual:\n x = self._bn_add_inplace(x, block.project_conv[1], identity)\n else:\n x = self._bn_act_inplace(x, block.project_conv[1], 0)\n return x\n\n def forward(self, x):\n # Optimized inference path: cuDNN convolutions plus fused CUDA BN/activation kernels.\n x = F.conv2d(x, self.conv1.weight, None, self.conv1.stride, self.conv1.padding,\n self.conv1.dilation, self.conv1.groups)\n x = self._bn_act_inplace(x, self.bn1, 1) # ReLU\n for block in self.blocks:\n x = self._forward_block(block, x)\n x = F.conv2d(x, self.conv2.weight, None, self.conv2.stride, self.conv2.padding,\n self.conv2.dilation, self.conv2.groups)\n x = self._bn_act_inplace(x, self.bn2, 1) # ReLU\n x = _effnet_fused.avgpool2d(x)\n x = F.linear(x, self.fc.weight, self.fc.bias)\n return x\n"
}