call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\ntorch::Tensor relu_groupnorm(torch::Tensor x, torch::Tensor gamma, torch::Tensor beta, int64_t groups, double eps);\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__inline__ __device__ float warp_reduce_sum(float val) {\n for (int offset = 16; offset > 0; offset >>= 1) val += __shfl_down_sync(0xffffffff, val, offset);\n return val;\n}\n__inline__ __device__ float block_reduce_sum(float val) {\n static __shared__ float shared[32];\n int lane = threadIdx.x & 31;\n int wid = threadIdx.x >> 5;\n val = warp_reduce_sum(val);\n if (lane == 0) shared[wid] = val;\n __syncthreads();\n val = (threadIdx.x < (blockDim.x >> 5)) ? shared[lane] : 0.0f;\n if (wid == 0) val = warp_reduce_sum(val);\n return val;\n}\n\n__global__ void relu_groupnorm_kernel(const float* __restrict__ x,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n float* __restrict__ out,\n int C, int S, int G, float eps) {\n int ng = blockIdx.x;\n int n = ng / G;\n int g = ng - n * G;\n int cpg = C / G;\n int64_t group_start = ((int64_t)n * C + (int64_t)g * cpg) * S;\n int total = cpg * S;\n float sum = 0.0f;\n float sumsq = 0.0f;\n for (int idx = threadIdx.x; idx < total; idx += blockDim.x) {\n float v = x[group_start + idx];\n v = fmaxf(v, 0.0f);\n sum += v;\n sumsq += v * v;\n }\n sum = block_reduce_sum(sum);\n sumsq = block_reduce_sum(sumsq);\n __shared__ float sh_mean, sh_invstd;\n if (threadIdx.x == 0) {\n float mean = sum / (float)total;\n float var = sumsq / (float)total - mean * mean;\n sh_mean = mean;\n sh_invstd = rsqrtf(fmaxf(var, 0.0f) + eps);\n }\n __syncthreads();\n float mean = sh_mean;\n float invstd = sh_invstd;\n for (int idx = threadIdx.x; idx < total; idx += blockDim.x) {\n int c = g * cpg + idx / S;\n float v = x[group_start + idx];\n v = fmaxf(v, 0.0f);\n out[group_start + idx] = (v - mean) * invstd * gamma[c] + beta[c];\n }\n}\n\ntorch::Tensor relu_groupnorm(torch::Tensor x, torch::Tensor gamma, torch::Tensor beta, int64_t groups, double eps) {\n auto out = torch::empty_like(x);\n int N = (int)x.size(0);\n int C = (int)x.size(1);\n int S = (int)(x.size(2) * x.size(3) * x.size(4));\n int G = (int)groups;\n relu_groupnorm_kernel<<<N * G, 256, 0, at::cuda::getCurrentCUDAStream()>>>(\n x.data_ptr<float>(), gamma.data_ptr<float>(), beta.data_ptr<float>(), out.data_ptr<float>(),\n C, S, G, (float)eps);\n return out;\n}\n'''\n\next = load_inline(name='relu_gn_ext_v2', cpp_sources=cpp_src, cuda_sources=cuda_src,\n functions=['relu_groupnorm'], verbose=False,\n extra_cuda_cflags=['-O3', '--use_fast_math'])\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels, out_channels, kernel_size, groups, bias=False):\n super(ModelNew, self).__init__()\n self.conv_transpose = nn.ConvTranspose3d(in_channels, out_channels, kernel_size, bias=bias)\n self.group_norm = nn.GroupNorm(num_groups=groups, num_channels=out_channels)\n self.groups = groups\n def forward(self, x):\n y = self.conv_transpose(x)\n return ext.relu_groupnorm(y, self.group_norm.weight, self.group_norm.bias, self.groups, self.group_norm.eps)\n"
}