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\ntorch::Tensor fire_forward(torch::Tensor x,\n torch::Tensor sw, torch::Tensor sb,\n torch::Tensor w1, torch::Tensor b1,\n torch::Tensor w3, torch::Tensor b3);\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\n#define C_IN 3\n#define S_CH 6\n#define E1_CH 64\n#define E3_CH 64\n#define E_CH 128\n#define TW 16\n#define TH 8\n#define OG 16\n#define PIX (TW*TH)\n#define SHW (TW+2)\n#define SHH (TH+2)\n\n__global__ void squeeze_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ s,\n long long total_pix, int H, int W) {\n long long t = (long long)blockIdx.x * blockDim.x + threadIdx.x;\n if (t >= total_pix) return;\n int HW = H * W;\n int p = (int)(t % HW);\n long long n = t / HW;\n const float* xp = x + n * (long long)C_IN * HW + p;\n float x0 = xp[0LL * HW];\n float x1 = xp[1LL * HW];\n float x2 = xp[2LL * HW];\n float* sp = s + n * (long long)S_CH * HW + p;\n#pragma unroll\n for (int sc = 0; sc < S_CH; ++sc) {\n float v = b[sc];\n v = fmaf(x0, w[sc*C_IN + 0], v);\n v = fmaf(x1, w[sc*C_IN + 1], v);\n v = fmaf(x2, w[sc*C_IN + 2], v);\n sp[(long long)sc * HW] = v > 0.0f ? v : 0.0f;\n }\n}\n\n__global__ void expand1_tiled_kernel(const float* __restrict__ s,\n const float* __restrict__ w1,\n const float* __restrict__ b1,\n float* __restrict__ out,\n int N, int H, int W) {\n __shared__ float sh[S_CH * PIX];\n int HW = H * W;\n int tile_x = blockIdx.x * TW;\n int tile_y = blockIdx.y * TH;\n int groups_per_n = E1_CH / OG;\n int n = blockIdx.z / groups_per_n;\n int g = blockIdx.z - n * groups_per_n;\n\n for (int t = threadIdx.x; t < S_CH * PIX; t += blockDim.x) {\n int pix = t % PIX;\n int ic = t / PIX;\n int py = pix / TW;\n int px = pix - py * TW;\n int gy = tile_y + py;\n int gx = tile_x + px;\n float v = 0.0f;\n if (gy < H && gx < W) {\n v = s[((long long)n * S_CH + ic) * HW + gy * W + gx];\n }\n sh[t] = v;\n }\n __syncthreads();\n\n for (int idx = threadIdx.x; idx < OG * PIX; idx += blockDim.x) {\n int pix = idx % PIX;\n int ocl = idx / PIX;\n int py = pix / TW;\n int px = pix - py * TW;\n int gy = tile_y + py;\n int gx = tile_x + px;\n int oc = g * OG + ocl;\n if (gy < H && gx < W) {\n float sum = b1[oc];\n#pragma unroll\n for (int ic = 0; ic < S_CH; ++ic) {\n sum = fmaf(sh[ic * PIX + pix], w1[oc * S_CH + ic], sum);\n }\n out[((long long)n * E_CH + oc) * HW + gy * W + gx] = sum > 0.0f ? sum : 0.0f;\n }\n }\n}\n\n__global__ void expand3_tiled_kernel(const float* __restrict__ s,\n const float* __restrict__ w3,\n const float* __restrict__ b3,\n float* __restrict__ out,\n int N, int H, int W) {\n __shared__ float sh[S_CH * SHH * SHW];\n int HW = H * W;\n int tile_x = blockIdx.x * TW;\n int tile_y = blockIdx.y * TH;\n int groups_per_n = E3_CH / OG;\n int n = blockIdx.z / groups_per_n;\n int g = blockIdx.z - n * groups_per_n;\n\n for (int t = threadIdx.x; t < S_CH * SHH * SHW; t += blockDim.x) {\n int rem = t;\n int sx = rem % SHW; rem /= SHW;\n int sy = rem % SHH;\n int ic = rem / SHH;\n int gy = tile_y + sy - 1;\n int gx = tile_x + sx - 1;\n float v = 0.0f;\n if ((unsigned)gy < (unsigned)H && (unsigned)gx < (unsigned)W) {\n v = s[((long long)n * S_CH + ic) * HW + gy * W + gx];\n }\n sh[t] = v;\n }\n __syncthreads();\n\n for (int idx = threadIdx.x; idx < OG * PIX; idx += blockDim.x) {\n int pix = idx % PIX;\n int ocl = idx / PIX;\n int py = pix / TW;\n int px = pix - py * TW;\n int gy = tile_y + py;\n int gx = tile_x + px;\n int oc = g * OG + ocl;\n if (gy < H && gx < W) {\n float sum = b3[oc];\n#pragma unroll\n for (int ic = 0; ic < S_CH; ++ic) {\n const float* shp = sh + ic * SHH * SHW + py * SHW + px;\n const float* wp = w3 + (oc * S_CH + ic) * 9;\n sum = fmaf(shp[0 * SHW + 0], wp[0], sum);\n sum = fmaf(shp[0 * SHW + 1], wp[1], sum);\n sum = fmaf(shp[0 * SHW + 2], wp[2], sum);\n sum = fmaf(shp[1 * SHW + 0], wp[3], sum);\n sum = fmaf(shp[1 * SHW + 1], wp[4], sum);\n sum = fmaf(shp[1 * SHW + 2], wp[5], sum);\n sum = fmaf(shp[2 * SHW + 0], wp[6], sum);\n sum = fmaf(shp[2 * SHW + 1], wp[7], sum);\n sum = fmaf(shp[2 * SHW + 2], wp[8], sum);\n }\n out[((long long)n * E_CH + (E1_CH + oc)) * HW + gy * W + gx] = sum > 0.0f ? sum : 0.0f;\n }\n }\n}\n\ntorch::Tensor fire_forward(torch::Tensor x,\n torch::Tensor sw, torch::Tensor sb,\n torch::Tensor w1, torch::Tensor b1,\n torch::Tensor w3, torch::Tensor b3) {\n const int N = (int)x.size(0);\n const int H = (int)x.size(2);\n const int W = (int)x.size(3);\n auto s = torch::empty({N, S_CH, H, W}, x.options());\n auto out = torch::empty({N, E_CH, H, W}, x.options());\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n long long total_pix = (long long)N * H * W;\n int threads = 256;\n int blocks = (int)((total_pix + threads - 1) / threads);\n squeeze_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), sw.data_ptr<float>(), sb.data_ptr<float>(),\n s.data_ptr<float>(), total_pix, H, W);\n\n dim3 block2(256);\n dim3 grid((W + TW - 1) / TW, (H + TH - 1) / TH, N * (E1_CH / OG));\n expand1_tiled_kernel<<<grid, block2, 0, stream>>>(s.data_ptr<float>(), w1.data_ptr<float>(), b1.data_ptr<float>(),\n out.data_ptr<float>(), N, H, W);\n expand3_tiled_kernel<<<grid, block2, 0, stream>>>(s.data_ptr<float>(), w3.data_ptr<float>(), b3.data_ptr<float>(),\n out.data_ptr<float>(), N, H, W);\n return out;\n}\n\"\"\"\n\n_fire_ext = load_inline(\n name=\"fire_module_fused_tiled_ext\",\n cpp_sources=[_cpp_src],\n cuda_sources=[_cuda_src],\n functions=[\"fire_forward\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\"],\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels, squeeze_channels, expand1x1_channels, expand3x3_channels):\n super(ModelNew, self).__init__()\n self.squeeze = nn.Conv2d(in_channels, squeeze_channels, kernel_size=1)\n self.squeeze_activation = nn.ReLU(inplace=True)\n self.expand1x1 = nn.Conv2d(squeeze_channels, expand1x1_channels, kernel_size=1)\n self.expand1x1_activation = nn.ReLU(inplace=True)\n self.expand3x3 = nn.Conv2d(squeeze_channels, expand3x3_channels, kernel_size=3, padding=1)\n self.expand3x3_activation = nn.ReLU(inplace=True)\n\n def forward(self, x):\n return _fire_ext.fire_forward(x, self.squeeze.weight, self.squeeze.bias,\n self.expand1x1.weight, self.expand1x1.bias,\n self.expand3x3.weight, self.expand3x3.bias)\n"
}