grok-4.3 · popcorn · pop_l123_default_gpt
correct 10_GFVLA_FusedPairwiseNodeAggregate.py
model
grok-4.3
turns / max
6 / 12
tool calls
6
tokens (total)
31505
wall clock
1827.8s
truncated
no
backend
cuda fp32
variant
popcorn
runtime
293.00 μs
ref runtime
0.11 μs
speedup
0.00x
started
2026-05-11T10:47:21Z
timingkernelbench.timing
kernel runtime
293.00 μs
ref runtime
0.11 μs
speedup
3.86e-04x
kernel mean / median / std
293.00 / — / 2.76 μs
ref mean / median / std
0.11 / — / 0.03 μs
numerical precisioneval_kernel_against_ref
max abs error
3.81e-06
mean abs error
3.88e-07
max rel error
0.01
mean rel error
2.12e-06
gpu memoryextended_metrics.measure_memory
kernel peak
33.71 MB
ref peak
38.84 MB
kernel / ref
0.87x
kernel launches / fusiontorch.profiler
kernel launches
5
ref launches
50
fusion ratio (ref / kernel)
10.00x
total cuda time
147 μs
energyNVML (pynvml)
kernel mJ / run
35904.78
ref mJ / run
0.00
ratio (ref / kernel)
—
avg power
122.01 W
ref avg power
0.00 W
SOL (speed-of-light)nsight_hardware_counters
SOL score (0–1)
0.066
dram util %
0.6%
compute util %
6.6%
bottleneck
compute-bound
dominant pipe
FP32
arithmetic intensity
—
ridge point
20.00
roofline / occupancynsight_hardware_counters
dram bandwidth
19.37 GB/s
dram util %
0.6%
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
28.7%
bottleneck
compute-bound
dominant pipe %
6.6%
arithmetic intensity
—
ridge point
20.00
L1 hit %
—
L2 hit %
289.9%
ld sectors / req
9.10
st sectors / req
—
regs / thread
72
smem / block
4096 B
block size
640
peak bw
3350.00 GB/s
peak fp32 tflops
67.00
peak fp16 tflops
1979.00
warp stalls (top 5)nsight
long_scoreboard
1451.9%
short_scoreboard
576.9%
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn
import torch.nn.functional as F

# Default ModelNew is PyTorch-only. run_and_check: use check_kernel=False with backend=cuda
# until the candidate file contains a real CUDA kernel (see kernel_static_checker).


class Model(nn.Module):
    """
    GF-VLA style **fused pairwise → node** scene-graph readout.

    For every ordered pair (i, j), fuse ``[node_i || node_j || pair_feat_ij]`` with
    an MLP, mask invalid graph edges, then **max-pool over outgoing neighbors j**
    to produce an updated per-object signal (object-centric scene graph refresh).

    Complements ``7_GFVLA_FusedSceneGraphUpdate`` (attention) with an MLP + reduce
    fusion pattern common for relation classifiers and affordance heads.
    """

    def __init__(self, dim: int, pair_dim: int, hidden: int):
        super().__init__()
        self.dim = dim
        self.pair_dim = pair_dim
        self.fuse = nn.Sequential(
            nn.Linear(2 * dim + pair_dim, hidden),
            nn.SiLU(),
            nn.Linear(hidden, dim),
        )
        self.out_norm = nn.LayerNorm(dim)

    def forward(
        self,
        nodes: torch.Tensor,
        pair_feats: torch.Tensor,
        edge_mask: torch.Tensor,
    ) -> torch.Tensor:
        """
        Args:
            nodes: (B, N, D)
            pair_feats: (B, N, N, P)
            edge_mask: (B, N, N) float {0,1}
        Returns:
            (B, N, D) residual ``nodes + LN( max_j fuse(...) )``
        """
        B, N, D = nodes.shape
        assert pair_feats.shape == (B, N, N, self.pair_dim)

        hi = nodes.unsqueeze(2).expand(-1, -1, N, -1)
        hj = nodes.unsqueeze(1).expand(-1, N, -1, -1)
        fused = self.fuse(torch.cat([hi, hj, pair_feats], dim=-1))

        neg = torch.finfo(fused.dtype).min
        fused = fused.masked_fill(edge_mask.unsqueeze(-1) < 0.5, neg)
        pooled, _ = fused.max(dim=2)
        return nodes + self.out_norm(pooled)


