Skip to content

Commit d80a771

Browse files
[CuTe,Bwd,Sm100] allow 2cta with score mod and mask mod in bwd (#2557)
1 parent fefa96a commit d80a771

3 files changed

Lines changed: 18 additions & 19 deletions

File tree

flash_attn/cute/flash_bwd_sm100.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,7 @@ def __init__(
8282
assert self.tile_hdim <= 128 or (self.tile_hdim == 192 and self.tile_hdimv == 128)
8383
assert self.tile_hdimv <= 128
8484

85-
self.use_2cta_instrs = bool(
86-
use_2cta_instrs
87-
and cluster_size == 2
88-
and score_mod is None
89-
and score_mod_bwd is None
90-
and mask_mod is None
91-
)
85+
self.use_2cta_instrs = bool(use_2cta_instrs and cluster_size == 2)
9286
self.cta_group_size = 2 if self.use_2cta_instrs else 1
9387

9488
assert self.tile_hdim != 192 or self.use_2cta_instrs, "Must use 2CTA for hdim 192"
@@ -2761,9 +2755,15 @@ def apply_score_mod(
27612755
fastdiv_mods=(None, None),
27622756
):
27632757
"""Apply forward score modification for SM100 backward pass."""
2764-
# In bwd, S is computed as K @ Q.T so dimensions are (tile_n, tile_m)
2765-
cS = cute.make_identity_tensor((self.tile_n, self.tile_m))
2766-
cS = cute.domain_offset((n_block * self.tile_n, m_block * self.tile_m), cS)
2758+
# In bwd, S is computed as K @ Q.T so dimensions are (tile_n, tile_m).
2759+
# With 2CTA, partition_C must see the full cluster tile so each CTA
2760+
# gets its own half of the tile.
2761+
cluster_tile_n = self.tile_n * self.cta_group_size
2762+
cluster_n_block = n_block // self.cta_group_size
2763+
cS = cute.make_identity_tensor((cluster_tile_n, self.tile_m))
2764+
cS = cute.domain_offset(
2765+
(cluster_n_block * cluster_tile_n, m_block * self.tile_m), cS
2766+
)
27672767
tScS = thr_mma_S.partition_C(cS)
27682768
tScS_idx = thr_copy_t2r.partition_D(tScS)
27692769

@@ -2979,13 +2979,13 @@ def compute_loop(
29792979
seqlen, n_block // self.cluster_shape_mnk[0]
29802980
)
29812981
mask = AttentionMaskCls(seqlen)
2982-
n_block_for_cluster = n_block // self.cta_group_size
2982+
cluster_n_block = n_block // self.cta_group_size
29832983
# TODO: condition mask_seqlen
29842984
mask_fn = partial(
29852985
mask.apply_mask_sm100_transposed,
29862986
tScS_t2r=tScS_t2r,
29872987
t0ScS_t2r=t0ScS_t2r,
2988-
n_block=n_block_for_cluster,
2988+
n_block=cluster_n_block,
29892989
mask_seqlen=True,
29902990
mask_causal=self.is_causal,
29912991
mask_local=self.is_local,
@@ -3197,9 +3197,12 @@ def compute_loop(
31973197

31983198
if const_expr(self.score_mod_bwd is not None):
31993199
tSrS_pre_cur = tSrS_pre[None, stage, 0, 0]
3200-
cS_bwd = cute.make_identity_tensor((self.tile_n, self.tile_m))
3200+
cluster_tile_n = self.tile_n * self.cta_group_size
3201+
cluster_n_block = n_block // self.cta_group_size
3202+
cS_bwd = cute.make_identity_tensor((cluster_tile_n, self.tile_m))
32013203
cS_bwd = cute.domain_offset(
3202-
(n_block * self.tile_n, m_block * self.tile_m), cS_bwd
3204+
(cluster_n_block * cluster_tile_n, m_block * self.tile_m),
3205+
cS_bwd,
32033206
)
32043207
tScS_bwd = thr_mma_S.partition_C(cS_bwd)
32053208
tScS_idx_bwd = thr_copy_t2r.partition_D(tScS_bwd)

flash_attn/cute/interface.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,9 +1366,6 @@ def _flash_attn_bwd(
13661366
requested_disable_2cta = utils._get_disable_2cta_default()
13671367
disable_2cta = (
13681368
requested_disable_2cta
1369-
or score_mod is not None
1370-
or score_mod_bwd is not None
1371-
or mask_mod is not None
13721369
or block_sparse_tensors is not None
13731370
)
13741371
cluster_size = 2 if head_dim >= 128 and not disable_2cta else 1

tests/cute/test_flash_attn.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,10 @@ def test_flash_attn_output(
347347
and not has_qv
348348
and not dv > 256
349349
and not attention_chunk != 0
350-
and softcap == 0.0
351350
and (
352351
(dv == d and d <= 128)
353352
or (d == 192 and dv == 128)
354-
or (IS_SM100 and d == 256 and dv == 256)
353+
or (IS_SM100 and d == 256 and dv == 256 and softcap == 0.0)
355354
)
356355
and learnable_sink is None
357356
# and False

0 commit comments

Comments
 (0)