kernelbench.com

KernelBench hard · H100

TopK Bitonic Claude Fable 5

4.70%geomean peak fraction across shapes

manually audited: clean

harnessor-fableagent session3h 52mtotal wall3h 53mcheck42sbenchmark2soutput tokens508,212cost$118.88gpu-lock wait0sgpu-lock held44sregimememory

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

1×131072×640.016 ms1.7%0.03 TB/s · 2% of 2.0 TB/s HBM · also 0 TFLOPS (0% of compute)
64×8192×80.013 ms7.8%0.16 TB/s · 8% of 2.0 TB/s HBM · also 0 TFLOPS (0% of compute)
32×16384×320.014 ms7.5%0.15 TB/s · 8% of 2.0 TB/s HBM · also 0 TFLOPS (0% of compute)
16×12000×160.013 ms2.9%0.06 TB/s · 3% of 2.0 TB/s HBM · also 0 TFLOPS (0% of compute)
128×4096×10.013 ms8.1%0.16 TB/s · 8% of 2.0 TB/s HBM · also 0 TFLOPS (0% of compute)

compute-bound memory-bound · bar + right column = official fraction of the ceiling (the geomean input)

geomean(1.7% · 7.8% · 7.5% · 2.9% · 8.1%) = 4.7%

Kernel source (redacted)
"""Top-k over the last dim of a 2D fp32 tensor via a single fused CUDA kernel.

Design notes (H100 PCIe; graded inputs are only 0.5-2 MB, so launch/dispatch
latency dominates and every phase is tuned for microsecond-scale latency):
  - ONE kernel launch per forward. Cross-block combining happens inside the
    same kernel: blocks of a row write candidates to a pool slot and take a
    ticket (release/acquire atomic); the last block of the row merges.
  - Histogram radix-select over monotonically-mapped uint32 keys, straight
    from global memory (inputs are L2-resident after first touch). A 12-bit
    histogram in shared memory plus a warp-0 window scan (starting at the
    block-max key's bin) locates the threshold bin; up to two refinement
    rounds (12 + 8 more bits) bound the candidate set even under massive
    ties; survivors (~k + epsilon) are compacted and emitted by rank
    (count-of-greater), which needs no sort network at all.
  - Slices small enough to fit in registers keep their mapped keys there
    (KR template), so refine/compact never re-touch memory.
  - Values are compared as mapped uint32 keys packed with the column index
    into a uint64: total order, consistent tie-breaks, distinct ranks, and
    output values are exact input bits.
  - k == 1 uses a dedicated argmax reduction kernel.
  - Python-side per-call work is one cached extension call; outputs and
    scratch are preallocated at first use.
"""

import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline

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

using ull = unsigned long long;
#define FULLM 0xffffffffu

constexpr int NB = 4096;   // first/second-round histogram bins (12 bits)
constexpr int CAP = 256;   // candidate buffer entries

__device__ __forceinline__ unsigned mapf(float f) {
  unsigned u = __float_as_uint(f);
  return u ^ (((int)u >> 31) | 0x80000000u);
}
__device__ __forceinline__ float unmapf(unsigned key) {
  unsigned u = (key & 0x80000000u) ? (key ^ 0x80000000u) : ~key;
  return __uint_as_float(u);
}

__device__ __forceinline__ long long gtimer() {
  long long t;
  asm volatile("mov.u64 %0, %%globaltimer;" : "=l"(t));
  return t;
}

// Emit the top-k of cand[0..cnt) in descending order WITHOUT sorting: each
// candidate's output slot is the count of strictly-greater candidates (packed
// keys are distinct, so ranks are a permutation). The inner scan reads the
// same smem word across the whole block (broadcast), so it costs O(cnt).
__device__ void rank_output(ull* cand, int cnt, int k,
                            float* __restrict__ ovals, long long* __restrict__ oidx) {
  const int T = blockDim.x;
  // zero-pad to a multiple of 8 so the inner scan can prefetch in groups
  for (int t = cnt + threadIdx.x; t < ((cnt + 7) & ~7); t += T) cand[t] = 0ull;
  __syncthreads();
  for (int i = threadIdx.x; i < cnt; i += T) {
    const ull me = cand[i];
    int r = 0;
    for (int j0 = 0; j0 < cnt; j0 += 8) {
      ull cj[8];
      #pragma unroll
      for (int u = 0; u < 8; ++u) cj[u] = cand[j0 + u];
      #pragma unroll
      for (int u = 0; u < 8; ++u) r += (cj[u] > me);
    }
    if (r < k) {
      ovals[r] = unmapf((unsigned)(me >> 32));
      oidx[r] = (long long)(unsigned)me;
    }
  }
}