class ModelNew(nn.Module):
    """KernelBench candidate entry point; default delegates to ``Model``."""

    def __init__(self, dim: int, pair_dim: int, hidden: int):
        super().__init__()
        self._impl = Model(dim, pair_dim, hidden)

    def forward(
        self,
        nodes: torch.Tensor,
        pair_feats: torch.Tensor,
        edge_mask: torch.Tensor,
    ) -> torch.Tensor:
        return self._impl(nodes, pair_feats, edge_mask)


batch_size = 4
num_objects = 24
dim = 96
pair_dim = 16
hidden = 192


def get_inputs():
    p = popcorn_pri
    nodes = torch.randn(p.jitter_int(batch_size), p.jitter_int(num_objects), dim)
    pair_feats = torch.randn(p.jitter_int(batch_size), p.jitter_int(num_objects), p.jitter_int(num_objects), pair_dim)
    edge_mask = torch.ones(p.jitter_int(batch_size), p.jitter_int(num_objects), p.jitter_int(num_objects))
    return [nodes, pair_feats, edge_mask]


def get_init_inputs():
    return [dim, pair_dim, hidden]
turn 08.7s turn · 8.7s LLM · 0.0s tools · tokens in=1,946 · out=6 · total=2,233
reasoning
The task is to replace the forward computation with a custom CUDA kernel for this GF-VLA style fused pairwise to node scene-graph readout.
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 1251.5s turn · 24.6s LLM · 227.0s tools · tokens in=2,466 · out=303 · total=3,061
reasoning
Hardware is H100. Good for CUDA optimizations.
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.h>\n#include <cuda_runtime.h>\n\n__global__ void dummy_kernel(float* out, const float* in, int n) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < n) out[idx] = in[idx];\n}\n\ntorch::Tensor dummy_forward(torch::Tensor input) {\n auto output = torch::empty_like(input);\n int n = input.numel();\n dummy_kernel<<<(n+255)/256, 256>>>(output.data_ptr<float>(), input.data_ptr<float>(), n);\n return output;\n}\n'''\n\ncpp_source = '''\ntorch::Tensor dummy_forward(torch::Tensor input);\n'''\n\nmodule = load_inline(\n name='dummy_module',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['dummy_forward'],\n verbose=True\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, dim, pair_dim, hidden):\n super().__init__()\n self._impl = None # placeholder\n self.dim = dim\n self.pair_dim = pair_dim\n self.hidden = hidden\n\n def forward(self, nodes, pair_feats, edge_mask):\n # For now, just return nodes to test compilation\n return nodes\nprint(\"Kernel compiled successfully\")\n" }
result ← compile_kernel (ok)
okcompile_kernel compile_kernel PASSED: kernel compiled without errors.
turn 2340.2s turn · 28.1s LLM · 312.2s tools · tokens in=3,078 · out=1,155 · total=4,567
reasoning
Good, compilation works. Now I need to implement the real kernel. I need to replace the forward computation of a PyTorch model with a custom CUDA kernel. The new ModelNew class should take the same inputs as the original Model, have the same forward signature, and produce the same outputs numerically.
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 = r'''\n#include <torch/extension.h>\n#include <cuda_runtime.h>\n#include <cfloat>\n\n__global__ void fused_scene_graph_kernel(\n const float* __restrict__ nodes,\n const float* __restrict__ pair_feats,\n const float* __restrict__ edge_mask,\n const float* __restrict__ w1,\n const float* __restrict__ b1,\n const float* __restrict__ w2,\n const float* __restrict__ b2,\n const float* __restrict__ norm_w,\n const float* __restrict__ norm_b,\n float* __restrict__ output,\n int B, int N, int D, int P, int H\n) {\n // Each block handles one (b, i) pair, computes max over j for that i\n int bi = blockIdx.x;\n int b = bi / N;\n int i = bi % N;\n if (b >= B) return;\n\n extern __shared__ float smem[];\n float* max_vals = smem; // D floats for max\n\n // Initialize max to -inf\n for (int d = threadIdx.x; d < D; d += blockDim.x) {\n max_vals[d] = -FLT_MAX;\n }\n __syncthreads();\n\n // For each j\n for (int j = 0; j < N; j++) {\n float mask_val = edge_mask[b * N * N + i * N + j];\n if (mask_val < 0.5f) continue;\n\n // Compute fused for this (i,j)\n // Input: [nodes[b,i], nodes[b,j], pair[b,i,j]]\n // First linear: H dim\n for (int h = threadIdx.x; h < H; h += blockDim.x) {\n float sum = b1[h];\n // nodes i: D\n const float* ni = nodes + (b * N + i) * D;\n const float* wi1 = w1 + h * (2*D + P);\n for (int d=0; d<D; d++) sum += ni[d] * wi1[d];\n // nodes j\n const float* nj = nodes + (b * N + j) * D;\n for (int d=0; d<D; d++) sum += nj[d] * wi1[D + d];\n // pair\n const float* pf = pair_feats + ((b * N + i) * N + j) * P;\n for (int p=0; p<P; p++) sum += pf[p] * wi1[2*D + p];\n // SiLU\n float silu = sum / (1.0f + expf(-sum));\n // Now second linear later\n // For now, accumulate? Wait, need to do second linear too\n }\n // Actually need full\n }\n // This is placeholder, too complex for quick write, will fix later\n // For testing, just copy nodes\n for (int d = threadIdx.x; d < D; d += blockDim.x) {\n output[(b*N + i)*D + d] = nodes[(b*N + i)*D + d];\n }\n}\n\ntorch::Tensor fused_forward(\n torch::Tensor nodes,\n torch::Tensor pair_feats,\n torch::Tensor edge_mask,\n torch::Tensor w1, torch::Tensor b1,\n torch::Tensor w2, torch::Tensor b2,\n torch::Tensor norm_w, torch::Tensor norm_b\n) {\n int B = nodes.size(0);\n int N = nodes.size(1);\n int D = nodes.size(2);\n int P = pair_feats.size(3);\n int H = b1.size(0);\n\n auto output = torch::empty_like(nodes);\n int threads = 256;\n fused_scene_graph_kernel<<<B*N, threads, D*sizeof(float)>>>(\n nodes.data_ptr<float>(),\n pair_feats.data_ptr<float>(),\n edge_mask.data_ptr<float>(),\n w1.data_ptr<float>(),\n b1.data_ptr<float>(),\n w2.data_ptr<float>(),\n b2.data_ptr<float>(),\n norm_w.data_ptr<float>(),\n norm_b.data_ptr<float>(),\n output.data_ptr<float>(),\n B, N, D, P, H\n );\n return output;\n}\n'''\n\ncpp_source = '''\ntorch::Tensor fused_forward(torch::Tensor nodes, torch::Tensor pair_feats, torch::Tensor edge_mask,\n torch::Tensor w1, torch::Tensor b1, torch::Tensor w2, torch::Tensor b2,\n torch::Tensor norm_w, torch::Tensor norm_b);\n'''\n\nmodule = load_inline(\n name='fused_scene_graph',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['fused_forward'],\n verbose=True\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, dim: int, pair_dim: int, hidden: int):\n super().__init__()\n self.dim = dim\n self.pair_dim = pair_dim\n self.hidden = hidden\n # Dummy weights for now\n self.register_buffer('dummy', torch.zeros(1))\n\n def forward(self, nodes, pair_feats, edge_mask):\n return nodes # placeholder\nprint(\"Setup done\")\n" }
result ← run_correctness (fail)
failrun_correctness run_correctness FAILED: (0 / 5) trials did not all match. correctness_issue: Output mismatch max_difference: ['3.851100', '4.214921', '3.714095', '4.332871', '3.306464'] avg_difference: ['0.798659', '0.796926', '0.802810', '0.800217', '0.800829']
turn 3447.2s turn · 5.9s LLM · 441.3s tools · tokens in=4,664 · out=50 · total=5,058
reasoning
Of course, it's placeholder returning nodes. I need to implement the full logic, but it's too complicated for one go. I need a better way. I realize the placeholder return isn't sufficient; I need to replace the forward computation with a custom CUDA kernel in the ModelNew class. The class must take the same inputs as Model, have theidentical forward signature, and produce matching outputs numerically.
call → compile_kernel
callcompile_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n# Full implementation will be in next attempts. This is to check structure.\nprint(\"Basic structure test\")\n" }
result ← compile_kernel (fail)
failcompile_kernel compile_kernel FAILED: ModelNew class not found or syntax error prevented execution. Basic structure test
turn 4 · 1 tool call(s) · 317.8s turn · 30.3s LLM · tokens in=5,084 · out=2,012 · total=7,336 · 8,315 chars (click to expand)
turn 4317.8s turn · 30.3s LLM · 287.5s tools · tokens in=5,084 · out=2,012 · total=7,336
reasoning
Oops, need full ModelNew in the code for the tool? No, the tool runs the code, but for compile_kernel it expects the module with ModelNew? Wait, looking back.
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 <cfloat>\n#include <cmath>\n\n__device__ float silu(float x) {\n return x / (1.0f + expf(-x));\n}\n\n__global__ void compute_fused_max_kernel(\n const float* __restrict__ nodes,\n const float* __restrict__ pair_feats,\n const float* __restrict__ edge_mask,\n const float* __restrict__ w1, const float* __restrict__ b1,\n const float* __restrict__ w2, const float* __restrict__ b2,\n float* __restrict__ pooled, // (B, N, D) initialized to -inf\n int B, int N, int D, int P, int H\n) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total_pairs = B * N * N;\n if (idx >= total_pairs) return;\n int b = idx / (N * N);\n int rem = idx % (N * N);\n int i = rem / N;\n int j = rem % N;\n\n float mask = edge_mask[b * N * N + i * N + j];\n if (mask < 0.5f) return;\n\n // Compute the output vector for this pair\n for (int d_out = 0; d_out < D; d_out++) {\n // First layer to hidden, but to avoid many loops, compute second directly? But for correctness, loop H\n float val = b2[d_out];\n for (int h = 0; h < H; h++) {\n float sum = b1[h];\n // cat input: nodes_i + nodes_j + pair\n int base_w1 = h * (2*D + P);\n // nodes_i\n for (int d=0; d<D; d++) {\n sum += nodes[(b*N + i)*D + d] * w1[base_w1 + d];\n }\n // nodes_j\n for (int d=0; d<D; d++) {\n sum += nodes[(b*N + j)*D + d] * w1[base_w1 + D + d];\n }\n // pair\n for (int p=0; p<P; p++) {\n sum += pair_feats[((b*N + i)*N + j)*P + p] * w1[base_w1 + 2*D + p];\n }\n float act = silu(sum);\n val += act * w2[d_out * H + h];\n }\n // Now atomicMax to pooled\n float* addr = &pooled[(b*N + i)*D + d_out];\n atomicMax((int*)addr, __float_as_int(val)); // but only if val > current, atomicMax for float needs care\n // Note: atomicMax on float cast not correct for negative, use loop or CAS\n }\n}\n\n// Better use CAS for atomic max float\n__device__ void atomicMaxFloat(float* addr, float val) {\n int old = __float_as_int(*addr);\n int assumed;\n do {\n assumed = old;\n float old_val = __int_as_float(assumed);\n if (old_val >= val) break;\n old = atomicCAS((int*)addr, assumed, __float_as_int(val));\n } while (old != assumed);\n}\n\n__global__ void compute_fused_max_kernel_v2(\n const float* __restrict__ nodes,\n const float* __restrict__ pair_feats,\n const float* __restrict__ edge_mask,\n const float* __restrict__ w1, const float* __restrict__ b1,\n const float* __restrict__ w2, const float* __restrict__ b2,\n float* __restrict__ pooled,\n int B, int N, int D, int P, int H\n) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total_pairs = B * N * N;\n if (idx >= total_pairs) return;\n int b = idx / (N * N);\n int rem = idx % (N * N);\n int i = rem / N;\n int j = rem % N;\n\n float mask = edge_mask[b * N * N + i * N + j];\n if (mask < 0.5f) return;\n\n for (int d_out = 0; d_out < D; d_out++) {\n float val = b2[d_out];\n for (int h = 0; h < H; h++) {\n float sum = b1[h];\n int base_w1 = h * (2 * D + P);\n for (int d = 0; d < D; d++) {\n sum += nodes[(b * N + i) * D + d] * w1[base_w1 + d];\n }\n for (int d = 0; d < D; d++) {\n sum += nodes[(b * N + j) * D + d] * w1[base_w1 + D + d];\n }\n for (int p = 0; p < P; p++) {\n sum += pair_feats[((b * N + i) * N + j) * P + p] * w1[base_w1 + 2 * D + p];\n }\n float act = silu(sum);\n val += act * w2[d_out * H + h];\n }\n atomicMaxFloat(&pooled[(b * N + i) * D + d_out], val);\n }\n}\n\n__global__ void layer_norm_add_kernel(\n const float* __restrict__ nodes,\n const float* __restrict__ pooled,\n const float* __restrict__ norm_w,\n const float* __restrict__ norm_b,\n float* __restrict__ output,\n int B, int N, int D\n) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n int total = B * N * D;\n if (idx >= total) return;\n int b = idx / (N * D);\n int rem = idx % (N * D);\n int i = rem / D;\n int d = rem % D;\n\n // Simple per element, but LN needs mean var, so this won't work alone. Need block for LN\n // Placeholder\n output[idx] = nodes[idx] + pooled[idx];\n}\n\ntorch::Tensor fused_forward(\n torch::Tensor nodes,\n torch::Tensor pair_feats,\n torch::Tensor edge_mask,\n torch::Tensor w1, torch::Tensor b1,\n torch::Tensor w2, torch::Tensor b2,\n torch::Tensor norm_w, torch::Tensor norm_b\n) {\n int B = nodes.size(0);\n int N = nodes.size(1);\n int D = nodes.size(2);\n int P = pair_feats.size(3);\n int H = b1.size(0);\n\n auto pooled = torch::full({B, N, D}, -FLT_MAX, nodes.options());\n auto output = torch::empty_like(nodes);\n\n int total_pairs = B * N * N;\n int threads = 256;\n compute_fused_max_kernel_v2<<<(total_pairs + threads - 1) / threads, threads>>>(\n nodes.data_ptr<float>(), pair_feats.data_ptr<float>(), edge_mask.data_ptr<float>(),\n w1.data_ptr<float>(), b1.data_ptr<float>(),\n w2.data_ptr<float>(), b2.data_ptr<float>(),\n pooled.data_ptr<float>(),\n B, N, D, P, H\n );\n\n // For LN, we need proper implementation, skip for now\n layer_norm_add_kernel<<<(B*N*D + threads-1)/threads, threads>>>(\n nodes.data_ptr<float>(), pooled.data_ptr<float>(),\n norm_w.data_ptr<float>(), norm_b.data_ptr<float>(),\n output.data_ptr<float>(),\n B, N, D\n );\n return output;\n}\n'''\n\ncpp_source = '''\ntorch::Tensor fused_forward(torch::Tensor nodes, torch::Tensor pair_feats, torch::Tensor edge_mask,\n torch::Tensor w1, torch::Tensor b1, torch::Tensor w2, torch::Tensor b2,\n torch::Tensor norm_w, torch::Tensor norm_b);\n'''\n\nmodule = load_inline(\n name='fused_scene_graph',\n cpp_sources=[cpp_source],\n cuda_sources=[cuda_source],\n functions=['fused_forward'],\n verbose=True\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, dim: int, pair_dim: int, hidden: int):\n super().__init__()\n self.dim = dim\n self.pair_dim = pair_dim\n self.hidden = hidden\n self.fuse = nn.Sequential(\n nn.Linear(2 * dim + pair_dim, hidden),\n nn.SiLU(),\n nn.Linear(hidden, dim),\n )\n self.out_norm = nn.LayerNorm(dim)\n # Copy weights from somewhere? But to match, we init same\n # For test, use dummy\n\n def forward(self, nodes, pair_feats, edge_mask):\n # To make correct, delegate temporarily but no, must use kernel\n # Since weights not passed, this will fail anyway\n return nodes\nprint(\"Compiled\")\n" }
result ← compile_kernel (ok)
okcompile_kernel compile_kernel PASSED: kernel compiled without errors.
turn 5 · FINAL · 1 tool call(s) · 462.3s turn · 21.8s LLM · tokens in=7,353 · out=1,667 · total=9,250 · 7,144 chars (click to expand)
turn 5462.3s turn · 21.8s LLM · 440.5s tools · tokens in=7,353 · out=1,667 · total=9,250 · FINAL
reasoning
Good, compiled. But to make it work, I need to integrate the weights into the class and fix the kernel for LN and atomic.
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 <cfloat>\n#include <cmath>\n\n__device__ __forceinline__ float silu(float x) {\n return x * __frcp_rn(1.0f + __expf(-x));\n}\n\n__device__ void atomicMaxFloat(float *addr, float val) {\n unsigned int *addr_as_ui = (unsigned int *)addr;\n unsigned int old = *addr_as_ui, assumed;\n do {\n assumed = old;\n if (__int_as_float(assumed) >= val) break;\n old = atomicCAS(addr_as_ui, assumed, __float_as_int(val));\n } while (assumed != old);\n}\n\n__global__ void fused_max_kernel(\n const float *__restrict__ nodes,\n const float *__restrict__ pair_feats,\n const float *__restrict__ edge_mask,\n const float *__restrict__ w1, const float *__restrict__ b1,\n const float *__restrict__ w2, const float *__restrict__ b2,\n float *__restrict__ pooled,\n int B, int N, int D, int P, int H) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= B * N * N) return;\n int b = idx / (N * N);\n int tmp = idx % (N * N);\n int i = tmp / N;\n int j = tmp % N;\n if (edge_mask[b * N * N + i * N + j] < 0.5f) return;\n\n for (int dout = 0; dout < D; dout++) {\n float val = b2[dout];\n for (int h = 0; h < H; h++) {\n float sum = b1[h];\n int w1_base = h * (2 * D + P);\n const float *ni = nodes + (b * N + i) * D;\n const float *nj = nodes + (b * N + j) * D;\n const float *wp = w1 + w1_base;\n for (int d = 0; d < D; d++) sum += ni[d] * wp[d];\n for (int d = 0; d < D; d++) sum += nj[d] * wp[D + d];\n const float *pf = pair_feats + ((b * N + i) * N + j) * P;\n for (int p = 0; p < P; p++) sum += pf[p] * wp[2 * D + p];\n val += silu(sum) * w2[dout * H + h];\n }\n atomicMaxFloat(&pooled[(b * N + i) * D + dout], val);\n }\n}\n\n__global__ void ln_residual_kernel(\n const float *__restrict__ nodes,\n const float *__restrict__ pooled,\n const float *__restrict__ nw, const float *__restrict__ nb,\n float *__restrict__ out,\n int B, int N, int D, float eps) {\n extern __shared__ float sdata[];\n int row = blockIdx.x;\n if (row >= B * N) return;\n const float *p = pooled + row * D;\n const float *nd = nodes + row * D;\n float *o = out + row * D;\n\n // mean\n float sum = 0.0f;\n for (int d = threadIdx.x; d < D; d += blockDim.x) sum += p[d];\n sdata[threadIdx.x] = sum;\n __syncthreads();\n for (int s = blockDim.x / 2; s > 0; s >>= 1) {\n if (threadIdx.x < s) sdata[threadIdx.x] += sdata[threadIdx.x + s];\n __syncthreads();\n }\n float mean = sdata[0] / D;\n\n // var\n float varsum = 0.0f;\n for (int d = threadIdx.x; d < D; d += blockDim.x) {\n float diff = p[d] - mean;\n varsum += diff * diff;\n }\n sdata[threadIdx.x] = varsum;\n __syncthreads();\n for (int s = blockDim.x / 2; s > 0; s >>= 1) {\n if (threadIdx.x < s) sdata[threadIdx.x] += sdata[threadIdx.x + s];\n __syncthreads();\n }\n float rstd = rsqrtf(sdata[0] / D + eps);\n\n for (int d = threadIdx.x; d < D; d += blockDim.x) {\n float nval = (p[d] - mean) * rstd * nw[d] + nb[d];\n o[d] = nd[d] + nval;\n }\n}\n\ntorch::Tensor fused_forward(torch::Tensor nodes, torch::Tensor pair_feats, torch::Tensor edge_mask,\n torch::Tensor w1, torch::Tensor b1, torch::Tensor w2, torch::Tensor b2,\n torch::Tensor norm_w, torch::Tensor norm_b) {\n int B = nodes.size(0), N = nodes.size(1), D = nodes.size(2);\n int P = pair_feats.size(3), H = b1.size(0);\n auto pooled = torch::full({B, N, D}, -FLT_MAX, nodes.options());\n auto output = torch::empty_like(nodes);\n int threads = 256;\n fused_max_kernel<<<(B * N * N + threads - 1) / threads, threads>>>(\n nodes.data_ptr<float>(), pair_feats.data_ptr<float>(), edge_mask.data_ptr<float>(),\n w1.data_ptr<float>(), b1.data_ptr<float>(), w2.data_ptr<float>(), b2.data_ptr<float>(),\n pooled.data_ptr<float>(), B, N, D, P, H);\n ln_residual_kernel<<<B * N, threads, threads * sizeof(float)>>>(\n nodes.data_ptr<float>(), pooled.data_ptr<float>(),\n norm_w.data_ptr<float>(), norm_b.data_ptr<float>(),\n output.data_ptr<float>(), B, N, D, 1e-5f);\n return output;\n}\n'''\n\ncpp_source = '''\ntorch::Tensor fused_forward(torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor,\n torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor);\n'''\n\nmod = load_inline(name='fsg', cpp_sources=[cpp_source], cuda_sources=[cuda_source], functions=['fused_forward'], verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, dim: int, pair_dim: int, hidden: int):\n super().__init__()\n self.dim = dim\n self.pair_dim = pair_dim\n self.hidden = hidden\n self.fuse = nn.Sequential(\n nn.Linear(2 * dim + pair_dim, hidden),\n nn.SiLU(),\n nn.Linear(hidden, dim),\n )\n self.out_norm = nn.LayerNorm(dim)\n\n def forward(self, nodes: torch.Tensor, pair_feats: torch.Tensor, edge_mask: torch.Tensor) -> torch.Tensor:\n w1, b1 = self.fuse[0].weight, self.fuse[0].bias\n w2, b2 = self.fuse[2].weight, self.fuse[2].bias\n nw, nb = self.out_norm.weight, self.out_norm.bias\n return mod.fused_forward(nodes, pair_feats, edge_mask, w1, b1, w2, b2, nw, nb)\n" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 293.00 μs Runtime stats: mean=293.00μs median=?μs std=2.76μs Numerical precision: max_abs_err=3.81e-06 mean_abs_err=3.88e-07 max_rel_err=9.66e-03 Memory: 33.71 MB peak (ref: 38.84 MB, ratio: 0.8678x) Kernel launches: 5 (ref: 50, fusion ratio: 10.0) Energy: 35904.78 mJ/run (ref: 0.0 mJ, ratio: -1x) SOL score: 0.0662
final submitted kernel (148 lines, 5,531 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 <cfloat>
#include <cmath>

__device__ __forceinline__ float silu(float x) {
    return x * __frcp_rn(1.0f + __expf(-x));
}

__device__ void atomicMaxFloat(float *addr, float val) {
    unsigned int *addr_as_ui = (unsigned int *)addr;
    unsigned int old = *addr_as_ui, assumed;
    do {
        assumed = old;
        if (__int_as_float(assumed) >= val) break;
        old = atomicCAS(addr_as_ui, assumed, __float_as_int(val));
    } while (assumed != old);
}

__global__ void fused_max_kernel(
    const float *__restrict__ nodes,
    const float *__restrict__ pair_feats,
    const float *__restrict__ edge_mask,
    const float *__restrict__ w1, const float *__restrict__ b1,
    const float *__restrict__ w2, const float *__restrict__ b2,
    float *__restrict__ pooled,
    int B, int N, int D, int P, int H) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx >= B * N * N) return;
    int b = idx / (N * N);
    int tmp = idx % (N * N);
    int i = tmp / N;
    int j = tmp % N;
    if (edge_mask[b * N * N + i * N + j] < 0.5f) return;

    for (int dout = 0; dout < D; dout++) {
        float val = b2[dout];
        for (int h = 0; h < H; h++) {
            float sum = b1[h];
            int w1_base = h * (2 * D + P);
            const float *ni = nodes + (b * N + i) * D;
            const float *nj = nodes + (b * N + j) * D;
            const float *wp = w1 + w1_base;
            for (int d = 0; d < D; d++) sum += ni[d] * wp[d];
            for (int d = 0; d < D; d++) sum += nj[d] * wp[D + d];
            const float *pf = pair_feats + ((b * N + i) * N + j) * P;
            for (int p = 0; p < P; p++) sum += pf[p] * wp[2 * D + p];
            val += silu(sum) * w2[dout * H + h];
        }
        atomicMaxFloat(&pooled[(b * N + i) * D + dout], val);
    }
}

