Skip to content

[Bugfix] Fix candidate buffer overflow in deepseek_v32 topk selector - #3280

Open
liuyun7345 wants to merge 1 commit into
tile-ai:mainfrom
liuyun7345:fix/topk-candidate-overflow
Open

liuyun7345 wants to merge 1 commit into
tile-ai:mainfrom
liuyun7345:fix/topk-candidate-overflow

Conversation

@liuyun7345

@liuyun7345 liuyun7345 commented Sep 25, 2026 •

Copy link
Copy Markdown

Summary

tl_topk in examples/deepseek_v32/topk_selector.py stages radix candidates in a fixed shared buffer:

s_input_idx = T.alloc_shared([2, 4096], T.int32)  # assume the threshold bucket size after first pass is less than 4K

Nothing bounds the threshold bucket chosen by the first radix pass to 4096 elements. Whenever more candidates land there — e.g. FP32 scores that share their low 10 mantissa bits (#1351), or simply torch.ones(...) with a small enough topk — the atomic appends write past the end of the buffer and the kernel crashes with CUDA_ERROR_ILLEGAL_ADDRESS.

Changes

  • tl_topk_impl now takes a workspace: T.Tensor[(batch, 2, seq_len), T.int32] argument. All s_input_idx[...] accesses become workspace[bx, ...], and the fixed SMEM_INPUT_SIZE shared allocation is removed, so both radix buffers are bounded by seq_len.
  • The tl_topk wrapper allocates the workspace with torch.empty((batch, 2, seq_len), dtype=torch.int32, ...) and forwards it. The public tl_topk() signature is unchanged.
  • Tie-breaking among equal values is unchanged: the kernel never guaranteed a stable order, and this PR does not change that; only the overflow is fixed.

Validation

RTX 4090D, CUDA 12.1, torch 2.6.0+cu124, tilelang 0.1.14 (wheel):

  • New regression test testing/python/issue/test_tilelang_issue_1351.py — 13 parameterized cases: low-mantissa-bit inputs (positive and negative), all-equal inputs at seq_len 4095/4096/4097/32768, boundary tie buckets (exactly topk-1 larger values followed by an oversized tied bucket), partial [starts, ends) ranges, and random inputs. Selected values are compared against a masked torch.topk reference with rtol=0, atol=0 (exact FP32 match, order-independent). 13/13 passed.
  • compute-sanitizer --tool memcheck: on the original kernel the first regression case (low-10-mantissa-bit input) already trips the sanitizer — ERROR SUMMARY: 129 errors — and the launch fails with CUDA_ERROR_LAUNCH_FAILED (the run stops there); the patched kernel passes the full 13-case matrix under the sanitizer with ERROR SUMMARY: 0 errors.
  • Kernel-only latency (CUDA events, median of 5 interleaved runs):
input shape topk before after
(2, 32768) 2048 23.0 µs 25.5 µs
(64, 32768) 2048 24.7 µs 26.4 µs
(64, 8192) 256 21.0 µs 23.0 µs

+7-10% from global-memory candidate atomics; the wrapper additionally pays one torch.empty (~8 µs) for the workspace (batch × 2 × seq_len × 4 B, e.g. 16 MB at batch=64, seq_len=32768).

  • ruff check / ruff format --check / codespell clean on both files (ruff 0.16.8, one minor version above the 0.16.6 CI pin).

Fixes #1351

Summary

  • Replace tl_topk_impl’s fixed 4,096-element candidate buffer with a workspace sized to seq_len. tl_topk allocates and passes the workspace; its public signature remains unchanged.
  • Use _RADIX threads for ROCm. Other platforms retain 1,024 threads.
  • Add a CUDA-gated regression test for low-bit and negative values, ties, random inputs, partial ranges, and edge cases. The test checks output properties and selected values against a masked torch.topk reference.

Testing

The changes add the regression test. No test run results are available in the supplied evidence.

tl_topk_impl staged radix candidates in a fixed [2, 4096] shared
buffer, but nothing bounds the threshold bucket selected by the first
radix pass to 4096 elements. Inputs where more candidates share that
bucket (e.g. FP32 scores with common low mantissa bits, or all-equal
inputs) made the atomic appends write past the buffer end and crash
with CUDA_ERROR_ILLEGAL_ADDRESS.

Allocate a (batch, 2, seq_len) global-memory workspace in the tl_topk
wrapper instead, bounding both radix buffers by seq_len. The public
tl_topk() signature is unchanged.

Fixes tile-ai#1351

Signed-off-by: liuyun7345 <liuyun7345@sina.com>
@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the TileLang project.

Please remember to run pre-commit run --all-files in the root directory of the project to ensure your changes are properly linted and formatted. This will help ensure your contribution passes the format check.

We appreciate you taking this step! Our team will review your contribution, and we look forward to your awesome work! 🚀

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: tile-ai/tilelang/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: b69e78f2-f5c5-48fd-a3f2-58120b510de6

📥 Commits

Reviewing files that changed from the base of the PR and between 356f309 and f07dfec.

📒 Files selected for processing (2)
  • examples/deepseek_v32/topk_selector.py
  • testing/python/issue/test_tilelang_issue_1351.py

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The top-k selector replaces its fixed shared-memory candidate buffer with a workspace sized to the input sequence. A CUDA-gated regression test checks selection results across value patterns, sequence lengths, top-k sizes, and full or partial ranges.

Changes

Top-k selection

Layer / File(s) Summary
Workspace-backed radix selection
examples/deepseek_v32/topk_selector.py
tl_topk_impl uses caller-provided workspace banks for radix candidates. tl_topk allocates workspace sized to seq_len. ROCm launches use _RADIX threads; other platforms use 1,024.
Top-k regression coverage
testing/python/issue/test_tilelang_issue_1351.py
The CUDA-gated test covers low-bit and negative values, tied values, random inputs, partial ranges, and edge cases. It checks output properties and compares selected values with a masked PyTorch topk reference.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: mengmeexix

Merge Risk: ⚪ Minimal · up to f07df

The workspace repair and regression coverage show no established merge-blocking issue. Merge after normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: fixing candidate buffer overflow in the DeepSeek V3.2 top-k selector.
Linked Issues check ✅ Passed The changes address issue [#1351]. tl_topk now allocates a sequence-length-bounded workspace and passes it to tl_topk_impl, replacing the fixed 4,096-element candidate buffer that could overflow. …
Out of Scope Changes check ✅ Passed The changed selector implementation and the CUDA regression test directly support issue [#1351]. The workspace change, platform launch handling, and test coverage are implementation or verification wo…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] illegal memory access when using topk_selector

1 participant