grok-4.3 · popcorn · pop_l123_default_gpt
correct 1_DeepSeekMLALoRAExpansion.py
model
grok-4.3
turns / max
6 / 12
tool calls
6
tokens (total)
27786
wall clock
2194.1s
truncated
no
backend
cuda fp32
variant
popcorn
runtime
71.80 μs
ref runtime
0.04 μs
speedup
0.00x
started
2026-05-11T13:09:16Z
timingkernelbench.timing
kernel runtime
71.80 μs
ref runtime
0.04 μs
speedup
4.99e-04x
kernel mean / median / std
71.80 / — / 336.00 μs
ref mean / median / std
0.04 / — / 0.00 μs
numerical precisioneval_kernel_against_ref
max abs error
0.00
mean abs error
0.00
max rel error
0.00
mean rel error
0.00
gpu memoryextended_metrics.measure_memory
kernel peak
34.29 MB
ref peak
34.29 MB
kernel / ref
1.00x
kernel launches / fusiontorch.profiler
kernel launches
12
ref launches
13
fusion ratio (ref / kernel)
1.08x
total cuda time
54 μs
energyNVML (pynvml)
kernel mJ / run
6073.24
ref mJ / run
242.76
ratio (ref / kernel)
0.04x
avg power
121.04 W
ref avg power
2998.25 W
SOL (speed-of-light)nsight_hardware_counters
SOL score (0–1)
0.561
dram util %
56.1%
compute util %
36.1%
bottleneck
memory-bound
dominant pipe
FP32
arithmetic intensity
—
ridge point
20.00
roofline / occupancynsight_hardware_counters
dram bandwidth
1878.68 GB/s
dram util %
56.1%
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
81.6%
bottleneck
memory-bound
dominant pipe %
36.1%
arithmetic intensity
—
ridge point
20.00
L1 hit %
—
L2 hit %
591.2%
ld sectors / req
43.50
st sectors / req
—
regs / thread
500
smem / block
80768 B
block size
1664
peak bw
3350.00 GB/s
peak fp32 tflops
67.00
peak fp16 tflops
1979.00
warp stalls (top 5)nsight
long_scoreboard
7552.3%
short_scoreboard
923.4%
mio_throttle
49.2%
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn


class Model(nn.Module):
    """
    Low-rank expansion of compressed KV activations into multi-head K/V tensors.

    This isolates the MLA-style compressed-cache pattern: a hidden activation is
    projected into a low-rank latent space and then expanded back into separate
    key and value tensors.
    """

    def __init__(self):
        super().__init__()

    def forward(
        self,
        hidden: torch.Tensor,
        w_down: torch.Tensor,
        w_up_k: torch.Tensor,
        w_up_v: torch.Tensor,
    ) -> torch.Tensor:
        batch_size, seq_len, model_dim = hidden.shape
        rank = w_down.shape[1]
        kv_heads = 4
        head_dim = w_up_k.shape[1] // kv_heads

        latent = hidden.reshape(batch_size * seq_len, model_dim) @ w_down
        k = latent @ w_up_k
        v = latent @ w_up_v
        k = k.view(batch_size, seq_len, kv_heads, head_dim)
        v = v.view(batch_size, seq_len, kv_heads, head_dim)
        return torch.stack((k, v), dim=2)


batch_size = 4
seq_len = 96
model_dim = 256
rank = 48
kv_heads = 4
head_dim = 32


def get_inputs():
    p = popcorn_pri
    hidden = torch.randn(p.jitter_int(batch_size), p.jitter_int(seq_len), p.jitter_int(model_dim, align=8), dtype=torch.float32)
    w_down = torch.randn(p.jitter_int(model_dim, align=8), rank, dtype=torch.float32)
    w_up_k = torch.randn(rank, p.jitter_int(kv_heads) * p.jitter_int(head_dim, align=8), dtype=torch.float32)
    w_up_v = torch.randn(rank, p.jitter_int(kv_heads) * p.jitter_int(head_dim, align=8), dtype=torch.float32)
    return [hidden, w_down, w_up_k, w_up_v]


def get_init_inputs():
    return []
