Skip to content

Commit d06f350

Browse files
CongMa13illsilin
authored andcommitted
[rocm-libraries] ROCm/rocm-libraries#4354 (commit d41f08a)
[CK TILE] fix numerical errors of preshuffle_b This pull request introduces several improvements and fixes related to quantized grouped GEMM (General Matrix Multiply) pipelines and their supporting utilities. # The numerical issue ## Steps to reproduce ```bash Run ./bin/tile_example_gemm_weight_preshuffle -prec=fp8 ./bin/tile_example_gemm_weight_preshuffle -prec=int4 ``` # Solution The main changes address type correctness, improve data layout and shuffling logic, and expand test coverage to better validate different GEMM configurations. **Key changes include:** ### Data layout and shuffling logic * Refactored the logic in `shuffle_b_permuteN` to use `constexpr` variables for `KLane` and `ItemsPerAccess`, simplifying tile view construction and correcting the permutation order for improved efficiency and correctness (`tensor_shuffle_utils.hpp`). * Fixed the calculation of `KLaneBytes` in weight preshuffle pipeline policies to account for internal data type conversion (e.g., from `pk_int4_t` to `fp8`), ensuring accurate memory access and alignment in quantized GEMM policies (`wp_pipeline_agmem_bgmem_creg_base_policy.hpp`, `gemm_wp_abquant_pipeline_ag_bg_cr_base_policy.hpp`). [[1]](diffhunk://#diff-93f16cd76e6e24404777e682a5ac8e039913ddd6a438c7efd61fdda42276e4efL274-R275) [[2]](diffhunk://#diff-9c3d0fc3c014feed435bfd93ba1f8f9fb3e054dcc322deada3addf70bee5a58cL100-R105) ### Test infrastructure enhancements * Unit tests did not catch this issue since there were no tests for fp8. Added new configuration structs (`config_mn_16x16`, `config_mn_32x32`) to support additional GEMM tile shapes and updated tests to run with these configurations for broader coverage (`test_gemm_pipeline_util.hpp`). [[1]](diffhunk://#diff-5a5962b2c4aa7f6a87d1d6201ad383135e30df13b42654e997d870d57420d5b8R86-R103) [[2]](diffhunk://#diff-5a5962b2c4aa7f6a87d1d6201ad383135e30df13b42654e997d870d57420d5b8L255-R269) Co-authored-by: Illia Silin <98187287+illsilin@users.noreply.github.com>
1 parent 807efa7 commit d06f350

7 files changed

Lines changed: 55 additions & 42 deletions

File tree

example/ck_tile/17_grouped_gemm/abquant_grouped_gemm.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ float grouped_gemm_abquant(const std::vector<grouped_gemm_kargs>& gemm_descs,
7575
ck_tile::GemmPipelineProblem<ADataType, BDataType, AccDataType, GemmShape, Traits>;
7676

7777
using BaseGemmPipeline =
78-
GemmQuantConfig<QuantMode>::template BaseGemmPipeline<GemmPipelineProblem,
79-
GemmConfig::PreshuffleB>;
78+
typename GemmQuantConfig<QuantMode>::template BaseGemmPipeline<GemmPipelineProblem,
79+
GemmConfig::PreshuffleB>;
8080

8181
const ck_tile::index_t k_grain = gemm_descs[0].k_batch * GemmConfig::K_Tile;
8282
const ck_tile::index_t K_split = (gemm_descs[0].K + k_grain - 1) / k_grain * GemmConfig::K_Tile;
@@ -108,8 +108,8 @@ float grouped_gemm_abquant(const std::vector<grouped_gemm_kargs>& gemm_descs,
108108
tail_number_v>;
109109

110110
using GemmPipeline =
111-
GemmQuantConfig<QuantMode>::template GemmPipeline<QuantGemmProblem,
112-
GemmConfig::PreshuffleB>;
111+
typename GemmQuantConfig<QuantMode>::template GemmPipeline<QuantGemmProblem,
112+
GemmConfig::PreshuffleB>;
113113

114114
using GemmEpilogue = ck_tile::CShuffleEpilogue<
115115
ck_tile::CShuffleEpilogueProblem<ADataType,
@@ -227,8 +227,9 @@ float grouped_gemm_tileloop(const ck_tile::stream_config& s,
227227
BQuantGroupSize,
228228
GemmConfig::TransposeC>;
229229

230-
using GemmPipeline = GemmQuantConfig<QuantMode>::template GemmPipeline<QuantGemmProblem,
231-
GemmConfig::PreshuffleB>;
230+
using GemmPipeline =
231+
typename GemmQuantConfig<QuantMode>::template GemmPipeline<QuantGemmProblem,
232+
GemmConfig::PreshuffleB>;
232233

233234
using GemmEpilogue = ck_tile::CShuffleEpilogue<
234235
ck_tile::CShuffleEpilogueProblem<ADataType,

include/ck_tile/host/tensor_shuffle_utils.hpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,25 +164,17 @@ auto shuffle_b_permuteN(const ck_tile::HostTensor<T>& t, const GemmConfig& gemmC
164164
}
165165
else
166166
{
167-
int divisor = 1;
168-
if(ck_tile::is_gfx11_supported())
169-
{
170-
divisor = 1;
171-
}
172-
else
173-
{
174-
assert(is_wave32() == false);
175-
divisor = get_warp_size() / gemmConfig.N_Warp_Tile;
176-
}
167+
constexpr int KLane = ck_tile::get_warp_size() / GemmConfig::N_Warp_Tile;
168+
constexpr int ItemsPerAccess =
169+
std::min(16 / static_cast<int>(sizeof(T)), GemmConfig::K_Warp_Tile / KLane);
177170
ck_tile::HostTensor<T> t_view({n_ / gemmConfig.N_Tile,
178171
gemmConfig.N_Warp,
179172
gemmConfig.N_Warp_Tile,
180173
NRepeat,
181-
k_ / gemmConfig.K_Warp_Tile,
182-
divisor,
183-
gemmConfig.K_Warp_Tile / divisor});
174+
k_ / ItemsPerAccess,
175+
ItemsPerAccess});
184176
std::copy(t.begin(), t.end(), t_view.begin());
185-
return ck_tile::reference_permute(t_view, {0, 3, 1, 4, 5, 2, 6});
177+
return ck_tile::reference_permute(t_view, {0, 3, 1, 4, 2, 5});
186178
}
187179
}
188180