__global__ void ln_residual_kernel(
    const float *__restrict__ nodes,
    const float *__restrict__ pooled,
    const float *__restrict__ nw, const float *__restrict__ nb,
    float *__restrict__ out,
    int B, int N, int D, float eps) {
    extern __shared__ float sdata[];
    int row = blockIdx.x;
    if (row >= B * N) return;
    const float *p = pooled + row * D;
    const float *nd = nodes + row * D;
    float *o = out + row * D;

    // mean
    float sum = 0.0f;
    for (int d = threadIdx.x; d < D; d += blockDim.x) sum += p[d];
    sdata[threadIdx.x] = sum;
    __syncthreads();
    for (int s = blockDim.x / 2; s > 0; s >>= 1) {
        if (threadIdx.x < s) sdata[threadIdx.x] += sdata[threadIdx.x + s];
        __syncthreads();
    }
    float mean = sdata[0] / D;

    // var
    float varsum = 0.0f;
    for (int d = threadIdx.x; d < D; d += blockDim.x) {
        float diff = p[d] - mean;
        varsum += diff * diff;
    }
    sdata[threadIdx.x] = varsum;
    __syncthreads();
    for (int s = blockDim.x / 2; s > 0; s >>= 1) {
        if (threadIdx.x < s) sdata[threadIdx.x] += sdata[threadIdx.x + s];
        __syncthreads();
    }
    float rstd = rsqrtf(sdata[0] / D + eps);

    for (int d = threadIdx.x; d < D; d += blockDim.x) {
        float nval = (p[d] - mean) * rstd * nw[d] + nb[d];
        o[d] = nd[d] + nval;
    }
}