turn 0213.4s turn · 5.8s LLM · 207.5s tools · tokens in=1,623 · out=6 · total=1,905
reasoning
The task is to replace the forward computation with a custom CUDA kernel that's faster than the PyTorch reference while being numerically equivalent.
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 1363.5s turn · 13.5s LLM · 350.0s tools · tokens in=2,138 · out=887 · total=3,355
reasoning
It's an H100, high bandwidth, tensor cores, but since we need fp32 and custom CUDA, probably no tensor cores easily unless using wmma or something, but for fp32, standard GEMM with FP32.
call → compile_kernel
callcompile_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncuda_source = \"\"\"\n#include <torch/extension.h>\n#include <cuda_runtime.h>\n\n__global__ void mla_kernel(\n const float* __restrict__ hidden,\n const float* __restrict__ w_down,\n const float* __restrict__ w_up_k,\n const float* __restrict__ w_up_v,\n float* __restrict__ output,\n int batch_size, int seq_len, int model_dim, int rank, int kv_heads, int head_dim\n) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = batch_size * seq_len * 2 * kv_heads * head_dim;\n if (idx >= total) return;\n\n // decode indices\n int h_dim = head_dim;\n int kvh = kv_heads;\n int hd = h_dim;\n int out_per_token = 2 * kvh * hd;\n int token_idx = idx / out_per_token;\n int rem = idx % out_per_token;\n int kv = rem / (kvh * hd);\n rem = rem % (kvh * hd);\n int h = rem / hd;\n int d = rem % hd;\n\n int b = token_idx / seq_len;\n int s = token_idx % seq_len;\n\n // compute latent\n float lat[48]; // assume rank <=48\n for(int r=0; r<rank; r++) {\n float sum = 0.0f;\n for(int m=0; m<model_dim; m++) {\n sum += hidden[token_idx * model_dim + m] * w_down[m * rank + r];\n }\n lat[r] = sum;\n }\n\n // now compute k or v\n const float* w_up = (kv == 0) ? w_up_k : w_up_v;\n float val = 0.0f;\n int out_dim = kvh * hd;\n int col = h * hd + d;\n for(int r=0; r<rank; r++) {\n val += lat[r] * w_up[r * out_dim + col];\n }\n output[idx] = val;\n}\n\ntorch::Tensor mla_forward(\n torch::Tensor hidden,\n torch::Tensor w_down,\n torch::Tensor w_up_k,\n torch::Tensor w_up_v\n) {\n int batch_size = hidden.size(0);\n int seq_len = hidden.size(1);\n int model_dim = hidden.size(2);\n int rank = w_down.size(1);\n int kv_heads = 4;\n int head_dim = w_up_k.size(1) / kv_heads;\n\n auto options = torch::TensorOptions().dtype(torch::kFloat32).device(hidden.device());\n auto output = torch::empty({batch_size, seq_len, 2, kv_heads, head_dim}, options);\n\n int total = batch_size * seq_len * 2 * kv_heads * head_dim;\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n\n mla_kernel<<<blocks, threads>>>(\n hidden.data_ptr<float>(),\n w_down.data_ptr<float>(),\n w_up_k.data_ptr<float>(),\n w_up_v.data_ptr<float>(),\n output.data_ptr<float>(),\n batch_size, seq_len, model_dim, rank, kv_heads, head_dim\n );\n\n return output;\n}\n\"\"\"\n\ncpp_source = \"\"\"\ntorch::Tensor mla_forward(torch::Tensor hidden, torch::Tensor w_down, torch::Tensor w_up_k, torch::Tensor w_up_v);\n\"\"\"\n\nmodule = load_inline(\n name='mla_cuda',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['mla_forward'],\n verbose=True,\n extra_cuda_cflags=['-O3']\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super().__init__()\n self.mla = module\n\n def forward(self, hidden, w_down, w_up_k, w_up_v):\n return self.mla.mla_forward(hidden, w_down, w_up_k, w_up_v)\n" }
result ← compile_kernel (ok)
okcompile_kernel compile_kernel PASSED: kernel compiled without errors.
turn 2322.8s turn · 6.1s LLM · 316.7s tools · tokens in=3,372 · out=888 · total=4,267
reasoning
Compiled ok. Now check correctness.
call → run_correctness
callrun_correctness { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncuda_source = \"\"\"\n#include <torch/extension.h>\n#include <cuda_runtime.h>\n\n__global__ void mla_kernel(\n const float* __restrict__ hidden,\n const float* __restrict__ w_down,\n const float* __restrict__ w_up_k,\n const float* __restrict__ w_up_v,\n float* __restrict__ output,\n int batch_size, int seq_len, int model_dim, int rank, int kv_heads, int head_dim\n) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = batch_size * seq_len * 2 * kv_heads * head_dim;\n if (idx >= total) return;\n\n // decode indices\n int h_dim = head_dim;\n int kvh = kv_heads;\n int hd = h_dim;\n int out_per_token = 2 * kvh * hd;\n int token_idx = idx / out_per_token;\n int rem = idx % out_per_token;\n int kv = rem / (kvh * hd);\n rem = rem % (kvh * hd);\n int h = rem / hd;\n int d = rem % hd;\n\n int b = token_idx / seq_len;\n int s = token_idx % seq_len;\n\n // compute latent\n float lat[48]; // assume rank <=48\n for(int r=0; r<rank; r++) {\n float sum = 0.0f;\n for(int m=0; m<model_dim; m++) {\n sum += hidden[token_idx * model_dim + m] * w_down[m * rank + r];\n }\n lat[r] = sum;\n }\n\n // now compute k or v\n const float* w_up = (kv == 0) ? w_up_k : w_up_v;\n float val = 0.0f;\n int out_dim = kvh * hd;\n int col = h * hd + d;\n for(int r=0; r<rank; r++) {\n val += lat[r] * w_up[r * out_dim + col];\n }\n output[idx] = val;\n}\n\ntorch::Tensor mla_forward(\n torch::Tensor hidden,\n torch::Tensor w_down,\n torch::Tensor w_up_k,\n torch::Tensor w_up_v\n) {\n int batch_size = hidden.size(0);\n int seq_len = hidden.size(1);\n int model_dim = hidden.size(2);\n int rank = w_down.size(1);\n int kv_heads = 4;\n int head_dim = w_up_k.size(1) / kv_heads;\n\n auto options = torch::TensorOptions().dtype(torch::kFloat32).device(hidden.device());\n auto output = torch::empty({batch_size, seq_len, 2, kv_heads, head_dim}, options);\n\n int total = batch_size * seq_len * 2 * kv_heads * head_dim;\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n\n mla_kernel<<<blocks, threads>>>(\n hidden.data_ptr<float>(),\n w_down.data_ptr<float>(),\n w_up_k.data_ptr<float>(),\n w_up_v.data_ptr<float>(),\n output.data_ptr<float>(),\n batch_size, seq_len, model_dim, rank, kv_heads, head_dim\n );\n\n return output;\n}\n\"\"\"\n\ncpp_source = \"\"\"\ntorch::Tensor mla_forward(torch::Tensor hidden, torch::Tensor w_down, torch::Tensor w_up_k, torch::Tensor w_up_v);\n\"\"\"\n\nmodule = load_inline(\n name='mla_cuda',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['mla_forward'],\n verbose=False,\n extra_cuda_cflags=['-O3']\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super().__init__()\n self.mla = module\n\n def forward(self, hidden, w_down, w_up_k, w_up_v):\n return self.mla.mla_forward(hidden, w_down, w_up_k, w_up_v)\n" }
result ← run_correctness (fail)
failrun_correctness run_correctness FAILED: (3 / 5) trials did not all match. correctness_issue: Output mismatch max_difference: ['0.000214', '0.000214'] avg_difference: ['0.000030', '0.000031']
turn 3188.2s turn · 13.6s LLM · 174.6s tools · tokens in=4,328 · out=769 · total=5,275
reasoning
Almost, max diff 2e-4, tolerance is 1e-4, close but fails.
call → compile_kernel
callcompile_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncuda_source = \"\"\"\n#include <torch/extension.h>\n#include <cuda_runtime.h>\n#include <cublas_v2.h>\n\ntorch::Tensor mla_forward(\n torch::Tensor hidden,\n torch::Tensor w_down,\n torch::Tensor w_up_k,\n torch::Tensor w_up_v\n) {\n int batch_size = hidden.size(0);\n int seq_len = hidden.size(1);\n int model_dim = hidden.size(2);\n int rank = w_down.size(1);\n int kv_heads = 4;\n int head_dim = w_up_k.size(1) / kv_heads;\n int bs = batch_size * seq_len;\n int kv_dim = kv_heads * head_dim;\n\n auto options = torch::TensorOptions().dtype(torch::kFloat32).device(hidden.device());\n auto latent = torch::empty({bs, rank}, options);\n auto k = torch::empty({bs, kv_dim}, options);\n auto v = torch::empty({bs, kv_dim}, options);\n auto output = torch::empty({batch_size, seq_len, 2, kv_heads, head_dim}, options);\n\n cublasHandle_t handle;\n cublasCreate(&handle);\n float alpha = 1.0f, beta = 0.0f;\n\n // hidden @ w_down -> latent : (bs x model) @ (model x rank)\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n rank, bs, model_dim,\n &alpha,\n w_down.data_ptr<float>(), rank,\n hidden.data_ptr<float>(), model_dim,\n &beta,\n latent.data_ptr<float>(), rank);\n\n // latent @ w_up_k -> k\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n kv_dim, bs, rank,\n &alpha,\n w_up_k.data_ptr<float>(), kv_dim,\n latent.data_ptr<float>(), rank,\n &beta,\n k.data_ptr<float>(), kv_dim);\n\n // latent @ w_up_v -> v\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n kv_dim, bs, rank,\n &alpha,\n w_up_v.data_ptr<float>(), kv_dim,\n latent.data_ptr<float>(), rank,\n &beta,\n v.data_ptr<float>(), kv_dim);\n\n // reshape and stack\n auto k_view = k.view({batch_size, seq_len, kv_heads, head_dim});\n auto v_view = v.view({batch_size, seq_len, kv_heads, head_dim});\n output.select(2, 0).copy_(k_view);\n output.select(2, 1).copy_(v_view);\n\n cublasDestroy(handle);\n return output;\n}\n\"\"\"\n\ncpp_source = \"\"\"\ntorch::Tensor mla_forward(torch::Tensor hidden, torch::Tensor w_down, torch::Tensor w_up_k, torch::Tensor w_up_v);\n\"\"\"\n\nmodule = load_inline(\n name='mla_cublas',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['mla_forward'],\n verbose=True,\n extra_cuda_cflags=['-O3'],\n extra_ldflags=['-lcublas']\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super().__init__()\n self.mla = module\n\n def forward(self, hidden, w_down, w_up_k, w_up_v):\n return self.mla.mla_forward(hidden, w_down, w_up_k, w_up_v)\n" }
result ← compile_kernel (ok)
okcompile_kernel compile_kernel PASSED: kernel compiled without errors.
turn 4590.3s turn · 8.4s LLM · 581.9s tools · tokens in=5,292 · out=770 · total=6,066
reasoning
Now test correctness.
call → run_correctness
callrun_correctness { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncuda_source = \"\"\"\n#include <torch/extension.h>\n#include <cuda_runtime.h>\n#include <cublas_v2.h>\n\ntorch::Tensor mla_forward(\n torch::Tensor hidden,\n torch::Tensor w_down,\n torch::Tensor w_up_k,\n torch::Tensor w_up_v\n) {\n int batch_size = hidden.size(0);\n int seq_len = hidden.size(1);\n int model_dim = hidden.size(2);\n int rank = w_down.size(1);\n int kv_heads = 4;\n int head_dim = w_up_k.size(1) / kv_heads;\n int bs = batch_size * seq_len;\n int kv_dim = kv_heads * head_dim;\n\n auto options = torch::TensorOptions().dtype(torch::kFloat32).device(hidden.device());\n auto latent = torch::empty({bs, rank}, options);\n auto k = torch::empty({bs, kv_dim}, options);\n auto v = torch::empty({bs, kv_dim}, options);\n auto output = torch::empty({batch_size, seq_len, 2, kv_heads, head_dim}, options);\n\n cublasHandle_t handle;\n cublasCreate(&handle);\n float alpha = 1.0f, beta = 0.0f;\n\n // hidden @ w_down -> latent : (bs x model) @ (model x rank)\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n rank, bs, model_dim,\n &alpha,\n w_down.data_ptr<float>(), rank,\n hidden.data_ptr<float>(), model_dim,\n &beta,\n latent.data_ptr<float>(), rank);\n\n // latent @ w_up_k -> k\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n kv_dim, bs, rank,\n &alpha,\n w_up_k.data_ptr<float>(), kv_dim,\n latent.data_ptr<float>(), rank,\n &beta,\n k.data_ptr<float>(), kv_dim);\n\n // latent @ w_up_v -> v\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n kv_dim, bs, rank,\n &alpha,\n w_up_v.data_ptr<float>(), kv_dim,\n latent.data_ptr<float>(), rank,\n &beta,\n v.data_ptr<float>(), kv_dim);\n\n // reshape and stack\n auto k_view = k.view({batch_size, seq_len, kv_heads, head_dim});\n auto v_view = v.view({batch_size, seq_len, kv_heads, head_dim});\n output.select(2, 0).copy_(k_view);\n output.select(2, 1).copy_(v_view);\n\n cublasDestroy(handle);\n return output;\n}\n\"\"\"\n\ncpp_source = \"\"\"\ntorch::Tensor mla_forward(torch::Tensor hidden, torch::Tensor w_down, torch::Tensor w_up_k, torch::Tensor w_up_v);\n\"\"\"\n\nmodule = load_inline(\n name='mla_cublas',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['mla_forward'],\n verbose=False,\n extra_cuda_cflags=['-O3'],\n extra_ldflags=['-lcublas']\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super().__init__()\n self.mla = module\n\n def forward(self, hidden, w_down, w_up_k, w_up_v):\n return self.mla.mla_forward(hidden, w_down, w_up_k, w_up_v)\n" }
result ← run_correctness (ok)
okrun_correctness run_correctness PASSED: (5 / 5) trials all matched the reference. Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00
turn 5515.8s turn · 9.2s LLM · 506.7s tools · tokens in=6,126 · out=769 · total=6,918 · FINAL
reasoning
Perfect, matches exactly. Now, since cublas is highly optimized, it should be fast.
call → submit_kernel
callsubmit_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncuda_source = \"\"\"\n#include <torch/extension.h>\n#include <cuda_runtime.h>\n#include <cublas_v2.h>\n\ntorch::Tensor mla_forward(\n torch::Tensor hidden,\n torch::Tensor w_down,\n torch::Tensor w_up_k,\n torch::Tensor w_up_v\n) {\n int batch_size = hidden.size(0);\n int seq_len = hidden.size(1);\n int model_dim = hidden.size(2);\n int rank = w_down.size(1);\n int kv_heads = 4;\n int head_dim = w_up_k.size(1) / kv_heads;\n int bs = batch_size * seq_len;\n int kv_dim = kv_heads * head_dim;\n\n auto options = torch::TensorOptions().dtype(torch::kFloat32).device(hidden.device());\n auto latent = torch::empty({bs, rank}, options);\n auto k = torch::empty({bs, kv_dim}, options);\n auto v = torch::empty({bs, kv_dim}, options);\n auto output = torch::empty({batch_size, seq_len, 2, kv_heads, head_dim}, options);\n\n cublasHandle_t handle;\n cublasCreate(&handle);\n float alpha = 1.0f, beta = 0.0f;\n\n // hidden @ w_down -> latent : (bs x model) @ (model x rank)\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n rank, bs, model_dim,\n &alpha,\n w_down.data_ptr<float>(), rank,\n hidden.data_ptr<float>(), model_dim,\n &beta,\n latent.data_ptr<float>(), rank);\n\n // latent @ w_up_k -> k\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n kv_dim, bs, rank,\n &alpha,\n w_up_k.data_ptr<float>(), kv_dim,\n latent.data_ptr<float>(), rank,\n &beta,\n k.data_ptr<float>(), kv_dim);\n\n // latent @ w_up_v -> v\n cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,\n kv_dim, bs, rank,\n &alpha,\n w_up_v.data_ptr<float>(), kv_dim,\n latent.data_ptr<float>(), rank,\n &beta,\n v.data_ptr<float>(), kv_dim);\n\n // reshape and stack\n auto k_view = k.view({batch_size, seq_len, kv_heads, head_dim});\n auto v_view = v.view({batch_size, seq_len, kv_heads, head_dim});\n output.select(2, 0).copy_(k_view);\n output.select(2, 1).copy_(v_view);\n\n cublasDestroy(handle);\n return output;\n}\n\"\"\"\n\ncpp_source = \"\"\"\ntorch::Tensor mla_forward(torch::Tensor hidden, torch::Tensor w_down, torch::Tensor w_up_k, torch::Tensor w_up_v);\n\"\"\"\n\nmodule = load_inline(\n name='mla_cublas',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['mla_forward'],\n verbose=False,\n extra_cuda_cflags=['-O3'],\n extra_ldflags=['-lcublas']\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super().__init__()\n self.mla = module\n\n def forward(self, hidden, w_down, w_up_k, w_up_v):\n return self.mla.mla_forward(hidden, w_down, w_up_k, w_up_v)\n" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 71.80 μs Runtime stats: mean=71.80μs median=?μs std=336.00μs Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00 Memory: 34.29 MB peak (ref: 34.29 MB, ratio: 1.0x) Kernel launches: 12 (ref: 13, fusion ratio: 1.0833) Energy: 6073.24 mJ/run (ref: 242.76 mJ, ratio: 0.04x) SOL score: 0.5608
final submitted kernel (94 lines, 2,860 chars) — full source, untruncated
import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline

