correct
31_VisionAttention.py
started
2026-05-04T21:39:01Z
timingkernelbench.timing
kernel mean / median / std
14.40 / — / 0.06 μs
ref mean / median / std
21.70 / — / 0.24 μs
numerical precisioneval_kernel_against_ref
gpu memoryextended_metrics.measure_memory
kernel launches / fusiontorch.profiler
fusion ratio (ref / kernel)
1.60x
energyNVML (pynvml)
ratio (ref / kernel)
1.50x
SOL (speed-of-light)nsight_hardware_counters
roofline / occupancynsight_hardware_counters
dram bandwidth
2404.50 GB/s
warp stalls (top 5)nsight
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self, embed_dim, num_heads):
"""
Attention Block using Multihead Self-Attention.
:param embed_dim: Embedding dimension (the number of channels)
:param num_heads: Number of attention heads
"""
super(Model, self).__init__()
self.attn = nn.MultiheadAttention(embed_dim, num_heads)
self.norm = nn.LayerNorm(embed_dim)
def forward(self, x):
"""
Forward pass of the AttentionBlock.
:param x: Input tensor of shape (B, C, H, W)
:return: Output tensor of the same shape (B, C, H, W)
"""
B, C, H, W = x.shape
x = x.view(B, C, H * W).permute(2, 0, 1) # (seq_len, batch_size, embed_dim)
attn_output, _ = self.attn(x, x, x)
x = self.norm(attn_output + x) # (seq_len, batch_size, embed_dim)
x = x.permute(1, 2, 0).view(B, C, H, W)
return x
embed_dim = 128
num_heads = 4
batch_size = 2
num_channels = embed_dim
image_height = 128
image_width = 128
def get_inputs():
return [torch.rand(batch_size, num_channels, image_height, image_width)]
def get_init_inputs():
return [embed_dim, num_heads]turn 011.1s turn · 11.1s LLM · 0.0s tools
reasoning
**Considering attention efficiency**
I'm thinking about skipping the returning of weights and focusing just on the output. I need to implement an efficient attention mechanism, possibly through a PyTorch extension. Maybe I can use a fused attention approach, like Flash, to achieve this. I wonder if calling the scaled_dot_product_attention function is feasible, or would I require a custom CUDA kernel? I need to evaluate if skipping attention weights is allowed but it might lead to a faster implementation!
**Exploring CUDA options**
I'm looking at the request to load inline for compiling and binding CUDA source. I wonder if I can use a wrapper to call the ATen scaled dot product attention without needing a custom kernel? I think I may need to define the CUDA source, but could I leave it empty? Compiling a C++ extension seems necessary, and I should definitely use load_inline. However, if a custom CUDA kernel is needed, does that mean I must have actual CUDA in play?
call → get_gpu_specs
callget_gpu_specs
{}
result ← get_gpu_specs (ok)
okget_gpu_specs
GPU specs for NVIDIA H100 80GB HBM3:
total memory (runtime): 79.1 GB
spec entry: H100
GPU Architecture: Hopper
GPU Memory: 80GB
Memory Bandwidth: 3.35 TB/s
FP64 TFLOPS: 34
FP64 Tensor Core TFLOPS: 67
FP32 TFLOPS: 67
TF32 Tensor Core TFLOPS: 989 with sparsity
BFLOAT16 Tensore Core TFLOPS: 1979 with sparsity
FP16 Tensor Core TFLOPS: 1979 with sparsity
FP8 Tensor Core TFLOPS: 3958 with sparsity
INT8 Tensor Core TOPS: 3958 with sparsity
Register File Size: 64K 32-bit registers per SM
Maximum number of registers per thread: 255
Maximum number of thread blocks per SM: 32
Shared memory capacity per SM: 228 KB
Maximum shared memory per thread block: 227 KB
turn 114.6s turn · 14.6s LLM · 0.0s tools
reasoning
**Creating CUDA source**
I see the user is asking about using `load_inline` to compile CUDA source. It seems like I could include `cuda_sources` with a dummy kernel. I'm considering how a C++ function might use ATen. Using `load_inline` with `cuda_sources` should trigger the nvcc compiler, and I need to think about how to structure the function effectively in C++. Okay, let's get started on creating that!
call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n#include <vector>\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n auto qkv = at::linear(x_blc, in_w, in_b); // B,L,3C\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2,0,3,1,4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0,2,1,3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n auto resid = proj + x_blc;\n auto y = at::layer_norm(resid, {C}, ln_w, ln_b, 1e-5, false);\n return y.permute({0,2,1}).contiguous().view({B, C, H, W});\n}\n'''\n\ncuda_src = r'''\n#include <cuda.h>\nextern \"C\" __global__ void _dummy_kernel_for_build() {}\n'''\n\n_ext = load_inline(name='attn_ext_v1', cpp_sources=[cpp_src], cuda_sources=[cuda_src], functions=['attn_forward'], verbose=False, extra_cflags=['-O3'], extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n def forward(self, x):\n return _ext.attn_forward(x, self.attn.in_proj_weight, self.attn.in_proj_bias,\n self.attn.out_proj.weight, self.attn.out_proj.bias,\n self.norm.weight, self.norm.bias, self.num_heads)\n"
}
result ← compile_kernel (ok)
okcompile_kernel
compile_kernel PASSED: kernel compiled without errors.
turn 24.5s turn · 4.5s LLM · 0.0s tools
call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n#include <vector>\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n auto qkv = at::linear(x_blc, in_w, in_b); // B,L,3C\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2,0,3,1,4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0,2,1,3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n auto resid = proj + x_blc;\n auto y = at::layer_norm(resid, {C}, ln_w, ln_b, 1e-5, false);\n return y.permute({0,2,1}).contiguous().view({B, C, H, W});\n}\n'''\n\ncuda_src = r'''\n#include <cuda.h>\nextern \"C\" __global__ void _dummy_kernel_for_build() {}\n'''\n\n_ext = load_inline(name='attn_ext_v1c', cpp_sources=[cpp_src], cuda_sources=[cuda_src], functions=['attn_forward'], verbose=False, extra_cflags=['-O3'], extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n def forward(self, x):\n return _ext.attn_forward(x, self.attn.in_proj_weight, self.attn.in_proj_bias,\n self.attn.out_proj.weight, self.attn.out_proj.bias,\n self.norm.weight, self.norm.bias, self.num_heads)\n"
}
result ← run_correctness (ok)
okrun_correctness
run_correctness PASSED: (5 / 5) trials all matched the reference.
Numerical precision: max_abs_err=7.27e-06 mean_abs_err=9.76e-07 max_rel_err=8.00e+00
turn 325.1s turn · 25.1s LLM · 0.0s tools
call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W);\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n auto qkv = at::linear(x_blc, in_w, in_b);\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2,0,3,1,4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0,2,1,3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n return fused_ln_out(proj, x_blc, ln_w, ln_b, H, W);\n}\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n\n__global__ void ln_out_kernel(const float* __restrict__ proj, const float* __restrict__ x,\n const float* __restrict__ gamma, const float* __restrict__ beta,\n float* __restrict__ out, int B, int L, int C) {\n int t = blockIdx.x;\n int tid = threadIdx.x;\n extern __shared__ float smem[];\n float v = 0.f;\n if (tid < C) {\n int idx = t * C + tid;\n v = proj[idx] + x[idx];\n }\n smem[tid] = (tid < C) ? v : 0.f;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float mean = smem[0] / (float)C;\n float diff = (tid < C) ? (v - mean) : 0.f;\n smem[tid] = diff * diff;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float inv = rsqrtf(smem[0] / (float)C + 1.0e-5f);\n if (tid < C) {\n int b = t / L;\n int l = t - b * L;\n int out_idx = (b * C + tid) * L + l;\n out[out_idx] = diff * inv * gamma[tid] + beta[tid];\n }\n}\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(proj));\n int B = proj.size(0);\n int L = proj.size(1);\n int C = proj.size(2);\n auto out = torch::empty({B, C, H, W}, proj.options());\n int threads = 1;\n while (threads < C) threads <<= 1;\n if (threads < 32) threads = 32;\n int blocks = B * L;\n size_t shmem = threads * sizeof(float);\n ln_out_kernel<<<blocks, threads, shmem, at::cuda::getCurrentCUDAStream()>>>(\n proj.data_ptr<float>(), x_blc.data_ptr<float>(), ln_w.data_ptr<float>(), ln_b.data_ptr<float>(), out.data_ptr<float>(), B, L, C);\n return out;\n}\n'''\n\n_ext = load_inline(name='attn_ext_v2', cpp_sources=[cpp_src], cuda_sources=[cuda_src], functions=['attn_forward'], verbose=False, extra_cflags=['-O3'], extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n def forward(self, x):\n return _ext.attn_forward(x, self.attn.in_proj_weight, self.attn.in_proj_bias,\n self.attn.out_proj.weight, self.attn.out_proj.bias,\n self.norm.weight, self.norm.bias, self.num_heads)\n"
}
result ← compile_kernel (ok)
okcompile_kernel
compile_kernel PASSED: kernel compiled without errors.
turn 48.7s turn · 8.7s LLM · 0.0s tools
call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W);\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n auto qkv = at::linear(x_blc, in_w, in_b);\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2,0,3,1,4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0,2,1,3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n return fused_ln_out(proj, x_blc, ln_w, ln_b, H, W);\n}\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n\n__global__ void ln_out_kernel(const float* __restrict__ proj, const float* __restrict__ x,\n const float* __restrict__ gamma, const float* __restrict__ beta,\n float* __restrict__ out, int B, int L, int C) {\n int t = blockIdx.x;\n int tid = threadIdx.x;\n extern __shared__ float smem[];\n float v = 0.f;\n if (tid < C) {\n int idx = t * C + tid;\n v = proj[idx] + x[idx];\n }\n smem[tid] = (tid < C) ? v : 0.f;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float mean = smem[0] / (float)C;\n float diff = (tid < C) ? (v - mean) : 0.f;\n smem[tid] = diff * diff;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float inv = rsqrtf(smem[0] / (float)C + 1.0e-5f);\n if (tid < C) {\n int b = t / L;\n int l = t - b * L;\n int out_idx = (b * C + tid) * L + l;\n out[out_idx] = diff * inv * gamma[tid] + beta[tid];\n }\n}\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(proj));\n int B = proj.size(0);\n int L = proj.size(1);\n int C = proj.size(2);\n auto out = torch::empty({B, C, H, W}, proj.options());\n int threads = 1;\n while (threads < C) threads <<= 1;\n if (threads < 32) threads = 32;\n int blocks = B * L;\n size_t shmem = threads * sizeof(float);\n ln_out_kernel<<<blocks, threads, shmem, at::cuda::getCurrentCUDAStream()>>>(\n proj.data_ptr<float>(), x_blc.data_ptr<float>(), ln_w.data_ptr<float>(), ln_b.data_ptr<float>(), out.data_ptr<float>(), B, L, C);\n return out;\n}\n'''\n\n_ext = load_inline(name='attn_ext_v2c', cpp_sources=[cpp_src], cuda_sources=[cuda_src], functions=['attn_forward'], verbose=False, extra_cflags=['-O3'], extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n def forward(self, x):\n return _ext.attn_forward(x, self.attn.in_proj_weight, self.attn.in_proj_bias,\n self.attn.out_proj.weight, self.attn.out_proj.bias,\n self.norm.weight, self.norm.bias, self.num_heads)\n"
}
result ← run_correctness (fail)
failrun_correctness
run_correctness FAILED: (0 / 5) trials did not all match.
correctness_issue: Output mismatch
max_difference: ['1.616889', '1.526676', '1.660918', '1.749289', '1.516175']
avg_difference: ['0.000024', '0.000023', '0.000084', '0.000061', '0.000071']
turn 524.5s turn · 24.5s LLM · 0.0s tools
call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W);\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n auto qkv = at::linear(x_blc, in_w, in_b);\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2,0,3,num_heads?1:1,4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0,2,1,3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n return fused_ln_out(proj, x_blc, ln_w, ln_b, H, W);\n}\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n\n__global__ void ln_out_kernel(const float* __restrict__ proj, const float* __restrict__ x,\n const float* __restrict__ gamma, const float* __restrict__ beta,\n float* __restrict__ out, int B, int L, int C) {\n int t = blockIdx.x;\n int tid = threadIdx.x;\n extern __shared__ float smem[];\n float v = 0.f;\n if (tid < C) {\n int idx = t * C + tid;\n v = proj[idx] + x[idx];\n }\n smem[tid] = (tid < C) ? v : 0.f;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float mean = smem[0] / (float)C;\n __syncthreads();\n float diff = (tid < C) ? (v - mean) : 0.f;\n smem[tid] = diff * diff;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float inv = rsqrtf(smem[0] / (float)C + 1.0e-5f);\n if (tid < C) {\n int b = t / L;\n int l = t - b * L;\n int out_idx = (b * C + tid) * L + l;\n out[out_idx] = diff * inv * gamma[tid] + beta[tid];\n }\n}\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(proj));\n int B = proj.size(0);\n int L = proj.size(1);\n int C = proj.size(2);\n auto out = torch::empty({B, C, H, W}, proj.options());\n int threads = 1;\n while (threads < C) threads <<= 1;\n if (threads < 32) threads = 32;\n ln_out_kernel<<<B * L, threads, threads * sizeof(float), at::cuda::getCurrentCUDAStream()>>>(\n proj.data_ptr<float>(), x_blc.data_ptr<float>(), ln_w.data_ptr<float>(), ln_b.data_ptr<float>(), out.data_ptr<float>(), B, L, C);\n return out;\n}\n'''\n\n_ext = load_inline(name='attn_ext_v2d', cpp_sources=[cpp_src], cuda_sources=[cuda_src], functions=['attn_forward'], verbose=False, extra_cflags=['-O3'], extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n def forward(self, x):\n return _ext.attn_forward(x, self.attn.in_proj_weight, self.attn.in_proj_bias,\n self.attn.out_proj.weight, self.attn.out_proj.bias,\n self.norm.weight, self.norm.bias, self.num_heads)\n"
}
result ← run_correctness (ok)
okrun_correctness
run_correctness PASSED: (5 / 5) trials all matched the reference.
Numerical precision: max_abs_err=7.15e-06 mean_abs_err=9.76e-07 max_rel_err=8.00e+00
turn 631.2s turn · 31.2s LLM · 0.0s tools
call → static_check
callstatic_check
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W);\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n auto qkv = at::linear(x_blc, in_w, in_b);\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2,0,3,1,4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0,2,1,3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n return fused_ln_out(proj, x_blc, ln_w, ln_b, H, W);\n}\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n\n__global__ void ln_out_kernel(const float* __restrict__ proj, const float* __restrict__ x,\n const float* __restrict__ gamma, const float* __restrict__ beta,\n float* __restrict__ out, int B, int L, int C) {\n int t = blockIdx.x;\n int tid = threadIdx.x;\n extern __shared__ float smem[];\n float v = 0.f;\n if (tid < C) {\n int idx = t * C + tid;\n v = proj[idx] + x[idx];\n }\n smem[tid] = (tid < C) ? v : 0.f;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float mean = smem[0] / (float)C;\n __syncthreads();\n float diff = (tid < C) ? (v - mean) : 0.f;\n smem[tid] = diff * diff;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float inv = rsqrtf(smem[0] / (float)C + 1.0e-5f);\n if (tid < C) {\n int b = t / L;\n int l = t - b * L;\n int out_idx = (b * C + tid) * L + l;\n out[out_idx] = diff * inv * gamma[tid] + beta[tid];\n }\n}\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(proj));\n int B = proj.size(0);\n int L = proj.size(1);\n int C = proj.size(2);\n auto out = torch::empty({B, C, H, W}, proj.options());\n int threads = 1;\n while (threads < C) threads <<= 1;\n if (threads < 32) threads = 32;\n ln_out_kernel<<<B * L, threads, threads * sizeof(float), at::cuda::getCurrentCUDAStream()>>>(\n proj.data_ptr<float>(), x_blc.data_ptr<float>(), ln_w.data_ptr<float>(), ln_b.data_ptr<float>(), out.data_ptr<float>(), B, L, C);\n return out;\n}\n'''\n\n_ext = load_inline(name='attn_ext_final_check', cpp_sources=[cpp_src], cuda_sources=[cuda_src], functions=['attn_forward'], verbose=False, extra_cflags=['-O3'], extra_cuda_cflags=['-O3'])\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n def forward(self, x):\n return _ext.attn_forward(x, self.attn.in_proj_weight, self.attn.in_proj_bias,\n self.attn.out_proj.weight, self.attn.out_proj.bias,\n self.norm.weight, self.norm.bias, self.num_heads)\n"
}
result ← static_check (ok)
okstatic_check
static_check PASSED: no violations or warnings detected.
turn 713.7s turn · 13.7s 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\ncpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W);\n\ntorch::Tensor attn_forward(torch::Tensor x,\n torch::Tensor in_w, torch::Tensor in_b,\n torch::Tensor out_w, torch::Tensor out_b,\n torch::Tensor ln_w, torch::Tensor ln_b,\n int64_t num_heads) {\n auto B = x.size(0);\n auto C = x.size(1);\n auto H = x.size(2);\n auto W = x.size(3);\n auto L = H * W;\n auto D = C / num_heads;\n\n auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();\n\n auto qkv = at::linear(x_blc, in_w, in_b);\n qkv = qkv.view({B, L, 3, num_heads, D}).permute({2, 0, 3, 1, 4});\n auto q = qkv.select(0, 0);\n auto k = qkv.select(0, 1);\n auto v = qkv.select(0, 2);\n\n auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);\n auto attn_blc = attn.permute({0, 2, 1, 3}).contiguous().view({B, L, C});\n auto proj = at::linear(attn_blc, out_w, out_b);\n\n return fused_ln_out(proj, x_blc, ln_w, ln_b, H, W);\n}\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n\n__global__ void ln_out_kernel(const float* __restrict__ proj,\n const float* __restrict__ x,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n float* __restrict__ out,\n int B, int L, int C) {\n int t = blockIdx.x;\n int tid = threadIdx.x;\n extern __shared__ float smem[];\n\n float v = 0.0f;\n if (tid < C) {\n int idx = t * C + tid;\n v = proj[idx] + x[idx];\n }\n\n smem[tid] = (tid < C) ? v : 0.0f;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float mean = smem[0] / (float)C;\n __syncthreads();\n\n float diff = (tid < C) ? (v - mean) : 0.0f;\n smem[tid] = diff * diff;\n __syncthreads();\n for (int s = blockDim.x >> 1; s > 0; s >>= 1) {\n if (tid < s) smem[tid] += smem[tid + s];\n __syncthreads();\n }\n float inv_std = rsqrtf(smem[0] / (float)C + 1.0e-5f);\n\n if (tid < C) {\n int b = t / L;\n int l = t - b * L;\n int out_idx = (b * C + tid) * L + l;\n out[out_idx] = diff * inv_std * gamma[tid] + beta[tid];\n }\n}\n\ntorch::Tensor fused_ln_out(torch::Tensor proj,\n torch::Tensor x_blc,\n torch::Tensor ln_w,\n torch::Tensor ln_b,\n int64_t H,\n int64_t W) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(proj));\n int B = (int)proj.size(0);\n int L = (int)proj.size(1);\n int C = (int)proj.size(2);\n\n auto out = torch::empty({B, C, H, W}, proj.options());\n\n int threads = 1;\n while (threads < C) threads <<= 1;\n if (threads < 32) threads = 32;\n\n ln_out_kernel<<<B * L, threads, threads * sizeof(float), at::cuda::getCurrentCUDAStream()>>>(\n proj.data_ptr<float>(),\n x_blc.data_ptr<float>(),\n ln_w.data_ptr<float>(),\n ln_b.data_ptr<float>(),\n out.data_ptr<float>(),\n B, L, C);\n return out;\n}\n'''\n\n_ext = load_inline(\n name='attn_block_ext_final',\n cpp_sources=[cpp_src],\n cuda_sources=[cuda_src],\n functions=['attn_forward'],\n verbose=False,\n extra_cflags=['-O3'],\n extra_cuda_cflags=['-O3'],\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, embed_dim, num_heads):\n super(ModelNew, self).__init__()\n self.attn = nn.MultiheadAttention(embed_dim, num_heads)\n self.norm = nn.LayerNorm(embed_dim)\n self.num_heads = num_heads\n\n def forward(self, x):\n return _ext.attn_forward(\n x,\n self.attn.in_proj_weight,\n self.attn.in_proj_bias,\n self.attn.out_proj.weight,\n self.attn.out_proj.bias,\n self.norm.weight,\n self.norm.bias,\n self.num_heads,\n )\n"
}
result ← submit_kernel (ok)
oksubmit_kernel
submit_kernel PASSED: (5 / 5) correctness trials all passed.
Kernel runtime: 14.40 μs
Runtime stats: mean=14.40μs median=?μs std=0.06μs
Numerical precision: max_abs_err=7.15e-06 mean_abs_err=9.76e-07 max_rel_err=8.00e+00
Memory: 161.51 MB peak (ref: 16497.51 MB, ratio: 0.0098x)
Kernel launches: 50 (ref: 80, fusion ratio: 1.6)
Energy: 2036.7 mJ/run (ref: 3055.94 mJ, ratio: 1.5004x)
SOL score: 0.7178
final submitted kernel (141 lines, 4,349 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>
torch::Tensor fused_ln_out(torch::Tensor proj, torch::Tensor x_blc, torch::Tensor ln_w, torch::Tensor ln_b, int64_t H, int64_t W);
torch::Tensor attn_forward(torch::Tensor x,
torch::Tensor in_w, torch::Tensor in_b,
torch::Tensor out_w, torch::Tensor out_b,
torch::Tensor ln_w, torch::Tensor ln_b,
int64_t num_heads) {
auto B = x.size(0);
auto C = x.size(1);
auto H = x.size(2);
auto W = x.size(3);
auto L = H * W;
auto D = C / num_heads;
auto x_blc = x.view({B, C, L}).permute({0, 2, 1}).contiguous();
auto qkv = at::linear(x_blc, in_w, in_b);
qkv = qkv.view({B, L, 3, num_heads, D}).permute({2, 0, 3, 1, 4});
auto q = qkv.select(0, 0);
auto k = qkv.select(0, 1);
auto v = qkv.select(0, 2);
auto attn = at::scaled_dot_product_attention(q, k, v, c10::nullopt, 0.0, false, c10::nullopt);
auto attn_blc = attn.permute({0, 2, 1, 3}).contiguous().view({B, L, C});
auto proj = at::linear(attn_blc, out_w, out_b);
return fused_ln_out(proj, x_blc, ln_w, ln_b, H, W);
}
'''
cuda_src = r'''
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <c10/cuda/CUDAGuard.h>
__global__ void ln_out_kernel(const float* __restrict__ proj,
const float* __restrict__ x,
const float* __restrict__ gamma,
const float* __restrict__ beta,
float* __restrict__ out,
int B, int L, int C) {
int t = blockIdx.x;
int tid = threadIdx.x;
extern __shared__ float smem[];
float v = 0.0f;
if (tid < C) {
int idx = t * C + tid;
v = proj[idx] + x[idx];
}
smem[tid] = (tid < C) ? v : 0.0f;
__syncthreads();
for (int s = blockDim.x >> 1; s > 0; s >>= 1) {
if (tid < s) smem[tid] += smem[tid + s];
__syncthreads();
}
float mean = smem[0] / (float)C;
__syncthreads();
float diff = (tid < C) ? (v - mean) : 0.0f;
smem[tid] = diff * diff;
__syncthreads();
for (int s = blockDim.x >> 1; s > 0; s >>= 1) {
if (tid < s) smem[tid] += smem[tid + s];
__syncthreads();
}
float inv_std = rsqrtf(smem[0] / (float)C + 1.0e-5f);
if (tid < C) {
int b = t / L;
int l = t - b * L;
int out_idx = (b * C + tid) * L + l;
out[out_idx] = diff * inv_std * gamma[tid] + beta[tid];
}
}
torch::Tensor fused_ln_out(torch::Tensor proj,
torch::Tensor x_blc,
torch::Tensor ln_w,
torch::Tensor ln_b,
int64_t H,
int64_t W) {
const at::cuda::OptionalCUDAGuard device_guard(device_of(proj));
int B = (int)proj.size(0);
int L = (int)proj.size(1);
int C = (int)proj.size(2);
auto out = torch::empty({B, C, H, W}, proj.options());
int threads = 1;
while (threads < C) threads <<= 1;
if (threads < 32) threads = 32;
ln_out_kernel<<<B * L, threads, threads * sizeof(float), at::cuda::getCurrentCUDAStream()>>>(
proj.data_ptr<float>(),
x_blc.data_ptr<float>(),
ln_w.data_ptr<float>(),
ln_b.data_ptr<float>(),
out.data_ptr<float>(),
B, L, C);
return out;
}
'''
_ext = load_inline(
name='attn_block_ext_final',
cpp_sources=[cpp_src],
cuda_sources=[cuda_src],
functions=['attn_forward'],
verbose=False,
extra_cflags=['-O3'],
extra_cuda_cflags=['-O3'],
)
class ModelNew(nn.Module):
def __init__(self, embed_dim, num_heads):
super(ModelNew, self).__init__()
self.attn = nn.MultiheadAttention(embed_dim, num_heads)
self.norm = nn.LayerNorm(embed_dim)
self.num_heads = num_heads
def forward(self, x):
return _ext.attn_forward(
x,
self.attn.in_proj_weight,
self.attn.in_proj_bias,
self.attn.out_proj.weight,
self.attn.out_proj.bias,
self.norm.weight,
self.norm.bias,
self.num_heads,
)