call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_src_cpp = r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor lenet_forward(torch::Tensor x,\n torch::Tensor c1w, torch::Tensor c1b,\n torch::Tensor c2w, torch::Tensor c2b,\n torch::Tensor f1w, torch::Tensor f1b,\n torch::Tensor f2w, torch::Tensor f2b,\n torch::Tensor f3w, torch::Tensor f3b);\n\"\"\"\n\n_src_cuda = 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 lenet_fused_kernel(const float* __restrict__ x,\n const float* __restrict__ c1w, const float* __restrict__ c1b,\n const float* __restrict__ c2w, const float* __restrict__ c2b,\n const float* __restrict__ f1w, const float* __restrict__ f1b,\n const float* __restrict__ f2w, const float* __restrict__ f2b,\n const float* __restrict__ f3w, const float* __restrict__ f3b,\n float* __restrict__ out,\n int K) {\n int n = blockIdx.x;\n int tid = threadIdx.x;\n __shared__ float p1[6*14*14];\n __shared__ float p2[16*5*5];\n __shared__ float h1[120];\n __shared__ float h2[84];\n\n const float* xin = x + ((size_t)n)*32*32;\n\n for (int idx = tid; idx < 6*14*14; idx += blockDim.x) {\n int tmp = idx;\n int px = tmp % 14; tmp /= 14;\n int py = tmp % 14; tmp /= 14;\n int oc = tmp;\n int oy = py * 2;\n int ox = px * 2;\n float s00 = c1b[oc], s01 = s00, s10 = s00, s11 = s00;\n const float* w = c1w + oc*25;\n #pragma unroll\n for (int ky = 0; ky < 5; ++ky) {\n int r0 = (oy + ky) * 32 + ox;\n int r1 = r0 + 32;\n #pragma unroll\n for (int kx = 0; kx < 5; ++kx) {\n float ww = w[ky*5 + kx];\n s00 += ww * xin[r0 + kx];\n s01 += ww * xin[r0 + kx + 1];\n s10 += ww * xin[r1 + kx];\n s11 += ww * xin[r1 + kx + 1];\n }\n }\n float m = 0.0f;\n m = fmaxf(m, s00); m = fmaxf(m, s01); m = fmaxf(m, s10); m = fmaxf(m, s11);\n p1[idx] = m;\n }\n __syncthreads();\n\n for (int idx = tid; idx < 16*5*5; idx += blockDim.x) {\n int tmp = idx;\n int px = tmp % 5; tmp /= 5;\n int py = tmp % 5; tmp /= 5;\n int oc = tmp;\n int oy = py * 2;\n int ox = px * 2;\n float s00 = c2b[oc], s01 = s00, s10 = s00, s11 = s00;\n const float* woc = c2w + oc*6*25;\n #pragma unroll\n for (int ic = 0; ic < 6; ++ic) {\n const float* pp = p1 + ic*14*14;\n const float* wwic = woc + ic*25;\n #pragma unroll\n for (int ky = 0; ky < 5; ++ky) {\n int r0 = (oy + ky) * 14 + ox;\n int r1 = r0 + 14;\n #pragma unroll\n for (int kx = 0; kx < 5; ++kx) {\n float ww = wwic[ky*5 + kx];\n s00 += ww * pp[r0 + kx];\n s01 += ww * pp[r0 + kx + 1];\n s10 += ww * pp[r1 + kx];\n s11 += ww * pp[r1 + kx + 1];\n }\n }\n }\n float m = 0.0f;\n m = fmaxf(m, s00); m = fmaxf(m, s01); m = fmaxf(m, s10); m = fmaxf(m, s11);\n p2[idx] = m;\n }\n __syncthreads();\n\n for (int o = tid; o < 120; o += blockDim.x) {\n float s = f1b[o];\n const float* w = f1w + o*400;\n #pragma unroll 4\n for (int i = 0; i < 400; ++i) s += w[i] * p2[i];\n h1[o] = fmaxf(s, 0.0f);\n }\n __syncthreads();\n\n for (int o = tid; o < 84; o += blockDim.x) {\n float s = f2b[o];\n const float* w = f2w + o*120;\n #pragma unroll 4\n for (int i = 0; i < 120; ++i) s += w[i] * h1[i];\n h2[o] = fmaxf(s, 0.0f);\n }\n __syncthreads();\n\n for (int o = tid; o < K; o += blockDim.x) {\n float s = f3b[o];\n const float* w = f3w + ((size_t)o)*84;\n #pragma unroll\n for (int i = 0; i < 84; ++i) s += w[i] * h2[i];\n out[((size_t)n)*K + o] = s;\n }\n}\n\ntorch::Tensor lenet_forward(torch::Tensor x,\n torch::Tensor c1w, torch::Tensor c1b,\n torch::Tensor c2w, torch::Tensor c2b,\n torch::Tensor f1w, torch::Tensor f1b,\n torch::Tensor f2w, torch::Tensor f2b,\n torch::Tensor f3w, torch::Tensor f3b) {\n const int N = (int)x.size(0);\n const int K = (int)f3b.size(0);\n auto out = torch::empty({N, K}, x.options());\n lenet_fused_kernel<<<N, 256, 0, at::cuda::getCurrentCUDAStream()>>>(\n x.data_ptr<float>(), c1w.data_ptr<float>(), c1b.data_ptr<float>(),\n c2w.data_ptr<float>(), c2b.data_ptr<float>(),\n f1w.data_ptr<float>(), f1b.data_ptr<float>(),\n f2w.data_ptr<float>(), f2b.data_ptr<float>(),\n f3w.data_ptr<float>(), f3b.data_ptr<float>(), out.data_ptr<float>(), K);\n return out;\n}\n\"\"\"\n\n_ext = load_inline(name=\"lenet5_fused_ext_v2\",\n cpp_sources=_src_cpp,\n cuda_sources=_src_cuda,\n functions=[\"lenet_forward\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n extra_cflags=[\"-O3\"],\n verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, num_classes):\n super(ModelNew, self).__init__()\n self.conv1 = nn.Conv2d(1, 6, 5, 1)\n self.conv2 = nn.Conv2d(6, 16, 5, 1)\n self.fc1 = nn.Linear(16*5*5, 120)\n self.fc2 = nn.Linear(120, 84)\n self.fc3 = nn.Linear(84, num_classes)\n def forward(self, x):\n return _ext.lenet_forward(x, self.conv1.weight, self.conv1.bias,\n self.conv2.weight, self.conv2.bias,\n self.fc1.weight, self.fc1.bias,\n self.fc2.weight, self.fc2.bias,\n self.fc3.weight, self.fc3.bias)\n"
}