// The float (!packed) path always reads GLOBAL memory -> __ldg keeps the
// loads independent of shared-memory stores (no aliasing stalls); the packed
// path always reads shared memory.
__device__ __forceinline__ unsigned hs_key(const ull* stage, int i, bool packed) {
  if (packed) return (unsigned)(__ldg(stage + i) >> 32);
  return mapf(__ldg((const float*)stage + i));
}
__device__ __forceinline__ ull hs_pack(const ull* stage, int i, int colbase, bool packed) {
  if (packed) return __ldg(stage + i);
  return ((ull)mapf(__ldg((const float*)stage + i)) << 32) | (unsigned)(colbase + i);
}

// Warp-inclusive suffix sum (lane l gets sum over lanes >= l).
__device__ __forceinline__ unsigned wsufsum(unsigned v, int lane) {
  #pragma unroll
  for (int off = 1; off < 32; off <<= 1) {
    unsigned o = __shfl_down_sync(FULLM, v, off);
    if (lane + off < 32) v += o;
  }
  return v;
}

// Histogram add. (A __match_any_sync warp-aggregated variant measured SLOWER
// on H100 -- warp collectives issue at ~4 cycles each -- so plain atomics win.)
__device__ __forceinline__ void hadd(unsigned* hist, unsigned bin, bool active) {
  if (active) atomicAdd(&hist[bin], 1u);
}

__device__ __forceinline__ unsigned wmax(unsigned v) {
  #pragma unroll
  for (int off = 16; off > 0; off >>= 1) {
    unsigned o = __shfl_xor_sync(FULLM, v, off);
    v = v > o ? v : o;
  }
  return v;
}

