Skip to content
Closed
14 changes: 14 additions & 0 deletions AGENTS.md
Comment thread
zhiyuan1i marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# AI Review Guidelines for flash-linear-attention

## Triton Kernel Integer Overflow Prevention

`tl.program_id()` and `tl.load()` from `cu_seqlens` return **int32** values. When these are multiplied by strides (e.g., `T`, `H*K`, `D`), the intermediate product can exceed `INT32_MAX` (2^31) for realistic tensor sizes (e.g., `B=4096, T=576, H=8, K=128`), causing silent wrong results or illegal CUDA memory accesses.

**Rule**: All index arithmetic derived from `tl.program_id()` or `cu_seqlens` loads should be cast to `int64` *before* any multiplication with strides or dimensions. Results should be cast back to `int32` before passing to `tl.make_block_ptr`, which requires 32-bit shape and offset arguments.

### When reviewing Triton kernels, flag:
- Any `i_b * T`, `i_n * T`, `i_b * D`, `i_n * D`, or `i_b * stride_*` without a prior `tl.cast(..., tl.int64)` **only when the product can plausibly exceed INT32_MAX** (consider the actual dimensions involved — not every int32 multiply needs promotion)
- Any `tl.load(cu_seqlens + ...).to(tl.int32)` (should be `.to(tl.int64)`)
- Any compound index expression like `(i_b * S + i_s) * D` where `i_b` or `i_s` comes from `tl.program_id()` without int64 promotion

