call → run_correctness
callrun_correctness
{
"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 conv2d_forward(torch::Tensor x, torch::Tensor w, c10::optional<torch::Tensor> bias_opt,\n int64_t stride_h,int64_t stride_w,int64_t pad_h,int64_t pad_w,int64_t dil_h,int64_t dil_w,int64_t groups);\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 conv8_kernel(const float* __restrict__ x,const float* __restrict__ w,const float* __restrict__ b,float* __restrict__ y,\n int H,int W,int OH,int OW,int has_bias){\n int m = blockIdx.x * blockDim.x + threadIdx.x;\n int oc0 = blockIdx.y * 8;\n int M = 8*OH*OW;\n if(m>=M) return;\n int ow = m % OW;\n int t = m / OW;\n int oh = t % OH;\n int n = t / OH;\n float a0=0.f,a1=0.f,a2=0.f,a3=0.f,a4=0.f,a5=0.f,a6=0.f,a7=0.f;\n if(has_bias){a0=b[oc0];a1=b[oc0+1];a2=b[oc0+2];a3=b[oc0+3];a4=b[oc0+4];a5=b[oc0+5];a6=b[oc0+6];a7=b[oc0+7];}\n const int K=1440;\n const float* xp0 = x + ((n*32)*H + oh)*W + ow;\n #pragma unroll 1\n for(int ic=0; ic<32; ++ic){\n const float* xp_ic = xp0 + ic*H*W;\n int kbic=ic*45;\n #pragma unroll\n for(int kh=0; kh<5; ++kh){\n const float* xp=xp_ic+kh*W;\n int kb=kbic+kh*9;\n #pragma unroll\n for(int kw=0; kw<9; ++kw){\n float xv=xp[kw]; int k=kb+kw;\n a0=fmaf(xv,w[(oc0+0)*K+k],a0); a1=fmaf(xv,w[(oc0+1)*K+k],a1);\n a2=fmaf(xv,w[(oc0+2)*K+k],a2); a3=fmaf(xv,w[(oc0+3)*K+k],a3);\n a4=fmaf(xv,w[(oc0+4)*K+k],a4); a5=fmaf(xv,w[(oc0+5)*K+k],a5);\n a6=fmaf(xv,w[(oc0+6)*K+k],a6); a7=fmaf(xv,w[(oc0+7)*K+k],a7);\n }\n }\n }\n int plane=OH*OW; int outbase=((n*64+oc0)*OH+oh)*OW+ow;\n y[outbase]=a0; y[outbase+plane]=a1; y[outbase+2*plane]=a2; y[outbase+3*plane]=a3;\n y[outbase+4*plane]=a4; y[outbase+5*plane]=a5; y[outbase+6*plane]=a6; y[outbase+7*plane]=a7;\n}\n\n__global__ void conv4_generic_kernel(const float* __restrict__ x,const float* __restrict__ w,const float* __restrict__ b,float* __restrict__ y,\n int N,int C,int H,int W,int O,int KH,int KW,int OH,int OW,int sh,int sw,int ph,int pw,int dh,int dw,int has_bias){\n int m=blockIdx.x*blockDim.x+threadIdx.x; int oc0=blockIdx.y*4; int M=N*OH*OW; if(m>=M) return;\n int ow=m%OW; int tmp=m/OW; int oh=tmp%OH; int n=tmp/OH;\n float a0=(has_bias&&oc0<O)?b[oc0]:0.0f,a1=(has_bias&&oc0+1<O)?b[oc0+1]:0.0f,a2=(has_bias&&oc0+2<O)?b[oc0+2]:0.0f,a3=(has_bias&&oc0+3<O)?b[oc0+3]:0.0f;\n int ih0=oh*sh-ph, iw0=ow*sw-pw; int K=C*KH*KW;\n for(int ic=0;ic<C;++ic) for(int kh=0;kh<KH;++kh){ int ih=ih0+kh*dh; if((unsigned)ih>=(unsigned)H) continue; for(int kw=0;kw<KW;++kw){ int iw=iw0+kw*dw; if((unsigned)iw<(unsigned)W){ float xv=x[((n*C+ic)*H+ih)*W+iw]; int k=(ic*KH+kh)*KW+kw; if(oc0<O)a0=fmaf(xv,w[(oc0)*K+k],a0); if(oc0+1<O)a1=fmaf(xv,w[(oc0+1)*K+k],a1); if(oc0+2<O)a2=fmaf(xv,w[(oc0+2)*K+k],a2); if(oc0+3<O)a3=fmaf(xv,w[(oc0+3)*K+k],a3); } } }\n int outbase=((n*O+oc0)*OH+oh)*OW+ow; int plane=OH*OW; if(oc0<O)y[outbase]=a0; if(oc0+1<O)y[outbase+plane]=a1; if(oc0+2<O)y[outbase+2*plane]=a2; if(oc0+3<O)y[outbase+3*plane]=a3;\n}\n\ntorch::Tensor conv2d_forward(torch::Tensor x, torch::Tensor w, c10::optional<torch::Tensor> bias_opt,\n int64_t sh,int64_t sw,int64_t ph,int64_t pw,int64_t dh,int64_t dw,int64_t groups){\n x=x.contiguous(); w=w.contiguous(); int N=x.size(0),C=x.size(1),H=x.size(2),W=x.size(3); int O=w.size(0),KH=w.size(2),KW=w.size(3);\n int OH=(H+2*ph-dh*(KH-1)-1)/sh+1; int OW=(W+2*pw-dw*(KW-1)-1)/sw+1; auto y=torch::empty({N,O,OH,OW},x.options());\n const float* bp=nullptr; int hb=0; torch::Tensor bias; if(bias_opt.has_value()&&bias_opt.value().defined()){bias=bias_opt.value().contiguous(); bp=bias.data_ptr<float>(); hb=1;}\n int M=N*OH*OW; dim3 block(128);\n if(N==8 && C==32 && O==64 && KH==5 && KW==9 && sh==1 && sw==1 && ph==0 && pw==0 && dh==1 && dw==1 && groups==1){ dim3 grid((M+127)/128,8); conv8_kernel<<<grid,block,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),w.data_ptr<float>(),bp,y.data_ptr<float>(),H,W,OH,OW,hb); }\n else { dim3 grid((M+127)/128,(O+3)/4); conv4_generic_kernel<<<grid,block,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),w.data_ptr<float>(),bp,y.data_ptr<float>(),N,C,H,W,O,KH,KW,OH,OW,sh,sw,ph,pw,dh,dw,hb); }\n return y;\n}\n'''\n_ext=load_inline(name='conv2d_conv8_ext_v1',cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=['conv2d_forward'],extra_cuda_cflags=['-O3','--use_fast_math'],verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,in_channels:int,out_channels:int,kernel_size:tuple,stride:int=1,padding:int=0,dilation:int=1,groups:int=1,bias:bool=False):\n super().__init__(); self.conv2d=nn.Conv2d(in_channels,out_channels,kernel_size,stride=stride,padding=padding,dilation=dilation,groups=groups,bias=bias); self.stride=stride if isinstance(stride,tuple) else (stride,stride); self.padding=padding if isinstance(padding,tuple) else (padding,padding); self.dilation=dilation if isinstance(dilation,tuple) else (dilation,dilation); self.groups=groups\n def forward(self,x): return _ext.conv2d_forward(x,self.conv2d.weight,self.conv2d.bias,self.stride[0],self.stride[1],self.padding[0],self.padding[1],self.dilation[0],self.dilation[1],self.groups)\n"
}