kernelbench.com

KernelBench cuda · RTX PRO 6000

MegaQwen Decode Claude Fable 5

5.78%geomean peak fraction across shapes

manually audited: clean

Genuine raw-CUDA (load_inline) decode implementation for the 4-layer Qwen3-0.6B block: six __global__ kernels per layer (RMSNorm+QKV GEMV with fused input-mix on layer 0; attention with in-block Q/K RMSNorm + RoPE + fresh-KV write + split-K online-softmax flash decode; split combine; O-proj GEMV + residual; RMSNorm + gate/up GEMV + SwiGLU; down GEMV + residual), driven by a device-side position counter so a CUDA graph of 64 unrolled steps is captured once and replayed for both prefill and decode with near-zero launch overhead. KV loads use __ldcs evict-first hints to keep the ~123MB packed weight buffer resident in the 128MB L2. All math fp32 internally with bf16 rounding exactly where the reference rounds, RNG protocol (seed / seed+1 / seed+2 CPU generator streams) reproduced faithfully. No Triton, no DSLs, no forbidden ops, no output caching.

harnessor-fableagent session1h 48mtotal wall2h 3mcheck34sbenchmark14moutput tokensgpu-lock wait0sgpu-lock held15mregimethroughput

Per-shape vs governing ceilingeach shape graded against whichever binds — bf16 compute or HBM bandwidth

No per-shape benchmark data archived for this run.

Kernel source (redacted)
"""Fused CUDA decode path for Qwen3-0.6B geometry on RTX PRO 6000 (SM120).

Design
------
The whole decode step (4 layers) runs as a fixed sequence of 6 CUDA kernels
per layer, driven by a device-side position counter, so a CUDA graph of 64
unrolled steps can be captured once and replayed for both prefill and decode
with near-zero launch overhead:

  1. qkv_kernel     : RMSNorm(x) fused into a bf16 GEMV over the packed
                      [Wq;Wk;Wv] matrix (4096x1024). Layer 0 also produces the
                      step input x_t = bf16(0.5*randn + 0.5*h) from a
                      pre-uploaded random stream.
  2. attn_kernel    : per (kv-head, split) block: Q/K RMSNorm + RoPE computed
                      in-block, fresh K/V written to the cache (bf16-rounded,
                      exactly like the reference), then an online-softmax
                      flash-decode pass over its chunk of cached positions,
                      writing one (acc, m, l) partial per (q-head, split).
                      KV loads use streaming (evict-first) hints so the
                      ~123MB of weights stay resident in the 128MB L2.
  3. combine_kernel : merges the split-K partials per q head (log-sum-exp
                      style) into the attention output.
  4. oproj_kernel   : O-projection GEMV + residual add.
  5. gateup_kernel  : RMSNorm fused into gate/up GEMV + SwiGLU.
  6. down_kernel    : down GEMV + residual, bf16 round-trip between layers
                      (matches reference y.to(bf16)); last layer bumps the
                      device position counter.

All arithmetic is fp32 internally with bf16 storage at exactly the points the
reference rounds (KV cache entries, inter-layer hidden), so numerics track the
eager reference well inside the 0.08 tolerance.
"""
from __future__ import annotations

import os

import torch
import torch.nn as nn

os.environ.setdefault("TORCH_CUDA_ARCH_LIST", "12.0")


def _ensure_cuda_home() -> None:
    """Point CUDA_HOME at a CUDA-13 toolkit with a working nvcc.

    torch is a cu13 wheel; the system toolkit on this box is 12.8 (major
    mismatch, rejected by torch's extension builder). The venv carries the
    pip CUDA-13 compiler (nvidia-cuda-nvcc) under site-packages/nvidia/cu13.
    """
    cur = os.environ.get("CUDA_HOME")
    if cur and os.path.exists(os.path.join(cur, "bin", "nvcc")):
        return
    candidates = []
    try:
        import nvidia  # type: ignore

        for p in nvidia.__path__:
            candidates.append(os.path.join(p, "cu13"))
    except Exception:
        pass
    candidates += ["/usr/local/cuda-13", "/usr/local/cuda"]
    for cand in candidates:
        nvcc = os.path.join(cand, "bin", "nvcc")
        if os.path.exists(nvcc):
            os.environ["CUDA_HOME"] = cand
            os.environ["PATH"] = (
                os.path.join(cand, "bin") + os.pathsep + os.environ.get("PATH", "")
            )
            # The pip toolkit ships libcudart.so.13 without the dev symlink
            # the -lcudart link line needs; create it if we can.
            libdir = os.path.join(cand, "lib")
            so = os.path.join(libdir, "libcudart.so")
            if os.path.isdir(libdir) and not os.path.exists(so):
                for v in ("libcudart.so.13", "libcudart.so.12"):
                    tgt = os.path.join(libdir, v)
                    if os.path.exists(tgt):
                        try:
                            os.symlink(v, so)
                        except OSError:
                            pass
                        break
            return