See [#783](https://github.com/fla-org/flash-linear-attention/pull/783) and [#803](https://github.com/fla-org/flash-linear-attention/pull/803) for prior instances of this bug class.
4 changes: 2 additions & 2 deletions fla/ops/attn/decoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def naive_attn_decoding_kernel(
i_b, i_hq = i_bh // HQ, i_bh % HQ
i_h = i_hq // G

bos, eos = tl.load(cu_seqlens + i_b).to(tl.int32), tl.load(cu_seqlens + i_b + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_b).to(tl.int64), tl.load(cu_seqlens + i_b + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)

p_q = tl.make_block_ptr(q + i_bh * K, (K,), (1, ), (0, ), (BK,), (0,))
p_o = tl.make_block_ptr(o + i_bh * V, (V,), (1, ), (0, ), (BV,), (0,))
Expand Down
18 changes: 9 additions & 9 deletions fla/ops/attn/parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ def parallel_attn_fwd_kernel(

if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
i_n = i_b
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
RCP_LN2: tl.constexpr = 1.4426950216

p_q = tl.make_block_ptr(q + (bos * HQ + i_hq) * K, (T, K), (HQ*K, 1), (i_t * BT, 0), (BT, BK), (1, 0))
Expand Down Expand Up @@ -203,11 +203,11 @@ def parallel_attn_bwd_kernel_dq(

if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
i_n = i_b
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
# NOTE: we must multiply RCP_LN2 after tl.dot for high precision
RCP_LN2: tl.constexpr = 1.4426950216

Expand Down Expand Up @@ -338,11 +338,11 @@ def parallel_attn_bwd_kernel_dkv(

if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
i_n = i_b
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
RCP_LN2: tl.constexpr = 1.4426950216

p_k = tl.make_block_ptr(k + (bos * H + i_h) * K, (T, K), (H*K, 1), (i_t * BT, 0), (BT, BK), (1, 0))
Expand Down
4 changes: 2 additions & 2 deletions fla/ops/comba/fused_recurrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def fused_recurrent_comba_fwd_kernel(
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
all = T
T = eos - bos
T = (eos - bos).to(tl.int32)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
all = B * T
o_k = i_k * BK + tl.arange(0, BK)
o_v = i_v * BV + tl.arange(0, BV)
Expand Down
12 changes: 6 additions & 6 deletions fla/ops/comba/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ def chunk_comba_cumsum_scalar_fwd_kernel(
i_b, i_h = i_bh // H, i_bh % H
if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T

p_g = tl.make_block_ptr(g + bos*H + i_h, (T,), (H,), (i_t * BT,), (BT,), (0,))
p_g0 = tl.make_block_ptr(g0 + bos*H + i_h, (T,), (H,), (i_t * BT,), (BT,), (0,))
Expand Down Expand Up @@ -120,10 +120,10 @@ def chunk_comba_cumsum_scalar_bwd_kernel(
i_b, i_h = i_bh // H, i_bh % H
if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T

p_dg0 = tl.make_block_ptr(dg0 + bos*H + i_h, (T,), (H,), (i_t * BT,), (BT,), (0,))
p_dgr = tl.make_block_ptr(dgr + bos*H + i_h, (T,), (H,), (i_t * BT,), (BT,), (0,))
Expand Down
18 changes: 9 additions & 9 deletions fla/ops/comba/wy_fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ def chunk_scaled_dot_comba_pkt_fwd_kernel(
i_b, i_h = i_bh // H, i_bh % H
if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T
o_t = i_t * BT + tl.arange(0, BT)
m_t = o_t < T

Expand Down Expand Up @@ -194,10 +194,10 @@ def prepare_wy_repr_bwd_kernel(
i_b, i_h = i_bh // H, i_bh % H
if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T

p_beta = tl.make_block_ptr(beta + (bos*H + i_h), (T,), (H,), (i_t * BT,), (BT,), (0,))
p_g0 = tl.make_block_ptr(g0 + (bos*H + i_h), (T,), (H,), (i_t * BT,), (BT,), (0,))
Expand Down Expand Up @@ -322,10 +322,10 @@ def recompute_w_u_fwd_kernel(
i_b, i_h = i_bh // H, i_bh % H
if IS_VARLEN:
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T
p_beta = tl.make_block_ptr(beta + bos*H + i_h, (T,), (H,), (i_t * BT,), (BT,), (0,))
p_g = tl.make_block_ptr(g + (bos*H + i_h), (T,), (H,), (i_t * BT,), (BT,), (0,))
p_A = tl.make_block_ptr(A + (bos*H + i_h) * BT, (T, BT), (H*BT, 1), (i_t * BT, 0), (BT, BT), (1, 0))
Expand Down
16 changes: 8 additions & 8 deletions fla/ops/common/chunk_delta_h.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ def chunk_gated_delta_rule_fwd_kernel_h_blockdim64(
i_v, i_nh = tl.program_id(0), tl.program_id(1)
i_n, i_h = i_nh // HV, i_nh % HV
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
boh = tl.load(chunk_offsets + i_n).to(tl.int32)
boh = tl.load(chunk_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NT = tl.cdiv(T, BT)
boh = i_n * NT
Comment thread
tmct marked this conversation as resolved.

Expand Down Expand Up @@ -375,12 +375,12 @@ def chunk_gated_delta_rule_bwd_kernel_dhu_blockdim64(
i_v, i_nh = tl.program_id(0), tl.program_id(1)
i_n, i_h = i_nh // HV, i_nh % HV
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
boh = tl.load(chunk_offsets + i_n).to(tl.int32)
boh = tl.load(chunk_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NT = tl.cdiv(T, BT)
boh = i_n * NT

Expand Down
16 changes: 8 additions & 8 deletions fla/ops/common/chunk_h.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ def chunk_fwd_kernel_h(
i_k, i_v, i_nh = tl.program_id(0), tl.program_id(1), tl.program_id(2)
i_n, i_h = i_nh // H, i_nh % H
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT, NS = tl.cdiv(T, BT), tl.cdiv(T, BS)
boh = tl.load(split_offsets + i_n).to(tl.int32)
boh = tl.load(split_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NT, NS = tl.cdiv(T, BT), tl.cdiv(T, BS)
boh = i_n * NS
NTS = BS // BT
Expand Down Expand Up @@ -195,13 +195,13 @@ def chunk_bwd_kernel_dh(
i_n, i_hq = i_nh // HQ, i_nh % HQ
i_h = i_hq // NG
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
NS = tl.cdiv(T, BS)
boh = tl.load(split_offsets + i_n).to(tl.int32)
boh = tl.load(split_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NT = tl.cdiv(T, BT)
NS = tl.cdiv(T, BS)
boh = i_n * NS
Expand Down
28 changes: 14 additions & 14 deletions fla/ops/common/chunk_h_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ def chunk_fwd_kernel_h_parallel(
if IS_VARLEN:
i_tg = i_t
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T
NT = tl.cdiv(T, BT)
i_n, i_tg = i_b, i_b * NT + i_t
i_nh = i_n * H + i_h
Expand Down Expand Up @@ -176,12 +176,12 @@ def chunk_fwd_kernel_h_reduction(
i_k, i_v, i_nh = tl.program_id(0), tl.program_id(1), tl.program_id(2)
i_n, i_h = i_nh // H, i_nh % H
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
boh = tl.load(chunk_offsets + i_n).to(tl.int32)
boh = tl.load(chunk_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NT = tl.cdiv(T, BT)
boh = i_n * NT

Expand Down Expand Up @@ -274,11 +274,11 @@ def chunk_bwd_kernel_dh_parallel(
if IS_VARLEN:
i_tg = i_t
i_n, i_t = tl.load(chunk_indices + i_t * 2).to(tl.int32), tl.load(chunk_indices + i_t * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
else:
bos, eos = i_b * T, i_b * T + T
bos, eos = tl.cast(i_b, tl.int64) * T, tl.cast(i_b, tl.int64) * T + T
NT = tl.cdiv(T, BT)
i_n, i_tg = i_b, i_b * NT + i_t
i_nh = i_n * HQ + i_hq
Expand Down Expand Up @@ -369,12 +369,12 @@ def chunk_bwd_kernel_dh_reduction(
i_n, i_hq = i_nh // HQ, i_nh % HQ
i_h = i_hq // NG
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NT = tl.cdiv(T, BT)
boh = tl.load(chunk_offsets + i_n).to(tl.int32)
boh = tl.load(chunk_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NT = tl.cdiv(T, BT)
boh = i_n * NT

Expand Down
28 changes: 14 additions & 14 deletions fla/ops/common/chunk_h_split.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ def chunk_fwd_kernel_h_split(
i_ss, i_h = i_sh // H, i_sh % H
if IS_VARLEN:
i_n, i_s = tl.load(split_indices + i_ss * 2).to(tl.int32), tl.load(split_indices + i_ss * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NS = tl.cdiv(T, S)
else:
NS = tl.cdiv(T, S)
i_n, i_s = i_ss // NS, i_ss % NS
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
i_nh = i_n * H + i_h

# [BK, BV]
Expand Down Expand Up @@ -176,12 +176,12 @@ def chunk_fwd_kernel_h_reduction(
i_k, i_v, i_nh = tl.program_id(0), tl.program_id(1), tl.program_id(2)
i_n, i_h = i_nh // H, i_nh % H
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NS = tl.cdiv(T, S)
boh = tl.load(split_offsets + i_n).to(tl.int32)
boh = tl.load(split_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NS = tl.cdiv(T, S)
boh = i_n * NS

Expand Down Expand Up @@ -275,13 +275,13 @@ def chunk_bwd_kernel_dh_split(
i_ss, i_hq = i_sh // HQ, i_sh % HQ
if IS_VARLEN:
i_n, i_s = tl.load(split_indices + i_ss * 2).to(tl.int32), tl.load(split_indices + i_ss * 2 + 1).to(tl.int32)
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NS = tl.cdiv(T, S)
else:
NS = tl.cdiv(T, S)
i_n, i_s = i_ss // NS, i_ss % NS
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
i_nh = i_n * HQ + i_hq
i_h = i_hq // NG

Expand Down Expand Up @@ -385,12 +385,12 @@ def chunk_bwd_kernel_dh_reduction(
i_n, i_hq = i_nh // HQ, i_nh % HQ
i_h = i_hq // NG
if IS_VARLEN:
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int32), tl.load(cu_seqlens + i_n + 1).to(tl.int32)
T = eos - bos
bos, eos = tl.load(cu_seqlens + i_n).to(tl.int64), tl.load(cu_seqlens + i_n + 1).to(tl.int64)
T = (eos - bos).to(tl.int32)
NS = tl.cdiv(T, S)
boh = tl.load(split_offsets + i_n).to(tl.int32)
boh = tl.load(split_offsets + i_n).to(tl.int64)
else:
bos, eos = i_n * T, i_n * T + T
bos, eos = tl.cast(i_n, tl.int64) * T, tl.cast(i_n, tl.int64) * T + T
NS = tl.cdiv(T, S)
boh = i_n * NS

Expand Down
Loading
Loading