gpt-5.5-priority · original · l123_single_gpt
correct 81_Gemm_Swish_Divide_Clamp_Tanh_Clamp.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
2.71 μs
ref runtime
2.84 μs
speedup
1.05x
started
2026-05-05T02:36:05Z
timingkernelbench.timing
kernel runtime
2.71 μs
ref runtime
2.84 μs
speedup
1.05x
kernel mean / median / std
2.71 / — / 0.01 μs
ref mean / median / std
2.84 / — / 0.01 μs
numerical precisioneval_kernel_against_ref
max abs error
5.54e-06
mean abs error
1.48e-07
max rel error
1.05e-05
mean rel error
2.44e-06
gpu memoryextended_metrics.measure_memory
kernel peak
609.06 MB
ref peak
673.06 MB
kernel / ref
0.90x
kernel launches / fusiontorch.profiler
kernel launches
5
ref launches
13
fusion ratio (ref / kernel)
2.60x
total cuda time
5625 μs
energyNVML (pynvml)
kernel mJ / run
483.82
ref mJ / run
1693.98
ratio (ref / kernel)
3.50x
avg power
178.69 W
ref avg power
596.93 W
SOL (speed-of-light)nsight_hardware_counters
SOL score (0–1)
0.864
dram util %
52.3%
compute util %
86.4%
bottleneck
compute-bound
dominant pipe
FP32
arithmetic intensity
—
ridge point
20.00
roofline / occupancynsight_hardware_counters
dram bandwidth
1751.12 GB/s
dram util %
52.3%
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
86.5%
bottleneck
compute-bound
dominant pipe %
86.4%
arithmetic intensity
—
ridge point
20.00
L1 hit %
—
L2 hit %
141.8%
ld sectors / req
8.00
st sectors / req
—
regs / thread
270
smem / block
35840 B
block size
384
peak bw
3350.00 GB/s
peak fp32 tflops
67.00
peak fp16 tflops
1979.00
warp stalls (top 5)nsight
long_scoreboard
2942.7%
short_scoreboard
364.0%
mio_throttle
63.6%
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn

class Model(nn.Module):
    """
    Simple model that performs a gemm, swish, divide, clamp, tanh, and clamp operations.
    """
    def __init__(self, in_features, out_features, bias=True):
        super(Model, self).__init__()
        self.gemm = nn.Linear(in_features, out_features, bias=bias)

    def forward(self, x):
        """
        Args:
            x (torch.Tensor): Input tensor of shape (batch_size, in_features).
        Returns:
            torch.Tensor: Output tensor of shape (batch_size, out_features).
        """
        x = self.gemm(x)
        x = x * torch.sigmoid(x)  # Swish activation
        x = x / 2.0
        x = torch.clamp(x, min=-1.0, max=1.0)  # Clamp between -1 and 1
        x = torch.tanh(x)  # Tanh activation
        x = torch.clamp(x, min=-1.0, max=1.0)  # Clamp between -1 and 1
        return x

batch_size = 1024
in_features = 8192
out_features = 8192

def get_inputs():
    return [torch.rand(batch_size, in_features)]

def get_init_inputs():
    return [in_features, out_features]
