call → run_correctness
callrun_correctness
{
"kernel_code": "import os\nos.environ['TORCH_EXTENSIONS_DIR']='/dev/shm/torch_ext_test'\nos.environ['TMPDIR']='/dev/shm'\nimport torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\ncpp_src=r'''#include <torch/extension.h>\ntorch::Tensor dw_sep_forward(torch::Tensor x, torch::Tensor dw_w, torch::Tensor pw_w, torch::Tensor dw_b, torch::Tensor pw_b, int stride, int padding, int dilation);\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#include <mma.h>\nusing namespace nvcuda;\n#define BM 64\n#define BN 32\n#define WARPS 8\n__device__ __forceinline__ float tf32_round(float x){ unsigned int u=__float_as_uint(x); unsigned int e=u & 0x7f800000u; if(e==0x7f800000u) return x; unsigned int lsb=(u>>13)&1u; u += 0x00000fffu + lsb; u &= 0xffffe000u; return __uint_as_float(u); }\n__global__ void kern(const float* __restrict__ x,const float* __restrict__ dw_w,const float* __restrict__ pw_w,const float* __restrict__ dw_b,const float* __restrict__ pw_b,float* __restrict__ out,int N,int C,int H,int W,int OC,int KH,int KW,int OH,int OW,int stride,int padding,int dilation,int has_dw_b,int has_pw_b){\n extern __shared__ float sm[]; float* D0=sm; float* D1=D0+BM*C; float* B0=D1+BM*C; float* B1=B0+C*BN; float* shO=B1+C*BN; int tid=threadIdx.x,lane=tid&31,warp=tid>>5; int mtile=blockIdx.x*BM,octile=blockIdx.y*BN; int M=N*OH*OW;\n for(int idx=tid;idx<BM*C;idx+=blockDim.x){int c=idx/BM,lm=idx-c*BM,m=mtile+lm;float acc=0.f;if(m<M){int t=m;int ow=t%OW;t/=OW;int oh=t%OH;t/=OH;int n=t;for(int r=0;r<3;r++){int ih=oh*stride+r*dilation-padding;if(r<KH&&(unsigned)ih<(unsigned)H){for(int s=0;s<3;s++){int iw=ow*stride+s*dilation-padding;if(s<KW&&(unsigned)iw<(unsigned)W)acc=fmaf(x[((n*C+c)*H+ih)*W+iw],dw_w[(c*KH+r)*KW+s],acc);}}}if(has_dw_b)acc+=dw_b[c];}float a0=tf32_round(acc);D0[lm*C+c]=a0;D1[lm*C+c]=acc-a0;}\n for(int idx=tid;idx<C*BN;idx+=blockDim.x){int c=idx/BN,ln=idx-c*BN,oc=octile+ln;float v=(oc<OC)?pw_w[oc*C+c]:0.f;float b0=tf32_round(v);B0[c*BN+ln]=b0;B1[c*BN+ln]=v-b0;} __syncthreads();\n int wm=warp&3,wn=warp>>2,row=wm*16,col=wn*16; wmma::fragment<wmma::matrix_a,16,16,8,wmma::precision::tf32,wmma::row_major> af; wmma::fragment<wmma::matrix_b,16,16,8,wmma::precision::tf32,wmma::row_major> bf; wmma::fragment<wmma::accumulator,16,16,8,float> cf; wmma::fill_fragment(cf,0.f); for(int k=0;k<C;k+=8){wmma::load_matrix_sync(af,D0+row*C+k,C);wmma::load_matrix_sync(bf,B0+k*BN+col,BN);wmma::mma_sync(cf,af,bf,cf);wmma::load_matrix_sync(af,D1+row*C+k,C);wmma::load_matrix_sync(bf,B0+k*BN+col,BN);wmma::mma_sync(cf,af,bf,cf);wmma::load_matrix_sync(af,D0+row*C+k,C);wmma::load_matrix_sync(bf,B1+k*BN+col,BN);wmma::mma_sync(cf,af,bf,cf);} float* tile=shO+warp*256; wmma::store_matrix_sync(tile,cf,16,wmma::mem_col_major); __syncwarp(); for(int i=lane;i<256;i+=32){int lm=row+(i%16),ln=col+(i/16),m=mtile+lm,oc=octile+ln;if(m<M&&oc<OC){float v=tile[i];if(has_pw_b)v+=pw_b[oc];int t=m;int ow=t%OW;t/=OW;int oh=t%OH;t/=OH;int n=t;out[((n*OC+oc)*OH+oh)*OW+ow]=v;}}\n}\ntorch::Tensor dw_sep_forward(torch::Tensor x,torch::Tensor dw_w,torch::Tensor pw_w,torch::Tensor dw_b,torch::Tensor pw_b,int stride,int padding,int dilation){x=x.contiguous();dw_w=dw_w.contiguous();pw_w=pw_w.contiguous();int N=x.size(0),C=x.size(1),H=x.size(2),W=x.size(3),KH=dw_w.size(2),KW=dw_w.size(3),OC=pw_w.size(0);int OH=(H+2*padding-dilation*(KH-1)-1)/stride+1,OW=(W+2*padding-dilation*(KW-1)-1)/stride+1;auto out=torch::empty({N,OC,OH,OW},x.options());int M=N*OH*OW;dim3 block(256),grid((M+BM-1)/BM,(OC+BN-1)/BN);size_t smem=(2*BM*C+2*C*BN+WARPS*256)*sizeof(float);cudaFuncSetAttribute(kern,cudaFuncAttributeMaxDynamicSharedMemorySize,(int)smem);int hdb=dw_b.numel()>0,hpb=pw_b.numel()>0;kern<<<grid,block,smem,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),dw_w.data_ptr<float>(),pw_w.data_ptr<float>(),hdb?dw_b.contiguous().data_ptr<float>():nullptr,hpb?pw_b.contiguous().data_ptr<float>():nullptr,out.data_ptr<float>(),N,C,H,W,OC,KH,KW,OH,OW,stride,padding,dilation,hdb,hpb);C10_CUDA_KERNEL_LAUNCH_CHECK();return out;}\n'''\n_ext=load_inline(name='dwsep_wmma_v5',cpp_sources=[cpp_src],cuda_sources=[cuda_src],functions=['dw_sep_forward'],extra_cuda_cflags=['-O3'],verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,in_channels:int,out_channels:int,kernel_size:int,stride:int=1,padding:int=0,dilation:int=1,bias:bool=False):\n super().__init__();self.depthwise=nn.Conv2d(in_channels,in_channels,kernel_size,stride=stride,padding=padding,dilation=dilation,groups=in_channels,bias=bias);self.pointwise=nn.Conv2d(in_channels,out_channels,1,bias=bias);self.stride=stride;self.padding=padding;self.dilation=dilation\n def forward(self,x):\n e=torch.empty(0,device=x.device,dtype=x.dtype);return _ext.dw_sep_forward(x,self.depthwise.weight,self.pointwise.weight,self.depthwise.bias if self.depthwise.bias is not None else e,self.pointwise.bias if self.pointwise.bias is not None else e,self.stride,self.padding,self.dilation)\n"
}