@@ -237,12 +237,12 @@ def end():
237237 l = l_scratch_ref [...]
238238 if fuse_reciprocal :
239239 l_inv = jnp .tile (1.0 / l , (head_dim_v_repeats , 1 ))
240- o_ref [...] = (o_scratch_ref [...] * l_inv ).astype (o_ref .dtype )
240+ o_ref [...] = (o_scratch_ref [...] * l_inv ).T . astype (o_ref .dtype )
241241 else :
242242 # Ring path: emit the un-normalized numerator plus the running softmax
243243 # stats (max logit `m` and linear denominator `l`) so the outer ring loop
244244 # can merge shard contributions and normalize only once at the very end.
245- o_ref [...] = o_scratch_ref [...].astype (o_ref .dtype )
245+ o_ref [...] = o_scratch_ref [...].T . astype (o_ref .dtype )
246246 if l_ring_ref is not None :
247247 l_ring_ref [...] = l .astype (l_ring_ref .dtype )
248248 if m_ring_ref is not None :
@@ -399,7 +399,7 @@ def end():
399399 for h_local in range (heads_per_tile ):
400400 l = l_scratch_ref [h_local ]
401401 l_inv = jnp .tile (1.0 / l , (head_dim_v_repeats , 1 ))
402- o_ref [h_local ] = (o_scratch_ref [h_local ] * l_inv ).astype (o_ref .dtype )
402+ o_ref [h_local ] = (o_scratch_ref [h_local ] * l_inv ).T . astype (o_ref .dtype )
403403
404404
405405def _splash_attention_forward (
@@ -436,7 +436,7 @@ def q_index_map(h, i, j, *_):
436436 return (h , i , 0 )
437437
438438 def out_index_map (h , i , j , * _ ):
439- return h , 0 , i
439+ return h , i , 0
440440
441441 def k_index_map (h , i , j , * _ ):
442442 return (h // q_heads_per_kv_head , j , 0 )
@@ -453,13 +453,13 @@ def v_index_map(h, i, j, *_):
453453 jax .ShapeDtypeStruct ((NUM_SUBLANES , bq ), jnp .float32 ),
454454 jax .ShapeDtypeStruct ((NUM_SUBLANES , bq ), jnp .float32 ),
455455 jax .ShapeDtypeStruct ((head_dim_v , bq ), jnp .float32 ),
456- jax .ShapeDtypeStruct ((num_q_heads , head_dim_v , actual_q_seq_len ), q .dtype ),
456+ jax .ShapeDtypeStruct ((num_q_heads , actual_q_seq_len , head_dim_v ), q .dtype ),
457457 ]
458458 out_specs = [
459459 pl .BlockSpec ((NUM_SUBLANES , bq ), lambda * _ : (0 , 0 )),
460460 pl .BlockSpec ((NUM_SUBLANES , bq ), lambda * _ : (0 , 0 )),
461461 pl .BlockSpec ((head_dim_v , bq ), lambda * _ : (0 , 0 )),
462- pl .BlockSpec ((None , head_dim_v , bq ), out_index_map ),
462+ pl .BlockSpec ((None , bq , head_dim_v ), out_index_map ),
463463 ]
464464 grid_width = (actual_kv_seq_len + bkv - 1 ) // bkv
465465 grid_height = (actual_q_seq_len + bq - 1 ) // bq
@@ -540,7 +540,10 @@ def _splash_attention_forward_ring(
540540 def q_index_map (h , i , j , * _ ):
541541 return (h , i , 0 )
542542
543- def out_index_map (h , i , j , * _ ):
543+ def out_index_map_o (h , i , j , * _ ):
544+ return h , i , 0
545+
546+ def out_index_map_stats (h , i , j , * _ ):
544547 return h , 0 , i
545548
546549 def k_index_map (h , i , j , * _ ):
@@ -558,17 +561,17 @@ def v_index_map(h, i, j, *_):
558561 jax .ShapeDtypeStruct ((NUM_SUBLANES , bq ), jnp .float32 ),
559562 jax .ShapeDtypeStruct ((NUM_SUBLANES , bq ), jnp .float32 ),
560563 jax .ShapeDtypeStruct ((head_dim_v , bq ), jnp .float32 ),
561- jax .ShapeDtypeStruct ((num_q_heads , head_dim_v , actual_q_seq_len ), jnp .float32 ),
564+ jax .ShapeDtypeStruct ((num_q_heads , actual_q_seq_len , head_dim_v ), jnp .float32 ),
562565 jax .ShapeDtypeStruct ((num_q_heads , NUM_SUBLANES , actual_q_seq_len ), jnp .float32 ),
563566 jax .ShapeDtypeStruct ((num_q_heads , NUM_SUBLANES , actual_q_seq_len ), jnp .float32 ),
564567 ]
565568 out_specs = [
566569 pl .BlockSpec ((NUM_SUBLANES , bq ), lambda * _ : (0 , 0 )),
567570 pl .BlockSpec ((NUM_SUBLANES , bq ), lambda * _ : (0 , 0 )),
568571 pl .BlockSpec ((head_dim_v , bq ), lambda * _ : (0 , 0 )),
569- pl .BlockSpec ((None , head_dim_v , bq ), out_index_map ),
570- pl .BlockSpec ((None , NUM_SUBLANES , bq ), out_index_map ),
571- pl .BlockSpec ((None , NUM_SUBLANES , bq ), out_index_map ),
572+ pl .BlockSpec ((None , bq , head_dim_v ), out_index_map_o ),
573+ pl .BlockSpec ((None , NUM_SUBLANES , bq ), out_index_map_stats ),
574+ pl .BlockSpec ((None , NUM_SUBLANES , bq ), out_index_map_stats ),
572575 ]
573576 grid_width = (actual_kv_seq_len + bkv - 1 ) // bkv
574577 grid_height = (actual_q_seq_len + bq - 1 ) // bq
@@ -612,7 +615,7 @@ def v_index_map(h, i, j, *_):
612615 ),
613616 out_shape = out_shapes ,
614617 )(mk , q , k , v )
615- out = jnp . swapaxes ( all_out [3 ], 1 , 2 ) # (h, head_dim_v, s) -> (h, s, head_dim_v)
618+ out = all_out [3 ]
616619 l = all_out [4 ][:, 0 , :] # (h, s)
617620 m = all_out [5 ][:, 0 , :] # (h, s)
618621 return out , m , l
@@ -653,7 +656,7 @@ def v_index_map(h, i, j, *_):
653656 return (h , j , 0 )
654657
655658 def out_index_map (h , i , j , * _ ):
656- return (h , 0 , i )
659+ return (h , i , 0 )
657660
658661 in_specs = [
659662 pl .BlockSpec ((hpt , bq , head_dim_qk ), q_index_map ),
@@ -664,13 +667,13 @@ def out_index_map(h, i, j, *_):
664667 jax .ShapeDtypeStruct ((hpt , NUM_SUBLANES , bq ), jnp .float32 ),
665668 jax .ShapeDtypeStruct ((hpt , NUM_SUBLANES , bq ), jnp .float32 ),
666669 jax .ShapeDtypeStruct ((hpt , head_dim_v , bq ), jnp .float32 ),
667- jax .ShapeDtypeStruct ((num_q_heads , head_dim_v , actual_q_seq_len ), q .dtype ),
670+ jax .ShapeDtypeStruct ((num_q_heads , actual_q_seq_len , head_dim_v ), q .dtype ),
668671 ]
669672 out_specs = [
670673 pl .BlockSpec ((hpt , NUM_SUBLANES , bq ), lambda * _ : (0 , 0 , 0 )),
671674 pl .BlockSpec ((hpt , NUM_SUBLANES , bq ), lambda * _ : (0 , 0 , 0 )),
672675 pl .BlockSpec ((hpt , head_dim_v , bq ), lambda * _ : (0 , 0 , 0 )),
673- pl .BlockSpec ((hpt , head_dim_v , bq ), out_index_map ),
676+ pl .BlockSpec ((hpt , bq , head_dim_v ), out_index_map ),
674677 ]
675678 grid_width = (actual_kv_seq_len + bkv - 1 ) // bkv
676679 grid_height = (actual_q_seq_len + bq - 1 ) // bq
0 commit comments