turn 015.4s turn · 15.4s 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\n_cpp_src = r'''\n#include <torch/extension.h>\n\n// CUDA launcher implemented in cuda source\nvoid swish_postprocess_cuda(torch::Tensor y);\n\n// Complete forward: use the highly optimized library GEMM used by PyTorch, then\n// replace the chain of pointwise kernels with one fused CUDA kernel.\ntorch::Tensor fused_forward(torch::Tensor x, torch::Tensor weight, c10::optional<torch::Tensor> bias) {\n torch::Tensor y;\n if (bias.has_value() && bias.value().defined()) {\n y = at::linear(x, weight, bias.value());\n } else {\n y = at::linear(x, weight, c10::nullopt);\n }\n swish_postprocess_cuda(y);\n return y;\n}\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#include <math_constants.h>\n\n__device__ __forceinline__ float sigmoidf_fast(float x) {\n return 1.0f / (1.0f + expf(-x));\n}\n\n__global__ void swish_postprocess_kernel(float* __restrict__ y, const long long n) {\n const long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < n) {\n float v = y[idx];\n // x * sigmoid(x), divide by 2, clamp to [-1,1], tanh, final clamp\n float t = 0.5f * v * sigmoidf_fast(v);\n t = fminf(1.0f, fmaxf(-1.0f, t));\n t = tanhf(t);\n // tanh(clamp([-1,1])) already lies in [-1,1], but keep exact op semantics.\n t = fminf(1.0f, fmaxf(-1.0f, t));\n y[idx] = t;\n }\n}\n\nvoid swish_postprocess_cuda(torch::Tensor y) {\n const long long n = y.numel();\n if (n == 0) return;\n const int threads = 256;\n const int blocks = (int)((n + threads - 1) / threads);\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n swish_postprocess_kernel<<<blocks, threads, 0, stream>>>(y.data_ptr<float>(), n);\n}\n'''\n\n_ext = load_inline(\n name='fused_linear_swish_clamp_tanh_ext',\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=['fused_forward'],\n extra_cflags=['-O3'],\n extra_cuda_cflags=['-O3', '--use_fast_math'],\n verbose=False,\n)\n\n\nclass ModelNew(nn.Module):\n \"\"\"Drop-in replacement for the reference module.\"\"\"\n def __init__(self, in_features, out_features, bias=True):\n super(ModelNew, self).__init__()\n self.gemm = nn.Linear(in_features, out_features, bias=bias)\n\n def forward(self, x):\n return _ext.fused_forward(x, self.gemm.weight, self.gemm.bias)\n" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 2.71 μs Runtime stats: mean=2.71μs median=?μs std=0.01μs Numerical precision: max_abs_err=5.54e-06 mean_abs_err=1.48e-07 max_rel_err=1.05e-05 Memory: 609.06 MB peak (ref: 673.06 MB, ratio: 0.9049x) Kernel launches: 5 (ref: 13, fusion ratio: 2.6) Energy: 483.82 mJ/run (ref: 1693.98 mJ, ratio: 3.5013x) SOL score: 0.8644
final submitted kernel (80 lines, 2,473 chars) — full source, untruncated
import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline


_cpp_src = r'''
#include <torch/extension.h>

// CUDA launcher implemented in cuda source
void swish_postprocess_cuda(torch::Tensor y);

// Complete forward: use the highly optimized library GEMM used by PyTorch, then
// replace the chain of pointwise kernels with one fused CUDA kernel.
torch::Tensor fused_forward(torch::Tensor x, torch::Tensor weight, c10::optional<torch::Tensor> bias) {
    torch::Tensor y;
    if (bias.has_value() && bias.value().defined()) {
        y = at::linear(x, weight, bias.value());
    } else {
        y = at::linear(x, weight, c10::nullopt);
    }
    swish_postprocess_cuda(y);
    return y;
}
'''

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

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

__global__ void swish_postprocess_kernel(float* __restrict__ y, const long long n) {
    const long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x;
    if (idx < n) {
        float v = y[idx];
        // x * sigmoid(x), divide by 2, clamp to [-1,1], tanh, final clamp
        float t = 0.5f * v * sigmoidf_fast(v);
        t = fminf(1.0f, fmaxf(-1.0f, t));
        t = tanhf(t);
        // tanh(clamp([-1,1])) already lies in [-1,1], but keep exact op semantics.
        t = fminf(1.0f, fmaxf(-1.0f, t));
        y[idx] = t;
    }
}

void swish_postprocess_cuda(torch::Tensor y) {
    const long long n = y.numel();
    if (n == 0) return;
    const int threads = 256;
    const int blocks = (int)((n + threads - 1) / threads);
    cudaStream_t stream = at::cuda::getCurrentCUDAStream();
    swish_postprocess_kernel<<<blocks, threads, 0, stream>>>(y.data_ptr<float>(), n);
}
'''

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


class ModelNew(nn.Module):
    """Drop-in replacement for the reference module."""
    def __init__(self, in_features, out_features, bias=True):
        super(ModelNew, self).__init__()
        self.gemm = nn.Linear(in_features, out_features, bias=bias)

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