include/ck_tile/ops/gemm/pipeline/wp_pipeline_agmem_bgmem_creg_base_policy.hpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -271,20 +271,19 @@ struct UniversalWeightPreshufflePipelineAgBgCrPolicy
271271

272272
constexpr index_t WaveSize = get_warp_size();
273273
constexpr index_t KLane = WarpTile::at(I2) * WarpTile::at(I0) / WaveSize;
274-
using BDataType = typename Problem::BDataType;
275-
constexpr index_t KLaneBytes =
276-
KLane / numeric_traits<BDataType>::PackedSize * sizeof(BDataType);
277-
constexpr auto NumAccess = static_cast<WGAttrNumAccessEnum>(max(1, KLaneBytes / 16));
278-
using WarpGemm = WarpGemmDispatcher<ATypeToUse,
279-
BTypeToUse,
280-
typename Problem::CDataType,
281-
WarpTile::at(I0),
282-
WarpTile::at(I1),
283-
WarpTile::at(I2),
284-
Problem::TransposeC,
285-
false,
286-
false,
287-
NumAccess>;
274+
// When BDataType is pk_int4_t, it is internally converted to fp8 for computation.
275+
constexpr index_t KLaneBytes = KLane * sizeof(BTypeToUse);
276+
constexpr auto NumAccess = static_cast<WGAttrNumAccessEnum>(max(1, KLaneBytes / 16));
277+
using WarpGemm = WarpGemmDispatcher<ATypeToUse,
278+
BTypeToUse,
279+
typename Problem::CDataType,
280+
WarpTile::at(I0),
281+
WarpTile::at(I1),
282+
WarpTile::at(I2),
283+
Problem::TransposeC,
284+
false,
285+
false,
286+
NumAccess>;
288287

289288
using BlockWeightPreshufflePolicy =
290289
BlockWeightPreshuffleASmemBSmemCRegV1CustomPolicy<typename Problem::ADataType,

