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 = r'''\n#include <torch/extension.h>\n\ntorch::Tensor conv3d_cuda_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int64_t stride, int64_t padding, int64_t dilation, int64_t groups);\n'''\n\n_cuda = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ __launch_bounds__(256)\nvoid conv3d_k331_d10_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n long units,\n int N, int OC, int ID, int IH, int IW,\n int OH, int OW,\n int has_bias) {\n long tid = (long)blockIdx.x * blockDim.x + threadIdx.x;\n long stride_grid = (long)blockDim.x * gridDim.x;\n const int plane_in = IH * IW;\n const int chan_in = ID * plane_in;\n const int plane_out = OW * IW; // OD == IW == 10\n const int chan_out = OH * plane_out;\n for (long u = tid; u < units; u += stride_grid) {\n int ow = (int)(u % OW);\n long t = u / OW;\n int oh = (int)(t % OH);\n t /= OH;\n int oc = (int)(t % OC);\n int n = (int)(t / OC);\n\n float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;\n if (has_bias) {\n float bv = b[oc];\n s0=s1=s2=s3=s4=s5=s6=s7=s8=s9=bv;\n } else {\n s0=s1=s2=s3=s4=s5=s6=s7=s8=s9=0.0f;\n }\n\n #pragma unroll\n for (int c = 0; c < 3; ++c) {\n int xbase_c = ((n * 3 + c) * ID + oh) * plane_in + ow * IW;\n int wbase_c = (oc * 3 + c) * 9;\n #pragma unroll\n for (int kd = 0; kd < 3; ++kd) {\n int xbase_kd = xbase_c + kd * plane_in;\n int wbase_kd = wbase_c + kd * 3;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n float ww = w[wbase_kd + kh];\n const float* xp = x + xbase_kd + kh * IW;\n s0 = fmaf(xp[0], ww, s0);\n s1 = fmaf(xp[1], ww, s1);\n s2 = fmaf(xp[2], ww, s2);\n s3 = fmaf(xp[3], ww, s3);\n s4 = fmaf(xp[4], ww, s4);\n s5 = fmaf(xp[5], ww, s5);\n s6 = fmaf(xp[6], ww, s6);\n s7 = fmaf(xp[7], ww, s7);\n s8 = fmaf(xp[8], ww, s8);\n s9 = fmaf(xp[9], ww, s9);\n }\n }\n }\n long ybase = (((long)n * OC + oc) * OH + oh) * (long)OW * IW + (long)ow * IW;\n y[ybase + 0] = s0;\n y[ybase + 1] = s1;\n y[ybase + 2] = s2;\n y[ybase + 3] = s3;\n y[ybase + 4] = s4;\n y[ybase + 5] = s5;\n y[ybase + 6] = s6;\n y[ybase + 7] = s7;\n y[ybase + 8] = s8;\n y[ybase + 9] = s9;\n }\n}\n\n__global__ __launch_bounds__(256)\nvoid conv3d_generic_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ b,\n float* __restrict__ y,\n long total,\n int N, int C, int OC, int ID, int IH, int IW,\n int KD, int KH, int KW, int OD, int OH, int OW,\n int stride_v, int pad, int dil, int has_bias) {\n long tid = (long)blockIdx.x * blockDim.x + threadIdx.x;\n long stride_grid = (long)blockDim.x * gridDim.x;\n for (long idx = tid; idx < total; idx += stride_grid) {\n int ow = idx % OW;\n long t = idx / OW;\n int oh = t % OH; t /= OH;\n int od = t % OD; t /= OD;\n int oc = t % OC; t /= OC;\n int n = t;\n float acc = has_bias ? b[oc] : 0.0f;\n for (int c=0;c<C;++c) {\n for (int kd=0;kd<KD;++kd) {\n int id = od*stride_v - pad + kd*dil;\n if ((unsigned)id >= (unsigned)ID) continue;\n for (int kh=0;kh<KH;++kh) {\n int ih = oh*stride_v - pad + kh*dil;\n if ((unsigned)ih >= (unsigned)IH) continue;\n for (int kw=0;kw<KW;++kw) {\n int iw = ow*stride_v - pad + kw*dil;\n if ((unsigned)iw >= (unsigned)IW) continue;\n long xi = (((long)n*C + c)*ID + id)*IH*IW + ih*IW + iw;\n long wi = (((long)oc*C + c)*KD + kd)*KH*KW + kh*KW + kw;\n acc = fmaf(x[xi], w[wi], acc);\n }\n }\n }\n }\n y[idx] = acc;\n }\n}\n\ntorch::Tensor conv3d_cuda_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int64_t stride, int64_t padding, int64_t dilation, int64_t groups) {\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int ID = (int)x.size(2);\n const int IH = (int)x.size(3);\n const int IW = (int)x.size(4);\n const int OC = (int)weight.size(0);\n const int KD = (int)weight.size(2);\n const int KH = (int)weight.size(3);\n const int KW = (int)weight.size(4);\n const int OD = (ID + 2*(int)padding - (int)dilation*(KD-1) - 1) / (int)stride + 1;\n const int OH = (IH + 2*(int)padding - (int)dilation*(KH-1) - 1) / (int)stride + 1;\n const int OW = (IW + 2*(int)padding - (int)dilation*(KW-1) - 1) / (int)stride + 1;\n auto y = torch::empty({N, OC, OD, OH, OW}, x.options());\n int has_bias = (bias.numel() > 0) ? 1 : 0;\n int threads = 256;\n cudaDeviceProp prop;\n cudaGetDeviceProperties(&prop, x.get_device());\n int max_blocks = prop.multiProcessorCount * 16;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if (x.scalar_type() == at::kFloat && C == 3 && KD == 3 && KH == 3 && KW == 1 &&\n stride == 1 && padding == 0 && dilation == 1 && groups == 1 && IW == 10) {\n long units = (long)N * OC * OD * OH; // each thread computes all 10 W positions\n int blocks = (int)((units + threads - 1) / threads);\n if (blocks > max_blocks) blocks = max_blocks;\n conv3d_k331_d10_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>(), units, N, OC, ID, IH, IW, OD, OH, has_bias);\n } else {\n long total = (long)N * OC * OD * OH * OW;\n int blocks = (int)((total + threads - 1) / threads);\n if (blocks > max_blocks) blocks = max_blocks;\n conv3d_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>(), total, N, C, OC, ID, IH, IW, KD, KH, KW, OD, OH, OW,\n (int)stride, (int)padding, (int)dilation, has_bias);\n }\n return y;\n}\n'''\n\n_ext = load_inline(name='conv3d_k331_ext', cpp_sources=[_cpp], cuda_sources=[_cuda], functions=['conv3d_cuda_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, out_channels: int, kernel_size: int, stride: int = 1, padding: int = 0, dilation: int = 1, groups: int = 1, bias: bool = False):\n super(ModelNew, self).__init__()\n self.conv3d = nn.Conv3d(in_channels, out_channels, (kernel_size, kernel_size, 1), stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)\n self.stride = stride\n self.padding = padding\n self.dilation = dilation\n self.groups = groups\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n b = self.conv3d.bias if self.conv3d.bias is not None else torch.empty(0, device=x.device, dtype=x.dtype)\n return _ext.conv3d_cuda_forward(x, self.conv3d.weight, b, self.stride, self.padding, self.dilation, self.groups)\n"
}