// Select the klocal largest keys among stage[0..N): fill cand[] with all
// elements >= a refined threshold (a superset of the top-klocal, <= CAP
// entries except via the tie-claim path which writes exactly klocal), and
// return the count. Caller sorts cand and keeps the first klocal.
// aux must hold >= 64 unsigneds.
template <int KR>
__device__ int hist_select(const ull* stage, int N, int klocal, bool packed,
                           unsigned* hist, unsigned* aux, ull* cand, int colbase,
                           int capq = CAP, long long* dbg = nullptr, ull* candout = nullptr) {
  if (candout == nullptr) candout = cand;
  const int T = blockDim.x;
  const int W = T >> 5;
  const int warp = threadIdx.x >> 5, lane = threadIdx.x & 31;
  __shared__ int sh_b, sh_def, sh_tot, sh_pos, sh_eq;
  unsigned lo = 0;
  unsigned bandw = 0;
  unsigned mymax = 0;   // max key over THIS thread's elements (round-0 layout)
  unsigned wgmax = 0;   // warp-wide max (gates whole-warp rescans)
  int defcnt = 0;
  int final_cnt = -1;
  const bool v4 = !packed && ((N & 3) == 0) && (((size_t)stage & 15) == 0);
  const float4* s4v = (const float4*)stage;
  const int n4s = N >> 2;
  // Register-resident keys: when the whole slice fits in KR float4s per
  // thread, later phases (refine/compact) never touch memory again.
  unsigned kreg[KR > 0 ? KR * 4 : 4];
  const bool useR = (KR > 0) && v4 && (n4s <= KR * T);
  #pragma unroll 1
  for (int r = 0; r < 3; ++r) {
    const int sh = (r == 0) ? 20 : (r == 1 ? 8 : 0);
    const int nb = (r == 2) ? 256 : NB;
    if (r > 0) {  // round 0 zeroes the histogram before the call
      for (int i = threadIdx.x * 4; i < nb; i += T * 4)
        *(uint4*)&hist[i] = make_uint4(0u, 0u, 0u, 0u);
      __syncthreads();
    }
    if (r == 0) {
      if (useR) {
        #pragma unroll
        for (int u = 0; u < (KR > 0 ? KR : 1); ++u) {
          const int i = u * T + threadIdx.x;
          float4 w;
          if (i < n4s) w = __ldg(&s4v[i]); else w = make_float4(0.f, 0.f, 0.f, 0.f);
          kreg[4 * u + 0] = mapf(w.x);
          kreg[4 * u + 1] = mapf(w.y);
          kreg[4 * u + 2] = mapf(w.z);
          kreg[4 * u + 3] = mapf(w.w);
        }
        #pragma unroll
        for (int u = 0; u < (KR > 0 ? KR : 1); ++u) {
          const int i = u * T + threadIdx.x;
          const bool valid = i < n4s;
          hadd(hist, kreg[4 * u + 0] >> 20, valid);
          hadd(hist, kreg[4 * u + 1] >> 20, valid);
          hadd(hist, kreg[4 * u + 2] >> 20, valid);
          hadd(hist, kreg[4 * u + 3] >> 20, valid);
          if (valid) {
            unsigned m01 = kreg[4 * u] > kreg[4 * u + 1] ? kreg[4 * u] : kreg[4 * u + 1];
            unsigned m23 = kreg[4 * u + 2] > kreg[4 * u + 3] ? kreg[4 * u + 2] : kreg[4 * u + 3];
            unsigned m = m01 > m23 ? m01 : m23;
            mymax = mymax > m ? mymax : m;
          }
        }
      } else if (v4) {
        for (int base = 0; base < n4s; base += T) {
          const int i = base + threadIdx.x;
          const bool valid = i < n4s;
          float4 w;
          if (valid) w = __ldg(&s4v[i]); else w = make_float4(0.f, 0.f, 0.f, 0.f);
          unsigned k0 = mapf(w.x), k1 = mapf(w.y), k2 = mapf(w.z), k3 = mapf(w.w);
          hadd(hist, k0 >> 20, valid);
          hadd(hist, k1 >> 20, valid);
          hadd(hist, k2 >> 20, valid);
          hadd(hist, k3 >> 20, valid);
          if (valid) {
            unsigned m01 = k0 > k1 ? k0 : k1, m23 = k2 > k3 ? k2 : k3;
            unsigned m = m01 > m23 ? m01 : m23;
            mymax = mymax > m ? mymax : m;
          }
        }
      } else {
        for (int base = 0; base < N; base += 8 * T) {
          unsigned keys[8];
          bool val[8];
          #pragma unroll
          for (int u = 0; u < 8; ++u) {
            const int i = base + u * T + threadIdx.x;
            val[u] = i < N;
            keys[u] = val[u] ? hs_key(stage, i, packed) : 0u;
            if (packed) val[u] = val[u] && (keys[u] != 0u);  // skip pool pads
          }
          #pragma unroll
          for (int u = 0; u < 8; ++u) {
            hadd(hist, keys[u] >> 20, val[u]);
            if (val[u]) mymax = mymax > keys[u] ? mymax : keys[u];
          }
        }
      }
      wgmax = wmax(mymax);
      if (lane == 0) aux[32 + warp] = wgmax;  // for the block-max window scan
      if (dbg) {
        __syncthreads();
        if (threadIdx.x == 0) dbg[0] = gtimer();
      }
    } else if (wgmax >= lo) {  // only warps owning candidates re-scan
      if (useR) {
        #pragma unroll
        for (int u = 0; u < (KR > 0 ? KR : 1); ++u) {
          const int i = u * T + threadIdx.x;
          const bool valid = i < n4s;
          #pragma unroll
          for (int c = 0; c < 4; ++c) {
            const unsigned key = kreg[4 * u + c];
            bool in = valid && (key >= lo) && ((key - lo) < bandw);
            hadd(hist, (key >> sh) & (nb - 1), in);
          }
        }
      } else if (v4) {
        for (int base = 0; base < n4s; base += T) {
          const int i = base + threadIdx.x;
          const bool valid = i < n4s;
          float4 w;
          if (valid) w = __ldg(&s4v[i]); else w = make_float4(0.f, 0.f, 0.f, 0.f);
          unsigned kk[4] = {mapf(w.x), mapf(w.y), mapf(w.z), mapf(w.w)};
          #pragma unroll
          for (int c = 0; c < 4; ++c) {
            bool in = valid && (kk[c] >= lo) && ((kk[c] - lo) < bandw);
            hadd(hist, (kk[c] >> sh) & (nb - 1), in);
          }
        }
      } else {
        for (int base = 0; base < N; base += T) {
          const int i = base + threadIdx.x;
          const bool valid = i < N;
          unsigned key = valid ? hs_key(stage, i, packed) : 0u;
          bool in = valid && (key >= lo) && ((key - lo) < bandw);
          hadd(hist, (key >> sh) & (nb - 1), in);
        }
      }
    }
    __syncthreads();
    // Locate the crossing bin with warp 0 alone.
    if (warp == 0) {
      if (r == 0) {
        // Descend 128-bin windows starting at the block-max key's bin; the
        // crossing is almost always inside the first window.
        unsigned bm = (lane < W) ? aux[32 + lane] : 0;
        bm = wmax(bm);
        const int topbin = (int)(bm >> 20);
        int wlo = min(max(0, (topbin - 124) & ~3), nb - 128);
        int carried = defcnt;
        for (;;) {
          const int b0l = wlo + lane * 4;
          uint4 h4 = *(const uint4*)&hist[b0l];
          const unsigned gsum = h4.x + h4.y + h4.z + h4.w;
          const unsigned gsuf = wsufsum(gsum, lane);  // bins >= b0l within window
          const int gafter = carried + (int)(gsuf - gsum);
          if ((carried + (int)gsuf >= klocal) && (gafter < klocal)) {
            int run = gafter;
            #pragma unroll
            for (int c = 3; c >= 0; --c) {
              unsigned hv = (c == 0) ? h4.x : (c == 1 ? h4.y : (c == 2 ? h4.z : h4.w));
              int cum = run + (int)hv;
              if (cum >= klocal && run < klocal) { sh_b = b0l + c; sh_tot = cum; sh_def = run; }
              run = cum;
            }
          }
          const int wtot = __shfl_sync(FULLM, (int)gsuf, 0);
          if (carried + wtot >= klocal || wlo == 0) break;
          carried += wtot;
          wlo = max(0, wlo - 128);
        }
      } else {
        // Refinement rounds (rare): full-span hierarchical scan.
        const int span = nb >> 5;
        unsigned lsum = 0;
        {
          const uint4* h4p = (const uint4*)hist;
          const int spanq = span >> 2;
          const int qb0 = lane * spanq;
          for (int jj = 0; jj < spanq; ++jj) {
            uint4 h4 = h4p[qb0 + ((jj + lane) & (spanq - 1))];
            lsum += h4.x + h4.y + h4.z + h4.w;
          }
        }
        const unsigned lsuf = wsufsum(lsum, lane);
        const int lafter = defcnt + (int)(lsuf - lsum);
        const bool own1 = (defcnt + (int)lsuf >= klocal) && (lafter < klocal);
        const unsigned om1 = __ballot_sync(FULLM, own1);
        const int ol1 = __ffs(om1) - 1;
        const int after1 = __shfl_sync(FULLM, lafter, ol1);
        const int sb0 = ol1 * span;
        int run = after1;
        if (own1) {
          for (int j = sb0 + span - 1; j >= sb0; --j) {
            int c = run + (int)hist[j];
            if (c >= klocal && run < klocal) { sh_b = j; sh_tot = c; sh_def = run; }
            run = c;
          }
        }
      }
    }
    __syncthreads();
    lo = lo | ((unsigned)sh_b << sh);
    defcnt = sh_def;
    int tot = sh_tot;
    bandw = 1u << sh;
    if (dbg && r == 0 && threadIdx.x == 0) dbg[1] = gtimer();
    if (tot <= capq) { final_cnt = tot; break; }
    __syncthreads();
  }
  if (threadIdx.x == 0) { sh_pos = 0; sh_eq = 0; }
  __syncthreads();
  if (dbg && threadIdx.x == 0) dbg[2] = gtimer();
  if (final_cnt >= 0) {
    if (mymax >= lo) {
      if (useR) {
        #pragma unroll
        for (int u = 0; u < (KR > 0 ? KR : 1); ++u) {
          const int i = u * T + threadIdx.x;
          if (i < n4s) {
            #pragma unroll
            for (int c = 0; c < 4; ++c) {
              const unsigned key = kreg[4 * u + c];
              if (key >= lo) {
                int p = atomicAdd(&sh_pos, 1);
                candout[p] = ((ull)key << 32) | (unsigned)(colbase + 4 * i + c);
              }
            }
          }
        }
      } else if (v4) {
        // stage 8 loads per iteration so L2 latency is paid once, not per trip
        for (int base = 0; base < n4s; base += 8 * T) {
          float4 w[8];
          #pragma unroll
          for (int u = 0; u < 8; ++u) {
            const int i = base + u * T + threadIdx.x;
            if (i < n4s) w[u] = __ldg(&s4v[i]);
            else w[u] = make_float4(0.f, 0.f, 0.f, 0.f);
          }
          #pragma unroll
          for (int u = 0; u < 8; ++u) {
            const int i = base + u * T + threadIdx.x;
            if (i < n4s) {
              unsigned kk[4] = {mapf(w[u].x), mapf(w[u].y), mapf(w[u].z), mapf(w[u].w)};
              #pragma unroll
              for (int c = 0; c < 4; ++c)
                if (kk[c] >= lo) {
                  int p = atomicAdd(&sh_pos, 1);
                  candout[p] = ((ull)kk[c] << 32) | (unsigned)(colbase + 4 * i + c);
                }
            }
          }
        }
      } else {
        for (int base = 0; base < N; base += 8 * T) {
          ull pk[8];
          #pragma unroll
          for (int u = 0; u < 8; ++u) {
            const int i = base + u * T + threadIdx.x;
            pk[u] = (i < N) ? hs_pack(stage, i, colbase, packed) : 0ull;
          }
          #pragma unroll
          for (int u = 0; u < 8; ++u) {
            if (pk[u] != 0ull && (unsigned)(pk[u] >> 32) >= lo) {
              int p = atomicAdd(&sh_pos, 1);
              candout[p] = pk[u];
            }
          }
        }
      }
    }
    __syncthreads();
    if (dbg && threadIdx.x == 0) dbg[3] = gtimer();
    return sh_pos;
  }
  // Tie flood at the fully-refined boundary (rare; no gating): take all
  // strictly-above keys, then claim just enough boundary-equal elements.
  for (int i = threadIdx.x; i < N; i += T) {
    unsigned key = hs_key(stage, i, packed);
    if (key > lo) {
      int p = atomicAdd(&sh_pos, 1);
      candout[p] = hs_pack(stage, i, colbase, packed);
    }
  }
  __syncthreads();
  const int defs = sh_pos;
  for (int i = threadIdx.x; i < N; i += T) {
    unsigned key = hs_key(stage, i, packed);
    if (key == lo) {
      int e = atomicAdd(&sh_eq, 1);
      if (defs + e < klocal) candout[defs + e] = hs_pack(stage, i, colbase, packed);
    }
  }
  __syncthreads();
  return min(klocal, defs + sh_eq);
}

