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 cross_scan_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias);\ntorch::Tensor cross_scan_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias) { return cross_scan_forward_cuda(x, weight, bias); }\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void cross_scan_kernel3_32_64(const float* __restrict__ x,\n const float* __restrict__ weight,\n const float* __restrict__ bias,\n float* __restrict__ y,\n int total) {\n int tid = blockIdx.x * blockDim.x + threadIdx.x;\n if (tid >= total) return;\n int spat = tid & 1023;\n int w = tid & 31;\n int h = (tid >> 5) & 31;\n int c = (tid >> 10) & 63;\n int bc_base = tid - spat;\n const float* xp = x + bc_base;\n const float* wc = weight + c * 3;\n float w0 = wc[0], w1 = wc[1], w2 = wc[2];\n float xv = xp[spat];\n float acc = 4.0f * bias[c] + (4.0f * w1) * xv;\n float ws = w0 + w2;\n\n if ((unsigned)(h - 1) < 30u && (unsigned)(w - 1) < 30u) {\n acc = fmaf(ws, xp[spat - 1], acc);\n acc = fmaf(ws, xp[spat + 1], acc);\n acc = fmaf(ws, xp[spat - 32], acc);\n acc = fmaf(ws, xp[spat + 32], acc);\n } else {\n // LR\n if (spat > 0) acc = fmaf(w0, xp[spat - 1], acc);\n if (spat < 1023) acc = fmaf(w2, xp[spat + 1], acc);\n // RL\n if (w < 31) acc = fmaf(w0, xp[spat + 1], acc);\n else if (h > 0) acc = fmaf(w0, xp[(h - 1) * 32], acc);\n if (w > 0) acc = fmaf(w2, xp[spat - 1], acc);\n else if (h < 31) acc = fmaf(w2, xp[(h + 1) * 32 + 31], acc);\n // TB\n if (h > 0) acc = fmaf(w0, xp[spat - 32], acc);\n else if (w > 0) acc = fmaf(w0, xp[992 + (w - 1)], acc);\n if (h < 31) acc = fmaf(w2, xp[spat + 32], acc);\n else if (w < 31) acc = fmaf(w2, xp[w + 1], acc);\n // BT\n if (h < 31) acc = fmaf(w0, xp[spat + 32], acc);\n else if (w > 0) acc = fmaf(w0, xp[w - 1], acc);\n if (h > 0) acc = fmaf(w2, xp[spat - 32], acc);\n else if (w < 31) acc = fmaf(w2, xp[992 + (w + 1)], acc);\n }\n y[tid] = xv + acc;\n}\n\n__global__ void cross_scan_kernel3(const float* __restrict__ x,\n const float* __restrict__ weight,\n const float* __restrict__ bias,\n float* __restrict__ y,\n int C, int H, int W, int total) {\n int tid = blockIdx.x * blockDim.x + threadIdx.x;\n if (tid >= total) return;\n int s = tid;\n int w = s % W; s /= W;\n int h = s % H; s /= H;\n int c = s % C;\n int HW = H * W;\n int spat = h * W + w;\n int bc_base = tid - spat;\n const float* xp = x + bc_base;\n const float* wc = weight + c * 3;\n float w0 = wc[0], w1 = wc[1], w2 = wc[2];\n float xv = xp[spat];\n float acc = 4.0f * bias[c] + (4.0f * w1) * xv;\n if (spat > 0) acc = fmaf(w0, xp[spat - 1], acc);\n if (spat < HW - 1) acc = fmaf(w2, xp[spat + 1], acc);\n if (w < W - 1) acc = fmaf(w0, xp[spat + 1], acc);\n else if (h > 0) acc = fmaf(w0, xp[(h - 1) * W], acc);\n if (w > 0) acc = fmaf(w2, xp[spat - 1], acc);\n else if (h < H - 1) acc = fmaf(w2, xp[(h + 1) * W + (W - 1)], acc);\n if (h > 0) acc = fmaf(w0, xp[spat - W], acc);\n else if (w > 0) acc = fmaf(w0, xp[(H - 1) * W + (w - 1)], acc);\n if (h < H - 1) acc = fmaf(w2, xp[spat + W], acc);\n else if (w < W - 1) acc = fmaf(w2, xp[w + 1], acc);\n if (h < H - 1) acc = fmaf(w0, xp[spat + W], acc);\n else if (w > 0) acc = fmaf(w0, xp[w - 1], acc);\n if (h > 0) acc = fmaf(w2, xp[spat - W], acc);\n else if (w < W - 1) acc = fmaf(w2, xp[(H - 1) * W + (w + 1)], acc);\n y[tid] = xv + acc;\n}\n\n__device__ __forceinline__ int spatial_from_rl(int n, int H, int W) { int row = n / W; int col = n - row * W; return row * W + (W - 1 - col); }\n__device__ __forceinline__ int spatial_from_tb(int n, int H, int W) { int col = n / H; int row = n - col * H; return row * W + col; }\n__device__ __forceinline__ int spatial_from_bt(int n, int H, int W) { int col = n / H; int rowf = n - col * H; return (H - 1 - rowf) * W + col; }\n\n__global__ void cross_scan_kernel_generic(const float* __restrict__ x,\n const float* __restrict__ weight,\n const float* __restrict__ bias,\n float* __restrict__ y,\n int C, int H, int W, int K, int total) {\n int tid = blockIdx.x * blockDim.x + threadIdx.x;\n if (tid >= total) return;\n int s = tid; int w = s % W; s /= W; int h = s % H; s /= H; int c = s % C;\n int HW = H * W; int spat = h * W + w; int bc_base = tid - spat;\n int pos_lr = spat, pos_rl = h * W + (W - 1 - w), pos_tb = w * H + h, pos_bt = w * H + (H - 1 - h);\n int pad = K >> 1; const float* wx = weight + c * K; float acc = 4.0f * bias[c];\n for (int kk = 0; kk < K; ++kk) {\n int off = kk - pad; float wk = wx[kk]; int n = pos_lr + off;\n if ((unsigned)n < (unsigned)HW) acc = fmaf(wk, x[bc_base + n], acc);\n n = pos_rl + off; if ((unsigned)n < (unsigned)HW) acc = fmaf(wk, x[bc_base + spatial_from_rl(n, H, W)], acc);\n n = pos_tb + off; if ((unsigned)n < (unsigned)HW) acc = fmaf(wk, x[bc_base + spatial_from_tb(n, H, W)], acc);\n n = pos_bt + off; if ((unsigned)n < (unsigned)HW) acc = fmaf(wk, x[bc_base + spatial_from_bt(n, H, W)], acc);\n }\n y[tid] = x[tid] + acc;\n}\n\ntorch::Tensor cross_scan_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias) {\n TORCH_CHECK(x.is_cuda() && weight.is_cuda() && bias.is_cuda(), \"CUDA tensors required\");\n TORCH_CHECK(x.scalar_type() == torch::kFloat32, \"only float32 supported\");\n TORCH_CHECK(x.is_contiguous() && weight.is_contiguous() && bias.is_contiguous(), \"contiguous tensors required\");\n int B = (int)x.size(0), C = (int)x.size(1), H = (int)x.size(2), W = (int)x.size(3), K = (int)weight.size(2);\n int total = B * C * H * W;\n auto y = torch::empty_like(x);\n int threads = 256, blocks = (total + threads - 1) / threads;\n if (K == 3 && C == 64 && H == 32 && W == 32) {\n cross_scan_kernel3_32_64<<<blocks, threads>>>(x.data_ptr<float>(), weight.data_ptr<float>(), bias.data_ptr<float>(), y.data_ptr<float>(), total);\n } else if (K == 3) {\n cross_scan_kernel3<<<blocks, threads>>>(x.data_ptr<float>(), weight.data_ptr<float>(), bias.data_ptr<float>(), y.data_ptr<float>(), C, H, W, total);\n } else {\n cross_scan_kernel_generic<<<blocks, threads>>>(x.data_ptr<float>(), weight.data_ptr<float>(), bias.data_ptr<float>(), y.data_ptr<float>(), C, H, W, K, total);\n }\n return y;\n}\n\"\"\"\n\n_ext = load_inline(name=\"cross_scan_ext_v3\", cpp_sources=_cpp_src, cuda_sources=_cuda_src, functions=[\"cross_scan_forward\"], extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"], extra_cflags=[\"-O3\"], verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, channels: int, kernel_size: int = 3):\n super().__init__()\n assert channels >= 1\n assert kernel_size % 2 == 1\n self.channels = channels\n pad = kernel_size // 2\n self.dw_conv = nn.Conv1d(channels, channels, kernel_size, padding=pad, groups=channels, bias=True)\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n if not x.is_contiguous():\n x = x.contiguous()\n return _ext.cross_scan_forward(x, self.dw_conv.weight.contiguous(), self.dw_conv.bias.contiguous())\n"
}