call → submit_kernel
callsubmit_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>\n\ntorch::Tensor dwconv1d_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, int64_t stride, int64_t padding);\n\"\"\"\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 dwconv1d_k3s1p1_vec4_kernel(\n const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ bias,\n float* __restrict__ y,\n int rows, int C, int L, int has_bias)\n{\n int vecs_per_row = L >> 2;\n int64_t idx = (int64_t)blockIdx.x * blockDim.x + threadIdx.x;\n int64_t total = (int64_t)rows * vecs_per_row;\n if (idx >= total) return;\n\n int row = (int)(idx / vecs_per_row);\n int vec = (int)(idx - (int64_t)row * vecs_per_row);\n int t = vec << 2;\n int c = row % C;\n int base = row * L + t;\n\n float w0 = w[c * 3 + 0];\n float w1 = w[c * 3 + 1];\n float w2 = w[c * 3 + 2];\n float bv = has_bias ? bias[c] : 0.0f;\n\n const float* xp = x + base;\n float xm1 = (t == 0) ? 0.0f : xp[-1];\n float x0 = xp[0];\n float x1 = xp[1];\n float x2 = xp[2];\n float x3 = xp[3];\n float x4 = (t + 4 >= L) ? 0.0f : xp[4];\n\n float o0 = fmaf(w2, x1, fmaf(w1, x0, w0 * xm1)) + bv;\n float o1 = fmaf(w2, x2, fmaf(w1, x1, w0 * x0)) + bv;\n float o2 = fmaf(w2, x3, fmaf(w1, x2, w0 * x1)) + bv;\n float o3 = fmaf(w2, x4, fmaf(w1, x3, w0 * x2)) + bv;\n\n *reinterpret_cast<float4*>(y + base) = make_float4(o0, o1, o2, o3);\n}\n\n__global__ void dwconv1d_generic_kernel(\n const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ bias,\n float* __restrict__ y,\n int B, int C, int L, int K, int Lout, int stride, int padding, int has_bias)\n{\n int64_t idx = (int64_t)blockIdx.x * blockDim.x + threadIdx.x;\n int64_t total = (int64_t)B * C * Lout;\n if (idx >= total) return;\n\n int t = (int)(idx % Lout);\n int tmp = (int)(idx / Lout);\n int c = tmp % C;\n int b = tmp / C;\n\n float acc = has_bias ? bias[c] : 0.0f;\n int in0 = t * stride - padding;\n const float* xrow = x + ((int64_t)b * C + c) * L;\n const float* wrow = w + (int64_t)c * K;\n #pragma unroll\n for (int k = 0; k < 16; ++k) {\n if (k >= K) break;\n int in_t = in0 + k;\n if ((unsigned)in_t < (unsigned)L) {\n acc = fmaf(wrow[k], xrow[in_t], acc);\n }\n }\n for (int k = 16; k < K; ++k) {\n int in_t = in0 + k;\n if ((unsigned)in_t < (unsigned)L) {\n acc = fmaf(wrow[k], xrow[in_t], acc);\n }\n }\n y[idx] = acc;\n}\n\ntorch::Tensor dwconv1d_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, int64_t stride64, int64_t padding64) {\n TORCH_CHECK(x.is_cuda(), \"x must be CUDA\");\n TORCH_CHECK(weight.is_cuda(), \"weight must be CUDA\");\n TORCH_CHECK(x.scalar_type() == torch::kFloat32, \"only fp32 supported\");\n TORCH_CHECK(weight.scalar_type() == torch::kFloat32, \"only fp32 supported\");\n TORCH_CHECK(x.is_contiguous(), \"x must be contiguous\");\n TORCH_CHECK(weight.is_contiguous(), \"weight must be contiguous\");\n\n int B = (int)x.size(0);\n int C = (int)x.size(1);\n int L = (int)x.size(2);\n int K = (int)weight.size(2);\n int stride = (int)stride64;\n int padding = (int)padding64;\n int Lout = (L + 2 * padding - K) / stride + 1;\n auto y = torch::empty({B, C, Lout}, x.options());\n int has_bias = (bias.numel() != 0) ? 1 : 0;\n\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n if (K == 3 && stride == 1 && padding == 1 && Lout == L && ((L & 3) == 0)) {\n int rows = B * C;\n int64_t total_vec = (int64_t)rows * (L >> 2);\n int blocks = (int)((total_vec + threads - 1) / threads);\n dwconv1d_k3s1p1_vec4_kernel<<<blocks, threads, 0, stream>>>(\n x.data_ptr<float>(), weight.data_ptr<float>(), has_bias ? bias.data_ptr<float>() : nullptr,\n y.data_ptr<float>(), rows, C, L, has_bias);\n } else {\n int64_t total = (int64_t)B * C * Lout;\n int blocks = (int)((total + threads - 1) / threads);\n dwconv1d_generic_kernel<<<blocks, threads, 0, stream>>>(\n x.data_ptr<float>(), weight.data_ptr<float>(), has_bias ? bias.data_ptr<float>() : nullptr,\n y.data_ptr<float>(), B, C, L, K, Lout, stride, padding, has_bias);\n }\n return y;\n}\n\"\"\"\n\n_dwconv1d_ext = load_inline(\n name=\"dwconv1d_depthwise_k3_ext\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"dwconv1d_forward\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\"],\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, channels: int, kernel_size: int, stride: int = 1, padding: int = 0, bias: bool = False):\n super(ModelNew, self).__init__()\n self.conv1d = nn.Conv1d(channels, channels, kernel_size, stride=stride, padding=padding, groups=channels, bias=bias)\n self._stride_val = stride\n self._padding_val = padding\n self.register_buffer(\"_empty_bias\", torch.empty(0), persistent=False)\n\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n if not x.is_contiguous():\n x = x.contiguous()\n b = self.conv1d.bias if self.conv1d.bias is not None else self._empty_bias\n return _dwconv1d_ext.dwconv1d_forward(x, self.conv1d.weight, b, int(self._stride_val), int(self._padding_val))\n"
}