// Phase stamps for offline profiling; free when dbg == nullptr.
#define STAMP(i)                                                        \
  do {                                                                  \
    if (dbg) {                                                          \
      __syncthreads();                                                  \
      if (threadIdx.x == 0) dbg[blockIdx.x * 16 + (i)] = gtimer();      \
    }                                                                   \
  } while (0)

template <int KR>
__device__ __forceinline__ void tk_hist_body(
    const float4* __restrict__ x4, int n, int k, int S, int sliceE, int vec,
    float* __restrict__ ovals, long long* __restrict__ oidx,
    ull* __restrict__ pool, unsigned* __restrict__ pcnt,
    unsigned* __restrict__ tickets, int capq,
    long long* __restrict__ dbg) {
  extern __shared__ __align__(16) ull smemu[];
  ull* cand = smemu;
  unsigned* hist = (unsigned*)(cand + CAP);
  unsigned* aux = hist + NB;

  const int T = blockDim.x;
  const int row = blockIdx.x / S, sl = blockIdx.x - row * S;
  const int sE = sl * sliceE;
  const int eE = min(sE + sliceE, n);
  const int N = (eE > sE) ? (eE - sE) : 0;
  const int klocal = min(k, N);

  STAMP(0);
  ull* prow = pool + ((size_t)row * S + sl) * capq;
  if (S > 1) {
    // pre-zero this block's pool slot; compact writes candidates directly
    for (int t = threadIdx.x; t < capq; t += T) prow[t] = 0ull;
  }
  for (int i = threadIdx.x * 4; i < NB; i += T * 4)
    *(uint4*)&hist[i] = make_uint4(0u, 0u, 0u, 0u);
  __syncthreads();
  STAMP(1);

  // Select straight from global memory: the first pass streams from DRAM, the
  // gated second pass (compact) hits L2 (inputs are far smaller than L2).
  const ull* src = (const ull*)((const float*)x4 + (size_t)row * n + sE);
  int scnt = 0;
  if (klocal > 0) {
    scnt = hist_select<KR>(src, N, klocal, false, hist, aux, cand, sE, capq,
                           dbg ? dbg + blockIdx.x * 16 + 6 : nullptr,
                           (S > 1) ? prow : nullptr);
  }
  STAMP(2);

  if (S == 1) {
    rank_output(cand, scnt, k, ovals + (size_t)row * k, oidx + (size_t)row * k);
    STAMP(3);
    return;
  }

  // Candidates already live in this block's pool slot; take a ticket.
  __shared__ bool amlast;
  if (threadIdx.x == 0) {
    unsigned old;
    asm volatile("atom.add.acq_rel.gpu.u32 %0, [%1], %2;"
                 : "=r"(old) : "l"(&tickets[row]), "r"(1u) : "memory");
    amlast = (old == (unsigned)(S - 1));
  }
  __syncthreads();
  STAMP(3);
  if (!amlast) return;

  // Merge: the same select, straight over the row's pool slots in L2
  // (zero pads lose to every real candidate).
  const int M = S * capq;
  const ull* pr = pool + (size_t)row * S * capq;
  STAMP(4);
  for (int i = threadIdx.x * 4; i < NB; i += T * 4)
    *(uint4*)&hist[i] = make_uint4(0u, 0u, 0u, 0u);
  __syncthreads();
  int mcnt = hist_select<0>(pr, M, k, true, hist, aux, cand, 0, max(128, k),
                            dbg ? dbg + blockIdx.x * 16 + 10 : nullptr);
  rank_output(cand, mcnt, k, ovals + (size_t)row * k, oidx + (size_t)row * k);
  if (threadIdx.x == 0) tickets[row] = 0;
  STAMP(5);
}

