Fix axis-swapped bounds mask in _to_fp8_row_major_t transposed store - #4792
Open
amanyagami wants to merge 1 commit into
Open
Fix axis-swapped bounds mask in _to_fp8_row_major_t transposed store#4792amanyagami wants to merge 1 commit into
amanyagami wants to merge 1 commit into
Conversation
The transposed store address in _to_fp8_row_major_t is:
out_offs = block_col_offs[:, None] * output_stride_row
+ block_row_offs[None, :] * output_stride_col
i.e. the tile's first axis addresses the output row via block_col_offs
and the second axis addresses the output col via block_row_offs (since
this kernel writes the transpose). The bounds mask instead compared
block_row_offs against output_num_rows and block_col_offs against
output_num_cols - axes swapped relative to the address. For
rectangular / non-tile-aligned inputs this masks off valid output
elements (leaving torch.empty garbage in the result) and/or lets writes
through for positions that are actually out of bounds.
Fix: swap the mask to check the same axes, in the same order, as
out_offs.
This kernel's own test (fp8_dynamic_tensorwise_test.py) hard-requires
CUDA (assert torch.cuda.is_available()), so it can't be exercised here.
Added test/prototype/float8nocompile/test_to_fp8_row_major_t_bounds_mask.py,
which isolates the block_row_offs/block_col_offs -> out_offs/out_mask
index arithmetic in plain Python (mirroring exactly what the kernel
computes per program instance) and checks it against several rectangular,
non-tile-aligned shapes:
- the fixed mask covers exactly the valid transposed output region
- the buggy (axis-swapped) mask both misses valid output positions
and, for some shapes, writes to positions outside the valid output
region entirely
This proves the fix is logically correct independent of running the
actual Triton kernel; end-to-end verification still needs GPU CI.
Fixes pytorch#4584
amanyagami
requested review from
andrewor14,
jerryzh168 and
vkuzo
as code owners
August 19, 2026 20:30
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/ao/4792
Note: Links to docs will display an error until the docs builds have been completed. This comment was automatically generated by Dr. CI and updates every 15 minutes. |
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
The transposed store address in
_to_fp8_row_major_t(torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py) is:i.e. the tile's first axis addresses the output row via
block_col_offs, and the second axis addresses the output col viablock_row_offs(this kernel writes the transpose of its input tile). The bounds mask instead comparedblock_row_offsagainstoutput_num_rowsandblock_col_offsagainstoutput_num_cols— axes swapped relative to the address. For rectangular / non-tile-aligned inputs this masks off valid output elements (leavingtorch.emptygarbage in the result) and/or lets writes through for positions that are actually out of bounds.Fix
Swap the mask to check the same axes, in the same order, as
out_offs.Test
This kernel's own test (
fp8_dynamic_tensorwise_test.py) hard-requires CUDA (assert torch.cuda.is_available()), so I can't exercise it in this environment (no GPU access). Instead, addedtest/prototype/float8nocompile/test_to_fp8_row_major_t_bounds_mask.py, which isolates the exactblock_row_offs/block_col_offs→out_offs/out_maskindex arithmetic in plain Python (mirroring precisely what the kernel computes per program instance, for any tile size / non-tile-aligned shape) and checks it against several rectangular shapes:This proves the fix is logically correct independent of actually running the Triton kernel. End-to-end verification (e.g. against the existing
test_fp8_hp_to_fp8_row_major_tinfp8_dynamic_tensorwise_test.py) still needs GPU CI — flagging this explicitly rather than claiming more than I could verify.Fixes #4584
🤖 Generated with Claude Code