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 avgpool3d_forward_cuda(torch::Tensor x,int64_t k,int64_t s,int64_t p);\ntorch::Tensor avgpool3d_forward(torch::Tensor x,int64_t k,int64_t s,int64_t p){return avgpool3d_forward_cuda(x,k,s,p);}'''\n_cuda_src=r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\nstatic inline long long ceil_div_ll(long long a,long long b){return (a+b-1)/b;}\n__global__ void interior4(const float* __restrict__ x,float* __restrict__ y,int N,int C,int D,int H,int W,int Do,int Ho,int Wo,long long total){\n long long idx=(long long)blockIdx.x*blockDim.x+threadIdx.x; if(idx>=total)return; int Wint=Wo-1; int G=(Wint+3)>>2; int g=idx%G; long long t=idx/G; int oh_i=t%(Ho-1); t/=(Ho-1); int od_i=t%(Do-1); t/=(Do-1); int nc=t; int od=od_i+1,oh=oh_i+1,ow0=1+(g<<2); int id0=(od<<1)-1,ih0=(oh<<1)-1,iw0=(ow0<<1)-1; long long base=(((long long)nc*D+id0)*H+ih0)*W+iw0; long long out=(((long long)nc*Do+od)*Ho+oh)*Wo+ow0; int plane=H*W; float s0=0,s1=0,s2=0,s3=0; if(ow0+3<Wo){\n #pragma unroll\n for(int dz=0;dz<3;++dz){long long bd=base+(long long)dz*plane;\n #pragma unroll\n for(int dy=0;dy<3;++dy){const float* p=x+bd+(long long)dy*W; float a0=p[0],a1=p[1],a2=p[2],a3=p[3],a4=p[4],a5=p[5],a6=p[6],a7=p[7],a8=p[8]; s0+=a0+a1+a2; s1+=a2+a3+a4; s2+=a4+a5+a6; s3+=a6+a7+a8;}\n } float inv=0.037037037037037035f; y[out]=s0*inv; y[out+1]=s1*inv; y[out+2]=s2*inv; y[out+3]=s3*inv;\n } else { // last group\n int remain=Wo-ow0; // interior outputs remaining\n #pragma unroll\n for(int dz=0;dz<3;++dz){long long bd=base+(long long)dz*plane;\n #pragma unroll\n for(int dy=0;dy<3;++dy){const float* p=x+bd+(long long)dy*W; float a0=p[0],a1=p[1],a2=p[2],a3=p[3],a4=p[4],a5=p[5],a6=p[6]; s0+=a0+a1+a2; if(remain>1)s1+=a2+a3+a4; if(remain>2)s2+=a4+a5+a6;}\n } float inv=0.037037037037037035f; y[out]=s0*inv; if(remain>1)y[out+1]=s1*inv; if(remain>2)y[out+2]=s2*inv;\n }\n}\n__device__ __forceinline__ float sump(const float* __restrict__ x,int nc,int od,int oh,int ow,int D,int H,int W){int ids=(od<<1)-1,ihs=(oh<<1)-1,iws=(ow<<1)-1;float s=0;#pragma unroll\n for(int dz=0;dz<3;++dz){int id=ids+dz;if((unsigned)id<(unsigned)D){#pragma unroll\n for(int dy=0;dy<3;++dy){int ih=ihs+dy;if((unsigned)ih<(unsigned)H){long long b=(((long long)nc*D+id)*H+ih)*W;#pragma unroll\n for(int dx=0;dx<3;++dx){int iw=iws+dx;if((unsigned)iw<(unsigned)W)s+=x[b+iw];}}}}}return s*0.037037037037037035f;}\n__global__ void boundary(const float* __restrict__ x,float* __restrict__ y,int N,int C,int D,int H,int W,int Do,int Ho,int Wo,long long seg0,long long seg1,long long total){long long idx=(long long)blockIdx.x*blockDim.x+threadIdx.x;if(idx>=total)return;int nc,od,oh,ow;if(idx<seg0){long long t=idx;ow=t%Wo;t/=Wo;oh=t%Ho;t/=Ho;od=0;nc=t;}else if(idx<seg0+seg1){long long t=idx-seg0;ow=t%Wo;t/=Wo;od=1+(t%(Do-1));t/=(Do-1);oh=0;nc=t;}else{long long t=idx-seg0-seg1;oh=1+(t%(Ho-1));t/=(Ho-1);od=1+(t%(Do-1));t/=(Do-1);ow=0;nc=t;}y[(((long long)nc*Do+od)*Ho+oh)*Wo+ow]=sump(x,nc,od,oh,ow,D,H,W);}\n__global__ void generic(const float* __restrict__ x,float* __restrict__ y,int N,int C,int D,int H,int W,int Do,int Ho,int Wo,int K,int S,int P,float inv,long long total){long long idx=(long long)blockIdx.x*blockDim.x+threadIdx.x;if(idx>=total)return;int ow=idx%Wo;long long t=idx/Wo;int oh=t%Ho;t/=Ho;int od=t%Do;t/=Do;int nc=t;float sum=0;int ids=od*S-P,ihs=oh*S-P,iws=ow*S-P;for(int dz=0;dz<K;++dz){int id=ids+dz;if((unsigned)id<(unsigned)D)for(int dy=0;dy<K;++dy){int ih=ihs+dy;if((unsigned)ih<(unsigned)H){long long b=(((long long)nc*D+id)*H+ih)*W;for(int dx=0;dx<K;++dx){int iw=iws+dx;if((unsigned)iw<(unsigned)W)sum+=x[b+iw];}}}}y[idx]=sum*inv;}\ntorch::Tensor avgpool3d_forward_cuda(torch::Tensor x,int64_t kernel_size,int64_t stride,int64_t padding){TORCH_CHECK(x.is_cuda());TORCH_CHECK(x.scalar_type()==at::kFloat);auto xc=x.contiguous();int N=xc.size(0),C=xc.size(1),D=xc.size(2),H=xc.size(3),W=xc.size(4);int K=kernel_size,S=stride>0?stride:K,P=padding;int Do=(D+2*P-K)/S+1,Ho=(H+2*P-K)/S+1,Wo=(W+2*P-K)/S+1;auto y=torch::empty({N,C,Do,Ho,Wo},xc.options());cudaStream_t stream=at::cuda::getCurrentCUDAStream();const float* xp=xc.data_ptr<float>();float* yp=y.data_ptr<float>();if(K==3&&S==2&&P==1&&Do>1&&Ho>1&&Wo>1){int Wint=Wo-1;int G=(Wint+3)/4;long long tot=(long long)N*C*(Do-1)*(Ho-1)*G;interior4<<<(int)ceil_div_ll(tot,256),256,0,stream>>>(xp,yp,N,C,D,H,W,Do,Ho,Wo,tot);long long seg0=(long long)N*C*Ho*Wo,seg1=(long long)N*C*(Do-1)*Wo,seg2=(long long)N*C*(Do-1)*(Ho-1),bt=seg0+seg1+seg2;boundary<<<(int)ceil_div_ll(bt,256),256,0,stream>>>(xp,yp,N,C,D,H,W,Do,Ho,Wo,seg0,seg1,bt);}else{long long total=(long long)N*C*Do*Ho*Wo;generic<<<(int)ceil_div_ll(total,256),256,0,stream>>>(xp,yp,N,C,D,H,W,Do,Ho,Wo,K,S,P,1.0f/(K*K*K),total);}C10_CUDA_KERNEL_LAUNCH_CHECK();return y;}\n'''\n_ext=load_inline(name='avgpool3d_ext_g4_v1',cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=['avgpool3d_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=None,padding:int=0): super().__init__(); self.kernel_size=int(kernel_size); self.stride=int(stride) if stride is not None else int(kernel_size); self.padding=int(padding)\n def forward(self,x): return _ext.avgpool3d_forward(x,self.kernel_size,self.stride,self.padding)\n"
}