template <int KR>
__global__ void __launch_bounds__(512) tk_hist(
    const float4* __restrict__ x4, int n, int k, int S, int sliceE, int vec,
    float* __restrict__ ovals, long long* __restrict__ oidx,
    ull* __restrict__ pool, unsigned* __restrict__ pcnt,
    unsigned* __restrict__ tickets, int capq, long long* __restrict__ dbg) {
  tk_hist_body<KR>(x4, n, k, S, sliceE, vec, ovals, oidx, pool, pcnt, tickets, capq, dbg);
}

__global__ void __launch_bounds__(512) tk_argmax(
    const float4* __restrict__ x4, int n, int n4,
    float* __restrict__ ovals, long long* __restrict__ oidx) {
  const int row = blockIdx.x;
  const int T = blockDim.x;
  __shared__ ull sm[32];
  const float4* xr = x4 + (size_t)row * n4;
  ull best = 0;
  for (int base = 0; base < n4; base += 4 * T) {
    float4 vv[4];
    #pragma unroll
    for (int u = 0; u < 4; ++u) {
      const int i = base + u * T + threadIdx.x;
      if (i < n4) vv[u] = __ldg(&xr[i]); else vv[u] = make_float4(0.f, 0.f, 0.f, 0.f);
    }
    #pragma unroll
    for (int u = 0; u < 4; ++u) {
      const int i = base + u * T + threadIdx.x;
      if (i < n4) {
        unsigned c = ((unsigned)i) << 2;
        ull p0 = ((ull)mapf(vv[u].x) << 32) | c;
        ull p1 = ((ull)mapf(vv[u].y) << 32) | (c + 1u);
        ull p2 = ((ull)mapf(vv[u].z) << 32) | (c + 2u);
        ull p3 = ((ull)mapf(vv[u].w) << 32) | (c + 3u);
        ull m01 = p0 > p1 ? p0 : p1, m23 = p2 > p3 ? p2 : p3;
        ull m = m01 > m23 ? m01 : m23;
        best = best > m ? best : m;
      }
    }
  }
  const float* xs = (const float*)x4 + (size_t)row * n;
  for (int i = n4 * 4 + threadIdx.x; i < n; i += T) {
    ull p = ((ull)mapf(xs[i]) << 32) | (unsigned)i;
    best = best > p ? best : p;
  }
  #pragma unroll
  for (int j = 16; j > 0; j >>= 1) {
    ull o = __shfl_xor_sync(FULLM, best, j);
    best = best > o ? best : o;
  }
  if ((threadIdx.x & 31) == 0) sm[threadIdx.x >> 5] = best;
  __syncthreads();
  if (threadIdx.x < 32) {
    int W = T >> 5;
    ull b = (threadIdx.x < W) ? sm[threadIdx.x] : 0;
    #pragma unroll
    for (int j = 16; j > 0; j >>= 1) {
      ull o = __shfl_xor_sync(FULLM, b, j);
      b = b > o ? b : o;
    }
    if (threadIdx.x == 0) {
      ovals[row] = unmapf((unsigned)(b >> 32));
      oidx[row] = (long long)(unsigned)b;
    }
  }
}

