Skip to content

[Fix] Fix shared memory race in tilelang chunk_bwd dg_last accumulation#890

Open
Erix025 wants to merge 4 commits into
fla-org:mainfrom
Erix025:dev/fix-tilelang-bwd
Open

[Fix] Fix shared memory race in tilelang chunk_bwd dg_last accumulation#890
Erix025 wants to merge 4 commits into
fla-org:mainfrom
Erix025:dev/fix-tilelang-bwd

Conversation

@Erix025

@Erix025 Erix025 commented May 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Root Cause

In the V-loop (line 85), after two T.reduce_sum operations produce f_hdh_scalar[0], every thread in the thread block executes:

s_dg_last_acc[0] = s_dg_last_acc[0] + f_hdh_scalar[0]

With multiple warps executing concurrently, inter-warp timing causes non-deterministic read-modify-write results on shared memory.

Fix

Guard the shared memory write with T.Parallel(1), consistent with the initialization pattern at lines 80-81:

# Before (all threads write — race condition):
s_dg_last_acc[0] = s_dg_last_acc[0] + f_hdh_scalar[0]

# After (single-thread write):
for _i in T.Parallel(1):
    s_dg_last_acc[0] = s_dg_last_acc[0] + f_hdh_scalar[0]

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses a shared memory race condition in the chunk_bwd kernel by wrapping the s_dg_last_acc accumulation in a T.Parallel(1) block and adds regression tests for gradient determinism. Feedback points out a potential visibility issue where a T.sync_threads() call is needed after the accumulation to ensure the updated value is correctly synchronized across all threads before subsequent reads.

Comment thread fla/ops/common/backends/tilelang/chunk_bwd.py
@yzhangcs

Copy link
Copy Markdown
Member

@Erix025 hey could you fix some conflicts

@zhiyuan1i

Copy link
Copy Markdown
Collaborator

These codes should not be changed and require further investigation into the underlying causes。 CC @yzhangcs

@zhiyuan1i zhiyuan1i added the help wanted Extra attention is needed label May 13, 2026
@tzj-fxz

tzj-fxz commented May 13, 2026

Copy link
Copy Markdown

As I understand it, this kernel will contribute f_hdh_scalar to the final dg when USE_G is set. Since f_hdh_scalar has only one element and is summed by all elements in the buffer f_hdh, it may be helpful to change the f_hdh_scalar into local variable of each thread in the register rather than shared memory to avoid data race.

s_dg_last_acc = T.alloc_shared((1,), T.float32)
# can be changed to
s_dg_last_acc = T.alloc_var((1,), T.float32)

Similar to https://github.com/tile-ai/tilelang/blob/bcb2da336a28cf641f88e7f1ae53a95c475b6202/examples/gdn/example_chunk_o_bwd.py#L203, all references to s_dg_last_acc should remove [0] since it is no longer a shared buffer.

CC @Erix025

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

Labels

help wanted Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants