diff --git a/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs.hpp b/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs.hpp index 7628c2616f..261fe2c30a 100644 --- a/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs.hpp +++ b/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs.hpp @@ -197,34 +197,23 @@ struct BlockFmhaFwdSplitKVPipelineNWarpSShuffleQRKSVS __builtin_amdgcn_sched_barrier(0); // Q tile in LDS - QDataType* q_lds_ptr = - static_cast(static_cast(static_cast(smem_ptr))); - auto q_lds = make_tensor_view( + QDataType* q_lds_ptr = static_cast(smem_ptr); + auto q_lds = make_tensor_view( q_lds_ptr, Policy::template MakeQLdsBlockDescriptor()); // K tile in LDS - KDataType* k_lds_ptr = - static_cast(static_cast(static_cast(smem_ptr))); + KDataType* k_lds_ptr = reinterpret_cast( + static_cast(smem_ptr) + max(Policy::template GetSmemSizeQ(), + Policy::template GetSmemSizeS())); auto k_lds = make_tensor_view( k_lds_ptr, Policy::template MakeKLdsBlockDescriptor()); auto k_lds_window = make_tile_window(k_lds, make_tuple(number{}, number{}), {0, 0}); - // V tile in LDS - auto v_lds = make_tensor_view( - reinterpret_cast(static_cast(smem_ptr) + - max(Policy::template GetSmemSizeQ(), - Policy::template GetSmemSizeK())), - Policy::template MakeVLdsBlockDescriptor()); - auto v_lds_window = make_tile_window( - v_lds, Policy::template MakeVLdsBlockDescriptor().get_lengths(), {0, 0}); - // S tile in LDS - auto s_lds = make_tensor_view( - reinterpret_cast(reinterpret_cast(smem_ptr) + - max(Policy::template GetSmemSizeQ(), - Policy::template GetSmemSizeK())), - Policy::template MakeSLdsBlockDescriptor()); + SaccDataType* s_lds_ptr = static_cast(smem_ptr); + auto s_lds = make_tensor_view( + s_lds_ptr, Policy::template MakeSLdsBlockDescriptor()); auto s_write_lds_window = make_tile_window( s_lds, Policy::template MakeSLdsBlockDescriptor().get_lengths(), {0, 0}); auto s_read_lds_window = @@ -233,6 +222,15 @@ struct BlockFmhaFwdSplitKVPipelineNWarpSShuffleQRKSVS {0, 0}, Policy::template MakeSRegTileDistribution()); + // V tile in LDS + VDataType* v_lds_ptr = reinterpret_cast( + static_cast(smem_ptr) + max(Policy::template GetSmemSizeQ(), + Policy::template GetSmemSizeS())); + auto v_lds = make_tensor_view( + v_lds_ptr, Policy::template MakeVLdsBlockDescriptor()); + auto v_lds_window = make_tile_window( + v_lds, Policy::template MakeVLdsBlockDescriptor().get_lengths(), {0, 0}); + // Block GEMM constexpr auto gemm_0 = Policy::template GetQKBlockGemm(); constexpr auto gemm_1 = Policy::template GetKVBlockGemm(); @@ -375,9 +373,6 @@ struct BlockFmhaFwdSplitKVPipelineNWarpSShuffleQRKSVS // prefetch K tile index_t i_total_loops = 0; - // ensure all the ds_read for q are done - block_sync_lds(); - do { // STAGE 1, QK gemm @@ -672,9 +667,6 @@ struct BlockFmhaFwdSplitKVPipelineNWarpSShuffleQRKSVS }); }); - // ensure all ds_read for s are done - block_sync_lds(); - auto v_shuffle_tmp = make_static_distributed_tensor( Policy::template MakeShuffledVRegBlockDescriptor()); shuffle_tile(v_shuffle_tmp, v_tiles[number<0>{}]); @@ -711,6 +703,8 @@ struct BlockFmhaFwdSplitKVPipelineNWarpSShuffleQRKSVS block_sync_lds(); }; }); + + block_sync_lds(); } while(++i_total_loops < num_total_loop); if constexpr(kStoreLSE) diff --git a/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs_default_policy.hpp b/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs_default_policy.hpp index 215aba288a..da18849f19 100644 --- a/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs_default_policy.hpp +++ b/include/ck_tile/ops/fmha/pipeline/block_fmha_fwd_splitkv_pipeline_nwarp_sshuffle_qr_ks_vs_default_policy.hpp @@ -255,8 +255,10 @@ struct BlockFmhaFwdSplitKVPipelineNWarpSShuffleQRKSVSDefaultPolicy template CK_TILE_HOST_DEVICE static constexpr ck_tile::index_t GetSmemSize() { - return max(GetSmemSizeQ(), GetSmemSizeK()) + - max(GetSmemSizeV(), GetSmemSizeS()); + // in hdim128 situtation, Q and S are 16x128, K and V are 32x128 or 64x128, + // so it makes sense to let Q and S reuse LDS, K and V resuse LDS + return max(GetSmemSizeQ(), GetSmemSizeS()) + + max(GetSmemSizeK(), GetSmemSizeV()); } };