struct Cfg {
  int batch, n, k, S, T, sliceE, vec, smem, KR, CAPQ;
  bool argmax;
  float* vals;
  long long* idx;
  ull* pool;
  unsigned* pcnt;
  unsigned* tickets;
};
static std::vector<Cfg> g_cfgs;

int64_t tk_make(at::Tensor vals, at::Tensor idx, at::Tensor pool, at::Tensor pcnt,
                at::Tensor tickets, int64_t batch, int64_t n, int64_t k, int64_t S,
                int64_t T, int64_t is_argmax) {
  Cfg c;
  TORCH_CHECK(S >= 1 && S <= 32, "S out of range");
  c.batch = (int)batch; c.n = (int)n; c.k = (int)k;
  c.S = (int)S; c.T = (int)T;
  c.vec = (n % 4 == 0) ? 1 : 0;
  int sliceE = (int)((n + S - 1) / S);
  if (c.vec) sliceE = ((sliceE + 3) / 4) * 4;
  c.sliceE = sliceE;
  c.KR = 0;
  if (c.vec) {
    int n4slice = (sliceE + 3) / 4;
    if (n4slice <= 4 * c.T) c.KR = 4;
    else if (n4slice <= 8 * c.T) c.KR = 8;
  }
  c.CAPQ = (S > 1 && k <= 64) ? 128 : CAP;
  TORCH_CHECK(k >= 1 && k <= CAP, "k out of supported range");
  c.smem = (CAP + NB / 2 + c.T / 2 + 8) * 8;
  c.argmax = is_argmax != 0;
  c.vals = vals.data_ptr<float>();
  c.idx = (long long*)idx.data_ptr<int64_t>();
  c.pool = (ull*)pool.data_ptr<int64_t>();
  c.pcnt = (unsigned*)pcnt.data_ptr<int>();
  c.tickets = (unsigned*)tickets.data_ptr<int>();
  if (!c.argmax && c.smem > 48 * 1024) {
    cudaFuncSetAttribute(tk_hist<0>, cudaFuncAttributeMaxDynamicSharedMemorySize, c.smem);
    cudaFuncSetAttribute(tk_hist<4>, cudaFuncAttributeMaxDynamicSharedMemorySize, c.smem);
    cudaFuncSetAttribute(tk_hist<8>, cudaFuncAttributeMaxDynamicSharedMemorySize, c.smem);
  }
  g_cfgs.push_back(c);
  return (int64_t)g_cfgs.size() - 1;
}

