feat(topk): add sample-verified exact Top-K - #93
Merged
Merged
Conversation
Add the exact FP32 variable-length Top-K operator with sampled long-row boundary localization, fused complete-row validation, and 11+11+10 frontier refinement. Expose CUDA Graph-friendly workspace APIs and cover exact, recovery, cooperative, row-local, and sanitizer paths.
VAthree
force-pushed
the
feat/hpcops-topk
branch
from
August 28, 2026 06:50
1006e09 to
cc04331
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds
hpc.topk_filtered, an exact FP32 row-wise Top-K operator for long-context sparse-attention indexers on NVIDIA Hopper GPUs.Top-K is a key operator in the sparse-attention indexers used by models such as GLM-5.3 and Hy4-preview. An indexer first produces a score row over the available KV positions, selects a fixed number of indices, and passes those indices to sparse attention. As context length grows, the downstream attention work remains bounded by
K, while standalone Top-K must still process every valid score in the row.HPC-Ops Top-K uses a small, regular view of the current row to propose a coarse upper-tail boundary before the mandatory complete-row traversal. The complete traversal validates that proposal, forms the candidate set, and starts exact FP32 refinement in one fused pass. Current-row sampling thereby removes the initial histogram-then-classification reread from the common long-row path, while complete-row validation preserves exact output semantics.
Design
A conventional radix selector first histograms the complete row to discover its rank boundary. Applying that boundary then requires a second traversal or a row-sized retained copy.
Early filtering has a coarser objective than final selection: retaining a compact upper tail containing the answer. A regular
1/sview of the current row provides this signal, with a deterministic row-dependent phase distributing consecutive rows across thespossible offsets. Its order statistic locates a conservativeO(K)upper-tail boundary. The sample controls the retained workload; the complete row certifies candidate sufficiency and the FP32 refinement determines the returned indices. On the common sampled path, score-row traffic is approximately one fractional view plus one complete traversal before frontier-only refinement.Dual-threshold rescue. The coarser wide-row view records two nested boundaries during the same sampled histogram prefix. The primary boundary serves the common path; a deeper secondary boundary remains dormant as a bounded recovery margin. Both boundaries share the same view and prefix scan.
The operator follows three logical phases:
11+11+10decomposition of the complete FP32 ordered key. Each round commits groups strictly ahead of the rank boundary, discards groups behind it, and carries the unique boundary group to the next digit.Sampling proposes the workload-reduction boundary; complete-row validation certifies candidate sufficiency, and every continuation finishes with the original FP32 values. An underfilled primary proposal may use the nested recovery boundary first, while an unavailable view or continued underfill uses the sample-independent exact coarse route. The operator returns an unordered Top-K set with an arbitrary valid choice among equal-valued boundary indices.
GPU implementation
The primary long-row path uses a persistent pool of 512-thread CTAs. Each CTA owns the three phases for one row and obtains subsequent rows from a device-side completion-order queue. This balances causal and ragged row lengths while keeping launch dimensions stable for CUDA Graph replay.
The sampled path combines vectorized cache-global loads, FP32 cutoff classification, candidate persistence, and construction of the leading exact histogram. Exact refinement revisits the unresolved frontier through ping-pong candidate buffers, and the shared 2,048-bin histogram allocation is reused across phases and radix digits. Persistent workers own bounded overflow slices, bounding scratch usage by the worker pool.
For a small number of long rows, a KV-split mapping partitions the complete-row validation across cooperating CTAs and merges compact count and histogram state before one finisher performs refinement. Shorter rows and a few other complementary shapes use direct-exact row-local or cooperating-CTA mappings. All mappings share the same operator contract and FP32 refinement procedure.
API
M_capis the captured row capacity andM_live <= M_capis the runtime number of valid rows. Rowrselects from[0, ke[r]); physically padded columns may contain arbitrary values.The counter buffer must be zero-initialized before first use and is returned to the same state after every launch. The candidate workspace needs no initialization and can be retained across CUDA Graph replays.
Performance
We randomly sample chunks with distinct shapes to cover a variety of real chunking patterns.
Kis fixed at 2,048, while the valid KV length varies by row;Mdenotes the number of rows andNdenotes the allocated row length.The values below are median device latency in milliseconds over 50 iterations on a single NVIDIA H20 with 78 SMs, measured from Nsight Systems NVTX projections. All compared implementations perform exact Top-K selection: no unselected score exceeds any selected score.
N=128K
N=192K
N=256K
N=320K
N=384K
N=420K
decode_varlenGMEM_SPILLtop_k_per_row_prefillREREADlarge_context_topktop_k_per_row_decodesingle_pass_multi_ctaThe SGLang row uses its raw-index JIT Top-K v2 entry,
topk_transform_512_v2, evaluated atK=2048with page-table transformation disabled.HPC-Ops Top-K has the lowest latency for all six shapes and is
1.17xto1.57xfaster than SGLang, the closest competitor. These measurements report internal Top-K latency.