call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n_cpp_src=r'''\n#include <torch/extension.h>\ntorch::Tensor bn_softmax_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps);\ntorch::Tensor softmax_forward_cuda(torch::Tensor x);\ntorch::Tensor bn_softmax_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, torch::Tensor mean, torch::Tensor var, double eps){return bn_softmax_forward_cuda(x,weight,bias,mean,var,eps);} \ntorch::Tensor softmax_forward(torch::Tensor x){return softmax_forward_cuda(x);} \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#include <math.h>\n__inline__ __device__ float wrmax(float v){for(int o=16;o>0;o>>=1)v=fmaxf(v,__shfl_down_sync(0xffffffff,v,o));return v;}\n__inline__ __device__ float wrsum(float v){for(int o=16;o>0;o>>=1)v+=__shfl_down_sync(0xffffffff,v,o);return v;}\n__inline__ __device__ float brmax(float v){__shared__ float sh[32];int lane=threadIdx.x&31,wid=threadIdx.x>>5;v=wrmax(v);if(lane==0)sh[wid]=v;__syncthreads();v=(threadIdx.x<(blockDim.x+31)/32)?sh[lane]:-INFINITY;if(wid==0)v=wrmax(v);return v;}\n__inline__ __device__ float brsum(float v){__shared__ float sh[32];int lane=threadIdx.x&31,wid=threadIdx.x>>5;v=wrsum(v);if(lane==0)sh[wid]=v;__syncthreads();v=(threadIdx.x<(blockDim.x+31)/32)?sh[lane]:0.0f;if(wid==0)v=wrsum(v);return v;}\n__global__ void softmax_kernel(const float* __restrict__ x,float* __restrict__ out,int rows,int W){int row=blockIdx.x,base=row*W;float m=-INFINITY;for(int w=threadIdx.x;w<W;w+=blockDim.x)m=fmaxf(m,x[base+w]);m=brmax(m);float s=0.f;for(int w=threadIdx.x;w<W;w+=blockDim.x)s+=expf(x[base+w]-m);s=brsum(s);float inv=1.f/s;for(int w=threadIdx.x;w<W;w+=blockDim.x)out[base+w]=expf(x[base+w]-m)*inv;}\n__global__ void bn_softmax_kernel(const float* __restrict__ x,const float* __restrict__ gamma,const float* __restrict__ beta,const float* __restrict__ mean,const float* __restrict__ var,float* __restrict__ out,int rows,int C,int H,int W,float eps){int row=blockIdx.x;if(row>=rows)return;int c=(row/H)%C;int base=row*W;float scale=gamma[c]*rsqrtf(var[c]+eps);float shift=beta[c]-mean[c]*scale;float m=-INFINITY;for(int w=threadIdx.x;w<W;w+=blockDim.x){float v=x[base+w]*scale+shift;m=fmaxf(m,v);}m=brmax(m);float s=0.f;for(int w=threadIdx.x;w<W;w+=blockDim.x)s+=expf((x[base+w]*scale+shift)-m);s=brsum(s);float inv=1.f/s;for(int w=threadIdx.x;w<W;w+=blockDim.x)out[base+w]=expf((x[base+w]*scale+shift)-m)*inv;}\ntorch::Tensor softmax_forward_cuda(torch::Tensor x){auto y=torch::empty_like(x);int rows=x.numel()/x.size(3),W=x.size(3);softmax_kernel<<<rows,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),y.data_ptr<float>(),rows,W);return y;}\ntorch::Tensor bn_softmax_forward_cuda(torch::Tensor x,torch::Tensor weight,torch::Tensor bias,torch::Tensor mean,torch::Tensor var,double eps){auto y=torch::empty_like(x);int N=x.size(0),C=x.size(1),H=x.size(2),W=x.size(3);int rows=N*C*H;bn_softmax_kernel<<<rows,256,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),weight.data_ptr<float>(),bias.data_ptr<float>(),mean.data_ptr<float>(),var.data_ptr<float>(),y.data_ptr<float>(),rows,C,H,W,(float)eps);return y;}\n'''\n_ext=load_inline(name='unet_sm_ext_v3',cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=['bn_softmax_forward','softmax_forward'],with_cuda=True,extra_cuda_cflags=['-O3','--use_fast_math'],extra_cflags=['-O3'],verbose=False)\nclass DoubleConv(nn.Module):\n def __init__(self,in_channels,out_channels):\n super().__init__(); self.double_conv=nn.Sequential(nn.Conv2d(in_channels,out_channels,3,padding=1),nn.BatchNorm2d(out_channels),nn.Softmax(dim=-1),nn.Conv2d(out_channels,out_channels,3,padding=1),nn.BatchNorm2d(out_channels),nn.Softmax(dim=-1))\nclass ModelNew(nn.Module):\n def __init__(self,in_channels,out_channels,features):\n super().__init__(); self.encoder1=DoubleConv(in_channels,features); self.pool1=nn.MaxPool2d(2,2); self.encoder2=DoubleConv(features,features*2); self.pool2=nn.MaxPool2d(2,2); self.encoder3=DoubleConv(features*2,features*4); self.pool3=nn.MaxPool2d(2,2); self.encoder4=DoubleConv(features*4,features*8); self.pool4=nn.MaxPool2d(2,2); self.bottleneck=DoubleConv(features*8,features*16); self.upconv4=nn.ConvTranspose2d(features*16,features*8,2,2); self.decoder4=DoubleConv(features*16,features*8); self.upconv3=nn.ConvTranspose2d(features*8,features*4,2,2); self.decoder3=DoubleConv(features*8,features*4); self.upconv2=nn.ConvTranspose2d(features*4,features*2,2,2); self.decoder2=DoubleConv(features*4,features*2); self.upconv1=nn.ConvTranspose2d(features*2,features,2,2); self.decoder1=DoubleConv(features*2,features); self.final_conv=nn.Conv2d(features,out_channels,1)\n def _bn_sm(self,x,bn):\n if self.training:\n x=F.batch_norm(x,bn.running_mean,bn.running_var,bn.weight,bn.bias,True,bn.momentum,bn.eps)\n return _ext.softmax_forward(x.contiguous())\n return _ext.bn_softmax_forward(x.contiguous(),bn.weight,bn.bias,bn.running_mean,bn.running_var,bn.eps)\n def _dc(self,x,m):\n s=m.double_conv; x=F.conv2d(x,s[0].weight,s[0].bias,padding=1); x=self._bn_sm(x,s[1]); x=F.conv2d(x,s[3].weight,s[3].bias,padding=1); x=self._bn_sm(x,s[4]); return x\n def forward(self,x):\n enc1=self._dc(x,self.encoder1); enc2=self._dc(F.max_pool2d(enc1,2,2),self.encoder2); enc3=self._dc(F.max_pool2d(enc2,2,2),self.encoder3); enc4=self._dc(F.max_pool2d(enc3,2,2),self.encoder4); bottleneck=self._dc(F.max_pool2d(enc4,2,2),self.bottleneck); dec4=F.conv_transpose2d(bottleneck,self.upconv4.weight,self.upconv4.bias,stride=2); dec4=self._dc(torch.cat((dec4,enc4),1),self.decoder4); dec3=F.conv_transpose2d(dec4,self.upconv3.weight,self.upconv3.bias,stride=2); dec3=self._dc(torch.cat((dec3,enc3),1),self.decoder3); dec2=F.conv_transpose2d(dec3,self.upconv2.weight,self.upconv2.bias,stride=2); dec2=self._dc(torch.cat((dec2,enc2),1),self.decoder2); dec1=F.conv_transpose2d(dec2,self.upconv1.weight,self.upconv1.bias,stride=2); dec1=self._dc(torch.cat((dec1,enc1),1),self.decoder1); return F.conv2d(dec1,self.final_conv.weight,self.final_conv.bias)\n"
}