call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = r'''\n#include <torch/extension.h>\ntorch::Tensor conv3d_k31_forward(torch::Tensor x, torch::Tensor weight, c10::optional<torch::Tensor> bias_opt,\n int64_t stride, int64_t padding, int64_t dilation, int64_t groups);\n'''\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\n__global__ void conv3d_k31_default_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int S) {\n constexpr int OD=10, OW=254, OH=254, IW=256, IH=256, IC=3;\n constexpr int SPN = OH*OW*OD;\n constexpr int CSTR = IH*IW*OD;\n constexpr int HSTR = IW*OD;\n int lane = threadIdx.x;\n int wy = threadIdx.y;\n int oc = blockIdx.y * 8 + wy;\n int base_s = blockIdx.x * 128 + lane;\n int xb0=0, xb1=0, xb2=0, xb3=0;\n int yo0=0, yo1=0, yo2=0, yo3=0;\n bool full = (base_s + 96) < S; // all four lane outputs valid\n#pragma unroll\n for (int v=0; v<4; ++v) {\n int s = base_s + v*32;\n if (full || s < S) {\n int t=s;\n int z=t%OD; t/=OD;\n int ow=t%OW; t/=OW;\n int oh=t%OH; t/=OH;\n int n=t;\n int xb = ((n*IC*IH + oh)*IW + ow)*OD + z;\n int pos = s - n*SPN;\n int yy = ((n*64 + oc)*SPN) + pos;\n if (v==0) { xb0=xb; yo0=yy; }\n else if (v==1) { xb1=xb; yo1=yy; }\n else if (v==2) { xb2=xb; yo2=yy; }\n else { xb3=xb; yo3=yy; }\n }\n }\n float acc0=0.f, acc1=0.f, acc2=0.f, acc3=0.f;\n int wk = oc*27;\n#pragma unroll\n for (int c=0; c<3; ++c) {\n int co = c*CSTR;\n#pragma unroll\n for (int kh=0; kh<3; ++kh) {\n int kho = co + kh*HSTR;\n#pragma unroll\n for (int kw=0; kw<3; ++kw) {\n float ww = __ldg(w + wk++);\n int off = kho + kw*OD;\n if (full) {\n acc0 = fmaf(__ldg(x + xb0 + off), ww, acc0);\n acc1 = fmaf(__ldg(x + xb1 + off), ww, acc1);\n acc2 = fmaf(__ldg(x + xb2 + off), ww, acc2);\n acc3 = fmaf(__ldg(x + xb3 + off), ww, acc3);\n } else {\n if (base_s < S) acc0 = fmaf(__ldg(x + xb0 + off), ww, acc0);\n if (base_s + 32 < S) acc1 = fmaf(__ldg(x + xb1 + off), ww, acc1);\n if (base_s + 64 < S) acc2 = fmaf(__ldg(x + xb2 + off), ww, acc2);\n if (base_s + 96 < S) acc3 = fmaf(__ldg(x + xb3 + off), ww, acc3);\n }\n }\n }\n }\n if (b != nullptr) { float bb=__ldg(b+oc); acc0+=bb; acc1+=bb; acc2+=bb; acc3+=bb; }\n if (full) {\n y[yo0]=acc0; y[yo1]=acc1; y[yo2]=acc2; y[yo3]=acc3;\n } else {\n if (base_s < S) y[yo0]=acc0;\n if (base_s+32 < S) y[yo1]=acc1;\n if (base_s+64 < S) y[yo2]=acc2;\n if (base_s+96 < S) y[yo3]=acc3;\n }\n}\n\n__global__ void conv3d_k31_general_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int N,int IC,int IH,int IW,int ID,int OC,int OH,int OW,int OD,int K,int stride,int pad,int dil,int groups,long long total) {\n long long idx=(long long)blockIdx.x*blockDim.x+threadIdx.x;\n if(idx>=total) return;\n int z=idx%OD; long long q=idx/OD; int ow=q%OW; q/=OW; int oh=q%OH; q/=OH; int oc=q%OC; q/=OC; int n=q;\n int ocpg=OC/groups, icpg=IC/groups, g=oc/ocpg;\n float acc=b?__ldg(b+oc):0.f;\n int ih0=oh*stride-pad, iw0=ow*stride-pad, iz=z*stride-pad;\n if((unsigned)iz<(unsigned)ID){\n for(int ci=0;ci<icpg;++ci){ int c=g*icpg+ci;\n for(int kh=0;kh<K;++kh){ int ih=ih0+kh*dil; if((unsigned)ih>=(unsigned)IH) continue;\n for(int kw=0;kw<K;++kw){ int iw=iw0+kw*dil; if((unsigned)iw>=(unsigned)IW) continue;\n float xv=__ldg(x+(((n*IC+c)*IH+ih)*IW+iw)*ID+iz);\n float ww=__ldg(w+(((oc*icpg+ci)*K+kh)*K+kw));\n acc=fmaf(xv,ww,acc);\n }\n }\n }\n }\n y[idx]=acc;\n}\n\ntorch::Tensor conv3d_k31_forward(torch::Tensor x, torch::Tensor weight, c10::optional<torch::Tensor> bias_opt,\n int64_t stride, int64_t padding, int64_t dilation, int64_t groups) {\n x=x.contiguous(); weight=weight.contiguous();\n const int64_t N=x.size(0),IC=x.size(1),IH=x.size(2),IW=x.size(3),ID=x.size(4);\n const int64_t OC=weight.size(0),K=weight.size(2);\n int64_t OH=(IH+2*padding-dilation*(K-1)-1)/stride+1;\n int64_t OW=(IW+2*padding-dilation*(K-1)-1)/stride+1;\n int64_t OD=(ID+2*padding-1)/stride+1;\n auto y=torch::empty({N,OC,OH,OW,OD},x.options());\n const float* bptr=nullptr; torch::Tensor bias;\n if(bias_opt.has_value()&&bias_opt.value().defined()){bias=bias_opt.value().contiguous(); bptr=bias.data_ptr<float>();}\n cudaStream_t stream=at::cuda::getCurrentCUDAStream();\n if(x.scalar_type()==at::kFloat && N==16 && IC==3 && IH==256 && IW==256 && ID==10 && OC==64 && K==3 && stride==1 && padding==0 && dilation==1 && groups==1 && OH==254 && OW==254 && OD==10){\n int S=(int)(N*OH*OW*OD); dim3 block(32,8,1); dim3 grid((S+127)/128,8,1);\n conv3d_k31_default_kernel<<<grid,block,0,stream>>>(x.data_ptr<float>(),weight.data_ptr<float>(),bptr,y.data_ptr<float>(),S);\n } else {\n long long total=N*OC*OH*OW*OD; int threads=256; int blocks=(total+threads-1)/threads;\n conv3d_k31_general_kernel<<<blocks,threads,0,stream>>>(x.data_ptr<float>(),weight.data_ptr<float>(),bptr,y.data_ptr<float>(),(int)N,(int)IC,(int)IH,(int)IW,(int)ID,(int)OC,(int)OH,(int)OW,(int)OD,(int)K,(int)stride,(int)padding,(int)dilation,(int)groups,total);\n }\n return y;\n}\n'''\n_ext=load_inline(name='conv3d_k31_ext_v3',cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=['conv3d_k31_forward'],verbose=False,extra_cuda_cflags=['-O3','--use_fast_math'],extra_cflags=['-O3'])\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,groups:int=1,bias:bool=False):\n super(ModelNew,self).__init__(); self.conv3d=nn.Conv3d(in_channels,out_channels,(kernel_size,kernel_size,1),stride=stride,padding=padding,dilation=dilation,groups=groups,bias=bias); self.stride=stride; self.padding=padding; self.dilation=dilation; self.groups=groups\n def forward(self,x:torch.Tensor)->torch.Tensor:\n return _ext.conv3d_k31_forward(x,self.conv3d.weight,self.conv3d.bias,self.stride,self.padding,self.dilation,self.groups)\n"
}