gpt-5.5-priority · original · l123_single_gpt
compile_fail 48_Conv3d_Scaling_Tanh_Multiply_Sigmoid.py
model
gpt-5.5-priority
turns / max
1 / 1
tool calls
1
tokens (total)
0
wall clock
—
truncated
no
backend
cuda fp32
variant
original
runtime
—
ref runtime
-1.00 μs
speedup
—
started
2026-05-05T02:21:31Z
compile error: Error building extension 'fused_conv3d_tanh_sigmoid_ext_v1': [1/3] /opt/conda/bin/x86_64-conda-linux-gnu-c++ -MMD -MF main.o.d -DTORCH_EXTENSION_NAME=fused_conv3d_tanh_sigmoid_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /opt/conda/include/python3.10 -fPIC -std=c++17 -O3 -c /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_
timingkernelbench.timing
kernel runtime
—
ref runtime
—
speedup
—
kernel mean / median / std
—
ref mean / median / std
—
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn

class Model(nn.Module):
    """
    Model that performs a 3D convolution, scales the output, applies tanh, multiplies by a scaling factor, and applies sigmoid.
    """
    def __init__(self, in_channels, out_channels, kernel_size, scaling_factor, bias_shape):
        super(Model, self).__init__()
        self.conv = nn.Conv3d(in_channels, out_channels, kernel_size)
        self.scaling_factor = nn.Parameter(torch.randn(bias_shape))
        self.bias = nn.Parameter(torch.randn(bias_shape)) 

    def forward(self, x):
        x = self.conv(x)
        x = x * self.scaling_factor 
        x = torch.tanh(x)
        x = x * self.bias
        x = torch.sigmoid(x)
        return x

batch_size = 128
in_channels = 3
out_channels = 16
depth, height, width = 16, 64, 64
kernel_size = 3
scaling_factor = 2
bias_shape = (out_channels, 1, 1, 1)

def get_inputs():
    return [torch.rand(batch_size, in_channels, depth, height, width)]

def get_init_inputs():
    return [in_channels, out_channels, kernel_size, scaling_factor, bias_shape]
