call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\ncpp_source = r'''\n#include <torch/extension.h>\ntorch::Tensor depthwise_conv2d_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, bool has_bias, int stride, int padding);\n'''\ncuda_source = r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#define TILE_W 128\n#define TILE_H 16\n#define BLOCK_X 128\n#define BLOCK_Y 4\n__global__ __launch_bounds__(512, 2)\nvoid dw3_direct_kernel(const float* __restrict__ x,const float* __restrict__ w,const float* __restrict__ bias,float* __restrict__ y,int N,int C,int H,int W,int OH,int OW,bool has_bias){\n const int tx=threadIdx.x, ty=threadIdx.y;\n const int plane=blockIdx.z, c=plane%C, n=plane/C;\n const int ox=blockIdx.x*TILE_W+tx;\n const int oy0=blockIdx.y*TILE_H+ty*4;\n if(ox>=OW) return;\n const float* __restrict__ xp=x+((size_t)n*C+c)*H*W;\n const float* __restrict__ wp=w+(size_t)c*9;\n float* __restrict__ yp=y+((size_t)n*C+c)*OH*OW;\n const float w00=wp[0],w01=wp[1],w02=wp[2],w10=wp[3],w11=wp[4],w12=wp[5],w20=wp[6],w21=wp[7],w22=wp[8];\n const float b=has_bias?bias[c]:0.0f;\n // preload up to 6 rows x 3 cols for four vertically adjacent outputs\n float r00=0,r01=0,r02=0,r10=0,r11=0,r12=0,r20=0,r21=0,r22=0,r30=0,r31=0,r32=0,r40=0,r41=0,r42=0,r50=0,r51=0,r52=0;\n const int maxrow=oy0+5;\n const size_t base_col=ox;\n if(maxrow < H){\n const float* p0=xp+(size_t)(oy0+0)*W+base_col;\n const float* p1=xp+(size_t)(oy0+1)*W+base_col;\n const float* p2=xp+(size_t)(oy0+2)*W+base_col;\n const float* p3=xp+(size_t)(oy0+3)*W+base_col;\n const float* p4=xp+(size_t)(oy0+4)*W+base_col;\n const float* p5=xp+(size_t)(oy0+5)*W+base_col;\n r00=p0[0]; r01=p0[1]; r02=p0[2]; r10=p1[0]; r11=p1[1]; r12=p1[2]; r20=p2[0]; r21=p2[1]; r22=p2[2];\n r30=p3[0]; r31=p3[1]; r32=p3[2]; r40=p4[0]; r41=p4[1]; r42=p4[2]; r50=p5[0]; r51=p5[1]; r52=p5[2];\n } else {\n if(oy0+0 < H){ const float* p=xp+(size_t)(oy0+0)*W+base_col; r00=p[0]; r01=p[1]; r02=p[2]; }\n if(oy0+1 < H){ const float* p=xp+(size_t)(oy0+1)*W+base_col; r10=p[0]; r11=p[1]; r12=p[2]; }\n if(oy0+2 < H){ const float* p=xp+(size_t)(oy0+2)*W+base_col; r20=p[0]; r21=p[1]; r22=p[2]; }\n if(oy0+3 < H){ const float* p=xp+(size_t)(oy0+3)*W+base_col; r30=p[0]; r31=p[1]; r32=p[2]; }\n if(oy0+4 < H){ const float* p=xp+(size_t)(oy0+4)*W+base_col; r40=p[0]; r41=p[1]; r42=p[2]; }\n if(oy0+5 < H){ const float* p=xp+(size_t)(oy0+5)*W+base_col; r50=p[0]; r51=p[1]; r52=p[2]; }\n }\n if(oy0+0<OH){ float s=b; s=fmaf(r00,w00,s); s=fmaf(r01,w01,s); s=fmaf(r02,w02,s); s=fmaf(r10,w10,s); s=fmaf(r11,w11,s); s=fmaf(r12,w12,s); s=fmaf(r20,w20,s); s=fmaf(r21,w21,s); s=fmaf(r22,w22,s); yp[(size_t)(oy0+0)*OW+ox]=s; }\n if(oy0+1<OH){ float s=b; s=fmaf(r10,w00,s); s=fmaf(r11,w01,s); s=fmaf(r12,w02,s); s=fmaf(r20,w10,s); s=fmaf(r21,w11,s); s=fmaf(r22,w12,s); s=fmaf(r30,w20,s); s=fmaf(r31,w21,s); s=fmaf(r32,w22,s); yp[(size_t)(oy0+1)*OW+ox]=s; }\n if(oy0+2<OH){ float s=b; s=fmaf(r20,w00,s); s=fmaf(r21,w01,s); s=fmaf(r22,w02,s); s=fmaf(r30,w10,s); s=fmaf(r31,w11,s); s=fmaf(r32,w12,s); s=fmaf(r40,w20,s); s=fmaf(r41,w21,s); s=fmaf(r42,w22,s); yp[(size_t)(oy0+2)*OW+ox]=s; }\n if(oy0+3<OH){ float s=b; s=fmaf(r30,w00,s); s=fmaf(r31,w01,s); s=fmaf(r32,w02,s); s=fmaf(r40,w10,s); s=fmaf(r41,w11,s); s=fmaf(r42,w12,s); s=fmaf(r50,w20,s); s=fmaf(r51,w21,s); s=fmaf(r52,w22,s); yp[(size_t)(oy0+3)*OW+ox]=s; }\n}\ntorch::Tensor depthwise_conv2d_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, bool has_bias, int stride, int padding){\n int N=x.size(0),C=x.size(1),H=x.size(2),W=x.size(3),K=weight.size(2); int OH=(H+2*padding-K)/stride+1, OW=(W+2*padding-K)/stride+1;\n auto y=torch::empty({N,C,OH,OW},x.options()); dim3 block(BLOCK_X,BLOCK_Y); dim3 grid((OW+TILE_W-1)/TILE_W,(OH+TILE_H-1)/TILE_H,N*C);\n dw3_direct_kernel<<<grid,block>>>(x.data_ptr<float>(),weight.data_ptr<float>(),has_bias?bias.data_ptr<float>():nullptr,y.data_ptr<float>(),N,C,H,W,OH,OW,has_bias); return y;\n}\n'''\n_ext=load_inline(name='dwconv_ext_v4', cpp_sources=[cpp_source], cuda_sources=[cuda_source], functions=['depthwise_conv2d_forward'], extra_cflags=['-O3'], extra_cuda_cflags=['-O3','--use_fast_math'], verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,in_channels:int,kernel_size:int,stride:int=1,padding:int=0,bias:bool=False):\n super(ModelNew,self).__init__(); self.conv2d=nn.Conv2d(in_channels,in_channels,kernel_size,stride=stride,padding=padding,groups=in_channels,bias=bias); self.stride=stride; self.padding=padding\n def forward(self,x:torch.Tensor)->torch.Tensor:\n b=self.conv2d.bias if self.conv2d.bias is not None else torch.empty(0,device=x.device,dtype=x.dtype)\n return _ext.depthwise_conv2d_forward(x.contiguous(),self.conv2d.weight.contiguous(),b,self.conv2d.bias is not None,self.stride,self.padding)\n"
}