static void tk_launch(const Cfg& c, const float4* x4, cudaStream_t stream, long long* dbg) {
  if (c.argmax) {
    tk_argmax<<<c.batch, c.T, 0, stream>>>(x4, c.n, c.n / 4, c.vals, c.idx);
    return;
  }
  #define TKL(F, KR) F<KR><<<c.batch * c.S, c.T, c.smem, stream>>>( \
      x4, c.n, c.k, c.S, c.sliceE, c.vec, c.vals, c.idx, c.pool, c.pcnt, \
      c.tickets, c.CAPQ, dbg)
  TORCH_CHECK(c.T <= 512, "T > 512 unsupported");
  if (c.KR == 4) TKL(tk_hist, 4);
  else if (c.KR == 8) TKL(tk_hist, 8);
  else TKL(tk_hist, 0);
  #undef TKL
}

void tk_run(int64_t slot, at::Tensor x) {
  const Cfg& c = g_cfgs[slot];
  TORCH_CHECK(x.is_contiguous(), "input must be contiguous");
  tk_launch(c, reinterpret_cast<const float4*>(x.data_ptr<float>()),
            at::cuda::getCurrentCUDAStream(), nullptr);
}

void tk_run_dbg(int64_t slot, at::Tensor x, at::Tensor dbg) {
  const Cfg& c = g_cfgs[slot];
  tk_launch(c, reinterpret_cast<const float4*>(x.data_ptr<float>()),
            at::cuda::getCurrentCUDAStream(), (long long*)dbg.data_ptr<int64_t>());
}
"""

_CPP_DECLS = r"""
int64_t tk_make(at::Tensor vals, at::Tensor idx, at::Tensor pool, at::Tensor pcnt,
                at::Tensor tickets, int64_t batch, int64_t n, int64_t k, int64_t S,
                int64_t T, int64_t is_argmax);
