call → submit_kernel
callsubmit_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = r\"\"\"\n#include <torch/extension.h>\n\nat::Tensor lenet_forward_cuda(at::Tensor x,\n at::Tensor c1w, at::Tensor c1b,\n at::Tensor c2w, at::Tensor c2b,\n at::Tensor f1w, at::Tensor f1b,\n at::Tensor f2w, at::Tensor f2b,\n at::Tensor f3w, at::Tensor f3b);\n\"\"\"\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#include <float.h>\n\n__global__ void conv1_pool_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = N * 6 * 14 * 14;\n if (idx >= total) return;\n\n int t = idx;\n int ox = t % 14; t /= 14;\n int oy = t % 14; t /= 14;\n int oc = t % 6; t /= 6;\n int n = t;\n\n const float* xp = x + n * 32 * 32;\n const float* wp = w + oc * 25;\n float best = -FLT_MAX;\n\n #pragma unroll\n for (int py = 0; py < 2; ++py) {\n #pragma unroll\n for (int px = 0; px < 2; ++px) {\n int iy = oy * 2 + py;\n int ix = ox * 2 + px;\n float s = b[oc];\n #pragma unroll\n for (int ky = 0; ky < 5; ++ky) {\n #pragma unroll\n for (int kx = 0; kx < 5; ++kx) {\n s = fmaf(xp[(iy + ky) * 32 + (ix + kx)], wp[ky * 5 + kx], s);\n }\n }\n best = fmaxf(best, s);\n }\n }\n y[idx] = fmaxf(best, 0.0f);\n}\n\n__global__ void conv2_pool_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = N * 16 * 5 * 5;\n if (idx >= total) return;\n\n int t = idx;\n int ox = t % 5; t /= 5;\n int oy = t % 5; t /= 5;\n int oc = t % 16; t /= 16;\n int n = t;\n\n const float* xp = x + n * (6 * 14 * 14);\n const float* wp0 = w + oc * (6 * 25);\n float best = -FLT_MAX;\n\n #pragma unroll\n for (int py = 0; py < 2; ++py) {\n #pragma unroll\n for (int px = 0; px < 2; ++px) {\n int iy = oy * 2 + py;\n int ix = ox * 2 + px;\n float s = b[oc];\n #pragma unroll\n for (int ic = 0; ic < 6; ++ic) {\n const float* xpc = xp + ic * 14 * 14;\n const float* wpc = wp0 + ic * 25;\n #pragma unroll\n for (int ky = 0; ky < 5; ++ky) {\n #pragma unroll\n for (int kx = 0; kx < 5; ++kx) {\n s = fmaf(xpc[(iy + ky) * 14 + (ix + kx)], wpc[ky * 5 + kx], s);\n }\n }\n }\n best = fmaxf(best, s);\n }\n }\n y[idx] = fmaxf(best, 0.0f);\n}\n\n__global__ void fc1_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = N * 120;\n if (idx >= total) return;\n int o = idx % 120;\n int n = idx / 120;\n const float* xp = x + n * 400;\n const float* wp = w + o * 400;\n float s = b[o];\n #pragma unroll 4\n for (int k = 0; k < 400; ++k) {\n s = fmaf(xp[k], wp[k], s);\n }\n y[idx] = fmaxf(s, 0.0f);\n}\n\n__global__ void fc2_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = N * 84;\n if (idx >= total) return;\n int o = idx % 84;\n int n = idx / 84;\n const float* xp = x + n * 120;\n const float* wp = w + o * 120;\n float s = b[o];\n #pragma unroll 4\n for (int k = 0; k < 120; ++k) {\n s = fmaf(xp[k], wp[k], s);\n }\n y[idx] = fmaxf(s, 0.0f);\n}\n\n__global__ void fc3_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N, int C) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = N * C;\n if (idx >= total) return;\n int o = idx % C;\n int n = idx / C;\n const float* xp = x + n * 84;\n const float* wp = w + o * 84;\n float s = b[o];\n #pragma unroll 4\n for (int k = 0; k < 84; ++k) {\n s = fmaf(xp[k], wp[k], s);\n }\n y[idx] = s;\n}\n\nat::Tensor lenet_forward_cuda(at::Tensor x,\n at::Tensor c1w, at::Tensor c1b,\n at::Tensor c2w, at::Tensor c2b,\n at::Tensor f1w, at::Tensor f1b,\n at::Tensor f2w, at::Tensor f2b,\n at::Tensor f3w, at::Tensor f3b) {\n const int N = (int)x.size(0);\n const int C = (int)f3b.size(0);\n auto opts = x.options();\n at::Tensor y1 = at::empty({N, 6, 14, 14}, opts);\n at::Tensor y2 = at::empty({N, 16, 5, 5}, opts);\n at::Tensor y3 = at::empty({N, 120}, opts);\n at::Tensor y4 = at::empty({N, 84}, opts);\n at::Tensor out = at::empty({N, C}, opts);\n\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n const int block = 256;\n int total1 = N * 6 * 14 * 14;\n conv1_pool_kernel<<<(total1 + block - 1) / block, block, 0, stream>>>(\n x.data_ptr<float>(), c1w.data_ptr<float>(), c1b.data_ptr<float>(), y1.data_ptr<float>(), N);\n int total2 = N * 16 * 5 * 5;\n conv2_pool_kernel<<<(total2 + block - 1) / block, block, 0, stream>>>(\n y1.data_ptr<float>(), c2w.data_ptr<float>(), c2b.data_ptr<float>(), y2.data_ptr<float>(), N);\n int total3 = N * 120;\n fc1_kernel<<<(total3 + block - 1) / block, block, 0, stream>>>(\n y2.data_ptr<float>(), f1w.data_ptr<float>(), f1b.data_ptr<float>(), y3.data_ptr<float>(), N);\n int total4 = N * 84;\n fc2_kernel<<<(total4 + block - 1) / block, block, 0, stream>>>(\n y3.data_ptr<float>(), f2w.data_ptr<float>(), f2b.data_ptr<float>(), y4.data_ptr<float>(), N);\n int total5 = N * C;\n fc3_kernel<<<(total5 + block - 1) / block, block, 0, stream>>>(\n y4.data_ptr<float>(), f3w.data_ptr<float>(), f3b.data_ptr<float>(), out.data_ptr<float>(), N, C);\n return out;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"lenet5_fused_forward_ext\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"lenet_forward_cuda\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, num_classes):\n super(ModelNew, self).__init__()\n self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, stride=1)\n self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5, stride=1)\n self.fc1 = nn.Linear(in_features=16*5*5, out_features=120)\n self.fc2 = nn.Linear(in_features=120, out_features=84)\n self.fc3 = nn.Linear(in_features=84, out_features=num_classes)\n\n def forward(self, x):\n return _ext.lenet_forward_cuda(\n x,\n 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 )\n"
}