_ensure_cuda_home()

from torch.utils.cpp_extension import load_inline  # noqa: E402

HIDDEN = 1024
INTERMEDIATE = 3072
NUM_Q = 16
NUM_KV = 8
HEAD_DIM = 128
NUM_LAYERS = 4
EPS = 1e-6

# Packed per-layer weight layout (elements, bf16):
#   [Wq(2048x1024); Wk(1024x1024); Wv(1024x1024)]  -> one 4096x1024 QKV matrix
#   Wo(1024x2048), Wgate(3072x1024), Wup(3072x1024), Wdown(1024x3072)
#   input_ln(1024), post_ln(1024), q_norm(128), k_norm(128)
_LAYER_ELEMS = (
    4096 * 1024 + 1024 * 2048 + 3 * 3072 * 1024 + 1024 + 1024 + 128 + 128
)

_CUDA_SRC = r"""
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <cuda_bf16.h>
#include <vector>

using bf16 = __nv_bfloat16;

#define HID   1024
#define IMED  3072
#define NQH   16
#define NKVH  8
#define HD    128
#define HHALF 64
#define RMS_EPS 1e-6f
#define ATT_SCALE 0.08838834764831845f

#define OFF_QKV 0L
#define OFF_O   4194304L
#define OFF_G   6291456L
#define OFF_U   9437184L
#define OFF_D   12582912L
#define OFF_ILN 15728640L
#define OFF_PLN 15729664L
#define OFF_QN  15730688L
#define OFF_KN  15730816L
#define LSTRIDE 15730944L


__device__ __forceinline__ float bf2f(bf16 v) { return __bfloat162float(v); }

__device__ __forceinline__ float warp_sum(float v) {
#pragma unroll
    for (int o = 16; o > 0; o >>= 1) v += __shfl_xor_sync(0xffffffffu, v, o);
    return v;
}

// dot of 8 packed bf16 weights against 8 fp32 activations
__device__ __forceinline__ float dot8(const uint4 pk, const float* __restrict__ h) {
    const __nv_bfloat162* w2 = reinterpret_cast<const __nv_bfloat162*>(&pk);
    float acc = 0.f;
#pragma unroll
    for (int j = 0; j < 4; j++) {
        const float2 f = __bfloat1622float2(w2[j]);
        acc = fmaf(f.x, h[2 * j], acc);
        acc = fmaf(f.y, h[2 * j + 1], acc);
    }
    return acc;
}

// ---------------------------------------------------------------------------
// Kernel 1: (optional input mix) + RMSNorm + QKV GEMV.
// grid 512 x 256; warp per output row (4096 rows).
// ---------------------------------------------------------------------------
__global__ void qkv_kernel(const bf16* __restrict__ W,
                           bf16* __restrict__ xbf,
                           const bf16* __restrict__ hbf,
                           const bf16* __restrict__ Xbuf,
                           const int* __restrict__ posctr,
                           int mix,
                           float* __restrict__ qkv) {
    __shared__ float hn[HID];
    __shared__ float red[8];
    const bf16* ln = W + OFF_ILN;
    const int tid = threadIdx.x;

    float xv[4];
    float ss = 0.f;
    if (mix) {
        const long idx = (long)(posctr[0] - posctr[1]);
        const bf16* Xr = Xbuf + idx * HID;
#pragma unroll
        for (int i = 0; i < 4; i++) {
            const int e = tid + i * 256;
            const float m = 0.5f * bf2f(Xr[e]) + 0.5f * bf2f(hbf[e]);
            const bf16 mb = __float2bfloat16(m);
            if (blockIdx.x == 0) xbf[e] = mb;
            xv[i] = bf2f(mb);
            ss += xv[i] * xv[i];
        }
    } else {
#pragma unroll
        for (int i = 0; i < 4; i++) {
            const int e = tid + i * 256;
            xv[i] = bf2f(xbf[e]);
            ss += xv[i] * xv[i];
        }
    }
    ss = warp_sum(ss);
    if ((tid & 31) == 0) red[tid >> 5] = ss;
    __syncthreads();
    const float tot = red[0] + red[1] + red[2] + red[3] +
                      red[4] + red[5] + red[6] + red[7];
    const float rs = rsqrtf(tot / (float)HID + RMS_EPS);
#pragma unroll
    for (int i = 0; i < 4; i++) {
        const int e = tid + i * 256;
        hn[e] = xv[i] * rs * bf2f(ln[e]);
    }
    __syncthreads();

    const int warp = tid >> 5;
    const int lane = tid & 31;
    const int r = blockIdx.x * 8 + warp;  // < 4096
    const bf16* wr = W + OFF_QKV + (long)r * HID;
    float acc = 0.f;
#pragma unroll
    for (int it = 0; it < 4; it++) {
        const int k = (lane + it * 32) * 8;
        const uint4 pk = *reinterpret_cast<const uint4*>(wr + k);
        acc += dot8(pk, hn + k);
    }
    acc = warp_sum(acc);
    if (lane == 0) qkv[r] = acc;
}

// ---------------------------------------------------------------------------
// Kernel 2: attention. grid (NKVH * S) x 256.
// Each block: Q norm + RoPE for its 2 q heads; owner split (S-1) also norms/
// ropes fresh K, writes K/V cache (bf16), and folds the fresh token into its
// partial. Online softmax over chunk of old positions, half-warp per position.
// Partials: part[qh][split][0..127]=acc, [128]=m, [129]=l.
// ---------------------------------------------------------------------------
__global__ void attn_kernel(const bf16* __restrict__ W,
                            const float* __restrict__ qkv,
                            bf16* __restrict__ kcache,
                            bf16* __restrict__ vcache,
                            const int* __restrict__ posctr,
                            int S, long max_seq,
                            float* __restrict__ part) {
    const int kh = blockIdx.x / S;
    const int split = blockIdx.x % S;
    const bool owner = (split == S - 1);
    const int pos = posctr[0];
    const int Lc = (pos + S - 1) / S;  // 0 when pos == 0
    const int tid = threadIdx.x;

    __shared__ float qs[2][HD];
    __shared__ float kf[HD], vf[HD];
    __shared__ float sred[8];
    __shared__ float sacc[2][16][HD];
    __shared__ float sml[2][16][2];
    __shared__ float sfresh[2];

    // --- Q rmsnorm + rope, both q heads (threads 0..127 head0, 128..255 head1)
    {
        const int hh = tid >> 7;
        const int d = tid & 127;
        const int qh = kh * 2 + hh;
        const float qraw = qkv[qh * HD + d];
        float w = warp_sum(qraw * qraw);
        if ((tid & 31) == 0) sred[tid >> 5] = w;
        __syncthreads();
        const float ss = (hh == 0) ? (sred[0] + sred[1] + sred[2] + sred[3])
                                   : (sred[4] + sred[5] + sred[6] + sred[7]);
        const float rs = rsqrtf(ss / (float)HD + RMS_EPS);
        const float qn = qraw * rs * bf2f(W[OFF_QN + d]);
        __syncthreads();
        qs[hh][d] = qn;
        __syncthreads();
        const int j = d & (HHALF - 1);
        const float theta =
            (float)pos * (1.0f / powf(10000.0f, (float)j / (float)HHALF));
        float sn, cs;
        sincosf(theta, &sn, &cs);
        const float x1 = qs[hh][j];
        const float x2 = qs[hh][j + HHALF];
        const float out = (d < HHALF) ? (x1 * cs - x2 * sn)
                                      : (x1 * sn + x2 * cs);
        __syncthreads();
        qs[hh][d] = out * ATT_SCALE;
        __syncthreads();
    }

    // --- fresh K/V (owner block only; uniform branch)
    if (owner) {
        const float kraw = (tid < HD) ? qkv[2048 + kh * HD + tid] : 0.f;
        float w = warp_sum(kraw * kraw);
        if ((tid & 31) == 0) sred[tid >> 5] = w;
        __syncthreads();
        const float ss = sred[0] + sred[1] + sred[2] + sred[3];
        const float rs = rsqrtf(ss / (float)HD + RMS_EPS);
        if (tid < HD) kf[tid] = kraw * rs * bf2f(W[OFF_KN + tid]);
        __syncthreads();
        float outk = 0.f;
        if (tid < HD) {
            const int j = tid & (HHALF - 1);
            const float theta =
                (float)pos * (1.0f / powf(10000.0f, (float)j / (float)HHALF));
            float sn, cs;
            sincosf(theta, &sn, &cs);
            const float x1 = kf[j];
            const float x2 = kf[j + HHALF];
            outk = (tid < HHALF) ? (x1 * cs - x2 * sn) : (x1 * sn + x2 * cs);
        }
        __syncthreads();
        if (tid < HD) {
            const bf16 kb = __float2bfloat16(outk);
            kcache[((long)kh * max_seq + pos) * HD + tid] = kb;
            kf[tid] = bf2f(kb);  // attention sees the bf16-rounded value
            const float vv = qkv[3072 + kh * HD + tid];
            const bf16 vb = __float2bfloat16(vv);
            vcache[((long)kh * max_seq + pos) * HD + tid] = vb;
            vf[tid] = bf2f(vb);
        }
        __syncthreads();
        {
            const int hh = tid >> 7;
            const int d = tid & 127;
            float p = qs[hh][d] * kf[d];
            float w2 = warp_sum(p);
            if ((tid & 31) == 0) sred[tid >> 5] = w2;
            __syncthreads();
            if (tid == 0) sfresh[0] = sred[0] + sred[1] + sred[2] + sred[3];
            if (tid == 128) sfresh[1] = sred[4] + sred[5] + sred[6] + sred[7];
        }
    }
    __syncthreads();

    // --- chunk of old positions [start, end) with online softmax
    const int start = split * Lc;
    const int end = min(start + Lc, pos);
    const int warp = tid >> 5;
    const int hw = (tid & 31) >> 4;
    const int lane16 = tid & 15;
    const int slot = warp * 2 + hw;

    float m0 = -INFINITY, m1 = -INFINITY, l0 = 0.f, l1 = 0.f;
    float a0[8], a1[8];
#pragma unroll
    for (int j = 0; j < 8; j++) { a0[j] = 0.f; a1[j] = 0.f; }

    const bf16* kbase = kcache + (long)kh * max_seq * HD;
    const bf16* vbase = vcache + (long)kh * max_seq * HD;

    for (int base = start + warp * 2; base < end; base += 16) {
        const int p = base + hw;
        const bool valid = p < end;
        const int pl = valid ? p : (end - 1);
        const uint4 kk = __ldcs(
            reinterpret_cast<const uint4*>(kbase + (long)pl * HD + lane16 * 8));
        const bf16* kvv = reinterpret_cast<const bf16*>(&kk);
        float s0 = 0.f, s1 = 0.f;
#pragma unroll
        for (int j = 0; j < 8; j++) {
            const float kx = bf2f(kvv[j]);
            s0 += qs[0][lane16 * 8 + j] * kx;
            s1 += qs[1][lane16 * 8 + j] * kx;
        }
#pragma unroll
        for (int o = 8; o > 0; o >>= 1) {
            s0 += __shfl_xor_sync(0xffffffffu, s0, o);
            s1 += __shfl_xor_sync(0xffffffffu, s1, o);
        }
        const uint4 vk = __ldcs(
            reinterpret_cast<const uint4*>(vbase + (long)pl * HD + lane16 * 8));
        const bf16* vvv = reinterpret_cast<const bf16*>(&vk);
        if (valid) {
            {
                const float mn = fmaxf(m0, s0);
                const float c = __expf(m0 - mn);
                const float pw = __expf(s0 - mn);
                l0 = l0 * c + pw;
#pragma unroll
                for (int j = 0; j < 8; j++)
                    a0[j] = a0[j] * c + pw * bf2f(vvv[j]);
                m0 = mn;
            }
            {
                const float mn = fmaxf(m1, s1);
                const float c = __expf(m1 - mn);
                const float pw = __expf(s1 - mn);
                l1 = l1 * c + pw;
#pragma unroll
                for (int j = 0; j < 8; j++)
                    a1[j] = a1[j] * c + pw * bf2f(vvv[j]);
                m1 = mn;
            }
        }
    }

    sml[0][slot][0] = m0;
    sml[0][slot][1] = l0;
    sml[1][slot][0] = m1;
    sml[1][slot][1] = l1;
#pragma unroll
    for (int j = 0; j < 8; j++) {
        sacc[0][slot][lane16 * 8 + j] = a0[j];
        sacc[1][slot][lane16 * 8 + j] = a1[j];
    }
    __syncthreads();

    // --- block-level merge of 16 half-warp partials (+ fresh token if owner)
    {
        const int hh = tid >> 7;
        const int d = tid & 127;
        float m = -INFINITY;
#pragma unroll
        for (int w2 = 0; w2 < 16; w2++) m = fmaxf(m, sml[hh][w2][0]);
        if (owner) m = fmaxf(m, sfresh[hh]);
        float l = 0.f, acc = 0.f;
        if (m > -INFINITY) {
#pragma unroll
            for (int w2 = 0; w2 < 16; w2++) {
                const float e = __expf(sml[hh][w2][0] - m);
                l += e * sml[hh][w2][1];
                acc += e * sacc[hh][w2][d];
            }
            if (owner) {
                const float e = __expf(sfresh[hh] - m);
                l += e;
                acc += e * vf[d];
            }
        }
        const long pi = ((long)(kh * 2 + hh) * S + split) * 130;
        part[pi + d] = acc;
        if (d == 0) {
            part[pi + 128] = m;
            part[pi + 129] = l;
        }
    }
}

// ---------------------------------------------------------------------------
// Kernel 3: combine split partials. grid NQH x 128.
// ---------------------------------------------------------------------------
__global__ void combine_kernel(const float* __restrict__ part, int S,
                               float* __restrict__ attn) {
    const int qh = blockIdx.x;
    const int d = threadIdx.x;
    float m = -INFINITY;
    for (int s = 0; s < S; s++)
        m = fmaxf(m, part[((long)qh * S + s) * 130 + 128]);
    float den = 0.f, num = 0.f;
    for (int s = 0; s < S; s++) {
        const long pi = ((long)qh * S + s) * 130;
        const float e = __expf(part[pi + 128] - m);
        den += e * part[pi + 129];
        num += e * part[pi + d];
    }
    attn[qh * HD + d] = num / den;
}

// ---------------------------------------------------------------------------
// Kernel 4: O projection + residual. grid 128 x 256; warp per row.
// ---------------------------------------------------------------------------
__global__ void oproj_kernel(const bf16* __restrict__ W,
                             const float* __restrict__ attn,
                             const bf16* __restrict__ xbf,
                             float* __restrict__ r2) {
    __shared__ float a[NQH * HD];
    const int tid = threadIdx.x;
#pragma unroll
    for (int i = 0; i < 8; i++) a[tid + i * 256] = attn[tid + i * 256];
    __syncthreads();
    const int warp = tid >> 5;
    const int lane = tid & 31;
    const int r = blockIdx.x * 8 + warp;
    const bf16* wr = W + OFF_O + (long)r * 2048;
    float acc = 0.f;
#pragma unroll
    for (int it = 0; it < 8; it++) {
        const int k = (lane + it * 32) * 8;
        const uint4 pk = *reinterpret_cast<const uint4*>(wr + k);
        acc += dot8(pk, a + k);
    }
    acc = warp_sum(acc);
    if (lane == 0) r2[r] = bf2f(xbf[r]) + acc;
}

// ---------------------------------------------------------------------------
// Kernel 5: RMSNorm + gate/up GEMV + SwiGLU. grid 384 x 256; warp per row j
// computes both gate[j] and up[j].
// ---------------------------------------------------------------------------
__global__ void gateup_kernel(const bf16* __restrict__ W,
                              const float* __restrict__ r2,
                              float* __restrict__ mlp) {
    __shared__ float hn[HID];
    __shared__ float red[8];
    const int tid = threadIdx.x;
    float xv[4];
    float ss = 0.f;
#pragma unroll
    for (int i = 0; i < 4; i++) {
        const int e = tid + i * 256;
        xv[i] = r2[e];
        ss += xv[i] * xv[i];
    }
    ss = warp_sum(ss);
    if ((tid & 31) == 0) red[tid >> 5] = ss;
    __syncthreads();
    const float tot = red[0] + red[1] + red[2] + red[3] +
                      red[4] + red[5] + red[6] + red[7];
    const float rs = rsqrtf(tot / (float)HID + RMS_EPS);
    const bf16* pln = W + OFF_PLN;
#pragma unroll
    for (int i = 0; i < 4; i++) {
        const int e = tid + i * 256;
        hn[e] = xv[i] * rs * bf2f(pln[e]);
    }
    __syncthreads();

    const int warp = tid >> 5;
    const int lane = tid & 31;
    const int j0 = blockIdx.x * 8 + warp;  // < 3072
    const bf16* wg = W + OFF_G + (long)j0 * HID;
    const bf16* wu = W + OFF_U + (long)j0 * HID;
    float g = 0.f, u = 0.f;
#pragma unroll
    for (int it = 0; it < 4; it++) {
        const int k = (lane + it * 32) * 8;
        const uint4 pg = *reinterpret_cast<const uint4*>(wg + k);
        const uint4 pu = *reinterpret_cast<const uint4*>(wu + k);
        g += dot8(pg, hn + k);
        u += dot8(pu, hn + k);
    }
    g = warp_sum(g);
    u = warp_sum(u);
    if (lane == 0) mlp[j0] = (g / (1.f + expf(-g))) * u;
}

// ---------------------------------------------------------------------------
// Kernel 6: down GEMV + residual, output bf16. Last layer bumps pos.
// grid 128 x 256; warp per row.
// ---------------------------------------------------------------------------
__global__ void down_kernel(const bf16* __restrict__ W,
                            const float* __restrict__ mlp,
                            const float* __restrict__ r2,
                            bf16* __restrict__ out,
                            int last, int* __restrict__ posctr) {
    __shared__ float m[IMED];
    const int tid = threadIdx.x;
#pragma unroll
    for (int i = 0; i < 12; i++) m[tid + i * 256] = mlp[tid + i * 256];
    __syncthreads();
    const int warp = tid >> 5;
    const int lane = tid & 31;
    const int r = blockIdx.x * 8 + warp;
    const bf16* wr = W + OFF_D + (long)r * IMED;
    float acc = 0.f;
#pragma unroll
    for (int it = 0; it < 12; it++) {
        const int k = (lane + it * 32) * 8;
        const uint4 pk = *reinterpret_cast<const uint4*>(wr + k);
        acc += dot8(pk, m + k);
    }
    acc = warp_sum(acc);
    if (lane == 0) out[r] = __float2bfloat16(r2[r] + acc);
    if (last && blockIdx.x == 0 && tid == 0) posctr[0] = posctr[0] + 1;
}

// ---------------------------------------------------------------------------
// Host: launch nsteps full decode steps on the current stream.
// ---------------------------------------------------------------------------
void step_batch(torch::Tensor W, torch::Tensor xbf, torch::Tensor hbf,
                torch::Tensor Xbuf, torch::Tensor posctr,
                std::vector<torch::Tensor> kc, std::vector<torch::Tensor> vc,
                torch::Tensor qkv, torch::Tensor part, torch::Tensor attn,
                torch::Tensor r2, torch::Tensor mlp,
                int64_t nsteps, int64_t S, int64_t max_seq) {
    auto stream = at::cuda::getCurrentCUDAStream();
    const bf16* Wp = reinterpret_cast<const bf16*>(W.data_ptr());
    bf16* xbfp = reinterpret_cast<bf16*>(xbf.data_ptr());
    bf16* hbfp = reinterpret_cast<bf16*>(hbf.data_ptr());
    const bf16* Xp = reinterpret_cast<const bf16*>(Xbuf.data_ptr());
    int* posp = posctr.data_ptr<int>();
    float* qkvp = qkv.data_ptr<float>();
    float* partp = part.data_ptr<float>();
    float* attnp = attn.data_ptr<float>();
    float* r2p = r2.data_ptr<float>();
    float* mlpp = mlp.data_ptr<float>();
    const int nl = (int)kc.size();
    for (int64_t step = 0; step < nsteps; ++step) {
        for (int l = 0; l < nl; ++l) {
            const bf16* Wl = Wp + (long)l * LSTRIDE;
            bf16* kcp = reinterpret_cast<bf16*>(kc[l].data_ptr());
            bf16* vcp = reinterpret_cast<bf16*>(vc[l].data_ptr());
            const int last = (l == nl - 1) ? 1 : 0;
            bf16* outp = last ? hbfp : xbfp;
            qkv_kernel<<<512, 256, 0, stream>>>(Wl, xbfp, hbfp, Xp, posp,
                                                l == 0 ? 1 : 0, qkvp);
            attn_kernel<<<NKVH * (int)S, 256, 0, stream>>>(
                Wl, qkvp, kcp, vcp, posp, (int)S, (long)max_seq, partp);
            combine_kernel<<<NQH, 128, 0, stream>>>(partp, (int)S, attnp);
            oproj_kernel<<<128, 256, 0, stream>>>(Wl, attnp, xbfp, r2p);
            gateup_kernel<<<384, 256, 0, stream>>>(Wl, r2p, mlpp);
            down_kernel<<<128, 256, 0, stream>>>(Wl, mlpp, r2p, outp, last,
                                                 posp);
        }
    }
}
"""