turn 0 · FINAL · 1 tool call(s) · 30.5s turn · 30.5s LLM · 13,236 chars (click to expand)
turn 030.5s turn · 30.5s LLM · 0.0s tools · FINAL
call → submit_kernel
callsubmit_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\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\nstatic inline void check_inputs(const torch::Tensor& x, const torch::Tensor& w) {\n TORCH_CHECK(x.is_cuda(), \"x must be CUDA\");\n TORCH_CHECK(w.is_cuda(), \"w must be CUDA\");\n TORCH_CHECK(x.scalar_type() == torch::kFloat32, \"only fp32 supported\");\n}\n\n__device__ __forceinline__ float sigmoidf_fast(float x) {\n return 1.0f / (1.0f + expf(-x));\n}\n\n// Specialized for the benchmark shape: C=3, K=3, O arbitrary (16 here), contiguous NCDHW.\n__global__ __launch_bounds__(256, 2)\nvoid conv3d_fused_k3_c3_kernel(\n const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ conv_b,\n const float* __restrict__ scale,\n const float* __restrict__ post_b,\n float* __restrict__ y,\n long total,\n int N, int O, int D, int H, int W,\n int Do, int Ho, int Wo)\n{\n long idx = (long)blockIdx.x * blockDim.x + threadIdx.x;\n long stride = (long)blockDim.x * gridDim.x;\n const int HW = H * W;\n const int DHW = D * HW;\n const int out_spatial = Do * Ho * Wo;\n const int out_hw = Ho * Wo;\n\n for (; idx < total; idx += stride) {\n long t = idx;\n int ow = (int)(t % Wo); t /= Wo;\n int oh = (int)(t % Ho); t /= Ho;\n int od = (int)(t % Do); t /= Do;\n int oc = (int)(t % O); t /= O;\n int n = (int)t;\n\n const float* xp = x + ((long)n * 3 * D + od) * HW + oh * W + ow;\n const float* wp = w + (long)oc * 3 * 27;\n float acc = conv_b ? __ldg(conv_b + oc) : 0.0f;\n\n #pragma unroll\n for (int c = 0; c < 3; ++c) {\n const float* xpc = xp + (long)c * DHW;\n const float* wpc = wp + c * 27;\n // kd = 0\n acc = fmaf(__ldg(xpc + 0*HW + 0*W + 0), __ldg(wpc + 0), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 0*W + 1), __ldg(wpc + 1), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 0*W + 2), __ldg(wpc + 2), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 1*W + 0), __ldg(wpc + 3), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 1*W + 1), __ldg(wpc + 4), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 1*W + 2), __ldg(wpc + 5), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 2*W + 0), __ldg(wpc + 6), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 2*W + 1), __ldg(wpc + 7), acc);\n acc = fmaf(__ldg(xpc + 0*HW + 2*W + 2), __ldg(wpc + 8), acc);\n // kd = 1\n acc = fmaf(__ldg(xpc + 1*HW + 0*W + 0), __ldg(wpc + 9), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 0*W + 1), __ldg(wpc + 10), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 0*W + 2), __ldg(wpc + 11), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 1*W + 0), __ldg(wpc + 12), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 1*W + 1), __ldg(wpc + 13), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 1*W + 2), __ldg(wpc + 14), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 2*W + 0), __ldg(wpc + 15), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 2*W + 1), __ldg(wpc + 16), acc);\n acc = fmaf(__ldg(xpc + 1*HW + 2*W + 2), __ldg(wpc + 17), acc);\n // kd = 2\n acc = fmaf(__ldg(xpc + 2*HW + 0*W + 0), __ldg(wpc + 18), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 0*W + 1), __ldg(wpc + 19), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 0*W + 2), __ldg(wpc + 20), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 1*W + 0), __ldg(wpc + 21), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 1*W + 1), __ldg(wpc + 22), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 1*W + 2), __ldg(wpc + 23), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 2*W + 0), __ldg(wpc + 24), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 2*W + 1), __ldg(wpc + 25), acc);\n acc = fmaf(__ldg(xpc + 2*HW + 2*W + 2), __ldg(wpc + 26), acc);\n }\n float v = acc * __ldg(scale + oc);\n v = tanhf(v);\n v *= __ldg(post_b + oc);\n y[idx] = sigmoidf_fast(v);\n }\n}\n\n// Generic direct fused kernel for less common constructor variants.\n__global__ void conv3d_fused_generic_kernel(\n const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ conv_b,\n const float* __restrict__ scale,\n const float* __restrict__ post_b,\n float* __restrict__ y,\n long total,\n int N, int C, int O, int D, int H, int W, int Kd, int Kh, int Kw,\n int Do, int Ho, int Wo)\n{\n long idx = (long)blockIdx.x * blockDim.x + threadIdx.x;\n long stride = (long)blockDim.x * gridDim.x;\n const int HW = H * W;\n const int DHW = D * HW;\n const int out_hw = Ho * Wo;\n const int KHW = Kh * Kw;\n const int Ktot = Kd * KHW;\n for (; idx < total; idx += stride) {\n long t = idx;\n int ow = (int)(t % Wo); t /= Wo;\n int oh = (int)(t % Ho); t /= Ho;\n int od = (int)(t % Do); t /= Do;\n int oc = (int)(t % O); t /= O;\n int n = (int)t;\n float acc = conv_b ? __ldg(conv_b + oc) : 0.0f;\n for (int c=0; c<C; ++c) {\n for (int kd=0; kd<Kd; ++kd) {\n for (int kh=0; kh<Kh; ++kh) {\n const float* xp = x + ((long)n*C + c)*DHW + (od+kd)*HW + (oh+kh)*W + ow;\n const float* wp = w + ((long)oc*C + c)*Ktot + kd*KHW + kh*Kw;\n for (int kw=0; kw<Kw; ++kw) acc = fmaf(__ldg(xp+kw), __ldg(wp+kw), acc);\n }\n }\n }\n float v = acc * __ldg(scale + oc);\n v = tanhf(v);\n v *= __ldg(post_b + oc);\n y[idx] = 1.0f / (1.0f + expf(-v));\n }\n}\n\ntorch::Tensor fused_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor conv_bias, torch::Tensor scale, torch::Tensor post_bias) {\n check_inputs(x, weight);\n TORCH_CHECK(x.dim() == 5 && weight.dim() == 5, \"expected 5D tensors\");\n auto xc = x.contiguous();\n auto wc = weight.contiguous();\n auto sc = scale.contiguous();\n auto pc = post_bias.contiguous();\n torch::Tensor bc = conv_bias.defined() ? conv_bias.contiguous() : conv_bias;\n\n int N = (int)xc.size(0), C = (int)xc.size(1), D = (int)xc.size(2), H = (int)xc.size(3), W = (int)xc.size(4);\n int O = (int)wc.size(0), Kd = (int)wc.size(2), Kh = (int)wc.size(3), Kw = (int)wc.size(4);\n int Do = D - Kd + 1, Ho = H - Kh + 1, Wo = W - Kw + 1;\n auto y = torch::empty({N, O, Do, Ho, Wo}, xc.options());\n long total = y.numel();\n if (total == 0) return y;\n int threads = 256;\n int blocks = (int)((total + threads - 1) / threads);\n int maxBlocks = 65535;\n if (blocks > maxBlocks) blocks = maxBlocks;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n const float* bp = bc.defined() ? bc.data_ptr<float>() : nullptr;\n if (C == 3 && Kd == 3 && Kh == 3 && Kw == 3) {\n conv3d_fused_k3_c3_kernel<<<blocks, threads, 0, stream>>>(\n xc.data_ptr<float>(), wc.data_ptr<float>(), bp, sc.data_ptr<float>(), pc.data_ptr<float>(), y.data_ptr<float>(),\n total, N, O, D, H, W, Do, Ho, Wo);\n } else {\n conv3d_fused_generic_kernel<<<blocks, threads, 0, stream>>>(\n xc.data_ptr<float>(), wc.data_ptr<float>(), bp, sc.data_ptr<float>(), pc.data_ptr<float>(), y.data_ptr<float>(),\n total, N, C, O, D, H, W, Kd, Kh, Kw, Do, Ho, Wo);\n }\n return y;\n}\n'''\n\n_ext = load_inline(\n name='fused_conv3d_tanh_sigmoid_ext_v1',\n cpp_sources='',\n cuda_sources=_cuda_src,\n functions=['fused_forward'],\n extra_cuda_cflags=['-O3', '--use_fast_math'],\n extra_cflags=['-O3'],\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels, out_channels, kernel_size, scaling_factor, bias_shape):\n super(ModelNew, self).__init__()\n self.conv = nn.Conv3d(in_channels, out_channels, kernel_size)\n self.scaling_factor = nn.Parameter(torch.randn(bias_shape))\n self.bias = nn.Parameter(torch.randn(bias_shape))\n\n def forward(self, x):\n return _ext.fused_forward(x, self.conv.weight, self.conv.bias, self.scaling_factor, self.bias)\n" }
result ← submit_kernel (fail)
failsubmit_kernel submit_kernel FAILED: kernel did not compile. Error building extension 'fused_conv3d_tanh_sigmoid_ext_v1': [1/3] /opt/conda/bin/x86_64-conda-linux-gnu-c++ -MMD -MF main.o.d -DTORCH_EXTENSION_NAME=fused_conv3d_tanh_sigmoid_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /opt/conda/include/python3.10 -fPIC -std=c++17 -O3 -c /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/main.cpp -o main.o FAILED: [code=1] main.o /opt/conda/bin/x86_64-conda-linux-gnu-c++ -MMD -MF main.o.d -DTORCH_EXTENSION_NAME=fused_conv3d_tanh_sigmoid_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /opt/conda/include/python3.10 -fPIC -std=c++17 -O3 -c /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/main.cpp -o main.o /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/main.cpp: In function 'void pybind11_init_fused_conv3d_tanh_sigmoid_ext_v1(pybind11::module_&)': /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/main.cpp:4:52: error: 'fused_forward' was not declared in this scope 4 | m.def("fused_forward", torch::wrap_pybind_function(fused_forward), "fused_forward"); | ^~~~~~~~~~~~~ [2/3] /usr/local/cuda/bin/nvcc -MD -MF cuda.cuda.o.d -ccbin /opt/conda/bin/x86_64-conda-linux-gnu-cc -DTORCH_EXTENSION_NAME=fused_conv3d_tanh_sigmoid_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/abaner/KernelBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /opt/conda/include/python3.10 -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_BFLOAT16_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ --expt-relaxed-constexpr -gencode=arch=compute_90,code=compute_90 -gencode=arch=compute_90,code=sm_90 --compiler-options '-fPIC' -O3 --use_fast_math -std=c++17 -c /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/cuda.cu -o cuda.cuda.o nvcc warning : incompatible redefinition for option 'compiler-bindir', the last value of this option was used /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/cuda.cu(37): warning #177-D: variable "out_spatial" was declared but never referenced const int out_spatial = Do * Ho * Wo; ^ Remark: The warnings can be suppressed with "-diag-suppress <warning-number>" /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/cuda.cu(38): warning #177-D: variable "out_hw" was declared but never referenced const int out_hw = Ho * Wo; ^ /scratch/abaner/KernelBench/runs/l123_single_gpt/original/gpt-5.5-priority/level_2_problem_48_cache/k_81e7cadd2d27/fused_conv3d_tanh_sigmoid_ext_v1/cuda.cu(110): warning #177-D: variable "out_hw" was declared but never referenced const int out_hw = Ho * Wo; ^ ninja: build stopped: subcommand failed.
final submitted kernel (191 lines, 8,102 chars) — full source, untruncated
import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline

_cuda_src = r'''
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <cuda.h>
#include <cuda_runtime.h>

static inline void check_inputs(const torch::Tensor& x, const torch::Tensor& w) {
    TORCH_CHECK(x.is_cuda(), "x must be CUDA");
    TORCH_CHECK(w.is_cuda(), "w must be CUDA");
    TORCH_CHECK(x.scalar_type() == torch::kFloat32, "only fp32 supported");
}

__device__ __forceinline__ float sigmoidf_fast(float x) {
    return 1.0f / (1.0f + expf(-x));
}

// Specialized for the benchmark shape: C=3, K=3, O arbitrary (16 here), contiguous NCDHW.
__global__ __launch_bounds__(256, 2)
void conv3d_fused_k3_c3_kernel(
    const float* __restrict__ x,
    const float* __restrict__ w,
    const float* __restrict__ conv_b,
    const float* __restrict__ scale,
    const float* __restrict__ post_b,
    float* __restrict__ y,
    long total,
    int N, int O, int D, int H, int W,
    int Do, int Ho, int Wo)
{
    long idx = (long)blockIdx.x * blockDim.x + threadIdx.x;
    long stride = (long)blockDim.x * gridDim.x;
    const int HW = H * W;
    const int DHW = D * HW;
    const int out_spatial = Do * Ho * Wo;
    const int out_hw = Ho * Wo;

    for (; idx < total; idx += stride) {
        long t = idx;
        int ow = (int)(t % Wo); t /= Wo;
        int oh = (int)(t % Ho); t /= Ho;
        int od = (int)(t % Do); t /= Do;
        int oc = (int)(t % O);  t /= O;
        int n  = (int)t;

        const float* xp = x + ((long)n * 3 * D + od) * HW + oh * W + ow;
        const float* wp = w + (long)oc * 3 * 27;
        float acc = conv_b ? __ldg(conv_b + oc) : 0.0f;

        #pragma unroll
        for (int c = 0; c < 3; ++c) {
            const float* xpc = xp + (long)c * DHW;
            const float* wpc = wp + c * 27;
            // kd = 0
            acc = fmaf(__ldg(xpc + 0*HW + 0*W + 0), __ldg(wpc + 0), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 0*W + 1), __ldg(wpc + 1), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 0*W + 2), __ldg(wpc + 2), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 1*W + 0), __ldg(wpc + 3), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 1*W + 1), __ldg(wpc + 4), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 1*W + 2), __ldg(wpc + 5), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 2*W + 0), __ldg(wpc + 6), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 2*W + 1), __ldg(wpc + 7), acc);
            acc = fmaf(__ldg(xpc + 0*HW + 2*W + 2), __ldg(wpc + 8), acc);
            // kd = 1
            acc = fmaf(__ldg(xpc + 1*HW + 0*W + 0), __ldg(wpc + 9), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 0*W + 1), __ldg(wpc + 10), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 0*W + 2), __ldg(wpc + 11), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 1*W + 0), __ldg(wpc + 12), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 1*W + 1), __ldg(wpc + 13), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 1*W + 2), __ldg(wpc + 14), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 2*W + 0), __ldg(wpc + 15), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 2*W + 1), __ldg(wpc + 16), acc);
            acc = fmaf(__ldg(xpc + 1*HW + 2*W + 2), __ldg(wpc + 17), acc);
            // kd = 2
            acc = fmaf(__ldg(xpc + 2*HW + 0*W + 0), __ldg(wpc + 18), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 0*W + 1), __ldg(wpc + 19), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 0*W + 2), __ldg(wpc + 20), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 1*W + 0), __ldg(wpc + 21), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 1*W + 1), __ldg(wpc + 22), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 1*W + 2), __ldg(wpc + 23), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 2*W + 0), __ldg(wpc + 24), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 2*W + 1), __ldg(wpc + 25), acc);
            acc = fmaf(__ldg(xpc + 2*HW + 2*W + 2), __ldg(wpc + 26), acc);
        }
        float v = acc * __ldg(scale + oc);
        v = tanhf(v);
        v *= __ldg(post_b + oc);
        y[idx] = sigmoidf_fast(v);
    }
}

// Generic direct fused kernel for less common constructor variants.
__global__ void conv3d_fused_generic_kernel(
    const float* __restrict__ x,
    const float* __restrict__ w,
    const float* __restrict__ conv_b,
    const float* __restrict__ scale,
    const float* __restrict__ post_b,
    float* __restrict__ y,
    long total,
    int N, int C, int O, int D, int H, int W, int Kd, int Kh, int Kw,
    int Do, int Ho, int Wo)
{
    long idx = (long)blockIdx.x * blockDim.x + threadIdx.x;
    long stride = (long)blockDim.x * gridDim.x;
    const int HW = H * W;
    const int DHW = D * HW;
    const int out_hw = Ho * Wo;
    const int KHW = Kh * Kw;
    const int Ktot = Kd * KHW;
    for (; idx < total; idx += stride) {
        long t = idx;
        int ow = (int)(t % Wo); t /= Wo;
        int oh = (int)(t % Ho); t /= Ho;
        int od = (int)(t % Do); t /= Do;
        int oc = (int)(t % O);  t /= O;
        int n = (int)t;
        float acc = conv_b ? __ldg(conv_b + oc) : 0.0f;
        for (int c=0; c<C; ++c) {
            for (int kd=0; kd<Kd; ++kd) {
                for (int kh=0; kh<Kh; ++kh) {
                    const float* xp = x + ((long)n*C + c)*DHW + (od+kd)*HW + (oh+kh)*W + ow;
                    const float* wp = w + ((long)oc*C + c)*Ktot + kd*KHW + kh*Kw;
                    for (int kw=0; kw<Kw; ++kw) acc = fmaf(__ldg(xp+kw), __ldg(wp+kw), acc);
                }
            }
        }
        float v = acc * __ldg(scale + oc);
        v = tanhf(v);
        v *= __ldg(post_b + oc);
        y[idx] = 1.0f / (1.0f + expf(-v));
    }
}

torch::Tensor fused_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor conv_bias, torch::Tensor scale, torch::Tensor post_bias) {
    check_inputs(x, weight);
    TORCH_CHECK(x.dim() == 5 && weight.dim() == 5, "expected 5D tensors");
    auto xc = x.contiguous();
    auto wc = weight.contiguous();
    auto sc = scale.contiguous();
    auto pc = post_bias.contiguous();
    torch::Tensor bc = conv_bias.defined() ? conv_bias.contiguous() : conv_bias;

    int N = (int)xc.size(0), C = (int)xc.size(1), D = (int)xc.size(2), H = (int)xc.size(3), W = (int)xc.size(4);
    int O = (int)wc.size(0), Kd = (int)wc.size(2), Kh = (int)wc.size(3), Kw = (int)wc.size(4);
    int Do = D - Kd + 1, Ho = H - Kh + 1, Wo = W - Kw + 1;
    auto y = torch::empty({N, O, Do, Ho, Wo}, xc.options());
    long total = y.numel();
    if (total == 0) return y;
    int threads = 256;
    int blocks = (int)((total + threads - 1) / threads);
    int maxBlocks = 65535;
    if (blocks > maxBlocks) blocks = maxBlocks;
    cudaStream_t stream = at::cuda::getCurrentCUDAStream();
    const float* bp = bc.defined() ? bc.data_ptr<float>() : nullptr;
    if (C == 3 && Kd == 3 && Kh == 3 && Kw == 3) {
        conv3d_fused_k3_c3_kernel<<<blocks, threads, 0, stream>>>(
            xc.data_ptr<float>(), wc.data_ptr<float>(), bp, sc.data_ptr<float>(), pc.data_ptr<float>(), y.data_ptr<float>(),
            total, N, O, D, H, W, Do, Ho, Wo);
    } else {
        conv3d_fused_generic_kernel<<<blocks, threads, 0, stream>>>(
            xc.data_ptr<float>(), wc.data_ptr<float>(), bp, sc.data_ptr<float>(), pc.data_ptr<float>(), y.data_ptr<float>(),
            total, N, C, O, D, H, W, Kd, Kh, Kw, Do, Ho, Wo);
    }
    return y;
}
'''

_ext = load_inline(
    name='fused_conv3d_tanh_sigmoid_ext_v1',
    cpp_sources='',
    cuda_sources=_cuda_src,
    functions=['fused_forward'],
    extra_cuda_cflags=['-O3', '--use_fast_math'],
    extra_cflags=['-O3'],
    verbose=False,
)

class ModelNew(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, scaling_factor, bias_shape):
        super(ModelNew, self).__init__()
        self.conv = nn.Conv3d(in_channels, out_channels, kernel_size)
        self.scaling_factor = nn.Parameter(torch.randn(bias_shape))
        self.bias = nn.Parameter(torch.randn(bias_shape))

    def forward(self, x):
        return _ext.fused_forward(x, self.conv.weight, self.conv.bias, self.scaling_factor, self.bias)