call → run_correctness
callrun_correctness
{
"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>\ntorch::Tensor mish_bn_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'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x \" must be a CUDA tensor\")\n__device__ __forceinline__ float mish_func(float x) { if (x > 20.0f) return x; float e = expf(x); return x * (e * (e + 2.0f)) / (e * e + 2.0f * e + 2.0f); }\ntemplate<int BLOCK>\n__global__ void act_partial_kernel(float* __restrict__ x, float* __restrict__ psum, float* __restrict__ psq, int C, int HW, int M, int parts) {\n int c=blockIdx.x,p=blockIdx.y,tid=threadIdx.x; int64_t start=((int64_t)p*M)/parts,end=((int64_t)(p+1)*M)/parts; float sum=0.f,sq=0.f;\n for(int64_t m=start+tid;m<end;m+=BLOCK){ int n=(int)(m/HW); int hw=(int)(m-(int64_t)n*HW); int64_t idx=((int64_t)n*C+c)*HW+hw; float a=mish_func(x[idx]); x[idx]=a; sum+=a; sq+=a*a; }\n __shared__ float ssum[BLOCK],ssq[BLOCK]; ssum[tid]=sum; ssq[tid]=sq; __syncthreads();\n for(int s=BLOCK/2;s>0;s>>=1){ if(tid<s){ssum[tid]+=ssum[tid+s]; ssq[tid]+=ssq[tid+s];} __syncthreads(); } if(tid==0){int off=c*parts+p; psum[off]=ssum[0]; psq[off]=ssq[0];}\n}\ntemplate<int BLOCK>\n__global__ void finalize_kernel(const float* __restrict__ psum,const float* __restrict__ psq,const float* __restrict__ weight,const float* __restrict__ bias,float* __restrict__ running_mean,float* __restrict__ running_var,float* __restrict__ scale_out,float* __restrict__ shift_out,int C,int M,int parts,float momentum,float eps){\n int c=blockIdx.x,tid=threadIdx.x; float sum=0.f,sq=0.f; for(int p=tid;p<parts;p+=BLOCK){int off=c*parts+p; sum+=psum[off]; sq+=psq[off];} __shared__ float ssum[BLOCK],ssq[BLOCK]; ssum[tid]=sum; ssq[tid]=sq; __syncthreads(); for(int s=BLOCK/2;s>0;s>>=1){if(tid<s){ssum[tid]+=ssum[tid+s]; ssq[tid]+=ssq[tid+s];} __syncthreads();} if(tid==0){float mean=ssum[0]/(float)M; float var=ssq[0]/(float)M-mean*mean; if(var<0.f)var=0.f; float inv=rsqrtf(var+eps); float w=weight[c]; scale_out[c]=w*inv; shift_out[c]=bias[c]-mean*w*inv; running_mean[c]=running_mean[c]*(1.f-momentum)+momentum*mean; running_var[c]=running_var[c]*(1.f-momentum)+momentum*(var*((float)M/(float)(M-1)));}}\ntemplate<int BLOCK>\n__global__ void norm_channel_kernel(float* __restrict__ x,const float* __restrict__ scale,const float* __restrict__ shift,int C,int HW,int M,int parts){\n int c=blockIdx.x,p=blockIdx.y,tid=threadIdx.x; float sc=scale[c], sh=shift[c]; int64_t start=((int64_t)p*M)/parts,end=((int64_t)(p+1)*M)/parts; for(int64_t m=start+tid;m<end;m+=BLOCK){int n=(int)(m/HW); int hw=(int)(m-(int64_t)n*HW); int64_t idx=((int64_t)n*C+c)*HW+hw; x[idx]=x[idx]*sc+sh;}}\ntemplate<int BLOCK>\n__global__ void eval_channel_kernel(float* __restrict__ x,const float* __restrict__ weight,const float* __restrict__ bias,const float* __restrict__ running_mean,const float* __restrict__ running_var,int C,int HW,int M,int parts,float eps){\n int c=blockIdx.x,p=blockIdx.y,tid=threadIdx.x; float sc=weight[c]*rsqrtf(running_var[c]+eps); float sh=bias[c]-running_mean[c]*sc; int64_t start=((int64_t)p*M)/parts,end=((int64_t)(p+1)*M)/parts; for(int64_t m=start+tid;m<end;m+=BLOCK){int n=(int)(m/HW); int hw=(int)(m-(int64_t)n*HW); int64_t idx=((int64_t)n*C+c)*HW+hw; float a=mish_func(x[idx]); x[idx]=a*sc+sh;}}\ntorch::Tensor mish_bn_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor running_mean, torch::Tensor running_var, bool training, double momentum, double eps){\n CHECK_CUDA(x); int N=(int)x.size(0),C=(int)x.size(1),HW=(int)(x.size(2)*x.size(3)),M=N*HW; cudaStream_t stream=at::cuda::getCurrentCUDAStream(); const int threads=256; int parts=16; if(training){auto opts=x.options(); auto ps=torch::empty({C,parts},opts),pq=torch::empty({C,parts},opts),sc=torch::empty({C},opts),sh=torch::empty({C},opts); act_partial_kernel<256><<<dim3(C,parts),threads,0,stream>>>(x.data_ptr<float>(),ps.data_ptr<float>(),pq.data_ptr<float>(),C,HW,M,parts); finalize_kernel<256><<<C,threads,0,stream>>>(ps.data_ptr<float>(),pq.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),running_mean.data_ptr<float>(),running_var.data_ptr<float>(),sc.data_ptr<float>(),sh.data_ptr<float>(),C,M,parts,(float)momentum,(float)eps); norm_channel_kernel<256><<<dim3(C,parts),threads,0,stream>>>(x.data_ptr<float>(),sc.data_ptr<float>(),sh.data_ptr<float>(),C,HW,M,parts);} else {eval_channel_kernel<256><<<dim3(C,parts),threads,0,stream>>>(x.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),running_mean.data_ptr<float>(),running_var.data_ptr<float>(),C,HW,M,parts,(float)eps);} return x;}\n'''\n_ext=load_inline(name='mish_bn_ext_v3',cpp_sources=[cpp_src],cuda_sources=[cuda_src],functions=['mish_bn_forward'],extra_cuda_cflags=['-O3','--use_fast_math'],extra_cflags=['-O3'],verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,in_channels,out_channels,kernel_size,eps=1e-5,momentum=0.1):\n super(ModelNew,self).__init__(); self.conv=nn.Conv2d(in_channels,out_channels,kernel_size); self.bn=nn.BatchNorm2d(out_channels,eps=eps,momentum=momentum)\n def forward(self,x):\n y=self.conv(x); return _ext.mish_bn_forward(y,self.bn.weight,self.bn.bias,self.bn.running_mean,self.bn.running_var,self.training,float(self.bn.momentum),float(self.bn.eps))\n"
}