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 bn_relu_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor running_mean, torch::Tensor running_var,\n bool training, double momentum, double eps);\n\ntorch::Tensor add_residual_cuda(torch::Tensor y, torch::Tensor x);\n\ntorch::Tensor bn_relu_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor running_mean, torch::Tensor running_var,\n bool training, double momentum, double eps) {\n return bn_relu_cuda(x, weight, bias, running_mean, running_var, training, momentum, eps);\n}\n\ntorch::Tensor add_residual(torch::Tensor y, torch::Tensor x) {\n return add_residual_cuda(y, x);\n}\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <math.h>\n\n#define BN_THREADS 256\n\n__global__ void bn_relu_train_kernel(const float* __restrict__ x,\n float* __restrict__ out,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n float* __restrict__ running_mean,\n float* __restrict__ running_var,\n int N, int C, int L,\n float momentum, float eps) {\n int c = blockIdx.x;\n int tid = threadIdx.x;\n int M = N * L;\n __shared__ float ssum[BN_THREADS];\n __shared__ float ssq[BN_THREADS];\n __shared__ float smu;\n __shared__ float sinv;\n float sum = 0.0f;\n float sumsq = 0.0f;\n\n for (int i = tid; i < M; i += BN_THREADS) {\n int n = i / L;\n int l = i - n * L;\n float v = x[(n * C + c) * L + l];\n sum += v;\n sumsq = fmaf(v, v, sumsq);\n }\n ssum[tid] = sum;\n ssq[tid] = sumsq;\n __syncthreads();\n\n for (int stride = BN_THREADS >> 1; stride > 0; stride >>= 1) {\n if (tid < stride) {\n ssum[tid] += ssum[tid + stride];\n ssq[tid] += ssq[tid + stride];\n }\n __syncthreads();\n }\n\n if (tid == 0) {\n float mean = ssum[0] / (float)M;\n float var = ssq[0] / (float)M - mean * mean;\n var = var < 0.0f ? 0.0f : var;\n smu = mean;\n sinv = rsqrtf(var + eps);\n // PyTorch BatchNorm updates running_var with the unbiased estimator.\n if (running_mean != nullptr && running_var != nullptr) {\n float unbiased = var * ((float)M / (float)(M - 1));\n running_mean[c] = running_mean[c] * (1.0f - momentum) + mean * momentum;\n running_var[c] = running_var[c] * (1.0f - momentum) + unbiased * momentum;\n }\n }\n __syncthreads();\n\n float g = gamma[c];\n float b = beta[c];\n float mean = smu;\n float inv = sinv;\n for (int i = tid; i < M; i += BN_THREADS) {\n int n = i / L;\n int l = i - n * L;\n int idx = (n * C + c) * L + l;\n float v = (x[idx] - mean) * inv;\n v = fmaf(v, g, b);\n out[idx] = v > 0.0f ? v : 0.0f;\n }\n}\n\n__global__ void bn_relu_eval_kernel(const float* __restrict__ x,\n float* __restrict__ out,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n const float* __restrict__ running_mean,\n const float* __restrict__ running_var,\n int total, int C, int L, float eps) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int stride = blockDim.x * gridDim.x;\n for (; idx < total; idx += stride) {\n int c = (idx / L) % C;\n float v = (x[idx] - running_mean[c]) * rsqrtf(running_var[c] + eps);\n v = fmaf(v, gamma[c], beta[c]);\n out[idx] = v > 0.0f ? v : 0.0f;\n }\n}\n\n__global__ void add_kernel(float* __restrict__ y, const float* __restrict__ x, int total) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int stride = blockDim.x * gridDim.x;\n for (; idx < total; idx += stride) {\n y[idx] += x[idx];\n }\n}\n\ntorch::Tensor bn_relu_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n torch::Tensor running_mean, torch::Tensor running_var,\n bool training, double momentum, 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 L = (int)x.size(2);\n int total = N * C * L;\n const float* xp = x.data_ptr<float>();\n float* op = out.data_ptr<float>();\n const float* gp = weight.data_ptr<float>();\n const float* bp = bias.data_ptr<float>();\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n if (training) {\n float* rmp = running_mean.defined() ? running_mean.data_ptr<float>() : nullptr;\n float* rvp = running_var.defined() ? running_var.data_ptr<float>() : nullptr;\n bn_relu_train_kernel<<<C, BN_THREADS, 0, stream>>>(xp, op, gp, bp, rmp, rvp, N, C, L,\n (float)momentum, (float)eps);\n } else {\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n if (blocks > 4096) blocks = 4096;\n bn_relu_eval_kernel<<<blocks, threads, 0, stream>>>(xp, op, gp, bp,\n running_mean.data_ptr<float>(),\n running_var.data_ptr<float>(),\n total, C, L, (float)eps);\n }\n return out;\n}\n\ntorch::Tensor add_residual_cuda(torch::Tensor y, torch::Tensor x) {\n int total = (int)y.numel();\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n if (blocks > 4096) blocks = 4096;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n add_kernel<<<blocks, threads, 0, stream>>>(y.data_ptr<float>(), x.data_ptr<float>(), total);\n return y;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"dilated_prenorm_bn_relu_ext_v1\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"bn_relu_forward\", \"add_residual\"],\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, channels, kernel_size, dilation):\n super(ModelNew, self).__init__()\n self.norm = nn.BatchNorm1d(channels)\n self.activation = nn.ReLU()\n self.conv = nn.Conv1d(channels, channels, kernel_size, padding=dilation, dilation=dilation)\n\n def forward(self, x):\n z = _ext.bn_relu_forward(x, self.norm.weight, self.norm.bias,\n self.norm.running_mean, self.norm.running_var,\n bool(self.norm.training), float(self.norm.momentum), float(self.norm.eps))\n y = self.conv(z)\n return _ext.add_residual(y, x)\n"
}