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#include <ATen/ATen.h>\n#include <vector>\n\ntorch::Tensor gelu_gn_cuda(torch::Tensor y, torch::Tensor weight, torch::Tensor bias, int64_t num_groups);\n\ntorch::Tensor model_forward(torch::Tensor x,\n torch::Tensor conv_w,\n torch::Tensor conv_b,\n torch::Tensor gn_w,\n torch::Tensor gn_b,\n int64_t num_groups,\n int64_t stride) {\n // ConvTranspose2d parameters match the reference model: padding=0,\n // output_padding=0, dilation=1, groups=1.\n auto y = at::conv_transpose2d(x, conv_w, conv_b,\n {stride, stride}, {0, 0}, {0, 0},\n 1, {1, 1});\n return gelu_gn_cuda(y, gn_w, gn_b, num_groups);\n}\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 BLOCK 256\n\n__device__ __forceinline__ float gelu_exact(float x) {\n return 0.5f * x * (1.0f + erff(x * 0.70710678118654752440f));\n}\n\n__global__ void gelu_stats_kernel(float* __restrict__ y,\n float* __restrict__ sums,\n float* __restrict__ sqsums,\n int N, int C, int H, int W, int G) {\n int gid = blockIdx.x; // one block per (n, group)\n int g = gid % G;\n int n = gid / G;\n int cpg = C / G;\n int HW = H * W;\n int M = cpg * HW;\n long long base = ((long long)n * C + (long long)g * cpg) * HW;\n\n float local_sum = 0.0f;\n float local_sq = 0.0f;\n\n for (int i = threadIdx.x; i < M; i += BLOCK) {\n float v = y[base + i];\n float gv = gelu_exact(v);\n y[base + i] = gv;\n local_sum += gv;\n local_sq += gv * gv;\n }\n\n __shared__ float sh_sum[BLOCK];\n __shared__ float sh_sq[BLOCK];\n sh_sum[threadIdx.x] = local_sum;\n sh_sq[threadIdx.x] = local_sq;\n __syncthreads();\n\n for (int offset = BLOCK / 2; offset > 0; offset >>= 1) {\n if (threadIdx.x < offset) {\n sh_sum[threadIdx.x] += sh_sum[threadIdx.x + offset];\n sh_sq[threadIdx.x] += sh_sq[threadIdx.x + offset];\n }\n __syncthreads();\n }\n\n if (threadIdx.x == 0) {\n sums[gid] = sh_sum[0];\n sqsums[gid] = sh_sq[0];\n }\n}\n\n__global__ void normalize_kernel(float* __restrict__ y,\n const float* __restrict__ sums,\n const float* __restrict__ sqsums,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n int N, int C, int H, int W, int G) {\n int gid = blockIdx.x; // one block per (n, group)\n int g = gid % G;\n int n = gid / G;\n int cpg = C / G;\n int HW = H * W;\n int M = cpg * HW;\n long long base = ((long long)n * C + (long long)g * cpg) * HW;\n\n float invM = 1.0f / (float)M;\n float mean = sums[gid] * invM;\n float var = sqsums[gid] * invM - mean * mean;\n var = var < 0.0f ? 0.0f : var;\n float rstd = rsqrtf(var + 1.0e-5f);\n\n for (int i = threadIdx.x; i < M; i += BLOCK) {\n int local_c = i / HW;\n int c = g * cpg + local_c;\n float v = y[base + i];\n y[base + i] = (v - mean) * rstd * gamma[c] + beta[c];\n }\n}\n\ntorch::Tensor gelu_gn_cuda(torch::Tensor y, torch::Tensor weight, torch::Tensor bias, int64_t num_groups) {\n const int N = (int)y.size(0);\n const int C = (int)y.size(1);\n const int H = (int)y.size(2);\n const int W = (int)y.size(3);\n const int G = (int)num_groups;\n auto stats = torch::empty({2, N * G}, y.options());\n float* sums = stats.data_ptr<float>();\n float* sqsums = sums + N * G;\n\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n dim3 grid(N * G);\n dim3 block(BLOCK);\n gelu_stats_kernel<<<grid, block, 0, stream>>>(y.data_ptr<float>(), sums, sqsums, N, C, H, W, G);\n normalize_kernel<<<grid, block, 0, stream>>>(y.data_ptr<float>(), sums, sqsums,\n weight.data_ptr<float>(), bias.data_ptr<float>(),\n N, C, H, W, G);\n return y;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"convtranspose_gelu_groupnorm_ext\",\n cpp_sources=[_cpp_src],\n cuda_sources=[_cuda_src],\n functions=[\"model_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, out_channels, kernel_size, stride, groups, num_groups):\n super(ModelNew, self).__init__()\n self.conv_transpose = nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=stride)\n self.group_norm = nn.GroupNorm(num_groups=num_groups, num_channels=out_channels)\n self.stride = int(stride)\n self.num_groups = int(num_groups)\n\n def forward(self, x):\n return _ext.model_forward(x, self.conv_transpose.weight, self.conv_transpose.bias,\n self.group_norm.weight, self.group_norm.bias,\n self.num_groups, self.stride)\n"
}