void tk_run(int64_t slot, at::Tensor x);
void tk_run_dbg(int64_t slot, at::Tensor x, at::Tensor dbg);
"""

_ext_cache = None


def _ext():
    global _ext_cache
    if _ext_cache is None:
        import os

        if "TORCH_CUDA_ARCH_LIST" not in os.environ and torch.cuda.is_available():
            maj, mnr = torch.cuda.get_device_capability(0)
            os.environ["TORCH_CUDA_ARCH_LIST"] = f"{maj}.{mnr}"
        _ext_cache = load_inline(
            name="tk_hist_v2",
            cpp_sources=_CPP_DECLS,
            cuda_sources=_CUDA_SRC,
            functions=["tk_make", "tk_run", "tk_run_dbg"],
            extra_cuda_cflags=["-O3", "--use_fast_math"],
            verbose=False,
        )
    return _ext_cache


# Per-shape launch configs: S slices per row, T threads per block.
_CONFIGS = {
    (1, 131072, 64): dict(S=16, T=512),
    (64, 8192, 8): dict(S=1, T=512),
    (32, 16384, 32): dict(S=1, T=512),
    (16, 12000, 16): dict(S=1, T=512),
    (128, 4096, 1): dict(argmax=True, T=512),
}


def _pick_cfg(b, n, k):
    cfg = _CONFIGS.get((b, n, k))
    if cfg is not None:
        return dict(cfg)
    if k == 1:
        return dict(argmax=True, T=256 if n < 2048 else 512)
    if k > 256:
        raise NotImplementedError("k > 256 not supported by this kernel")
    # generic: keep the staged slice near 8K elements, S within the merge cap
    S = 1
    while (n + S - 1) // S > 8192 and S < 32:
        S += 1
    return dict(S=S, T=512)


class Model(nn.Module):
    """Top-k over the last dim of a 2D fp32 tensor (values desc + int64 indices)."""

    def __init__(self, batch: int, n: int, k: int):
        super().__init__()
        self.batch, self.n, self.k = int(batch), int(n), int(k)
        self.register_buffer("_dummy", torch.zeros(1))
        self._slot = None

    def _lazy_init(self, x):
        ext = _ext()
        b, n, k = self.batch, self.n, self.k
        cfg = _pick_cfg(b, n, k)
        dev = x.device
        vals = torch.empty((b, k), dtype=torch.float32, device=dev)
        idx = torch.empty((b, k), dtype=torch.int64, device=dev)
        if cfg.get("argmax"):
            pool = torch.empty(1, dtype=torch.int64, device=dev)
            pcnt = torch.zeros(1, dtype=torch.int32, device=dev)
            tick = torch.zeros(1, dtype=torch.int32, device=dev)
            slot = ext.tk_make(vals, idx, pool, pcnt, tick, b, n, k, 1, cfg["T"], 1)
        else:
            S, T = cfg["S"], cfg["T"]
            assert S <= 32
            pool = torch.empty(max(1, b * S * 256), dtype=torch.int64, device=dev)
            pcnt = torch.zeros(max(1, b * S), dtype=torch.int32, device=dev)
            tick = torch.zeros(max(1, b), dtype=torch.int32, device=dev)
            slot = ext.tk_make(vals, idx, pool, pcnt, tick, b, n, k, S, T, 0)
        self._keep = (vals, idx, pool, pcnt, tick)
        self._out = (vals, idx)
        self._runf = ext.tk_run
        self._slot = slot

    def forward(self, x):
        if self._slot is None:
            self._lazy_init(x)
        self._runf(self._slot, x)
        return self._out

    __call__ = forward


# Module-level shims rebuilt by check.py / benchmark.py per shape.
batch = 64
n = 8192
k = 8


def get_inputs():
    x = torch.randn(batch, n, dtype=torch.float32)
    return [x]


def get_init_inputs():
    return [batch, n, k]

20260703_111328_claude_claude-fable-5_05_topk_bitonic