call → run_correctness
callrun_correctness
{
"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 conv_transpose2d_forward(torch::Tensor x, torch::Tensor weight, c10::optional<torch::Tensor> bias,\n int64_t stride_h, int64_t stride_w,\n int64_t pad_h, int64_t pad_w,\n int64_t dil_h, int64_t dil_w,\n int64_t groups);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <ATen/cuda/CUDAContext.h>\n\n__device__ __forceinline__ void add8s(const float* __restrict__ xs, const float* __restrict__ wptr, int pos, float &acc) {\n acc = fmaf(xs[0*8 + pos], __ldg(wptr + 0*240), acc);\n acc = fmaf(xs[1*8 + pos], __ldg(wptr + 1*240), acc);\n acc = fmaf(xs[2*8 + pos], __ldg(wptr + 2*240), acc);\n acc = fmaf(xs[3*8 + pos], __ldg(wptr + 3*240), acc);\n acc = fmaf(xs[4*8 + pos], __ldg(wptr + 4*240), acc);\n acc = fmaf(xs[5*8 + pos], __ldg(wptr + 5*240), acc);\n acc = fmaf(xs[6*8 + pos], __ldg(wptr + 6*240), acc);\n acc = fmaf(xs[7*8 + pos], __ldg(wptr + 7*240), acc);\n}\n\n__global__ __launch_bounds__(256, 2) void deconv2d_tile_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n float* __restrict__ y) {\n __shared__ float xs[3*8*8];\n int tx = threadIdx.x; // ow in tile\n int ty = threadIdx.y; // output channel in group\n int tid = ty * 16 + tx;\n int tile = blockIdx.x; // 0..47\n int orow = blockIdx.y; // 0..127\n int zg = blockIdx.z;\n int g = zg & 3;\n int n = zg >> 2;\n int ow_start = tile * 16;\n int iw_base = (ow_start >= 2) ? ((ow_start - 2) / 3) : 0;\n int ci0 = g << 3;\n int x_n_base = n * 1048576 + ci0 * 32768;\n\n if (tid < 192) {\n int pos = tid & 7;\n int ci = (tid >> 3) & 7;\n int kh = tid >> 6;\n int ih = orow + 1 - kh;\n int iw = iw_base + pos;\n float v = 0.0f;\n if ((unsigned)ih < 128u && iw < 256) {\n v = __ldg(x + x_n_base + ci * 32768 + ih * 256 + iw);\n }\n xs[(kh * 8 + ci) * 8 + pos] = v;\n }\n __syncthreads();\n\n int ow = ow_start + tx;\n if (ow >= 766) return;\n int co = g * 16 + ty;\n int cog = ty;\n int w_co_base = (ci0 * 16 + cog) * 15;\n float acc = 0.0f;\n int mode = ow % 3;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n const float* xsk = xs + kh * 64;\n int wkh = w_co_base + kh * 5;\n if (mode == 0) {\n int pos = ow / 3 - iw_base;\n add8s(xsk, w + wkh + 2, pos, acc);\n } else if (mode == 1) {\n int pos0 = (ow + 2) / 3 - iw_base;\n add8s(xsk, w + wkh + 0, pos0, acc);\n int pos1 = (ow - 1) / 3 - iw_base;\n add8s(xsk, w + wkh + 3, pos1, acc);\n } else {\n int pos0 = (ow + 1) / 3 - iw_base;\n add8s(xsk, w + wkh + 1, pos0, acc);\n int pos1 = (ow - 2) / 3 - iw_base;\n add8s(xsk, w + wkh + 4, pos1, acc);\n }\n }\n int out_index = (((n * 64 + co) * 257 + (orow * 2 + 1)) * 766 + ow);\n y[out_index] = acc;\n}\n\n__global__ void deconv2d_generic_kernel(const float* __restrict__ x, const float* __restrict__ w, const float* __restrict__ b, float* __restrict__ y,\n int N,int Cin,int H,int W,int Cout,int kH,int kW,int sh,int sw,int ph,int pw,int dh,int dw,int groups,int Hout,int Wout,int total) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx >= total) return;\n int ow = idx % Wout; int t = idx / Wout; int oh = t % Hout; t /= Hout; int co = t % Cout; int n = t / Cout;\n int cin_g = Cin/groups, cout_g=Cout/groups, g=co/cout_g, cog=co-g*cout_g; float acc = b ? b[co] : 0.0f;\n for(int kh=0; kh<kH; ++kh){ int ihn=oh+ph-kh*dh; if(ihn%sh) continue; int ih=ihn/sh; if((unsigned)ih>=(unsigned)H) continue;\n for(int kw=0; kw<kW; ++kw){ int iwn=ow+pw-kw*dw; if(iwn%sw) continue; int iw=iwn/sw; if((unsigned)iw>=(unsigned)W) continue;\n for(int c=0;c<cin_g;++c) acc=fmaf(x[((n*Cin+g*cin_g+c)*H+ih)*W+iw], w[(((g*cin_g+c)*cout_g+cog)*kH+kh)*kW+kw], acc);\n }} y[idx]=acc;\n}\n\ntorch::Tensor conv_transpose2d_forward(torch::Tensor x, torch::Tensor weight, c10::optional<torch::Tensor> bias,\n int64_t stride_h, int64_t stride_w, int64_t pad_h, int64_t pad_w,\n int64_t dil_h, int64_t dil_w, int64_t groups) {\n x = x.contiguous(); weight = weight.contiguous();\n int N=x.size(0), Cin=x.size(1), H=x.size(2), W=x.size(3), kH=weight.size(2), kW=weight.size(3), Cout=weight.size(1)*groups;\n int Hout=(H-1)*(int)stride_h-2*(int)pad_h+(int)dil_h*(kH-1)+1;\n int Wout=(W-1)*(int)stride_w-2*(int)pad_w+(int)dil_w*(kW-1)+1;\n auto y=torch::empty({N,Cout,Hout,Wout}, x.options());\n if (N==16 && Cin==32 && H==128 && W==256 && Cout==64 && kH==3 && kW==5 && stride_h==2 && stride_w==3 && pad_h==1 && pad_w==2 && dil_h==2 && dil_w==1 && groups==4 && !(bias.has_value() && bias.value().defined())) {\n cudaMemsetAsync(y.data_ptr<float>(), 0, (size_t)N*Cout*Hout*Wout*sizeof(float), at::cuda::getCurrentCUDAStream());\n dim3 block(16,16,1); dim3 grid(48,128,64);\n deconv2d_tile_kernel<<<grid,block,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(), weight.data_ptr<float>(), y.data_ptr<float>());\n } else {\n const float* bp=nullptr; torch::Tensor bc; if(bias.has_value() && bias.value().defined()){bc=bias.value().contiguous(); bp=bc.data_ptr<float>();}\n int total=N*Cout*Hout*Wout; int threads=256, blocks=(total+threads-1)/threads;\n deconv2d_generic_kernel<<<blocks,threads,0,at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(),weight.data_ptr<float>(),bp,y.data_ptr<float>(),N,Cin,H,W,Cout,kH,kW,(int)stride_h,(int)stride_w,(int)pad_h,(int)pad_w,(int)dil_h,(int)dil_w,(int)groups,Hout,Wout,total);\n }\n return y;\n}\n\"\"\"\n\n_ext = load_inline(name=\"deconv2d_ext_v4\", cpp_sources=_cpp_src, cuda_sources=_cuda_src,\n functions=[\"conv_transpose2d_forward\"], verbose=False,\n extra_cuda_cflags=[\"-O3\"], extra_cflags=[\"-O3\"])\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels: int, out_channels: int, kernel_size: tuple, stride: tuple = (1, 1), padding: tuple = (0, 0), dilation: tuple = (1, 1), groups: int = 1, bias: bool = False):\n super(ModelNew, self).__init__()\n self.conv_transpose2d = nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)\n self.stride = stride; self.padding = padding; self.dilation = dilation; self.groups = groups\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n return _ext.conv_transpose2d_forward(x, self.conv_transpose2d.weight, self.conv_transpose2d.bias, self.stride[0], self.stride[1], self.padding[0], self.padding[1], self.dilation[0], self.dilation[1], self.groups)\n"
}