call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = r'''\n#include <torch/extension.h>\ntorch::Tensor post_interleave(torch::Tensor y00, torch::Tensor y01, torch::Tensor y10, torch::Tensor y11, double addv, double mulv);\ntorch::Tensor pack_w(torch::Tensor w);\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\n__global__ void pack_kernel(const float* __restrict__ w, float* __restrict__ p, int I, int O) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = 4*O*I*4;\n if (idx >= total) return;\n int t = idx;\n int kk = t % 4; t /= 4;\n int ci = t % I; t /= I;\n int co = t % O; t /= O;\n int par = t;\n int ph = par / 2, pw = par & 1;\n int kh, kw;\n if (kk == 0) { kh = ph + 2; kw = pw + 2; }\n else if (kk == 1) { kh = ph + 2; kw = pw; }\n else if (kk == 2) { kh = ph; kw = pw + 2; }\n else { kh = ph; kw = pw; }\n // w layout [I,O,4,4], p [4,O,I,2,2]\n p[idx] = w[(((ci * O + co) * 4 + kh) * 4 + kw)];\n}\n\ntorch::Tensor pack_w(torch::Tensor w) {\n int I = w.size(0), O = w.size(1);\n auto p = torch::empty({4, O, I, 2, 2}, w.options());\n int total = 4*O*I*4;\n pack_kernel<<<(total+255)/256,256,0,at::cuda::getCurrentCUDAStream()>>>(w.data_ptr<float>(), p.data_ptr<float>(), I, O);\n return p;\n}\n\n__device__ __forceinline__ float post(float v, float addv, float mulv) {\n float x = v + addv;\n if (x >= 0.0f) return 0.0f;\n const float inv_sqrt2 = 0.7071067811865475244f;\n return (0.5f * x * (1.0f + erff(x * inv_sqrt2))) * mulv;\n}\n\n__global__ void inter_kernel(const float* __restrict__ y00,const float* __restrict__ y01,const float* __restrict__ y10,const float* __restrict__ y11,\n float* __restrict__ out, long long total, int N, int C, int H, int W, float addv, float mulv) {\n long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x;\n long long stride = (long long)blockDim.x * gridDim.x;\n int Hp = H/2, Wp = W/2; //65\n for (long long linear=idx; linear<total; linear+=stride) {\n long long t=linear;\n int wo = t % W; t/=W;\n int ho = t % H; t/=H;\n int co = t % C; t/=C;\n int n = (int)t;\n int ph = ho & 1, pw = wo & 1;\n int r = ho >> 1, c = wo >> 1;\n long long src = ((long long)n*C + co)*Hp*Wp + r*Wp + c;\n const float* yp = (ph==0 ? (pw==0?y00:y01) : (pw==0?y10:y11));\n out[linear] = post(yp[src], addv, mulv);\n }\n}\n\ntorch::Tensor post_interleave(torch::Tensor y00, torch::Tensor y01, torch::Tensor y10, torch::Tensor y11, double addv, double mulv) {\n int N=y00.size(0), C=y00.size(1), Hp=y00.size(2), Wp=y00.size(3);\n int H=Hp*2, W=Wp*2;\n auto out=torch::empty({N,C,H,W}, y00.options());\n long long total=out.numel();\n int blocks=(int)((total+255)/256); if(blocks>65535) blocks=65535;\n inter_kernel<<<blocks,256,0,at::cuda::getCurrentCUDAStream()>>>(y00.data_ptr<float>(),y01.data_ptr<float>(),y10.data_ptr<float>(),y11.data_ptr<float>(),out.data_ptr<float>(),total,N,C,H,W,(float)addv,(float)mulv);\n return out;\n}\n'''\n_ext = load_inline(name='deconv4conv_ext_v1', cpp_sources=_cpp_src, cuda_sources=_cuda_src, functions=['pack_w','post_interleave'], verbose=False, extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels, out_channels, kernel_size, stride, add_value, multiply_value):\n super(ModelNew, self).__init__()\n self.conv_transpose = nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=stride)\n self.add_value = add_value\n self.multiply_value = multiply_value\n def forward(self, x):\n p = _ext.pack_w(self.conv_transpose.weight.contiguous())\n b = self.conv_transpose.bias\n y00 = F.conv2d(x, p[0], b, padding=1)\n y01 = F.conv2d(x, p[1], b, padding=1)\n y10 = F.conv2d(x, p[2], b, padding=1)\n y11 = F.conv2d(x, p[3], b, padding=1)\n return _ext.post_interleave(y00,y01,y10,y11,float(self.add_value),float(self.multiply_value))\n"
}