cuda_source = """
#include <torch/extension.h>
#include <cuda_runtime.h>
#include <cublas_v2.h>

torch::Tensor mla_forward(
    torch::Tensor hidden,
    torch::Tensor w_down,
    torch::Tensor w_up_k,
    torch::Tensor w_up_v
) {
    int batch_size = hidden.size(0);
    int seq_len = hidden.size(1);
    int model_dim = hidden.size(2);
    int rank = w_down.size(1);
    int kv_heads = 4;
    int head_dim = w_up_k.size(1) / kv_heads;
    int bs = batch_size * seq_len;
    int kv_dim = kv_heads * head_dim;

    auto options = torch::TensorOptions().dtype(torch::kFloat32).device(hidden.device());
    auto latent = torch::empty({bs, rank}, options);
    auto k = torch::empty({bs, kv_dim}, options);
    auto v = torch::empty({bs, kv_dim}, options);
    auto output = torch::empty({batch_size, seq_len, 2, kv_heads, head_dim}, options);

    cublasHandle_t handle;
    cublasCreate(&handle);
    float alpha = 1.0f, beta = 0.0f;

    // hidden @ w_down -> latent : (bs x model) @ (model x rank)
    cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
                rank, bs, model_dim,
                &alpha,
                w_down.data_ptr<float>(), rank,
                hidden.data_ptr<float>(), model_dim,
                &beta,
                latent.data_ptr<float>(), rank);

    // latent @ w_up_k -> k
    cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
                kv_dim, bs, rank,
                &alpha,
                w_up_k.data_ptr<float>(), kv_dim,
                latent.data_ptr<float>(), rank,
                &beta,
                k.data_ptr<float>(), kv_dim);

    // latent @ w_up_v -> v
    cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
                kv_dim, bs, rank,
                &alpha,
                w_up_v.data_ptr<float>(), kv_dim,
                latent.data_ptr<float>(), rank,
                &beta,
                v.data_ptr<float>(), kv_dim);

    // reshape and stack
    auto k_view = k.view({batch_size, seq_len, kv_heads, head_dim});
    auto v_view = v.view({batch_size, seq_len, kv_heads, head_dim});
    output.select(2, 0).copy_(k_view);
    output.select(2, 1).copy_(v_view);

    cublasDestroy(handle);
    return output;
}
"""

cpp_source = """
torch::Tensor mla_forward(torch::Tensor hidden, torch::Tensor w_down, torch::Tensor w_up_k, torch::Tensor w_up_v);
"""

module = load_inline(
    name='mla_cublas',
    cpp_sources=[cpp_source],
    cuda_sources=[cuda_source],
    functions=['mla_forward'],
    verbose=False,
    extra_cuda_cflags=['-O3'],
    extra_ldflags=['-lcublas']
)

class ModelNew(nn.Module):
    def __init__(self):
        super().__init__()
        self.mla = module

    def forward(self, hidden, w_down, w_up_k, w_up_v):
        return self.mla.mla_forward(hidden, w_down, w_up_k, w_up_v)