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 maxpool3d_forward(torch::Tensor x,\n int64_t kernel_size,\n int64_t stride,\n int64_t padding,\n int64_t dilation,\n bool ceil_mode);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n#include <cfloat>\n\n#define TILE 8\n#define IN_TILE 21\n#define IN_PLANE (IN_TILE * IN_TILE)\n#define SH_SIZE (IN_TILE * IN_TILE * IN_TILE)\n\n__global__ __launch_bounds__(512, 2)\nvoid maxpool3d_ks3_s2_p1_d3_kernel(const float* __restrict__ x,\n float* __restrict__ y,\n int N, int C, int D, int H, int W,\n int OD, int OH, int OW,\n int dBlocks) {\n __shared__ float smem[SH_SIZE];\n\n const int tx = threadIdx.x;\n const int ty = threadIdx.y;\n const int tz = threadIdx.z;\n const int tid = tx + TILE * (ty + TILE * tz);\n\n const int ow0 = blockIdx.x * TILE;\n const int oh0 = blockIdx.y * TILE;\n const int db = blockIdx.z % dBlocks;\n const int nc = blockIdx.z / dBlocks;\n const int od0 = db * TILE;\n\n const int iw_start = ow0 * 2 - 1;\n const int ih_start = oh0 * 2 - 1;\n const int id_start = od0 * 2 - 1;\n\n const bool interior = (iw_start >= 0) && (ih_start >= 0) && (id_start >= 0) &&\n (iw_start + IN_TILE - 1 < W) &&\n (ih_start + IN_TILE - 1 < H) &&\n (id_start + IN_TILE - 1 < D);\n\n const long long base_nc = (long long)nc * D * H * W;\n\n if (interior) {\n #pragma unroll 1\n for (int idx = tid; idx < SH_SIZE; idx += 512) {\n int t = idx;\n const int liw = t % IN_TILE; t /= IN_TILE;\n const int lih = t % IN_TILE;\n const int lid = t / IN_TILE;\n const int gd = id_start + lid;\n const int gh = ih_start + lih;\n const int gw = iw_start + liw;\n smem[idx] = x[base_nc + ((long long)gd * H + gh) * W + gw];\n }\n } else {\n #pragma unroll 1\n for (int idx = tid; idx < SH_SIZE; idx += 512) {\n int t = idx;\n const int liw = t % IN_TILE; t /= IN_TILE;\n const int lih = t % IN_TILE;\n const int lid = t / IN_TILE;\n const int gd = id_start + lid;\n const int gh = ih_start + lih;\n const int gw = iw_start + liw;\n float v = -FLT_MAX;\n if ((unsigned)gd < (unsigned)D && (unsigned)gh < (unsigned)H && (unsigned)gw < (unsigned)W) {\n v = x[base_nc + ((long long)gd * H + gh) * W + gw];\n }\n smem[idx] = v;\n }\n }\n\n __syncthreads();\n\n const int ow = ow0 + tx;\n const int oh = oh0 + ty;\n const int od = od0 + tz;\n\n if (ow < OW && oh < OH && od < OD) {\n const int lbase = (tz * 2) * IN_PLANE + (ty * 2) * IN_TILE + (tx * 2);\n float m = -FLT_MAX;\n\n #pragma unroll\n for (int kd = 0; kd < 3; ++kd) {\n const int doff = lbase + kd * 3 * IN_PLANE;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n const int hoff = doff + kh * 3 * IN_TILE;\n float v0 = smem[hoff + 0];\n float v1 = smem[hoff + 3];\n float v2 = smem[hoff + 6];\n m = fmaxf(m, v0);\n m = fmaxf(m, v1);\n m = fmaxf(m, v2);\n }\n }\n\n y[((long long)nc * OD * OH * OW) + ((long long)od * OH + oh) * OW + ow] = m;\n }\n}\n\n// A simple generic kernel is included only for uncommon constructor choices. The benchmarked\n// problem uses the specialized k=3,s=2,p=1,d=3 path above.\n__global__ void maxpool3d_generic_kernel(const float* __restrict__ x,\n float* __restrict__ y,\n long long total,\n int C, int D, int H, int W,\n int OD, int OH, int OW,\n int k, int s, int p, int dil) {\n long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n\n int ow = idx % OW;\n long long t = idx / OW;\n int oh = t % OH; t /= OH;\n int od = t % OD; t /= OD;\n int nc = (int)t;\n\n int id0 = od * s - p;\n int ih0 = oh * s - p;\n int iw0 = ow * s - p;\n float m = -FLT_MAX;\n const long long base = (long long)nc * D * H * W;\n\n for (int kd = 0; kd < k; ++kd) {\n int gd = id0 + kd * dil;\n if ((unsigned)gd >= (unsigned)D) continue;\n for (int kh = 0; kh < k; ++kh) {\n int gh = ih0 + kh * dil;\n if ((unsigned)gh >= (unsigned)H) continue;\n for (int kw = 0; kw < k; ++kw) {\n int gw = iw0 + kw * dil;\n if ((unsigned)gw < (unsigned)W) {\n float v = x[base + ((long long)gd * H + gh) * W + gw];\n m = fmaxf(m, v);\n }\n }\n }\n }\n y[idx] = m;\n}\n\ntorch::Tensor maxpool3d_forward(torch::Tensor x,\n int64_t kernel_size,\n int64_t stride,\n int64_t padding,\n int64_t dilation,\n bool ceil_mode) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(x));\n\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int D = (int)x.size(2);\n const int H = (int)x.size(3);\n const int W = (int)x.size(4);\n const int k = (int)kernel_size;\n const int s = (int)stride;\n const int p = (int)padding;\n const int dil = (int)dilation;\n\n int OD, OH, OW;\n if (!ceil_mode) {\n OD = (D + 2 * p - dil * (k - 1) - 1) / s + 1;\n OH = (H + 2 * p - dil * (k - 1) - 1) / s + 1;\n OW = (W + 2 * p - dil * (k - 1) - 1) / s + 1;\n } else {\n OD = (D + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;\n OH = (H + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;\n OW = (W + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;\n if ((OD - 1) * s >= D + p) --OD;\n if ((OH - 1) * s >= H + p) --OH;\n if ((OW - 1) * s >= W + p) --OW;\n }\n\n auto y = torch::empty({N, C, OD, OH, OW}, x.options());\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n if (x.scalar_type() == at::kFloat && k == 3 && s == 2 && p == 1 && dil == 3 && !ceil_mode) {\n const int dBlocks = (OD + TILE - 1) / TILE;\n dim3 block(TILE, TILE, TILE);\n dim3 grid((OW + TILE - 1) / TILE, (OH + TILE - 1) / TILE, N * C * dBlocks);\n maxpool3d_ks3_s2_p1_d3_kernel<<<grid, block, 0, stream>>>(\n x.data_ptr<float>(), y.data_ptr<float>(), N, C, D, H, W, OD, OH, OW, dBlocks);\n } else {\n long long total = (long long)N * C * OD * OH * OW;\n int threads = 256;\n int blocks = (int)((total + threads - 1) / threads);\n maxpool3d_generic_kernel<<<blocks, threads, 0, stream>>>(\n x.data_ptr<float>(), y.data_ptr<float>(), total, C, D, H, W, OD, OH, OW, k, s, p, dil);\n }\n\n C10_CUDA_KERNEL_LAUNCH_CHECK();\n return y;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"maxpool3d_dilated_ext_v1\",\n cpp_sources=[_cpp_src],\n cuda_sources=[_cuda_src],\n functions=[\"maxpool3d_forward\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False,\n)\n\n\nclass ModelNew(nn.Module):\n def __init__(self, kernel_size: int, stride: int = None, padding: int = 0, dilation: int = 1,\n return_indices: bool = False, ceil_mode: bool = False):\n super(ModelNew, self).__init__()\n self.kernel_size = int(kernel_size)\n self.stride = int(kernel_size if stride is None else stride)\n self.padding = int(padding)\n self.dilation = int(dilation)\n self.return_indices = bool(return_indices)\n self.ceil_mode = bool(ceil_mode)\n\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n # The supplied task uses return_indices=False and fp32 CUDA tensors.\n return _ext.maxpool3d_forward(x, self.kernel_size, self.stride, self.padding, self.dilation, self.ceil_mode)\n"
}