call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n_cpp_src=r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor maxpool2d_forward(torch::Tensor x,int64_t kernel_size,int64_t stride,int64_t padding,int64_t dilation);\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 <cmath>\n#define TILE_W 64\n#define TILE_H 64\n#define BLOCK_X 32\n#define BLOCK_Y 8\n#define SMEM_W 67\n#define SMEM_H 67\n__global__ __launch_bounds__(256,2)\nvoid maxpool4s1p1_kernel(const float* __restrict__ x,float* __restrict__ y,int H,int W,int OH,int OW){\n __shared__ float smem[SMEM_H][SMEM_W];\n int tile_x=blockIdx.x*TILE_W, tile_y=blockIdx.y*TILE_H, nc=blockIdx.z;\n int tx=threadIdx.x, ty=threadIdx.y, tid=ty*BLOCK_X+tx;\n int in_base_y=tile_y-1, in_base_x=tile_x-1;\n const float* __restrict__ ximg=x+(size_t)nc*H*W;\n if(in_base_y>=0 && in_base_x>=0 && in_base_y+SMEM_H<=H && in_base_x+SMEM_W<=W){\n for(int idx=tid; idx<SMEM_H*SMEM_W; idx+=256){int sy=idx/SMEM_W; int sx=idx-sy*SMEM_W; smem[sy][sx]=ximg[(in_base_y+sy)*W+(in_base_x+sx)];}\n }else{\n for(int idx=tid; idx<SMEM_H*SMEM_W; idx+=256){int sy=idx/SMEM_W; int sx=idx-sy*SMEM_W; int iy=in_base_y+sy; int ix=in_base_x+sx; float v=-INFINITY; if((unsigned)iy<(unsigned)H && (unsigned)ix<(unsigned)W) v=ximg[iy*W+ix]; smem[sy][sx]=v;}\n }\n __syncthreads();\n int oh0=tile_y+ty*8; int sy0=ty*8; float* __restrict__ yimg=y+(size_t)nc*OH*OW;\n #pragma unroll\n for(int off=0; off<64; off+=32){\n int ow=tile_x+tx+off; int sx=tx+off;\n float h0=fmaxf(fmaxf(smem[sy0+0][sx+0],smem[sy0+0][sx+1]),fmaxf(smem[sy0+0][sx+2],smem[sy0+0][sx+3]));\n float h1=fmaxf(fmaxf(smem[sy0+1][sx+0],smem[sy0+1][sx+1]),fmaxf(smem[sy0+1][sx+2],smem[sy0+1][sx+3]));\n float h2=fmaxf(fmaxf(smem[sy0+2][sx+0],smem[sy0+2][sx+1]),fmaxf(smem[sy0+2][sx+2],smem[sy0+2][sx+3]));\n float h3=fmaxf(fmaxf(smem[sy0+3][sx+0],smem[sy0+3][sx+1]),fmaxf(smem[sy0+3][sx+2],smem[sy0+3][sx+3]));\n float h4=fmaxf(fmaxf(smem[sy0+4][sx+0],smem[sy0+4][sx+1]),fmaxf(smem[sy0+4][sx+2],smem[sy0+4][sx+3]));\n float h5=fmaxf(fmaxf(smem[sy0+5][sx+0],smem[sy0+5][sx+1]),fmaxf(smem[sy0+5][sx+2],smem[sy0+5][sx+3]));\n float h6=fmaxf(fmaxf(smem[sy0+6][sx+0],smem[sy0+6][sx+1]),fmaxf(smem[sy0+6][sx+2],smem[sy0+6][sx+3]));\n float h7=fmaxf(fmaxf(smem[sy0+7][sx+0],smem[sy0+7][sx+1]),fmaxf(smem[sy0+7][sx+2],smem[sy0+7][sx+3]));\n float h8=fmaxf(fmaxf(smem[sy0+8][sx+0],smem[sy0+8][sx+1]),fmaxf(smem[sy0+8][sx+2],smem[sy0+8][sx+3]));\n float h9=fmaxf(fmaxf(smem[sy0+9][sx+0],smem[sy0+9][sx+1]),fmaxf(smem[sy0+9][sx+2],smem[sy0+9][sx+3]));\n float h10=fmaxf(fmaxf(smem[sy0+10][sx+0],smem[sy0+10][sx+1]),fmaxf(smem[sy0+10][sx+2],smem[sy0+10][sx+3]));\n if(ow<OW){\n if(oh0+0<OH) yimg[(oh0+0)*OW+ow]=fmaxf(fmaxf(h0,h1),fmaxf(h2,h3));\n if(oh0+1<OH) yimg[(oh0+1)*OW+ow]=fmaxf(fmaxf(h1,h2),fmaxf(h3,h4));\n if(oh0+2<OH) yimg[(oh0+2)*OW+ow]=fmaxf(fmaxf(h2,h3),fmaxf(h4,h5));\n if(oh0+3<OH) yimg[(oh0+3)*OW+ow]=fmaxf(fmaxf(h3,h4),fmaxf(h5,h6));\n if(oh0+4<OH) yimg[(oh0+4)*OW+ow]=fmaxf(fmaxf(h4,h5),fmaxf(h6,h7));\n if(oh0+5<OH) yimg[(oh0+5)*OW+ow]=fmaxf(fmaxf(h5,h6),fmaxf(h7,h8));\n if(oh0+6<OH) yimg[(oh0+6)*OW+ow]=fmaxf(fmaxf(h6,h7),fmaxf(h8,h9));\n if(oh0+7<OH) yimg[(oh0+7)*OW+ow]=fmaxf(fmaxf(h7,h8),fmaxf(h9,h10));\n }\n }\n}\ntorch::Tensor maxpool2d_forward(torch::Tensor x,int64_t kernel_size,int64_t stride,int64_t padding,int64_t dilation){\n TORCH_CHECK(x.is_cuda() && x.scalar_type()==torch::kFloat32 && x.dim()==4,\"bad input\"); TORCH_CHECK(kernel_size==4 && stride==1 && padding==1 && dilation==1,\"unsupported\");\n auto xc=x.contiguous(); int N=xc.size(0), C=xc.size(1), H=xc.size(2), W=xc.size(3); int OH=(H+2*(int)padding-((int)dilation*((int)kernel_size-1)+1))/(int)stride+1; int OW=(W+2*(int)padding-((int)dilation*((int)kernel_size-1)+1))/(int)stride+1; auto y=torch::empty({N,C,OH,OW},xc.options()); dim3 block(BLOCK_X,BLOCK_Y); dim3 grid((OW+TILE_W-1)/TILE_W,(OH+TILE_H-1)/TILE_H,N*C); maxpool4s1p1_kernel<<<grid,block,0,at::cuda::getCurrentCUDAStream()>>>(xc.data_ptr<float>(),y.data_ptr<float>(),H,W,OH,OW); return y;\n}\n\"\"\"\n_ext=load_inline(name=\"maxpool2d_k4s1p1_ext_v4\",cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=[\"maxpool2d_forward\"],extra_cuda_cflags=[\"-O3\",\"--use_fast_math\"],extra_cflags=[\"-O3\"],verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,kernel_size:int,stride:int,padding:int,dilation:int): super(ModelNew,self).__init__(); self.kernel_size=kernel_size; self.stride=stride; self.padding=padding; self.dilation=dilation\n def forward(self,x:torch.Tensor)->torch.Tensor: return _ext.maxpool2d_forward(x,self.kernel_size,self.stride,self.padding,self.dilation)\n"
}