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 fused_forward(torch::Tensor x, torch::Tensor w, torch::Tensor bias,\n torch::Tensor gn_w, torch::Tensor gn_b,\n int64_t stride, int64_t padding, int64_t groups, double eps);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <vector>\n\n#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x \" must be a CUDA tensor\")\n#define CHECK_FLOAT(x) TORCH_CHECK(x.scalar_type() == at::kFloat, #x \" must be float32\")\n\n__global__ void convtranspose3d_swish_kernel(\n const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N, int Cin, int Din, int Hin, int Win,\n int Cout, int KD, int KH, int KW,\n int OD, int OH, int OW,\n int stride, int pad, int has_bias)\n{\n int s = blockIdx.x * blockDim.x + threadIdx.x;\n int S = OD * OH * OW;\n if (s >= S) return;\n\n int nc = blockIdx.y;\n int co = nc % Cout;\n int n = nc / Cout;\n\n int tmp = s;\n int ow = tmp % OW; tmp /= OW;\n int oh = tmp % OH;\n int od = tmp / OH;\n\n float acc = has_bias ? b[co] : 0.0f;\n\n #pragma unroll\n for (int ci = 0; ci < 3; ++ci) {\n if (ci >= Cin) break;\n for (int kd = 0; kd < KD; ++kd) {\n int id_num = od + pad - kd;\n if (id_num < 0 || (id_num % stride) != 0) continue;\n int id = id_num / stride;\n if ((unsigned)id >= (unsigned)Din) continue;\n for (int kh = 0; kh < KH; ++kh) {\n int ih_num = oh + pad - kh;\n if (ih_num < 0 || (ih_num % stride) != 0) continue;\n int ih = ih_num / stride;\n if ((unsigned)ih >= (unsigned)Hin) continue;\n for (int kw = 0; kw < KW; ++kw) {\n int iw_num = ow + pad - kw;\n if (iw_num < 0 || (iw_num % stride) != 0) continue;\n int iw = iw_num / stride;\n if ((unsigned)iw >= (unsigned)Win) continue;\n float xv = x[(((n * Cin + ci) * Din + id) * Hin + ih) * Win + iw];\n float wv = w[(((ci * Cout + co) * KD + kd) * KH + kh) * KW + kw];\n acc = fmaf(xv, wv, acc);\n }\n }\n }\n }\n\n float sig = 1.0f / (1.0f + expf(-acc));\n y[((n * Cout + co) * S) + s] = acc * sig;\n}\n\n__global__ void group_reduce_kernel(\n const float* __restrict__ y,\n float* __restrict__ mean,\n float* __restrict__ invstd,\n int N, int C, int G, int S, float eps)\n{\n extern __shared__ float sh[];\n float* shsum = sh;\n float* shsq = sh + blockDim.x;\n\n int ng = blockIdx.x;\n int g = ng % G;\n int n = ng / G;\n int cpg = C / G;\n int L = cpg * S;\n int base = (n * C + g * cpg) * S;\n\n float sum = 0.0f;\n float sq = 0.0f;\n for (int i = threadIdx.x; i < L; i += blockDim.x) {\n float v = y[base + i];\n sum += v;\n sq = fmaf(v, v, sq);\n }\n shsum[threadIdx.x] = sum;\n shsq[threadIdx.x] = sq;\n __syncthreads();\n\n for (int off = blockDim.x >> 1; off > 0; off >>= 1) {\n if (threadIdx.x < off) {\n shsum[threadIdx.x] += shsum[threadIdx.x + off];\n shsq[threadIdx.x] += shsq[threadIdx.x + off];\n }\n __syncthreads();\n }\n\n if (threadIdx.x == 0) {\n float m = shsum[0] / (float)L;\n float var = shsq[0] / (float)L - m * m;\n if (var < 0.0f) var = 0.0f;\n mean[ng] = m;\n invstd[ng] = rsqrtf(var + eps);\n }\n}\n\n__global__ void groupnorm_hardswish_kernel(\n float* __restrict__ y,\n const float* __restrict__ mean,\n const float* __restrict__ invstd,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n int N, int C, int G, int S)\n{\n int s = blockIdx.x * blockDim.x + threadIdx.x;\n if (s >= S) return;\n int nc = blockIdx.y;\n int c = nc % C;\n int n = nc / C;\n int g = c / (C / G);\n\n int idx = (n * C + c) * S + s;\n float v = y[idx];\n float z = (v - mean[n * G + g]) * invstd[n * G + g];\n z = z * gamma[c] + beta[c];\n\n float t = z + 3.0f;\n float out;\n if (t <= 0.0f) out = 0.0f;\n else if (t >= 6.0f) out = z;\n else out = z * t * (1.0f / 6.0f);\n y[idx] = out;\n}\n\ntorch::Tensor fused_forward(torch::Tensor x, torch::Tensor w, torch::Tensor bias,\n torch::Tensor gn_w, torch::Tensor gn_b,\n int64_t stride64, int64_t padding64, int64_t groups64, double eps_d) {\n CHECK_CUDA(x); CHECK_CUDA(w); CHECK_CUDA(gn_w); CHECK_CUDA(gn_b);\n CHECK_FLOAT(x); CHECK_FLOAT(w); CHECK_FLOAT(gn_w); CHECK_FLOAT(gn_b);\n TORCH_CHECK(x.is_contiguous(), \"x must be contiguous\");\n TORCH_CHECK(w.is_contiguous(), \"w must be contiguous\");\n\n int N = (int)x.size(0);\n int Cin = (int)x.size(1);\n int Din = (int)x.size(2);\n int Hin = (int)x.size(3);\n int Win = (int)x.size(4);\n int Cout = (int)w.size(1);\n int KD = (int)w.size(2);\n int KH = (int)w.size(3);\n int KW = (int)w.size(4);\n int stride = (int)stride64;\n int pad = (int)padding64;\n int G = (int)groups64;\n int OD = (Din - 1) * stride - 2 * pad + KD;\n int OH = (Hin - 1) * stride - 2 * pad + KH;\n int OW = (Win - 1) * stride - 2 * pad + KW;\n int S = OD * OH * OW;\n\n auto y = torch::empty({N, Cout, OD, OH, OW}, x.options());\n auto stats_opts = x.options();\n auto mean = torch::empty({N * G}, stats_opts);\n auto invstd = torch::empty({N * G}, stats_opts);\n\n const int threads = 256;\n dim3 grid_conv((S + threads - 1) / threads, N * Cout);\n int has_bias = (bias.defined() && bias.numel() > 0) ? 1 : 0;\n const float* bptr = has_bias ? bias.data_ptr<float>() : nullptr;\n convtranspose3d_swish_kernel<<<grid_conv, threads>>>(\n x.data_ptr<float>(), w.data_ptr<float>(), bptr, y.data_ptr<float>(),\n N, Cin, Din, Hin, Win, Cout, KD, KH, KW, OD, OH, OW, stride, pad, has_bias);\n\n int red_threads = 256;\n group_reduce_kernel<<<N * G, red_threads, red_threads * 2 * sizeof(float)>>>(\n y.data_ptr<float>(), mean.data_ptr<float>(), invstd.data_ptr<float>(),\n N, Cout, G, S, (float)eps_d);\n\n dim3 grid_apply((S + threads - 1) / threads, N * Cout);\n groupnorm_hardswish_kernel<<<grid_apply, threads>>>(\n y.data_ptr<float>(), mean.data_ptr<float>(), invstd.data_ptr<float>(),\n gn_w.data_ptr<float>(), gn_b.data_ptr<float>(), N, Cout, G, S);\n\n return y;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"convtrans3d_swish_gn_hswish_ext_v1\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"fused_forward\"],\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, in_channels, out_channels, kernel_size, stride, padding, groups, eps, bias=True):\n super(ModelNew, self).__init__()\n self.conv_transpose = nn.ConvTranspose3d(in_channels, out_channels, kernel_size, stride=stride, padding=padding, bias=bias)\n self.group_norm = nn.GroupNorm(num_groups=groups, num_channels=out_channels, eps=eps)\n self._groups = groups\n self._eps = eps\n if isinstance(stride, tuple):\n self._stride = int(stride[0])\n else:\n self._stride = int(stride)\n if isinstance(padding, tuple):\n self._padding = int(padding[0])\n else:\n self._padding = int(padding)\n self.register_buffer(\"_empty_bias\", torch.empty(0), persistent=False)\n\n def forward(self, x):\n if not x.is_contiguous():\n x = x.contiguous()\n b = self.conv_transpose.bias\n if b is None:\n b = self._empty_bias\n return _ext.fused_forward(x, self.conv_transpose.weight, b,\n self.group_norm.weight, self.group_norm.bias,\n self._stride, self._padding, self._groups, float(self._eps))\n"
}