_CPP_SRC = """
#include <torch/extension.h>
#include <vector>
void step_batch(torch::Tensor W, torch::Tensor xbf, torch::Tensor hbf,
                torch::Tensor Xbuf, torch::Tensor posctr,
                std::vector<torch::Tensor> kc, std::vector<torch::Tensor> vc,
                torch::Tensor qkv, torch::Tensor part, torch::Tensor attn,
                torch::Tensor r2, torch::Tensor mlp,
                int64_t nsteps, int64_t S, int64_t max_seq);
"""

_mod = load_inline(
    name="megaqwen_decode_sm120",
    cpp_sources=_CPP_SRC,
    cuda_sources=_CUDA_SRC,
    functions=["step_batch"],
    extra_cuda_cflags=["-O3"],
    verbose=False,
)


class Block(nn.Module):
    def __init__(self):
        super().__init__()
        H, I, D = HIDDEN, INTERMEDIATE, HEAD_DIM
        self.input_ln = nn.Parameter(torch.ones(H, dtype=torch.bfloat16))
        self.q_proj = nn.Parameter(torch.empty(NUM_Q * D, H, dtype=torch.bfloat16))
        self.k_proj = nn.Parameter(torch.empty(NUM_KV * D, H, dtype=torch.bfloat16))
        self.v_proj = nn.Parameter(torch.empty(NUM_KV * D, H, dtype=torch.bfloat16))
        self.q_norm = nn.Parameter(torch.ones(D, dtype=torch.bfloat16))
        self.k_norm = nn.Parameter(torch.ones(D, dtype=torch.bfloat16))
        self.o_proj = nn.Parameter(torch.empty(H, NUM_Q * D, dtype=torch.bfloat16))
        self.post_ln = nn.Parameter(torch.ones(H, dtype=torch.bfloat16))
        self.gate_proj = nn.Parameter(torch.empty(I, H, dtype=torch.bfloat16))
        self.up_proj = nn.Parameter(torch.empty(I, H, dtype=torch.bfloat16))
        self.down_proj = nn.Parameter(torch.empty(H, I, dtype=torch.bfloat16))
        for name, p in self.named_parameters():
            if p.dim() >= 2:
                nn.init.normal_(p, std=0.02)


