call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_sources = r'''\n#include <torch/extension.h>\ntorch::Tensor mbconv_forward_cuda(\n torch::Tensor x,\n torch::Tensor ew, torch::Tensor ebnw, torch::Tensor ebnb, torch::Tensor erm, torch::Tensor erv, double eeps,\n torch::Tensor dw,\n torch::Tensor dbnw, torch::Tensor dbnb, torch::Tensor drm, torch::Tensor drv, double deps,\n torch::Tensor pw, torch::Tensor pbnw, torch::Tensor pbnb, torch::Tensor prm, torch::Tensor prv, double peps,\n bool residual, bool training);\ntorch::Tensor mbconv_forward(\n torch::Tensor x,\n torch::Tensor ew, torch::Tensor ebnw, torch::Tensor ebnb, torch::Tensor erm, torch::Tensor erv, double eeps,\n torch::Tensor dw,\n torch::Tensor dbnw, torch::Tensor dbnb, torch::Tensor drm, torch::Tensor drv, double deps,\n torch::Tensor pw, torch::Tensor pbnw, torch::Tensor pbnb, torch::Tensor prm, torch::Tensor prv, double peps,\n bool residual, bool training) {\n return mbconv_forward_cuda(x, ew, ebnw, ebnb, erm, erv, eeps, dw, dbnw, dbnb, drm, drv, deps, pw, pbnw, pbnb, prm, prv, peps, residual, training);\n}\n'''\n\ncuda_sources = r'''\n#include <torch/extension.h>\n#include <ATen/ATen.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <ATen/ops/conv2d.h>\n#include <ATen/ops/batch_norm.h>\n#include <cuda_runtime.h>\n#include <optional>\n\n__global__ void relu6_kernel(float* y, long total) {\n long idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < total) { float v = y[idx]; y[idx] = fminf(fmaxf(v,0.0f),6.0f); }\n}\n__global__ void affine_relu6_kernel(float* __restrict__ y, const float* __restrict__ gamma,\n const float* __restrict__ beta, const float* __restrict__ mean,\n const float* __restrict__ var, float eps,\n long total, int C, int HW) {\n long idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n int c = (idx / HW) % C;\n float v = y[idx];\n v = (v - mean[c]) * (gamma[c] * rsqrtf(var[c] + eps)) + beta[c];\n y[idx] = fminf(fmaxf(v, 0.0f), 6.0f);\n}\n__global__ void affine_kernel(float* __restrict__ y, const float* __restrict__ gamma,\n const float* __restrict__ beta, const float* __restrict__ mean,\n const float* __restrict__ var, const float* __restrict__ ident,\n float eps, long total, int C, int HW, bool residual) {\n long idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n int c = (idx / HW) % C;\n float v = (y[idx] - mean[c]) * (gamma[c] * rsqrtf(var[c] + eps)) + beta[c];\n if (residual) v += ident[idx];\n y[idx] = v;\n}\n__global__ void add_kernel(float* y, const float* ident, long total) {\n long idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < total) y[idx] += ident[idx];\n}\n__global__ void depthwise5s2_kernel(const float* __restrict__ x, const float* __restrict__ w,\n float* __restrict__ y, long total, int C, int H, int Wd, int OH, int OW) {\n long idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n int ow = idx % OW;\n int oh = (idx / OW) % OH;\n int c = (idx / (OW * OH)) % C;\n int n = idx / (OW * OH * C);\n int ih0 = oh * 2 - 2;\n int iw0 = ow * 2 - 2;\n const float* xbase = x + ((long)n * C + c) * H * Wd;\n const float* wbase = w + (long)c * 25;\n float acc = 0.0f;\n#pragma unroll\n for (int kh = 0; kh < 5; ++kh) {\n int ih = ih0 + kh;\n if ((unsigned)ih < (unsigned)H) {\n#pragma unroll\n for (int kw = 0; kw < 5; ++kw) {\n int iw = iw0 + kw;\n if ((unsigned)iw < (unsigned)Wd) acc = fmaf(xbase[ih * Wd + iw], wbase[kh * 5 + kw], acc);\n }\n }\n }\n y[idx] = acc;\n}\n\ntorch::Tensor mbconv_forward_cuda(\n torch::Tensor x,\n torch::Tensor ew, torch::Tensor ebnw, torch::Tensor ebnb, torch::Tensor erm, torch::Tensor erv, double eeps,\n torch::Tensor dw,\n torch::Tensor dbnw, torch::Tensor dbnb, torch::Tensor drm, torch::Tensor drv, double deps,\n torch::Tensor pw, torch::Tensor pbnw, torch::Tensor pbnb, torch::Tensor prm, torch::Tensor prv, double peps,\n bool residual, bool training) {\n x = x.contiguous(); ew = ew.contiguous(); pw = pw.contiguous(); dw = dw.contiguous();\n std::optional<at::Tensor> bias = std::nullopt;\n std::vector<int64_t> s1 = {1,1}, p0 = {0,0}, d1 = {1,1};\n const int threads = 256; cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n auto y = at::conv2d(x, ew, bias, s1, p0, d1, 1);\n if (training) {\n y = at::batch_norm(y, ebnw, ebnb, erm, erv, true, 0.1, eeps, true);\n relu6_kernel<<<(y.numel()+threads-1)/threads, threads, 0, stream>>>(y.template data_ptr<float>(), y.numel());\n } else {\n affine_relu6_kernel<<<(y.numel()+threads-1)/threads, threads, 0, stream>>>(y.template data_ptr<float>(), ebnw.template data_ptr<float>(), ebnb.template data_ptr<float>(), erm.template data_ptr<float>(), erv.template data_ptr<float>(), (float)eeps, y.numel(), y.size(1), y.size(2)*y.size(3));\n }\n\n int N = y.size(0), C = y.size(1), H = y.size(2), W = y.size(3);\n int OH = (H + 4 - 5) / 2 + 1, OW = (W + 4 - 5) / 2 + 1;\n auto ydw = torch::empty({N, C, OH, OW}, x.options());\n depthwise5s2_kernel<<<(ydw.numel()+threads-1)/threads, threads, 0, stream>>>(y.template data_ptr<float>(), dw.template data_ptr<float>(), ydw.template data_ptr<float>(), ydw.numel(), C, H, W, OH, OW);\n if (training) {\n ydw = at::batch_norm(ydw, dbnw, dbnb, drm, drv, true, 0.1, deps, true);\n relu6_kernel<<<(ydw.numel()+threads-1)/threads, threads, 0, stream>>>(ydw.template data_ptr<float>(), ydw.numel());\n } else {\n affine_relu6_kernel<<<(ydw.numel()+threads-1)/threads, threads, 0, stream>>>(ydw.template data_ptr<float>(), dbnw.template data_ptr<float>(), dbnb.template data_ptr<float>(), drm.template data_ptr<float>(), drv.template data_ptr<float>(), (float)deps, ydw.numel(), C, OH*OW);\n }\n\n auto out = at::conv2d(ydw, pw, bias, s1, p0, d1, 1);\n if (training) {\n out = at::batch_norm(out, pbnw, pbnb, prm, prv, true, 0.1, peps, true);\n if (residual) add_kernel<<<(out.numel()+threads-1)/threads, threads, 0, stream>>>(out.template data_ptr<float>(), x.template data_ptr<float>(), out.numel());\n } else {\n affine_kernel<<<(out.numel()+threads-1)/threads, threads, 0, stream>>>(out.template data_ptr<float>(), pbnw.template data_ptr<float>(), pbnb.template data_ptr<float>(), prm.template data_ptr<float>(), prv.template data_ptr<float>(), x.template data_ptr<float>(), (float)peps, out.numel(), out.size(1), out.size(2)*out.size(3), residual);\n }\n return out;\n}\n'''\n\n_ext = load_inline(name='mbconv_fused_ext_v3', cpp_sources=cpp_sources, cuda_sources=cuda_sources,\n functions=['mbconv_forward'], extra_cuda_cflags=['-O3', '--use_fast_math'], extra_cflags=['-O3'], verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels, out_channels, kernel_size, stride, expand_ratio):\n super(ModelNew, self).__init__()\n self.use_residual = (stride == 1 and in_channels == out_channels)\n hidden_dim = in_channels * expand_ratio\n self.kernel_size=kernel_size; self.stride=stride; self.expand_ratio=expand_ratio\n if expand_ratio != 1:\n self.expand_conv = nn.Sequential(nn.Conv2d(in_channels, hidden_dim, 1, 1, 0, bias=False), nn.BatchNorm2d(hidden_dim), nn.ReLU6(inplace=True))\n self.depthwise_conv = nn.Sequential(nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size-1)//2, groups=hidden_dim, bias=False), nn.BatchNorm2d(hidden_dim), nn.ReLU6(inplace=True))\n self.project_conv = nn.Sequential(nn.Conv2d(hidden_dim, out_channels, 1, 1, 0, bias=False), nn.BatchNorm2d(out_channels))\n def forward(self, x):\n return _ext.mbconv_forward(x, self.expand_conv[0].weight, self.expand_conv[1].weight, self.expand_conv[1].bias, self.expand_conv[1].running_mean, self.expand_conv[1].running_var, float(self.expand_conv[1].eps), self.depthwise_conv[0].weight, self.depthwise_conv[1].weight, self.depthwise_conv[1].bias, self.depthwise_conv[1].running_mean, self.depthwise_conv[1].running_var, float(self.depthwise_conv[1].eps), self.project_conv[0].weight, self.project_conv[1].weight, self.project_conv[1].bias, self.project_conv[1].running_mean, self.project_conv[1].running_var, float(self.project_conv[1].eps), bool(self.use_residual), bool(self.training))\n"
}