call → compile_kernel
callcompile_kernel
{
"kernel_code": "import os\nos.environ.setdefault('TMPDIR', '/tmp')\nimport torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = \"\"\"\n#include <torch/extension.h>\ntorch::Tensor depthwise_asym_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, bool has_bias, int stride, int padding, int dilation);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/types.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__device__ __forceinline__ float4 madd3(float4 a, float aw, float4 b, float bw, float4 c, float cw, float bv) {\n float4 o;\n o.x = fmaf(c.x, cw, fmaf(b.x, bw, a.x * aw)) + bv;\n o.y = fmaf(c.y, cw, fmaf(b.y, bw, a.y * aw)) + bv;\n o.z = fmaf(c.z, cw, fmaf(b.z, bw, a.z * aw)) + bv;\n o.w = fmaf(c.w, cw, fmaf(b.w, bw, a.w * aw)) + bv;\n return o;\n}\n\n__global__ void dw_k3s1p0_row6_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n int total, bool has_bias) {\n int tid = blockIdx.x * blockDim.x + threadIdx.x;\n int step = blockDim.x * gridDim.x;\n for (int idx = tid; idx < total; idx += step) {\n int vecw = idx & 127;\n int q = idx >> 7;\n int rg = q % 85;\n int nc = q / 85;\n int c = nc & 7;\n int oh = rg * 6;\n int offx = (nc * 512 + oh) * 512 + (vecw << 2);\n int offy = (nc * 510 + oh) * 512 + (vecw << 2);\n float w0 = __ldg(w + c * 3 + 0);\n float w1 = __ldg(w + c * 3 + 1);\n float w2 = __ldg(w + c * 3 + 2);\n float bv = has_bias ? __ldg(b + c) : 0.0f;\n float4 r0 = *reinterpret_cast<const float4*>(x + offx);\n float4 r1 = *reinterpret_cast<const float4*>(x + offx + 512);\n float4 r2 = *reinterpret_cast<const float4*>(x + offx + 1024);\n *reinterpret_cast<float4*>(y + offy) = madd3(r0, w0, r1, w1, r2, w2, bv);\n float4 r3 = *reinterpret_cast<const float4*>(x + offx + 1536);\n *reinterpret_cast<float4*>(y + offy + 512) = madd3(r1, w0, r2, w1, r3, w2, bv);\n float4 r4 = *reinterpret_cast<const float4*>(x + offx + 2048);\n *reinterpret_cast<float4*>(y + offy + 1024) = madd3(r2, w0, r3, w1, r4, w2, bv);\n float4 r5 = *reinterpret_cast<const float4*>(x + offx + 2560);\n *reinterpret_cast<float4*>(y + offy + 1536) = madd3(r3, w0, r4, w1, r5, w2, bv);\n float4 r6 = *reinterpret_cast<const float4*>(x + offx + 3072);\n *reinterpret_cast<float4*>(y + offy + 2048) = madd3(r4, w0, r5, w1, r6, w2, bv);\n float4 r7 = *reinterpret_cast<const float4*>(x + offx + 3584);\n *reinterpret_cast<float4*>(y + offy + 2560) = madd3(r5, w0, r6, w1, r7, w2, bv);\n }\n}\n\n__global__ void dw_generic_kernel(const float* __restrict__ x, const float* __restrict__ w,\n const float* __restrict__ b, float* __restrict__ y,\n long total, int C, int H, int W, int Hout, int Wout, int K,\n int stride, int padding, int dilation, bool has_bias) {\n long tid = (long)blockIdx.x * blockDim.x + threadIdx.x;\n long step = (long)blockDim.x * gridDim.x;\n for (long idx = tid; idx < total; idx += step) {\n int ow = idx % Wout;\n long q = idx / Wout;\n int oh = q % Hout; q /= Hout;\n int c = q % C;\n long n = q / C;\n float acc = has_bias ? b[c] : 0.0f;\n int ih0 = oh * stride - padding;\n int iw = ow * stride - padding;\n if ((unsigned)iw < (unsigned)W) {\n const float* xp = x + ((n*C + c)*H)*W + iw;\n const float* wp = w + c*K;\n for (int kh = 0; kh < K; ++kh) {\n int ih = ih0 + kh * dilation;\n if ((unsigned)ih < (unsigned)H) acc = fmaf(xp[ih * W], wp[kh], acc);\n }\n }\n y[idx] = acc;\n }\n}\n\ntorch::Tensor depthwise_asym_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, bool has_bias, int stride, int padding, int dilation) {\n int N = (int)x.size(0), C = (int)x.size(1), H = (int)x.size(2), W = (int)x.size(3);\n int K = (int)weight.size(2);\n int Hout = (H + 2*padding - dilation*(K-1) - 1) / stride + 1;\n int Wout = (W + 2*padding - 1) / stride + 1;\n auto y = torch::empty({N, C, Hout, Wout}, x.options());\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if (K == 3 && C == 8 && H == 512 && W == 512 && stride == 1 && padding == 0 && dilation == 1) {\n int total = N * C * 85 * 128;\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n if (blocks > 65535) blocks = 65535;\n dw_k3s1p0_row6_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), weight.data_ptr<float>(), has_bias ? bias.data_ptr<float>() : nullptr, y.data_ptr<float>(), total, has_bias);\n } else {\n long total = (long)N*C*Hout*Wout;\n int threads = 256;\n int blocks = (int)((total + threads - 1) / threads);\n if (blocks > 65535) blocks = 65535;\n dw_generic_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), weight.data_ptr<float>(), has_bias ? bias.data_ptr<float>() : nullptr, y.data_ptr<float>(), total, C, H, W, Hout, Wout, K, stride, padding, dilation, has_bias);\n }\n return y;\n}\n\"\"\"\n\n_ext = load_inline(name=\"dw_asym_ext_opt\", cpp_sources=[_cpp_src], cuda_sources=[_cuda_src], functions=[\"depthwise_asym_forward\"], verbose=False, extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"], extra_cflags=[\"-O3\"])\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels: int, kernel_size: int, stride: int = 1, padding: int = 0, dilation: int = 1, bias: bool = False):\n super(ModelNew, self).__init__()\n self.conv2d = nn.Conv2d(in_channels, in_channels, kernel_size=(kernel_size, 1), stride=stride, padding=padding, dilation=dilation, groups=in_channels, bias=bias)\n self._stride = stride\n self._padding = padding\n self._dilation = dilation\n self.register_buffer('_dummy_bias', torch.empty(0), persistent=False)\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n b = self.conv2d.bias\n if b is None:\n return _ext.depthwise_asym_forward(x, self.conv2d.weight, self._dummy_bias, False, self._stride, self._padding, self._dilation)\n return _ext.depthwise_asym_forward(x, self.conv2d.weight, b, True, self._stride, self._padding, self._dilation)\n"
}