torch::Tensor fused_forward(torch::Tensor nodes, torch::Tensor pair_feats, torch::Tensor edge_mask,
                            torch::Tensor w1, torch::Tensor b1, torch::Tensor w2, torch::Tensor b2,
                            torch::Tensor norm_w, torch::Tensor norm_b) {
    int B = nodes.size(0), N = nodes.size(1), D = nodes.size(2);
    int P = pair_feats.size(3), H = b1.size(0);
    auto pooled = torch::full({B, N, D}, -FLT_MAX, nodes.options());
    auto output = torch::empty_like(nodes);
    int threads = 256;
    fused_max_kernel<<<(B * N * N + threads - 1) / threads, threads>>>(
        nodes.data_ptr<float>(), pair_feats.data_ptr<float>(), edge_mask.data_ptr<float>(),
        w1.data_ptr<float>(), b1.data_ptr<float>(), w2.data_ptr<float>(), b2.data_ptr<float>(),
        pooled.data_ptr<float>(), B, N, D, P, H);
    ln_residual_kernel<<<B * N, threads, threads * sizeof(float)>>>(
        nodes.data_ptr<float>(), pooled.data_ptr<float>(),
        norm_w.data_ptr<float>(), norm_b.data_ptr<float>(),
        output.data_ptr<float>(), B, N, D, 1e-5f);
    return output;
}
'''

cpp_source = '''
torch::Tensor fused_forward(torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor,
                            torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor);
'''

mod = load_inline(name='fsg', cpp_sources=[cpp_source], cuda_sources=[cuda_source], functions=['fused_forward'], verbose=False)

class ModelNew(nn.Module):
    def __init__(self, dim: int, pair_dim: int, hidden: int):
        super().__init__()
        self.dim = dim
        self.pair_dim = pair_dim
        self.hidden = hidden
        self.fuse = nn.Sequential(
            nn.Linear(2 * dim + pair_dim, hidden),
            nn.SiLU(),
            nn.Linear(hidden, dim),
        )
        self.out_norm = nn.LayerNorm(dim)

    def forward(self, nodes: torch.Tensor, pair_feats: torch.Tensor, edge_mask: torch.Tensor) -> torch.Tensor:
        w1, b1 = self.fuse[0].weight, self.fuse[0].bias
        w2, b2 = self.fuse[2].weight, self.fuse[2].bias
        nw, nb = self.out_norm.weight, self.out_norm.bias
        return mod.fused_forward(nodes, pair_feats, edge_mask, w1, b1, w2, b2, nw, nb)