Skip to content

[Fix] Use modulo for the inner tile index in global_compose - #165

Merged
yaoyaoding merged 2 commits into
NVIDIA:mainfrom
v0ropaev:fix/global-compose-rhs-index
Oct 22, 2026
Merged

yaoyaoding merged 2 commits into
NVIDIA:mainfrom
v0ropaev:fix/global-compose-rhs-index

Conversation

@v0ropaev

Copy link
Copy Markdown
Contributor

global_compose computes the index inside the rhs tile with // instead of %. In _global_compose the line for rhs_indices is the same as the line for lhs_indices, so every element of a tile maps to the same rhs offset. For example global_compose(global_row_major(2, 2), global_row_major(2, 3)) evaluated over its 4x6 grid gives

[[ 0,  0,  0,  7,  7,  7],
 [ 0,  0,  0,  7,  7,  7],
 [15, 15, 15, 22, 22, 22],
 [15, 15, 15, 22, 22, 22]]

which is 4 distinct offsets for 24 elements. Anyone passing such a layout to global_view(..., layout=...) would read and write the wrong addresses. Nothing in the tree calls global_compose today, which is likely why it went unnoticed.

The fix changes the inner index to axes[i] % rhs.shape[i], which gives the same lhs_offset * rhs.size + rhs_offset blocking that shared_compose uses. The function exists twice, in ir/layout/global_layout.py and in ir/layout/ops/global_ops.py, and tilus.ir.layout and tilus.ir.layout.ops each export their own copy, so both are fixed. The same example now gives [[0, 1, 2, 6, 7, 8], [3, 4, 5, 9, 10, 11], [12, 13, 14, 18, 19, 20], [15, 16, 17, 21, 22, 23]]. I left the duplication alone to keep the change small, but I can make one module re-export the other if you prefer.

The new test in tests/ir/layout/global_layout/test_global_layout_compose.py evaluates the composed offsets with vectorized_evaluate for row-major and column-major inner tiles, through both modules. Its 4 cases fail on main and pass with the fix. I ran pytest tests/ir tests/transforms tests/docs on a Mac without a GPU. It gives 172 passed and 2 failed with the fix, against 168 passed and 2 failed on main. The 2 failures are the same test_verify_load_shared cases both times, and they fail because no GPU target is detected on this machine. pre-commit run --all passes.

_global_compose split each axis into an outer index (axis // rhs.shape)
for the lhs layout and an inner index for the rhs layout, but the inner
index was also computed with //. Every element inside a tile therefore
got the same rhs offset, so the composed layout was not injective and
pointed at the wrong addresses. For example, composing
global_row_major(2, 2) with global_row_major(2, 3) produced only four
distinct offsets (0, 7, 15 and 22) for 24 elements.

The inner index is now axis % rhs.shape, which gives the
lhs_offset * rhs.size + rhs_offset blocking that shared_compose already
uses. The fix is applied to both copies of the function, in
global_layout.py and in ops/global_ops.py, since tilus.ir.layout and
tilus.ir.layout.ops each export their own global_compose.

A new test evaluates the composed offsets over the full grid through both
modules.

Signed-off-by: Dmitry Voropaev <dy.voropaev@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Oct 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@yaoyaoding

yaoyaoding commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

/ok to test 5f4c85e

1 similar comment
@yaoyaoding

Copy link
Copy Markdown
Member

/ok to test 5f4c85e

@copy-pr-bot

copy-pr-bot Bot commented Oct 21, 2026

Copy link
Copy Markdown

/ok to test 5f4c85e

@yaoyaoding, there was an error processing your request: E2

See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/2/

…ut.py

Keep only the GlobalLayout class in ir/layout/global_layout.py and make
ir/layout/ops/global_ops.py the single home of global_row_major,
global_column_major, global_strides, global_compose and global_slice,
matching how register and shared layouts are organized. tilus.ir.layout
re-exports them from ops, so the public API is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Yaoyao Ding <dingyaoyao.cs@gmail.com>
@yaoyaoding
yaoyaoding force-pushed the fix/global-compose-rhs-index branch from 5f4c85e to a426084 Compare October 21, 2026 23:53
@yaoyaoding

Copy link
Copy Markdown
Member

/ok to test a426084

@yaoyaoding
yaoyaoding merged commit d49e499 into NVIDIA:main Oct 22, 2026
10 checks passed
@yaoyaoding

Copy link
Copy Markdown
Member

thanks @v0ropaev !

github-actions Bot added a commit that referenced this pull request Oct 22, 2026
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.

2 participants