class Model(nn.Module):
    def __init__(self, num_layers: int = NUM_LAYERS, max_seq: int = 131072):
        super().__init__()
        self.num_layers = num_layers
        self.max_seq = max_seq
        self.blocks = nn.ModuleList([Block() for _ in range(num_layers)])
        self._ws = None

    # -- workspace ---------------------------------------------------------
    def _workspace(self):
        dev = next(self.parameters()).device
        assert dev.type == "cuda", "solution requires a CUDA device"
        if self._ws is not None and self._ws["dev"] == dev:
            return self._ws
        L = self.num_layers
        S = int(min(64, max(4, self.max_seq // 64)))
        ws = {
            "dev": dev,
            "S": S,
            "W": torch.empty(L * _LAYER_ELEMS, dtype=torch.bfloat16, device=dev),
            "xbf": torch.empty(HIDDEN, dtype=torch.bfloat16, device=dev),
            "hbf": torch.empty(HIDDEN, dtype=torch.bfloat16, device=dev),
            "X": torch.empty(self.max_seq, HIDDEN, dtype=torch.bfloat16, device=dev),
            "pos": torch.zeros(2, dtype=torch.int32, device=dev),
            "kc": [
                torch.zeros(NUM_KV, self.max_seq, HEAD_DIM,
                            dtype=torch.bfloat16, device=dev)
                for _ in range(L)
            ],
            "vc": [
                torch.zeros(NUM_KV, self.max_seq, HEAD_DIM,
                            dtype=torch.bfloat16, device=dev)
                for _ in range(L)
            ],
            "qkv": torch.empty(4096, dtype=torch.float32, device=dev),
            "part": torch.zeros(NUM_Q * S * 130, dtype=torch.float32, device=dev),
            "attn": torch.empty(NUM_Q * HEAD_DIM, dtype=torch.float32, device=dev),
            "r2": torch.empty(HIDDEN, dtype=torch.float32, device=dev),
            "mlp": torch.empty(INTERMEDIATE, dtype=torch.float32, device=dev),
            "graphs": {},
            "warm": False,
        }
        self._ws = ws
        return ws

    def _pack(self):
        ws = self._workspace()
        W = ws["W"].view(self.num_layers, _LAYER_ELEMS)
        with torch.no_grad():
            for i, b in enumerate(self.blocks):
                row = W[i]
                o = 0
                for t in (b.q_proj, b.k_proj, b.v_proj, b.o_proj, b.gate_proj,
                          b.up_proj, b.down_proj, b.input_ln, b.post_ln,
                          b.q_norm, b.k_norm):
                    n = t.numel()
                    row[o:o + n].copy_(t.detach().reshape(-1))
                    o += n

    def _launch(self, nsteps: int):
        ws = self._ws
        _mod.step_batch(ws["W"], ws["xbf"], ws["hbf"], ws["X"], ws["pos"],
                        ws["kc"], ws["vc"], ws["qkv"], ws["part"],
                        ws["attn"], ws["r2"], ws["mlp"], nsteps, ws["S"],
                        self.max_seq)

    def _graph(self, nsteps: int):
        ws = self._workspace()
        if nsteps in ws["graphs"]:
            return ws["graphs"][nsteps]
        if not ws["warm"]:
            # One eager warmup pass; corrupts device state, so callers must
            # (re)initialize state after graph creation, which prefill and
            # decode_steps both do.
            ws["pos"].zero_()
            self._launch(1)
            torch.cuda.synchronize()
            ws["warm"] = True
        g = torch.cuda.CUDAGraph()
        with torch.cuda.graph(g):
            self._launch(nsteps)
        ws["graphs"][nsteps] = g
        return g

    def _run_steps(self, n: int):
        ws = self._ws
        n64, rem = divmod(n, 64)
        if n64:
            g64 = ws["graphs"][64]
            for _ in range(n64):
                g64.replay()
        if rem:
            g1 = ws["graphs"][1]
            for _ in range(rem):
                g1.replay()

    def forward(self, *args, **kwargs):  # not used by the harness
        raise NotImplementedError


def _seeded_hidden(seed: int) -> torch.Tensor:
    g = torch.Generator(device="cpu")
    g.manual_seed(seed)
    return torch.randn(HIDDEN, generator=g, dtype=torch.bfloat16)


@torch.no_grad()
def prefill(model: Model, ctx_len: int, seed: int, device=None):
    """Build KV of length ctx_len (sequential steps, exact reference numerics)."""
    assert ctx_len <= model.max_seq
    ws = model._workspace()
    model._pack()
    model._graph(64)
    model._graph(1)
    # Deterministic input stream (matches per-step randn draws bit-exactly).
    g = torch.Generator(device="cpu")
    g.manual_seed(seed + 1)
    X = torch.randn((ctx_len, HIDDEN), generator=g, dtype=torch.bfloat16)
    ws["X"][:ctx_len].copy_(X)
    ws["hbf"].copy_(_seeded_hidden(seed))
    ws["pos"][0] = 0
    ws["pos"][1] = 0
    model._run_steps(ctx_len)
    torch.cuda.synchronize()
    return ws["hbf"].clone(), ws["kc"], ws["vc"]


@torch.no_grad()
def decode_steps(model: Model, hidden: torch.Tensor, k_caches, v_caches,
                 start_pos: int, n_steps: int, seed: int):
    """Run n_steps decode steps starting at start_pos (timed section)."""
    ws = model._workspace()
    if not ws["graphs"]:
        model._pack()
        model._graph(64)
        model._graph(1)
    # If the caller passed foreign caches, adopt their contents.
    if k_caches and k_caches[0].data_ptr() != ws["kc"][0].data_ptr():
        for i in range(model.num_layers):
            ws["kc"][i][:, :start_pos].copy_(k_caches[i][:, :start_pos])
            ws["vc"][i][:, :start_pos].copy_(v_caches[i][:, :start_pos])
    ws["hbf"].copy_(hidden.reshape(-1).to(torch.bfloat16))
    g = torch.Generator(device="cpu")
    g.manual_seed(seed + 2)
    X = torch.randn((n_steps, HIDDEN), generator=g, dtype=torch.bfloat16)
    ws["X"][:n_steps].copy_(X)
    ws["pos"][0] = start_pos
    ws["pos"][1] = start_pos
    model._run_steps(n_steps)
    torch.cuda.synchronize()
    return ws["hbf"].clone(), ws["kc"], ws["vc"]


def run(ctx_len: int, n_decode: int, seed: int, model: Model | None = None) -> dict:
    device = torch.device("cuda:0")
    if model is None:
        model = Model(NUM_LAYERS, max(ctx_len + n_decode, 512))
    model = model.to(device).eval()
    h, kc, vc = prefill(model, ctx_len, seed)
    h, kc, vc = decode_steps(model, h, kc, vc, ctx_len, n_decode, seed)
    return {
        "last_hidden": h.detach(),
        "ctx_len": ctx_len,
        "decode_steps": n_decode,
    }

20260719_190250_or-fable_anthropic_claude-fable-5_03_megaqwen_decode