include/ck_tile/ops/gemm/warp/warp_gemm_dispatcher.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ template<> struct Dispatcher<fp8_t, fp8_t, float, 32, 32, 64, false> { using Ty
131131
template<> struct Dispatcher<fp8_t, bf8_t, float, 32, 32, 64, false> { using Type = WarpGemmMfma_f32_32x32x64_fp8_bf8<>; };
132132
template<> struct Dispatcher<bf8_t, fp8_t, float, 32, 32, 64, false> { using Type = WarpGemmMfma_f32_32x32x64_bf8_fp8<>; };
133133
template<> struct Dispatcher<bf8_t, bf8_t, float, 32, 32, 64, false> { using Type = WarpGemmMfma_f32_32x32x64_bf8_bf8<>; };
134+
template<> struct Dispatcher<fp8_t, fp8_t, float, 32, 32, 64, false, false, false, EDouble> { using Type = WarpGemmMfma_f32_32x32x64_fp8_fp8<EDouble>; };
135+
template<> struct Dispatcher<fp8_t, bf8_t, float, 32, 32, 64, false, false, false, EDouble> { using Type = WarpGemmMfma_f32_32x32x64_fp8_bf8<EDouble>; };
136+
template<> struct Dispatcher<bf8_t, fp8_t, float, 32, 32, 64, false, false, false, EDouble> { using Type = WarpGemmMfma_f32_32x32x64_bf8_fp8<EDouble>; };
137+
template<> struct Dispatcher<bf8_t, bf8_t, float, 32, 32, 64, false, false, false, EDouble> { using Type = WarpGemmMfma_f32_32x32x64_bf8_bf8<EDouble>; };
134138
template<> struct Dispatcher<fp8_t, fp8_t, float, 32, 32, 64, false, false, false, EQuad> { using Type = WarpGemmMfma_f32_32x32x64_fp8_fp8<EQuad>; };
135139
template<> struct Dispatcher<fp8_t, bf8_t, float, 32, 32, 64, false, false, false, EQuad> { using Type = WarpGemmMfma_f32_32x32x64_fp8_bf8<EQuad>; };
136140
template<> struct Dispatcher<bf8_t, fp8_t, float, 32, 32, 64, false, false, false, EQuad> { using Type = WarpGemmMfma_f32_32x32x64_bf8_fp8<EQuad>; };

include/ck_tile/ops/gemm_quant/pipeline/gemm_abquant_pipeline_ag_bg_cr_v3.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ struct ABQuantGemmPipelineAgBgCrCompV3 : public BaseGemmPipelineAgBgCrCompV3<Pro
6565
using BlockGemm = remove_cvref_t<decltype(Policy::template GetBlockGemm<Problem>())>;
6666

6767
// A/B DataType gets converted from PkInt4/PkFp4 during loading
68-
using OverrideADataType = BlockGemm::OverrideADataType;
69-
using OverrideBDataType = BlockGemm::OverrideBDataType;
68+
using OverrideADataType = typename BlockGemm::OverrideADataType;
69+
using OverrideBDataType = typename BlockGemm::OverrideBDataType;
7070

7171
static constexpr index_t BlockSize = Problem::kBlockSize;
7272
static constexpr index_t MPerBlock = BlockGemmShape::kM;

include/ck_tile/ops/gemm_quant/pipeline/gemm_wp_abquant_pipeline_ag_bg_cr_base_policy.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,13 @@ struct GemmWPABQuantPipelineAgBgCrPolicy : public UniversalWeightPreshufflePipel
9797

9898
constexpr index_t WaveSize = get_warp_size();
9999
constexpr index_t KLane = WarpTile::at(I2) * WarpTile::at(I0) / WaveSize;
100-
using BDataType = typename Problem::BDataType;
101-
constexpr index_t KLaneBytes =
102-
KLane / numeric_traits<BDataType>::PackedSize * sizeof(BDataType);
103-
constexpr auto NumAccess = static_cast<WGAttrNumAccessEnum>(max(1, KLaneBytes / 16));
100+
101+
// When BDataType is pk_int4_t, it is internally converted to fp8 for computation.
102+
using BTypeToUse = mixed_prec_compute_type_from_input_t<typename Problem::BDataType,
103+
typename Problem::ADataType,
104+
typename Problem::ComputeDataType>;
105+
constexpr index_t KLaneBytes = KLane * sizeof(BTypeToUse);
106+
constexpr auto NumAccess = static_cast<WGAttrNumAccessEnum>(max(1, KLaneBytes / 16));
104107

105108
using WarpGemm = WarpGemmDispatcher<typename Problem::ComputeDataType,
106109
typename Problem::ComputeDataType,

test/ck_tile/gemm_weight_preshuffle/test_gemm_pipeline_util.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,22 @@ struct config
8383
static constexpr ck_tile::index_t M_Warp = 1;
8484
static constexpr ck_tile::index_t N_Warp = 4;
8585
static constexpr ck_tile::index_t K_Warp = 1;
86+
};
8687

88+
template <typename Datatype>
89+
struct config_mn_32x32 : public config<Datatype>
90+
{
8791
static constexpr ck_tile::index_t M_Warp_Tile = 32;
8892
static constexpr ck_tile::index_t N_Warp_Tile = 32;
89-
static constexpr ck_tile::index_t K_Warp_Tile = sizeof(Datatype) == 2 ? 16 : 32;
93+
static constexpr ck_tile::index_t K_Warp_Tile = get_k_warp_tile<Datatype, M_Warp_Tile>();
94+
};
95+
96+
template <typename Datatype>
97+
struct config_mn_16x16 : public config<Datatype>
98+
{
99+
static constexpr ck_tile::index_t M_Warp_Tile = 16;
100+
static constexpr ck_tile::index_t N_Warp_Tile = 16;
101+
static constexpr ck_tile::index_t K_Warp_Tile = get_k_warp_tile<Datatype, M_Warp_Tile>();
90102
};
91103

92104
template <typename Datatype>
@@ -252,7 +264,9 @@ class TestCkTileGemmPipeline : public ::testing::Test
252264
RunSingle<config_wmma<ADataType>, PadM, PadN, PadK, Preshuffle>(
253265
M, N, K, StrideA, StrideB, StrideC, kb);
254266
#else
255-
RunSingle<config<ADataType>, PadM, PadN, PadK, Preshuffle>(
267+
RunSingle<config_mn_16x16<ADataType>, PadM, PadN, PadK, Preshuffle>(
268+
M, N, K, StrideA, StrideB, StrideC, kb);
269+
RunSingle<config_mn_32x32<ADataType>, PadM, PadN, PadK, Preshuffle>(
256270
M, N, K, StrideA, StrideB, StrideC, kb);
257271
#endif
258272
}

0 commit comments

Comments
 (0)