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\ntorch::Tensor fused_forward(torch::Tensor x, torch::Tensor w, torch::Tensor bias,\n torch::Tensor bn_w, torch::Tensor bn_b,\n torch::Tensor running_mean, torch::Tensor running_var,\n double scale, double eps, double momentum, bool training);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <ATen/ops/conv_transpose3d.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void reduce_x_kernel(const float* __restrict__ x, float* __restrict__ xs,\n int N, int Ci, int D, int H, int W) {\n int idx = blockIdx.x; int n = idx / Ci; int c = idx - n * Ci; int S = D*H*W;\n const float* ptr = x + ((n * Ci + c) * S);\n float sum = 0.f;\n for (int t=threadIdx.x; t<S; t+=blockDim.x) sum += ptr[t];\n __shared__ float smem[256]; smem[threadIdx.x]=sum; __syncthreads();\n for (int s=blockDim.x>>1; s>0; s>>=1){ if(threadIdx.x<s) smem[threadIdx.x]+=smem[threadIdx.x+s]; __syncthreads(); }\n if(threadIdx.x==0) xs[idx]=smem[0];\n}\n__global__ void reduce_w_kernel(const float* __restrict__ w, float* __restrict__ ws, int Ci, int Co, int K) {\n int idx=blockIdx.x; int ci=idx/Co; int co=idx-ci*Co; int K3=K*K*K;\n const float* ptr=w+((ci*Co+co)*K3); float sum=0.f;\n for(int t=threadIdx.x;t<K3;t+=blockDim.x) sum += ptr[t];\n __shared__ float smem[128]; smem[threadIdx.x]=sum; __syncthreads();\n for(int s=blockDim.x>>1;s>0;s>>=1){ if(threadIdx.x<s) smem[threadIdx.x]+=smem[threadIdx.x+s]; __syncthreads(); }\n if(threadIdx.x==0) ws[idx]=smem[0];\n}\n__global__ void eval_out_kernel(const float* __restrict__ xs, const float* __restrict__ ws,\n const float* __restrict__ bias, const float* __restrict__ bn_w,\n const float* __restrict__ bn_b, const float* __restrict__ rm,\n const float* __restrict__ rv, float* __restrict__ out,\n int N, int Ci, int Co, int Vout, float scale, float eps) {\n int idx=blockIdx.x*blockDim.x+threadIdx.x; if(idx>=N*Co) return;\n int n=idx/Co; int co=idx-n*Co; float dot=0.f; const float* xrow=xs+n*Ci;\n for(int ci=0;ci<Ci;++ci) dot += xrow[ci]*ws[ci*Co+co];\n float mean_conv=(bias?bias[co]:0.f)+dot/(float)Vout;\n float z=mean_conv*scale;\n out[idx]=(z-rm[co])*rsqrtf(rv[co]+eps)*bn_w[co]+bn_b[co];\n}\n\n__global__ void reduce_y_kernel(const float* __restrict__ y, float* __restrict__ sums, float* __restrict__ sqs,\n int N, int Co, int S) {\n int idx = blockIdx.x; // N*Co\n const float* ptr = y + idx * S;\n float sum=0.f, sq=0.f;\n for(int t=threadIdx.x; t<S; t+=blockDim.x){ float v=ptr[t]; sum += v; sq = fmaf(v, v, sq); }\n __shared__ float sm1[256]; __shared__ float sm2[256];\n sm1[threadIdx.x]=sum; sm2[threadIdx.x]=sq; __syncthreads();\n for(int s=blockDim.x>>1; s>0; s>>=1){ if(threadIdx.x<s){ sm1[threadIdx.x]+=sm1[threadIdx.x+s]; sm2[threadIdx.x]+=sm2[threadIdx.x+s]; } __syncthreads(); }\n if(threadIdx.x==0){ sums[idx]=sm1[0]; sqs[idx]=sm2[0]; }\n}\n\n__global__ void train_out_kernel(const float* __restrict__ sums, const float* __restrict__ sqs,\n const float* __restrict__ bn_w, const float* __restrict__ bn_b,\n float* __restrict__ rm, float* __restrict__ rv,\n float* __restrict__ out, int N, int Co, int S,\n float scale, float eps, float momentum) {\n int idx=blockIdx.x*blockDim.x+threadIdx.x; if(idx>=N*Co) return;\n int n=idx/Co; int co=idx-n*Co;\n float tsum=0.f, tsq=0.f;\n for(int nn=0; nn<N; ++nn){ int j=nn*Co+co; tsum += sums[j]; tsq += sqs[j]; }\n float M = (float)(N*S);\n float mean = tsum / M;\n float var = tsq / M - mean * mean;\n if (var < 0.f) var = 0.f;\n float mean_s = mean * scale;\n float var_s = var * scale * scale;\n float sample_mean_s = (sums[idx] / (float)S) * scale;\n out[idx] = (sample_mean_s - mean_s) * rsqrtf(var_s + eps) * bn_w[co] + bn_b[co];\n if(n==0){\n float unbiased = var_s * (M / (M - 1.0f));\n rm[co] = rm[co] * (1.f - momentum) + momentum * mean_s;\n rv[co] = rv[co] * (1.f - momentum) + momentum * unbiased;\n }\n}\n\ntorch::Tensor eval_fast(torch::Tensor x, torch::Tensor w, torch::Tensor bias, torch::Tensor bn_w, torch::Tensor bn_b,\n torch::Tensor running_mean, torch::Tensor running_var, double scale_d, double eps_d) {\n x=x.contiguous(); w=w.contiguous();\n int N=x.size(0), Ci=x.size(1), D=x.size(2), H=x.size(3), W=x.size(4); int Co=w.size(1), K=w.size(2);\n int Vout=(D+K-1)*(H+K-1)*(W+K-1);\n auto xs=torch::empty({N,Ci}, x.options()); auto ws=torch::empty({Ci,Co}, x.options()); auto out=torch::empty({N,Co,1,1,1}, x.options());\n cudaStream_t stream=at::cuda::getCurrentCUDAStream();\n reduce_x_kernel<<<N*Ci,256,0,stream>>>(x.data_ptr<float>(), xs.data_ptr<float>(), N,Ci,D,H,W);\n reduce_w_kernel<<<Ci*Co,128,0,stream>>>(w.data_ptr<float>(), ws.data_ptr<float>(), Ci,Co,K);\n eval_out_kernel<<<(N*Co+255)/256,256,0,stream>>>(xs.data_ptr<float>(), ws.data_ptr<float>(), bias.defined()?bias.data_ptr<float>():nullptr, bn_w.data_ptr<float>(), bn_b.data_ptr<float>(), running_mean.data_ptr<float>(), running_var.data_ptr<float>(), out.data_ptr<float>(), N,Ci,Co,Vout,(float)scale_d,(float)eps_d);\n return out;\n}\n\ntorch::Tensor fused_forward(torch::Tensor x, torch::Tensor w, torch::Tensor bias,\n torch::Tensor bn_w, torch::Tensor bn_b,\n torch::Tensor running_mean, torch::Tensor running_var,\n double scale_d, double eps_d, double momentum_d, bool training) {\n if(!training) return eval_fast(x,w,bias,bn_w,bn_b,running_mean,running_var,scale_d,eps_d);\n x=x.contiguous(); w=w.contiguous();\n c10::optional<at::Tensor> bb = bias.defined() ? c10::optional<at::Tensor>(bias) : c10::nullopt;\n auto y = at::conv_transpose3d(x, w, bb, {1,1,1}, {0,0,0}, {0,0,0}, 1, {1,1,1});\n int N=y.size(0), Co=y.size(1), S=y.size(2)*y.size(3)*y.size(4);\n auto sums=torch::empty({N,Co}, y.options()); auto sqs=torch::empty({N,Co}, y.options()); auto out=torch::empty({N,Co,1,1,1}, y.options());\n cudaStream_t stream=at::cuda::getCurrentCUDAStream();\n reduce_y_kernel<<<N*Co,256,0,stream>>>(y.data_ptr<float>(), sums.data_ptr<float>(), sqs.data_ptr<float>(), N, Co, S);\n train_out_kernel<<<(N*Co+255)/256,256,0,stream>>>(sums.data_ptr<float>(), sqs.data_ptr<float>(), bn_w.data_ptr<float>(), bn_b.data_ptr<float>(), running_mean.data_ptr<float>(), running_var.data_ptr<float>(), out.data_ptr<float>(), N, Co, S, (float)scale_d, (float)eps_d, (float)momentum_d);\n return out;\n}\n\"\"\"\n\n_ext = load_inline(name=\"fused_deconv_bn_pool_v2\", cpp_sources=_cpp_src, cuda_sources=_cuda_src,\n functions=[\"fused_forward\"], extra_cflags=[\"-O3\"], extra_cuda_cflags=[\"-O3\"], 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 def forward(self, x):\n return _ext.fused_forward(x, self.conv_transpose.weight, self.conv_transpose.bias,\n self.batch_norm.weight, self.batch_norm.bias,\n self.batch_norm.running_mean, self.batch_norm.running_var,\n float(self.scale_factor), float(self.batch_norm.eps),\n float(self.batch_norm.momentum), bool(self.training and self.batch_norm.training))\n"
}