call → compile_kernel
callcompile_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\nvoid launch_bn_train_unscaled(torch::Tensor y, torch::Tensor bias, torch::Tensor scale,\n torch::Tensor gamma, torch::Tensor beta,\n torch::Tensor running_mean, torch::Tensor running_var,\n double eps, double momentum);\nvoid launch_bn_eval_unscaled(torch::Tensor y, torch::Tensor bias, torch::Tensor scale,\n torch::Tensor gamma, torch::Tensor beta,\n torch::Tensor running_mean, torch::Tensor running_var, double eps);\n\ntorch::Tensor forward_train(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor scale,\n torch::Tensor gamma, torch::Tensor beta, torch::Tensor running_mean,\n torch::Tensor running_var, double eps, double momentum) {\n auto y = torch::mm(x, weight.t());\n launch_bn_train_unscaled(y, bias, scale, gamma, beta, running_mean, running_var, eps, momentum);\n return y;\n}\n\ntorch::Tensor forward_eval(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor scale,\n torch::Tensor gamma, torch::Tensor beta, torch::Tensor running_mean,\n torch::Tensor running_var, double eps) {\n auto y = torch::mm(x, weight.t());\n launch_bn_eval_unscaled(y, bias, scale, gamma, beta, running_mean, running_var, eps);\n return y;\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__global__ void bn_train_unscaled_kernel(float* __restrict__ y,\n const float* __restrict__ bias,\n const float* __restrict__ scale,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n float* __restrict__ running_mean,\n float* __restrict__ running_var,\n int M, int N, float eps, float momentum) {\n const int tx = threadIdx.x;\n const int ty = threadIdx.y;\n const int col = blockIdx.x * 32 + tx;\n __shared__ float red[8][32];\n __shared__ float mean_s[32];\n __shared__ float fac_s[32];\n __shared__ float beta_s[32];\n if (col >= N) return;\n\n float sum = 0.0f;\n for (int r = ty; r < M; r += 8) sum += y[(long long)r * N + col];\n red[ty][tx] = sum;\n __syncthreads();\n if (ty == 0) {\n float total = red[0][tx] + red[1][tx] + red[2][tx] + red[3][tx] + red[4][tx] + red[5][tx] + red[6][tx] + red[7][tx];\n mean_s[tx] = total / (float)M;\n }\n __syncthreads();\n const float mean = mean_s[tx];\n float vsum = 0.0f;\n for (int r = ty; r < M; r += 8) { float d = y[(long long)r * N + col] - mean; vsum += d * d; }\n red[ty][tx] = vsum;\n __syncthreads();\n if (ty == 0) {\n float vtotal = red[0][tx] + red[1][tx] + red[2][tx] + red[3][tx] + red[4][tx] + red[5][tx] + red[6][tx] + red[7][tx];\n float var = vtotal / (float)M;\n float sc = scale[col];\n float inv = 1.0f / sqrtf(sc * sc * var + eps);\n fac_s[tx] = sc * inv * gamma[col];\n beta_s[tx] = beta[col];\n float zmean = sc * (mean + bias[col]);\n float zvar_unbiased = (M > 1) ? (sc * sc * var * ((float)M / (float)(M - 1))) : 0.0f;\n running_mean[col] = running_mean[col] * (1.0f - momentum) + momentum * zmean;\n running_var[col] = running_var[col] * (1.0f - momentum) + momentum * zvar_unbiased;\n }\n __syncthreads();\n const float fac = fac_s[tx];\n const float be = beta_s[tx];\n for (int r = ty; r < M; r += 8) {\n long long idx = (long long)r * N + col;\n y[idx] = (y[idx] - mean) * fac + be;\n }\n}\n\n__global__ void bn_eval_unscaled_kernel(float* __restrict__ y,\n const float* __restrict__ bias,\n const float* __restrict__ scale,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n const float* __restrict__ running_mean,\n const float* __restrict__ running_var,\n long long total, int N, float eps) {\n long long i = (long long)blockIdx.x * blockDim.x + threadIdx.x;\n long long stride = (long long)blockDim.x * gridDim.x;\n for (; i < total; i += stride) {\n int col = (int)(i % N);\n float v = (y[i] + bias[col]) * scale[col];\n y[i] = (v - running_mean[col]) * (1.0f / sqrtf(running_var[col] + eps)) * gamma[col] + beta[col];\n }\n}\n\nvoid launch_bn_train_unscaled(torch::Tensor y, torch::Tensor bias, torch::Tensor scale,\n torch::Tensor gamma, torch::Tensor beta,\n torch::Tensor running_mean, torch::Tensor running_var,\n double eps, double momentum) {\n int M = (int)y.size(0), N = (int)y.size(1);\n dim3 block(32, 8), grid((N + 31) / 32);\n bn_train_unscaled_kernel<<<grid, block, 0, at::cuda::getCurrentCUDAStream()>>>(\n y.data_ptr<float>(), bias.data_ptr<float>(), scale.data_ptr<float>(), gamma.data_ptr<float>(), beta.data_ptr<float>(),\n running_mean.data_ptr<float>(), running_var.data_ptr<float>(), M, N, (float)eps, (float)momentum);\n}\n\nvoid launch_bn_eval_unscaled(torch::Tensor y, torch::Tensor bias, torch::Tensor scale,\n torch::Tensor gamma, torch::Tensor beta,\n torch::Tensor running_mean, torch::Tensor running_var, double eps) {\n long long total = y.numel(); int N = (int)y.size(1); int threads = 256;\n int blocks = (int)((total + threads - 1) / threads); if (blocks > 65535) blocks = 65535;\n bn_eval_unscaled_kernel<<<blocks, threads, 0, at::cuda::getCurrentCUDAStream()>>>(\n y.data_ptr<float>(), bias.data_ptr<float>(), scale.data_ptr<float>(), gamma.data_ptr<float>(), beta.data_ptr<float>(),\n running_mean.data_ptr<float>(), running_var.data_ptr<float>(), total, N, (float)eps);\n}\n\"\"\"\n\n_ext = load_inline(name=\"gemm_scale_bn_ext_v3\", cpp_sources=_cpp_src, cuda_sources=_cuda_src,\n functions=[\"forward_train\", \"forward_eval\"],\n extra_cflags=[\"-O3\"], extra_cuda_cflags=[\"-O3\"], verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_features, out_features, scale_shape, eps=1e-5, momentum=0.1):\n super(ModelNew, self).__init__()\n self.gemm = nn.Linear(in_features, out_features)\n self.scale = nn.Parameter(torch.randn(scale_shape))\n self.bn = nn.BatchNorm1d(out_features, eps=eps, momentum=momentum)\n def forward(self, x):\n if self.training:\n if self.bn.num_batches_tracked is not None:\n self.bn.num_batches_tracked.add_(1)\n mom = (1.0 / float(self.bn.num_batches_tracked.item())) if self.bn.momentum is None else float(self.bn.momentum)\n else:\n mom = float(self.bn.momentum if self.bn.momentum is not None else 0.0)\n return _ext.forward_train(x, self.gemm.weight, self.gemm.bias, self.scale, self.bn.weight, self.bn.bias,\n self.bn.running_mean, self.bn.running_var, float(self.bn.eps), mom)\n else:\n return _ext.forward_eval(x, self.gemm.weight, self.gemm.bias, self.scale, self.bn.weight, self.bn.bias,\n self.bn.running_mean, self.bn.running_var, float(self.bn.eps))\n"
}