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>\n#include <ATen/ATen.h>\n#include <ATen/Functions.h>\n\ntorch::Tensor reduce_bn_pool_cuda(torch::Tensor y, torch::Tensor bn_w, torch::Tensor bn_b, double scale, double eps);\n\ntorch::Tensor bn_pool_forward(torch::Tensor x, torch::Tensor w, torch::Tensor conv_b, torch::Tensor bn_w, torch::Tensor bn_b, double scale, double eps) {\n auto y = at::conv_transpose3d(x, w, conv_b, {1,1,1}, {0,0,0}, {0,0,0}, 1, {1,1,1});\n return reduce_bn_pool_cuda(y, bn_w, bn_b, scale, eps);\n}\n\"\"\"\n\ncuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void reduce_nc_kernel(const float* __restrict__ y, float* __restrict__ sums, float* __restrict__ sqs,\n int N, int C, int S) {\n int idx = blockIdx.x;\n int n = idx / C;\n int c = idx - n*C;\n int tid = threadIdx.x;\n float sum = 0.0f, sq = 0.0f;\n const float* p = y + ((n*C + c) * S);\n for (int i=tid; i<S; i+=blockDim.x) {\n float v = p[i];\n sum += v;\n sq += v*v;\n }\n __shared__ float sm1[256];\n __shared__ float sm2[256];\n sm1[tid]=sum; sm2[tid]=sq; __syncthreads();\n for (int s=128; s>0; s>>=1) { if (tid<s) { sm1[tid]+=sm1[tid+s]; sm2[tid]+=sm2[tid+s]; } __syncthreads(); }\n if (tid==0) { sums[idx]=sm1[0]; sqs[idx]=sm2[0]; }\n}\n\n__global__ void finalize_kernel(const float* __restrict__ sums, const float* __restrict__ sqs,\n const float* __restrict__ gamma, const float* __restrict__ beta,\n float* __restrict__ out, float scale, float eps, int N, int C, int S) {\n int c = blockIdx.x * blockDim.x + threadIdx.x;\n if (c >= C) return;\n float ts=0.f, tq=0.f;\n for (int n=0; n<N; ++n) { ts += sums[n*C+c]; tq += sqs[n*C+c]; }\n float denom = (float)(N*S);\n float mean = scale * ts / denom;\n float ex2 = (scale*scale) * tq / denom;\n float var = ex2 - mean*mean;\n float inv = rsqrtf(var + eps);\n float g = gamma[c], b=beta[c];\n for (int n=0; n<N; ++n) {\n float avg = scale * sums[n*C+c] / (float)S;\n out[n*C+c] = (avg - mean) * inv * g + b;\n }\n}\n\ntorch::Tensor reduce_bn_pool_cuda(torch::Tensor y, torch::Tensor bn_w, torch::Tensor bn_b, double scale, double eps) {\n int N=y.size(0), C=y.size(1), S=y.size(2)*y.size(3)*y.size(4);\n auto sums = torch::empty({N, C}, y.options());\n auto sqs = torch::empty({N, C}, y.options());\n auto out = torch::empty({N, C, 1, 1, 1}, y.options());\n reduce_nc_kernel<<<N*C, 256>>>(y.data_ptr<float>(), sums.data_ptr<float>(), sqs.data_ptr<float>(), N, C, S);\n finalize_kernel<<<(C+127)/128, 128>>>(sums.data_ptr<float>(), sqs.data_ptr<float>(), bn_w.data_ptr<float>(), bn_b.data_ptr<float>(), out.data_ptr<float>(), (float)scale, (float)eps, N, C, S);\n return out;\n}\n\"\"\"\n\n_ext = load_inline(name='conv_bn_pool_ext_v3', cpp_sources=cpp_src, cuda_sources=cuda_src, functions=['bn_pool_forward'], verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels, out_channels, kernel_size, scale_factor, eps=1e-5, momentum=0.1):\n super(ModelNew, self).__init__()\n self.conv_transpose = nn.ConvTranspose3d(in_channels, out_channels, kernel_size)\n self.scale_factor = scale_factor\n self.batch_norm = nn.BatchNorm3d(out_channels, eps=eps, momentum=momentum)\n self.global_avg_pool = nn.AdaptiveAvgPool3d((1,1,1))\n def forward(self, x):\n return _ext.bn_pool_forward(x, self.conv_transpose.weight, self.conv_transpose.bias, self.batch_norm.weight, self.batch_norm.bias, float(self.scale_factor), float(self.batch_norm.eps))\n"
}