[PyTorch] Make the Triton mask-map permute respect num_out_tokens - #3347
Open
truong-v wants to merge 1 commit into
Open
[PyTorch] Make the Triton mask-map permute respect num_out_tokens#3347truong-v wants to merge 1 commit into
truong-v wants to merge 1 commit into
Conversation
The Triton _permute_kernel received num_out_tokens explicitly marked unused, and nothing clamped destination rows against it, while the host sizes the output at exactly num_out_tokens rows: a routing map that routes more tokens than num_out_tokens wrote the excess rows past the end of the allocation. The CUDA index-map path behind the same public API drops over-capacity entries by marking them -1 in the row map (moe_permute_row_map); do the same in row-id-map pass 2, so every consumer of the map (permute, unpermute, backward) skips them via the existing -1 handling. The JAX lowering passes an explicit no-drop sentinel, keeping its current behavior unchanged. Signed-off-by: Truong Vu <truongvu0911nd@gmail.com>
Contributor
Greptile SummaryThe PR bounds Triton mask-map row IDs by the PyTorch output capacity while preserving JAX’s existing no-drop behavior.
Confidence Score: 5/5The PR appears safe to merge; no actionable correctness, security, or compatibility issue was identified. The new bound is applied before map compaction, all downstream kernels consume only compacted valid routes, PyTorch callers provide the real allocation size, and JAX explicitly retains its existing full-buffer semantics. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Routing mask] --> B[Pass 1: block counts]
B --> C[Pass 2: global row IDs]
C --> D{row ID below num_out_tokens?}
D -- Yes --> E[Keep destination]
D -- No --> F[Mark as -1]
E --> G[Pass 3: compact valid routes]
F --> G
G --> H[Permute / unpermute / backward]
Reviews (1): Last reviewed commit: "[PyTorch] Make the Triton mask-map permu..." | Re-trigger Greptile |
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.
Description
Fixes #3346.
The Triton mask-map path of
moe_permutesizes its output at exactlynum_out_tokensrows, but_permute_kernelreceivesnum_out_tokensmarked unused and the row-id map assigns destination rows as an unbounded cumsum — so a routing map with more routed entries thannum_out_tokenswrites the excess rows past the end of the allocation (48 invalid global writes under compute-sanitizer in the linked issue's repro, ending in an unspecified launch failure; 0 errors after this change). The CUDA index-map path behind the same public API implements the capacity limit by marking over-capacity entries-1in its row map (moe_permute_row_map'sidx >= num_out_tokensbranch).This PR gives the Triton path the same semantics at the same place:
_row_id_map_pass_2_kerneltakesnum_out_tokensand marks destinations at or past it as-1— pass 3 then excludes them fromn_routed, and every consumer of the map (permute, unpermute, and their backwards) already skips dropped entries via the existing-1handling. No compute kernel changes.make_row_id_mapand its caller threadnum_out_tokensthrough.2**31 - 1), keeping JAX behavior unchanged; wiringtoken_dispatch'snum_out_tokensinto it can follow separately if desired.test_permutation_mask_map_capacity_drop(fp32/fp16/bf16): capacity 17 belowrouting_map.sum(), checking the kept rows against an expert-major reference permutation, the row map'sn_routedaccounting, and the unpermute of the dropped map. All three fail without the fix and pass with it; the rest of the mask-map suite is unchanged — 151 passed / 113 skipped / 16 failed, with the same 16 failing ids, both with and without the change (those 16 are FP8DelayedScalingcases that already fail at this commit in my prebuilt-wheel setup, on an NVRTC/CUDA-header version mismatch that has nothing to do with permutation).Checklist
make_row_id_map).Environment