已合并
qbmm mxA8W4 supports k % 8 == 0 #5439
yuanshuai000创建于 5月29日
qbmm mxA8W4 supports k % 8 == 0 #5439
已合并
共 15 个文件变更+198-138
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | namespace Cmct::Gemm::Block { | 31 | namespace Cmct::Gemm::Block { |
| 32 | using AscendC::BLOCK_CUBE; | 32 | using AscendC::BLOCK_CUBE; |
| 33 | +using AscendC::ONE_BLK_SIZE; | ||
| 33 | using AscendC::CrossCoreSetFlag; | 34 | using AscendC::CrossCoreSetFlag; |
| 34 | using AscendC::CrossCoreWaitFlag; | 35 | using AscendC::CrossCoreWaitFlag; |
| 35 | using AscendC::GlobalTensor; | 36 | using AscendC::GlobalTensor; |
| @@ -317,7 +318,7 @@ private: | |||
| 317 | WaitFlag<HardEvent::MTE1_MTE2>(eventIdsScaleBMte1ToMte2_[scaleBBufIdx_]); | 318 | WaitFlag<HardEvent::MTE1_MTE2>(eventIdsScaleBMte1ToMte2_[scaleBBufIdx_]); |
| 318 | CopyScaleB2L1(tensorBlockScaleB); | 319 | CopyScaleB2L1(tensorBlockScaleB); |
| 319 | } | 320 | } |
| 320 | - if (kL1Len_ % K_ALIGN_SIZE != 0) { | 321 | + if (CeilAlign(kL1Len_, ONE_BLK_SIZE) % K_ALIGN_SIZE != 0) { |
| 321 | LocalTensor<ElementA> bL1Tensor; | 322 | LocalTensor<ElementA> bL1Tensor; |
| 322 | if (l1BufIdx_ == IDX_0) { | 323 | if (l1BufIdx_ == IDX_0) { |
| 323 | bL1Tensor = bL1LocalBuf0_; | 324 | bL1Tensor = bL1LocalBuf0_; |
| @@ -328,7 +329,8 @@ private: | |||
| 328 | } else { | 329 | } else { |
| 329 | bL1Tensor = bL1LocalBuf3_; | 330 | bL1Tensor = bL1LocalBuf3_; |
| 330 | } | 331 | } |
| 331 | - FillL1WithZero(bL1Tensor[CeilAlign(nL1Len_, BLOCK_CUBE) * kL1Len_].template ReinterpretCast<uint32_t>(), nL1Len_); | 332 | + uint64_t offset = CeilAlign(nL1Len_, BLOCK_CUBE) * CeilAlign(kL1Len_, ONE_BLK_SIZE); |
| 333 | + FillL1WithZero(bL1Tensor[offset].template ReinterpretCast<uint32_t>(), nL1Len_); | ||
| 332 | } | 334 | } |
| 333 | WaitForVector(l1BufIdx_); | 335 | WaitForVector(l1BufIdx_); |
| 334 | } | 336 | } |
| @@ -590,8 +592,9 @@ private: | |||
| 590 | } | 592 | } |
| 591 | DataCopy(aL1LocalBuf, srcTensor, nd2nzParams); | 593 | DataCopy(aL1LocalBuf, srcTensor, nd2nzParams); |
| 592 | 594 | ||
| 593 | - if (kL1Len_ % K_ALIGN_SIZE != 0) { | 595 | + if (CeilAlign(kL1Len_, ONE_BLK_SIZE) % K_ALIGN_SIZE != 0) { |
| 594 | - FillL1WithZero(aL1LocalBuf[CeilAlign(mL1Len_, BLOCK_CUBE) * kL1Len_].template ReinterpretCast<uint32_t>(), mL1Len_); | 596 | + uint64_t offset = CeilAlign(mL1Len_, BLOCK_CUBE) * CeilAlign(kL1Len_, ONE_BLK_SIZE); |
| 597 | + FillL1WithZero(aL1LocalBuf[offset].template ReinterpretCast<uint32_t>(), mL1Len_); | ||
| 595 | } | 598 | } |
| 596 | } | 599 | } |
| 597 | 600 | ||
| @@ -376,7 +376,7 @@ private: | |||
| 376 | if constexpr (weightNz) { | 376 | if constexpr (weightNz) { |
| 377 | int64_t nAlignSize = CeilAlign(nSize_, static_cast<uint64_t>(BLOCK_CUBE)); | 377 | int64_t nAlignSize = CeilAlign(nSize_, static_cast<uint64_t>(BLOCK_CUBE)); |
| 378 | int64_t nUbAlignSize = CeilAlign(nUbLen_, BLOCK_CUBE); | 378 | int64_t nUbAlignSize = CeilAlign(nUbLen_, BLOCK_CUBE); |
| 379 | - intriParams.blockCount = kUbLen_ / C0_SIZE_B8; | 379 | + intriParams.blockCount = CeilDiv(kUbLen_, C0_SIZE_B8); |
| 380 | intriParams.blockLen = nUbAlignSize * C0_SIZE_B8; | 380 | intriParams.blockLen = nUbAlignSize * C0_SIZE_B8; |
| 381 | intriParams.srcStride = (nAlignSize - nUbAlignSize) * C0_SIZE_B8; | 381 | intriParams.srcStride = (nAlignSize - nUbAlignSize) * C0_SIZE_B8; |
| 382 | } else { | 382 | } else { |
| @@ -422,7 +422,9 @@ private: | |||
| 422 | AscendC::DataCopyParams params; | 422 | AscendC::DataCopyParams params; |
| 423 | if constexpr (weightNz) { | 423 | if constexpr (weightNz) { |
| 424 | params.blockLen = BLOCK_NUM_REG; | 424 | params.blockLen = BLOCK_NUM_REG; |
| 425 | - params.blockCount = CeilAlign(nUbLen_, BLOCK_CUBE) * kUbLen_ * sizeof(ElementOut) / VECTOR_REG_WIDTH; | 425 | + params.blockCount = CeilAlign(nUbLen_, BLOCK_CUBE) * |
| 426 | + CeilAlign(kUbLen_, static_cast<int32_t>(ONE_BLK_SIZE)) * | ||
| 427 | + sizeof(ElementOut) / VECTOR_REG_WIDTH; | ||
| 426 | params.srcStride = (l1BufNum_ - 1) * BLOCK_NUM_REG; | 428 | params.srcStride = (l1BufNum_ - 1) * BLOCK_NUM_REG; |
| 427 | params.dstStride = 0; | 429 | params.dstStride = 0; |
| 428 | DataCopy(l1Local_[l1Offset], ubLocal, params); | 430 | DataCopy(l1Local_[l1Offset], ubLocal, params); |
| @@ -466,11 +468,12 @@ private: | |||
| 466 | wParams.dataBlockStride = CeilAlign(nUbLen_, BLOCK_CUBE) + 1; | 468 | wParams.dataBlockStride = CeilAlign(nUbLen_, BLOCK_CUBE) + 1; |
| 467 | wParams.repeatStride = wParams.dataBlockStride * BLOCK_CUBE; | 469 | wParams.repeatStride = wParams.dataBlockStride * BLOCK_CUBE; |
| 468 | wParams.outDimOffset = ONE_BLOCK_SIZE - wParams.innerExtend * wParams.repeatStride * ONE_BLOCK_SIZE; | 470 | wParams.outDimOffset = ONE_BLOCK_SIZE - wParams.innerExtend * wParams.repeatStride * ONE_BLOCK_SIZE; |
| 469 | - wParams.maskB8Tail0 = Min(kUbLen_ % VECTOR_REG_WIDTH_FOR_4BITS, static_cast<int32_t>(VECTOR_REG_WIDTH)) + | 471 | + int32_t kUbLenAlign = CeilAlign(kUbLen_, static_cast<int32_t>(ONE_BLOCK_SIZE)); |
| 470 | - kUbLen_ / VECTOR_REG_WIDTH_FOR_4BITS * VECTOR_REG_WIDTH; | 472 | + wParams.maskB8Tail0 = Min(kUbLenAlign % VECTOR_REG_WIDTH_FOR_4BITS, static_cast<int32_t>(VECTOR_REG_WIDTH)) + |
| 473 | + kUbLenAlign / VECTOR_REG_WIDTH_FOR_4BITS * VECTOR_REG_WIDTH; | ||
| 471 | wParams.maskB8Tail1 = | 474 | wParams.maskB8Tail1 = |
| 472 | - Cmct::Gemm::Max(kUbLen_ % VECTOR_REG_WIDTH_FOR_4BITS - static_cast<int32_t>(VECTOR_REG_WIDTH), 0) + | 475 | + Cmct::Gemm::Max(kUbLenAlign % VECTOR_REG_WIDTH_FOR_4BITS - static_cast<int32_t>(VECTOR_REG_WIDTH), 0) + |
| 473 | - kUbLen_ / VECTOR_REG_WIDTH_FOR_4BITS * VECTOR_REG_WIDTH; | 476 | + kUbLenAlign / VECTOR_REG_WIDTH_FOR_4BITS * VECTOR_REG_WIDTH; |
| 474 | wParams.weightInUbBaseAddr = weightInUbBaseAddr_; | 477 | wParams.weightInUbBaseAddr = weightInUbBaseAddr_; |
| 475 | wParams.weightOutUbAddr = weightOutUbAddr_; | 478 | wParams.weightOutUbAddr = weightOutUbAddr_; |
| 476 | wParams.weightOutUbAddr1 = weightOutUbAddr1_; | 479 | wParams.weightOutUbAddr1 = weightOutUbAddr1_; |
| @@ -579,13 +579,14 @@ aclnnStatus aclnnQuantMatmulWeightNz( | |||
| 579 | 579 | ||
| 580 | |量化类型|x1 dtype |x2 dtype | x1Scale dtype |x2Scale dtype |bias dtype| yScale dtype | out dtype | x1 shape | x2 shape| x1Scale shape | x2Scale shape |bias shape | yScale shape| [groupSizeM, groupSizeN, groupSizeK]| | 580 | |量化类型|x1 dtype |x2 dtype | x1Scale dtype |x2Scale dtype |bias dtype| yScale dtype | out dtype | x1 shape | x2 shape| x1Scale shape | x2Scale shape |bias shape | yScale shape| [groupSizeM, groupSizeN, groupSizeK]| |
| 581 | |---------------| ------------| -------------- |--------------|-------------|--------- | -------- |--------| ---------- | --------------| ------------ |---------- | ------------| ---------------------------------------|-------| | 581 | |---------------| ------------| -------------- |--------------|-------------|--------- | -------- |--------| ---------- | --------------| ------------ |---------- | ------------| ---------------------------------------|-------| |
| 582 | - | mx量化 |FLOAT8_E4M3FN |FLOAT4_E2M1 |FLOAT8_E8M0 |FLOAT8_E8M0 |null/BFLOAT16/FLOAT16| null |BFLOAT16/FLOAT16|(m, k) |(n, k) |(m, k/64, 2) |(n, k/64, 2) |(1, n) | null | [0, 0, 32] / [1, 1, 32] | | 582 | + | mx量化 |FLOAT8_E4M3FN |FLOAT4_E2M1 |FLOAT8_E8M0 |FLOAT8_E8M0 |null/BFLOAT16/FLOAT16| null |BFLOAT16/FLOAT16|(m, k) |(n, k) |(m, ceil(k/64), 2) |(n, ceil(k/64), 2) |(1, n) | null | [0, 0, 32] / [1, 1, 32] | |
| 583 | - | mx量化 |FLOAT8_E4M3FN |FLOAT32 |FLOAT8_E8M0 |FLOAT8_E8M0 |null/BFLOAT16/FLOAT16| null |BFLOAT16/FLOAT16|(m, k) |(n, k/8)|(m, k/64, 2) |(n, k/64, 2) |(1, n) | null | [0, 0, 32] / [1, 1, 32] | | 583 | + | mx量化 |FLOAT8_E4M3FN |FLOAT32 |FLOAT8_E8M0 |FLOAT8_E8M0 |null/BFLOAT16/FLOAT16| null |BFLOAT16/FLOAT16|(m, k) |(n, k/8)|(m, ceil(k/64), 2) |(n, ceil(k/64), 2) |(1, n) | null | [0, 0, 32] / [1, 1, 32] | |
| 584 | | T-CG量化 |FLOAT8_E4M3FN |FLOAT4_E2M1 |null |BFLOAT16/FLOAT16 |null| uint64/int64 |BFLOAT16/FLOAT16|(m, k) |(k, n) |null |(k/32, n) |null |(1, n) | [0, 0, 32] / [1, 1, 32] | | 584 | | T-CG量化 |FLOAT8_E4M3FN |FLOAT4_E2M1 |null |BFLOAT16/FLOAT16 |null| uint64/int64 |BFLOAT16/FLOAT16|(m, k) |(k, n) |null |(k/32, n) |null |(1, n) | [0, 0, 32] / [1, 1, 32] | |
| 585 | | T-CG量化 |FLOAT8_E4M3FN |FLOAT32 |null |BFLOAT16/FLOAT16 |null| uint64/int64 |BFLOAT16/FLOAT16|(m, k) |(k, n/8)|null |(k/32, n) |null |(1, n) | [0, 0, 32] / [1, 1, 32] | | 585 | | T-CG量化 |FLOAT8_E4M3FN |FLOAT32 |null |BFLOAT16/FLOAT16 |null| uint64/int64 |BFLOAT16/FLOAT16|(m, k) |(k, n/8)|null |(k/32, n) |null |(1, n) | [0, 0, 32] / [1, 1, 32] | |
| 586 | 586 | ||
| 587 | - 约束说明: | 587 | - 约束说明: |
| 588 | - - k要求32对齐, n要求8对齐。MX量化模式下k要求大于32,n大于等于8;T-CG量化模式下k要求大于等于64,n的要求大于等于8。 | 588 | + - MX量化模式下, k要求8对齐, n要求8对齐。 |
| 589 | + - T-CG量化模式下,k要求32对齐且大于等于64,n要求8对齐。 | ||
| 589 | - x1是FLOAT8_E4M3FN,x2是FLOAT32时, x2表示一个FLOAT32存储8个FLOAT4_E2M1的紧密排布的数据格式。 | 590 | - x1是FLOAT8_E4M3FN,x2是FLOAT32时, x2表示一个FLOAT32存储8个FLOAT4_E2M1的紧密排布的数据格式。 |
| 590 | - MX量化模式下,bias数据类型与out数据类型需要一致;T-CG量化模式下,x2Scale的数据类型和out的数据类型需要一致。 | 591 | - MX量化模式下,bias数据类型与out数据类型需要一致;T-CG量化模式下,x2Scale的数据类型和out的数据类型需要一致。 |
| 591 | 592 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -85,7 +85,8 @@ static constexpr int64_t M_RANGE1_RIGHT = 512; | |||
| 85 | static constexpr int32_t CORE_NUM_20 = 20; | 85 | static constexpr int32_t CORE_NUM_20 = 20; |
| 86 | static constexpr int64_t SUPPORTED_GROUP_SIZE = 32; | 86 | static constexpr int64_t SUPPORTED_GROUP_SIZE = 32; |
| 87 | static constexpr uint64_t B4_PER_B32 = 8UL; | 87 | static constexpr uint64_t B4_PER_B32 = 8UL; |
| 88 | -static constexpr int64_t SUPPORTED_K_ALIGN_NUM = 32; | 88 | +static constexpr int64_t SUPPORTED_TCG_A8W4_K_ALIGN_NUM = 32; |
| 89 | +static constexpr int64_t SUPPORTED_MX_A8W4_K_ALIGN_NUM = 8; | ||
| 89 | static constexpr int64_t SUPPORTED_N_ALIGN_NUM = 8; | 90 | static constexpr int64_t SUPPORTED_N_ALIGN_NUM = 8; |
| 90 | static constexpr size_t MAX_DIM_VALUE = 2; | 91 | static constexpr size_t MAX_DIM_VALUE = 2; |
| 91 | static constexpr size_t MX_SCALE_DIM_VALUE = 3; | 92 | static constexpr size_t MX_SCALE_DIM_VALUE = 3; |
| @@ -640,8 +641,7 @@ static inline bool CheckDimValue(const aclTensor *scale, const aclTensor *offset | |||
| 640 | if (offset != nullptr) { | 641 | if (offset != nullptr) { |
| 641 | OP_CHECK_WRONG_DIMENSION(offset, 1, return false); | 642 | OP_CHECK_WRONG_DIMENSION(offset, 1, return false); |
| 642 | if (offset->GetViewShape().GetDim(0) != x2NDim && offset->GetViewShape().GetDim(0) != 1) { | 643 | if (offset->GetViewShape().GetDim(0) != x2NDim && offset->GetViewShape().GetDim(0) != 1) { |
| 643 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, | 644 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Offset 1st dim should equal to x2 n dim %ld or 1, but actual is %ld.", |
| 644 | - "Offset 1st dim should equal to x2 n dim %ld or 1, but actual is %ld.", | ||
| 645 | x2NDim, offset->GetViewShape().GetDim(0)); | 645 | x2NDim, offset->GetViewShape().GetDim(0)); |
| 646 | return false; | 646 | return false; |
| 647 | } | 647 | } |
| @@ -948,8 +948,7 @@ static inline bool CheckA8W4ScaleX1Shape( | |||
| 948 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1Scale", | 948 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1Scale", |
| 949 | FormatString("%ld, %ld, %ld", x1Scale->GetViewShape().GetDim(0), | 949 | FormatString("%ld, %ld, %ld", x1Scale->GetViewShape().GetDim(0), |
| 950 | x1Scale->GetViewShape().GetDim(1), x1Scale->GetViewShape().GetDim(2)).c_str(), | 950 | x1Scale->GetViewShape().GetDim(1), x1Scale->GetViewShape().GetDim(2)).c_str(), |
| 951 | - FormatString("the shape of x1Scale must be [%ld, %ld, 2]", groupDimM, | 951 | + FormatString("the shape of x1Scale must be [%ld, %ld, 2]", groupDimM, CeilDiv(groupDimK, 2L)).c_str()); |
| 952 | - CeilDiv(groupDimK, 2L)).c_str()); | ||
| 953 | return false; | 952 | return false; |
| 954 | } | 953 | } |
| 955 | } | 954 | } |
| @@ -971,8 +970,7 @@ static inline bool CheckA8W4ScaleX2Shape( | |||
| 971 | x2Scale->GetViewShape().GetDim(2) != 2) { | 970 | x2Scale->GetViewShape().GetDim(2) != 2) { |
| 972 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 971 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 973 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x2Scale", | 972 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x2Scale", |
| 974 | - FormatString("%ld, %ld, %ld", x2ScaleNDim, x2ScaleGroupDim, | 973 | + FormatString("%ld, %ld, %ld", x2ScaleNDim, x2ScaleGroupDim, x2Scale->GetViewShape().GetDim(2)).c_str(), |
| 975 | - x2Scale->GetViewShape().GetDim(2)).c_str(), | ||
| 976 | FormatString("the shape of x2Scale must be [%ld, %ld, 2]", groupDimN, | 974 | FormatString("the shape of x2Scale must be [%ld, %ld, 2]", groupDimN, |
| 977 | CeilDiv(groupDimK, x2ScaleReshapeFactor)).c_str()); | 975 | CeilDiv(groupDimK, x2ScaleReshapeFactor)).c_str()); |
| 978 | return false; | 976 | return false; |
| @@ -1014,8 +1012,7 @@ static inline bool CheckA8W4OutAndBiasShape(const TupleOptional& optionalTensors | |||
| 1014 | if (yScale->GetViewShape().GetDim(1) != x2NDim || yScale->GetViewShape().GetDim(0) != 1) { | 1012 | if (yScale->GetViewShape().GetDim(1) != x2NDim || yScale->GetViewShape().GetDim(0) != 1) { |
| 1015 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 1013 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 1016 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "yScale", | 1014 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "yScale", |
| 1017 | - FormatString("%ld, %ld", yScale->GetViewShape().GetDim(0), yScale->GetViewShape().GetDim(1)) | 1015 | + FormatString("%ld, %ld", yScale->GetViewShape().GetDim(0), yScale->GetViewShape().GetDim(1)).c_str(), |
| 1018 | - .c_str(), | ||
| 1019 | FormatString("the shape of yScale must be [1, %ld]", x2NDim).c_str()); | 1016 | FormatString("the shape of yScale must be [1, %ld]", x2NDim).c_str()); |
| 1020 | return false; | 1017 | return false; |
| 1021 | } | 1018 | } |
| @@ -1023,7 +1020,7 @@ static inline bool CheckA8W4OutAndBiasShape(const TupleOptional& optionalTensors | |||
| 1023 | return true; | 1020 | return true; |
| 1024 | } | 1021 | } |
| 1025 | 1022 | ||
| 1026 | -static inline bool CheckA8W4X1X2Shape(int64_t x1KDim, int64_t x2KDim, int64_t x2NDim) { | 1023 | +static inline bool CheckA8W4X1X2Shape(int64_t x1KDim, int64_t x2KDim, int64_t x2NDim, bool isMx) { |
| 1027 | // CHECK x1KDim | 1024 | // CHECK x1KDim |
| 1028 | if (x1KDim <= 0) { | 1025 | if (x1KDim <= 0) { |
| 1029 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( | 1026 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( |
| @@ -1037,19 +1034,24 @@ static inline bool CheckA8W4X1X2Shape(int64_t x1KDim, int64_t x2KDim, int64_t x2 | |||
| 1037 | "the n dimension of x2 must be greater than 0"); | 1034 | "the n dimension of x2 must be greater than 0"); |
| 1038 | return false; | 1035 | return false; |
| 1039 | } | 1036 | } |
| 1040 | - | ||
| 1041 | if (x1KDim != x2KDim) { | 1037 | if (x1KDim != x2KDim) { |
| 1042 | OP_LOGE_FOR_INVALID_VALUES_WITH_REASON( | 1038 | OP_LOGE_FOR_INVALID_VALUES_WITH_REASON( |
| 1043 | - "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1 K, x2 K", | 1039 | + "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1 K, x2 K", FormatString("%ld, %ld", x1KDim, x2KDim).c_str(), |
| 1044 | - FormatString("%ld, %ld", x1KDim, x2KDim).c_str(), | ||
| 1045 | "the k dimension of x1 and x2 must be equal"); | 1040 | "the k dimension of x1 and x2 must be equal"); |
| 1046 | return false; | 1041 | return false; |
| 1047 | } | 1042 | } |
| 1048 | - if (x1KDim % SUPPORTED_K_ALIGN_NUM != 0 || x1KDim <= SUPPORTED_K_ALIGN_NUM) { | 1043 | + if (isMx && (x1KDim % SUPPORTED_MX_A8W4_K_ALIGN_NUM != 0)) { // Mx量化k方向8对齐 |
| 1044 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( | ||
| 1045 | + "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1", std::to_string(x1KDim).c_str(), | ||
| 1046 | + FormatString("the k dimension of x1 must be aligned to %ld for MX quantization", | ||
| 1047 | + SUPPORTED_MX_A8W4_K_ALIGN_NUM).c_str()); | ||
| 1048 | + return false; | ||
| 1049 | + } | ||
| 1050 | + if (!isMx && (x1KDim % SUPPORTED_TCG_A8W4_K_ALIGN_NUM != 0 || x1KDim <= SUPPORTED_TCG_A8W4_K_ALIGN_NUM)) { | ||
| 1049 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( | 1051 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( |
| 1050 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1", std::to_string(x1KDim).c_str(), | 1052 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1", std::to_string(x1KDim).c_str(), |
| 1051 | FormatString("the k dimension of x1 must be aligned to %ld and greater than %ld", | 1053 | FormatString("the k dimension of x1 must be aligned to %ld and greater than %ld", |
| 1052 | - SUPPORTED_K_ALIGN_NUM, SUPPORTED_K_ALIGN_NUM).c_str()); | 1054 | + SUPPORTED_TCG_A8W4_K_ALIGN_NUM, SUPPORTED_TCG_A8W4_K_ALIGN_NUM).c_str()); |
| 1053 | return false; | 1055 | return false; |
| 1054 | } | 1056 | } |
| 1055 | if (x2NDim % SUPPORTED_N_ALIGN_NUM != 0) { | 1057 | if (x2NDim % SUPPORTED_N_ALIGN_NUM != 0) { |
| @@ -1084,7 +1086,9 @@ static inline bool CheckA8W4Shape(const TupleTensor &mandatoryTensors, const Tup | |||
| 1084 | "the m dimension of x1 must be greater than 0"); | 1086 | "the m dimension of x1 must be greater than 0"); |
| 1085 | return false; | 1087 | return false; |
| 1086 | } | 1088 | } |
| 1087 | - CHECK_RET(CheckA8W4X1X2Shape(x1KDim, x2KDim, x2NDim), false); | 1089 | + auto x1Scale = std::get<INDEX_PERTOKEN_IN_OPTIONAL_TUPLE>(optionalTensors); |
| 1090 | + auto x2Scale = std::get<INDEX_SCALE_IN_MANDTORY_TUPLE>(mandatoryTensors); | ||
| 1091 | + CHECK_RET(CheckA8W4X1X2Shape(x1KDim, x2KDim, x2NDim, IsMicroScaling(x1Scale, x2Scale)), false); | ||
| 1088 | int64_t groupDimK = (x2KDim + SUPPORTED_GROUP_SIZE - 1) / SUPPORTED_GROUP_SIZE; | 1092 | int64_t groupDimK = (x2KDim + SUPPORTED_GROUP_SIZE - 1) / SUPPORTED_GROUP_SIZE; |
| 1089 | int64_t groupDimM = x1MDim; | 1093 | int64_t groupDimM = x1MDim; |
| 1090 | int64_t groupDimN = x2NDim; | 1094 | int64_t groupDimN = x2NDim; |
| @@ -1497,8 +1501,8 @@ static inline bool CheckInputAttrExistence(const TupleAttr &boolsTrans, const Tu | |||
| 1497 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "transposeX2", transposeX2 ? "true" : "false", | 1501 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "transposeX2", transposeX2 ? "true" : "false", |
| 1498 | "in A8W4 scenario with NZ format, when the quant mode is t-cg, transposeX2 must be false"); | 1502 | "in A8W4 scenario with NZ format, when the quant mode is t-cg, transposeX2 must be false"); |
| 1499 | return false; | 1503 | return false; |
| 1500 | - } else if (IsMicroScaling(x1Scale, x2Scale) && !transposeX2) { | 1504 | + } else if (IsMicroScaling(x1Scale, x2Scale) && !transposeX2) { |
| 1501 | - // A8W4 scenario with mx quant mode | 1505 | + // A8W4 scenario with mx quant mode |
| 1502 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( | 1506 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON( |
| 1503 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "transposeX2", transposeX2 ? "true" : "false", | 1507 | "aclnnQuantMatmulWeightNzGetWorkspaceSize", "transposeX2", transposeX2 ? "true" : "false", |
| 1504 | "in A8W4 scenario with NZ format, when the quant mode is mx, transposeX2 must be true"); | 1508 | "in A8W4 scenario with NZ format, when the quant mode is mx, transposeX2 must be true"); |
| @@ -1521,31 +1525,23 @@ static inline bool CheckDimRangeA8W4(const TupleTensor& mandatoryTensors, const | |||
| 1521 | auto bias = std::get<INDEX_BIAS_IN_OPTIONAL_TUPLE>(optionalTensors); | 1525 | auto bias = std::get<INDEX_BIAS_IN_OPTIONAL_TUPLE>(optionalTensors); |
| 1522 | 1526 | ||
| 1523 | if (x1->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { | 1527 | if (x1->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { |
| 1524 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | 1528 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON("aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1", |
| 1525 | - "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x1", | 1529 | + FormatString("%zuD", x1->GetViewShape().GetDimNum()).c_str(), "the shape dim of x1 must be 2"); |
| 1526 | - FormatString("%zuD", x1->GetViewShape().GetDimNum()).c_str(), | ||
| 1527 | - "the shape dim of x1 must be 2"); | ||
| 1528 | return false; | 1530 | return false; |
| 1529 | } | 1531 | } |
| 1530 | if (x2->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { | 1532 | if (x2->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { |
| 1531 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | 1533 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON("aclnnQuantMatmulWeightNzGetWorkspaceSize", "x2", |
| 1532 | - "aclnnQuantMatmulWeightNzGetWorkspaceSize", "x2", | 1534 | + FormatString("%zuD", x2->GetViewShape().GetDimNum()).c_str(), "the shape dim of x2 must be 2"); |
| 1533 | - FormatString("%zuD", x2->GetViewShape().GetDimNum()).c_str(), | ||
| 1534 | - "the shape dim of x2 must be 2"); | ||
| 1535 | return false; | 1535 | return false; |
| 1536 | } | 1536 | } |
| 1537 | if (bias != nullptr && bias->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { | 1537 | if (bias != nullptr && bias->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { |
| 1538 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | 1538 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON("aclnnQuantMatmulWeightNzGetWorkspaceSize", "bias", |
| 1539 | - "aclnnQuantMatmulWeightNzGetWorkspaceSize", "bias", | 1539 | + FormatString("%zuD", bias->GetViewShape().GetDimNum()).c_str(), "the shape dim of bias must be 2"); |
| 1540 | - FormatString("%zuD", bias->GetViewShape().GetDimNum()).c_str(), | ||
| 1541 | - "the shape dim of bias must be 2"); | ||
| 1542 | return false; | 1540 | return false; |
| 1543 | } | 1541 | } |
| 1544 | if (out->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { | 1542 | if (out->GetViewShape().GetDimNum() != MAX_DIM_VALUE) { |
| 1545 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | 1543 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON("aclnnQuantMatmulWeightNzGetWorkspaceSize", "out", |
| 1546 | - "aclnnQuantMatmulWeightNzGetWorkspaceSize", "out", | 1544 | + FormatString("%zuD", out->GetViewShape().GetDimNum()).c_str(), "the shape dim of out must be 2"); |
| 1547 | - FormatString("%zuD", out->GetViewShape().GetDimNum()).c_str(), | ||
| 1548 | - "the shape dim of out must be 2"); | ||
| 1549 | return false; | 1545 | return false; |
| 1550 | } | 1546 | } |
| 1551 | OP_LOGD("QuantMatmul check dimension range success."); | 1547 | OP_LOGD("QuantMatmul check dimension range success."); |
| @@ -902,7 +902,7 @@ aclnnStatus aclnnQuantMatmulV5( | |||
| 902 | - 注:上表中gsM、gsK和gsN分别表示groupSizeM、groupSizeK和groupSizeN。gsM、gsK和gsN为0的维度会自动推导,上表中是不用自动推导的情况。 | 902 | - 注:上表中gsM、gsK和gsN分别表示groupSizeM、groupSizeK和groupSizeN。gsM、gsK和gsN为0的维度会自动推导,上表中是不用自动推导的情况。 |
| 903 | - mx全量化场景下,当x2数据类型为FLOAT8_E4M3FN/FLOAT8_E5M2时,x1和x1Scale的转置属性需要保持一致,x2和x2Scale的转置属性需要保持一致。 | 903 | - mx全量化场景下,当x2数据类型为FLOAT8_E4M3FN/FLOAT8_E5M2时,x1和x1Scale的转置属性需要保持一致,x2和x2Scale的转置属性需要保持一致。 |
| 904 | - mx全量化场景下,当x2数据类型为FLOAT4_E2M1时,x1和x2的内轴必须为偶数,且k必须大于2。 | 904 | - mx全量化场景下,当x2数据类型为FLOAT4_E2M1时,x1和x2的内轴必须为偶数,且k必须大于2。 |
| 905 | - - mx伪量化场景下,当x2数据类型为FLOAT4_E2M1时,transposeX1为false且transposeX2为true,不支持batch轴。数据格式支持ND格式。要求支持k是32的倍数。 | 905 | + - mx伪量化场景下,当x2数据类型为FLOAT4_E2M1时,transposeX1为false且transposeX2为true,不支持batch轴。数据格式支持ND格式。要求支持k是8的倍数。 |
| 906 | - mx伪量化场景下,bias为可选参数。数据类型支持BFLOAT16或FLOAT16,数据类型要求与输出类型保持一致。数据格式支持ND,shape支持2维,shape表示(1,n)。如不需要使用该参数,传入nullptr。 | 906 | - mx伪量化场景下,bias为可选参数。数据类型支持BFLOAT16或FLOAT16,数据类型要求与输出类型保持一致。数据格式支持ND,shape支持2维,shape表示(1,n)。如不需要使用该参数,传入nullptr。 |
| 907 | 907 | ||
| 908 | </details> | 908 | </details> |
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -46,7 +46,8 @@ static const int64_t SUPPORTED_GROUP_SIZE = 32; | |||
| 46 | static const int64_t MAX_SHAPE_SIZE_A8W4_INT = 29576; | 46 | static const int64_t MAX_SHAPE_SIZE_A8W4_INT = 29576; |
| 47 | static const int64_t SUPPORTED_GROUP_SIZE_A8W4_INT = 256; | 47 | static const int64_t SUPPORTED_GROUP_SIZE_A8W4_INT = 256; |
| 48 | static const int64_t SUPPORTED_K_ALIGN_NUM = 64; | 48 | static const int64_t SUPPORTED_K_ALIGN_NUM = 64; |
| 49 | -static const int64_t SUPPORTED_A8W4_K_ALIGN_NUM = 32; | 49 | +static const int64_t SUPPORTED_TCG_A8W4_K_ALIGN_NUM = 32; |
| 50 | +static const int64_t SUPPORTED_MX_A8W4_K_ALIGN_NUM = 8; | ||
| 50 | static const int64_t SUPPORTED_N_ALIGN_NUM = 8; | 51 | static const int64_t SUPPORTED_N_ALIGN_NUM = 8; |
| 51 | static const uint64_t GROUP_M_OFFSET = 32; | 52 | static const uint64_t GROUP_M_OFFSET = 32; |
| 52 | static const uint64_t GROUP_N_OFFSET = 16; | 53 | static const uint64_t GROUP_N_OFFSET = 16; |
| @@ -591,18 +592,44 @@ static inline bool CheckOutAndOffsetShape(const TupleQuant& quantTensors, int64_ | |||
| 591 | return true; | 592 | return true; |
| 592 | } | 593 | } |
| 593 | 594 | ||
| 594 | -static inline bool CheckKDimAndBasicShape( | 595 | +static inline bool CheckA8W4KDim(const TupleInput& inputTensors, const TupleQuant& quantTensors, int64_t kDim) |
| 595 | - const TupleInput& inputTensors, const TupleQuant& quantTensors, int64_t x1KDim, int64_t x2KDim, int64_t x2NDim) | ||
| 596 | { | 596 | { |
| 597 | auto x1 = std::get<INDEX_X1_IN_INPUT_TUPLE>(inputTensors); | 597 | auto x1 = std::get<INDEX_X1_IN_INPUT_TUPLE>(inputTensors); |
| 598 | auto x2 = std::get<INDEX_X2_IN_INPUT_TUPLE>(inputTensors); | 598 | auto x2 = std::get<INDEX_X2_IN_INPUT_TUPLE>(inputTensors); |
| 599 | auto x1Scale = std::get<INDEX_X1_SCALE_IN_QUANT_TUPLE>(quantTensors); | 599 | auto x1Scale = std::get<INDEX_X1_SCALE_IN_QUANT_TUPLE>(quantTensors); |
| 600 | auto x2Scale = std::get<INDEX_X2_SCALE_IN_QUANT_TUPLE>(quantTensors); | 600 | auto x2Scale = std::get<INDEX_X2_SCALE_IN_QUANT_TUPLE>(quantTensors); |
| 601 | - bool isPerChannel = x2Scale->GetViewShape().GetDimNum() == 1; | 601 | + if (isA8W4IntAfterPre(x1, x2)) { |
| 602 | - bool isA8W4INT = isA8W4IntAfterPre(x1, x2); | 602 | + bool isPerChannel = x2Scale->GetViewShape().GetDimNum() == 1; |
| 603 | - bool isA8W4TCG = isA8W4FloatTCG(x1, x2, x1Scale); | 603 | + size_t kAlign = isPerChannel ? SUPPORTED_K_ALIGN_NUM_INT4 : SUPPORTED_GROUP_SIZE_A8W4_INT; |
| 604 | - bool isA8W4Mx = isA8W4FloatMx(x1, x2, x1Scale, x2Scale); | 604 | + if (kDim % kAlign != 0) { |
| 605 | - // CHECK x1KDim | 605 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "the k dim must be align to %ld, which is %ld", kAlign, kDim); |
| 606 | + return false; | ||
| 607 | + } | ||
| 608 | + } else if (isA8W4FloatTCG(x1, x2, x1Scale)) { | ||
| 609 | + if (kDim % SUPPORTED_TCG_A8W4_K_ALIGN_NUM != 0 || kDim <= SUPPORTED_TCG_A8W4_K_ALIGN_NUM) { | ||
| 610 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "the k dim must to be aligned to %ld and more than %ld, which is %ld", | ||
| 611 | + SUPPORTED_TCG_A8W4_K_ALIGN_NUM, SUPPORTED_TCG_A8W4_K_ALIGN_NUM, kDim); | ||
| 612 | + return false; | ||
| 613 | + } | ||
| 614 | + } else if (isA8W4FloatMx(x1, x2, x1Scale, x2Scale)) { | ||
| 615 | + if (kDim % SUPPORTED_MX_A8W4_K_ALIGN_NUM != 0) { | ||
| 616 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "The k dim must be aligned to %ld for MX quantization, which is %ld", | ||
| 617 | + SUPPORTED_MX_A8W4_K_ALIGN_NUM, kDim); | ||
| 618 | + return false; | ||
| 619 | + } | ||
| 620 | + } else { | ||
| 621 | + if (kDim % SUPPORTED_K_ALIGN_NUM != 0) { | ||
| 622 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "the k dim must be align to %ld, which is %ld", SUPPORTED_K_ALIGN_NUM, kDim); | ||
| 623 | + return false; | ||
| 624 | + } | ||
| 625 | + } | ||
| 626 | + return true; | ||
| 627 | +} | ||
| 628 | + | ||
| 629 | +static inline bool CheckKDimAndBasicShape( | ||
| 630 | + const TupleInput& inputTensors, const TupleQuant& quantTensors, int64_t x1KDim, int64_t x2KDim, int64_t x2NDim) | ||
| 631 | +{ | ||
| 632 | + // CHECK basic shape | ||
| 606 | auto npuArch = op::GetCurrentPlatformInfo().GetCurNpuArch(); | 633 | auto npuArch = op::GetCurrentPlatformInfo().GetCurNpuArch(); |
| 607 | if (npuArch == NpuArch::DAV_2201) { // A8W4INT A2 A3 | 634 | if (npuArch == NpuArch::DAV_2201) { // A8W4INT A2 A3 |
| 608 | if (x1KDim <= 0 || x1KDim > MAX_SHAPE_SIZE_A8W4_INT) { | 635 | if (x1KDim <= 0 || x1KDim > MAX_SHAPE_SIZE_A8W4_INT) { |
| @@ -624,23 +651,9 @@ static inline bool CheckKDimAndBasicShape( | |||
| 624 | x1KDim, x2KDim); | 651 | x1KDim, x2KDim); |
| 625 | return false; | 652 | return false; |
| 626 | } | 653 | } |
| 627 | - if (isA8W4INT) { | 654 | + // CHECK kDim |
| 628 | - size_t kAlign = isPerChannel ? SUPPORTED_K_ALIGN_NUM_INT4 : SUPPORTED_GROUP_SIZE_A8W4_INT; | 655 | + if (!CheckA8W4KDim(inputTensors, quantTensors, x1KDim)) { |
| 629 | - if (x1KDim % kAlign != 0) { | 656 | + return false; |
| 630 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "the k dim must be align to %ld, which is %ld", kAlign, x1KDim); | ||
| 631 | - return false; | ||
| 632 | - } | ||
| 633 | - } else if (isA8W4TCG || isA8W4Mx) { | ||
| 634 | - if (x1KDim % SUPPORTED_A8W4_K_ALIGN_NUM != 0 || x1KDim <= SUPPORTED_A8W4_K_ALIGN_NUM) { | ||
| 635 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID,"the k dim must to be aligned to %ld and more than %ld, which is %ld", | ||
| 636 | - SUPPORTED_A8W4_K_ALIGN_NUM, SUPPORTED_A8W4_K_ALIGN_NUM, x1KDim); | ||
| 637 | - return false; | ||
| 638 | - } | ||
| 639 | - } else { | ||
| 640 | - if (x1KDim % SUPPORTED_K_ALIGN_NUM != 0) { | ||
| 641 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "the k dim must be align to %ld, which is %ld", SUPPORTED_K_ALIGN_NUM, x1KDim); | ||
| 642 | - return false; | ||
| 643 | - } | ||
| 644 | } | 657 | } |
| 645 | return true; | 658 | return true; |
| 646 | } | 659 | } |
Mmatmul/quant_batch_matmul_v4/op_host/op_tiling/arch35/quant_batch_matmul_v4_basic_block_tiling.cpp+4-4
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -121,7 +121,7 @@ void QuantBatchMatmulV4BasicBlockTiling::SetShape(int64_t mSize, int64_t nSize, | |||
| 121 | basicBlockParam_.mSize = mSize; | 121 | basicBlockParam_.mSize = mSize; |
| 122 | basicBlockParam_.nSize = nSize; | 122 | basicBlockParam_.nSize = nSize; |
| 123 | basicBlockParam_.kSize = kSize; | 123 | basicBlockParam_.kSize = kSize; |
| 124 | - basicBlockParam_.singleK = kSize; | 124 | + basicBlockParam_.singleK = ops::CeilAlign(kSize, ONE_BLOCK_SIZE); // k方向单核处理粒度需32对齐 |
| 125 | basicBlockParam_.groupSize = groupSize; | 125 | basicBlockParam_.groupSize = groupSize; |
| 126 | OP_LOGI(opName_, "Init shape param, mSize: %ld, nSize: %ld, kSize: %ld, groupSize: %ld", basicBlockParam_.mSize, | 126 | OP_LOGI(opName_, "Init shape param, mSize: %ld, nSize: %ld, kSize: %ld, groupSize: %ld", basicBlockParam_.mSize, |
| 127 | basicBlockParam_.nSize, basicBlockParam_.kSize, basicBlockParam_.groupSize); | 127 | basicBlockParam_.nSize, basicBlockParam_.kSize, basicBlockParam_.groupSize); |
| @@ -183,7 +183,7 @@ bool QuantBatchMatmulV4BasicBlockTiling::ValidateInputParam() const | |||
| 183 | 183 | ||
| 184 | OP_TILING_CHECK(basicBlockParam_.groupSize < 0, | 184 | OP_TILING_CHECK(basicBlockParam_.groupSize < 0, |
| 185 | VECTOR_INNER_ERR_REPORT_TILIING( | 185 | VECTOR_INNER_ERR_REPORT_TILIING( |
| 186 | - opName_, "Invalid param, groupSize must be greater than or equalt to 0, groupSize: %ld", | 186 | + opName_, "Invalid param, groupSize must be greater than or equal to 0, groupSize: %ld", |
| 187 | basicBlockParam_.groupSize), | 187 | basicBlockParam_.groupSize), |
| 188 | return false); | 188 | return false); |
| 189 | 189 | ||
| @@ -313,7 +313,7 @@ void QuantBatchMatmulV4BasicBlockTiling::GetMte2DataSizeMx(BasicBlockParam& basi | |||
| 313 | CeilDiv(basicBlockParam.singleK, basicBlockParam.basicBlock.baseK * basicBlockParam.l1Param.stepKa * | 313 | CeilDiv(basicBlockParam.singleK, basicBlockParam.basicBlock.baseK * basicBlockParam.l1Param.stepKa * |
| 314 | basicBlockParam.l1Param.scaleFactor); | 314 | basicBlockParam.l1Param.scaleFactor); |
| 315 | // 每行搬运量都小于cacheline, 按照cacheline大小计算 | 315 | // 每行搬运量都小于cacheline, 按照cacheline大小计算 |
| 316 | - int64_t scaleSingleK = basicBlockParam.singleK / basicBlockParam.groupSize; | 316 | + int64_t scaleSingleK = CeilDiv(basicBlockParam.singleK, basicBlockParam.groupSize); |
| 317 | int64_t scaleKLoopNumHbm = min(CeilDiv(scaleSingleK, platformParam_.cacheLine), scaleKloopNumTotal); | 317 | int64_t scaleKLoopNumHbm = min(CeilDiv(scaleSingleK, platformParam_.cacheLine), scaleKloopNumTotal); |
| 318 | int64_t scaleKLoopNumL2 = scaleKloopNumTotal - scaleKLoopNumHbm; | 318 | int64_t scaleKLoopNumL2 = scaleKloopNumTotal - scaleKLoopNumHbm; |
| 319 | int64_t scaleASizeHbm = basicBlockParam.singleM * platformParam_.cacheLine * scaleKLoopNumHbm; | 319 | int64_t scaleASizeHbm = basicBlockParam.singleM * platformParam_.cacheLine * scaleKLoopNumHbm; |
Mmatmul/quant_batch_matmul_v4/op_host/op_tiling/arch35/quant_batch_matmul_v4_basic_block_tiling.h+2-1
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -42,6 +42,7 @@ constexpr double BYTE_BITS = 8; | |||
| 42 | constexpr int64_t BITS_16 = 16; | 42 | constexpr int64_t BITS_16 = 16; |
| 43 | constexpr int64_t BITS_4 = 4; | 43 | constexpr int64_t BITS_4 = 4; |
| 44 | constexpr int64_t BLOCK_CUBE = 16; | 44 | constexpr int64_t BLOCK_CUBE = 16; |
| 45 | +constexpr int64_t ONE_BLOCK_SIZE = 32; | ||
| 45 | constexpr int64_t BUFF_NUM_1 = 1; | 46 | constexpr int64_t BUFF_NUM_1 = 1; |
| 46 | constexpr int64_t BUFF_NUM_2 = 2; | 47 | constexpr int64_t BUFF_NUM_2 = 2; |
| 47 | constexpr int64_t BUFF_NUM_3 = 3; | 48 | constexpr int64_t BUFF_NUM_3 = 3; |
Mmatmul/quant_batch_matmul_v4/op_host/op_tiling/arch35/quant_batch_matmul_v4_pergroup_arch35_tiling.cpp+7-9
| @@ -71,6 +71,11 @@ ge::graphStatus QuantBatchMatmulV4PergroupArch35Tiling::CalcDequantTiling( | |||
| 71 | 71 | ||
| 72 | ge::graphStatus QuantBatchMatmulV4PergroupArch35Tiling::DoOpTiling() | 72 | ge::graphStatus QuantBatchMatmulV4PergroupArch35Tiling::DoOpTiling() |
| 73 | { | 73 | { |
| 74 | + OPS_CHECK_NULL_WITH_CONTEXT(context_, context_->GetRawTilingData()); | ||
| 75 | + OP_TILING_CHECK(context_->GetRawTilingData()->GetCapacity() < tilingDataSize_, | ||
| 76 | + CUBE_INNER_ERR_REPORT(inputParams_.opName, "context tiling data capacity %zu < actual tiling data size %zu.", | ||
| 77 | + context_->GetRawTilingData()->GetCapacity(), tilingDataSize_), | ||
| 78 | + return ge::GRAPH_FAILED); | ||
| 74 | isUbQuant_ = true; | 79 | isUbQuant_ = true; |
| 75 | InitCompileInfo(); | 80 | InitCompileInfo(); |
| 76 | SetTransAttr(trans_); | 81 | SetTransAttr(trans_); |
| @@ -108,9 +113,8 @@ ge::graphStatus QuantBatchMatmulV4PergroupArch35Tiling::DoOpTiling() | |||
| 108 | stepK = std::max(1U, stepK); | 113 | stepK = std::max(1U, stepK); |
| 109 | basicTiling_.stepKa = stepK; | 114 | basicTiling_.stepKa = stepK; |
| 110 | basicTiling_.stepKb = stepK; | 115 | basicTiling_.stepKb = stepK; |
| 111 | - OP_LOGD( | 116 | + OP_LOGD(inputParams_.opName, "arch35 int8 tiling: groupSizeK=%u, stepK=%u, l1Size=%u", |
| 112 | - inputParams_.opName, "arch35 int8 tiling: groupSizeK=%u, stepK=%u, l1Size=%u", inputParams_.groupSizeK, stepK, | 117 | + inputParams_.groupSizeK, stepK, l1Size); |
| 113 | - l1Size); | ||
| 114 | 118 | ||
| 115 | basicTiling_.baseK = inputParams_.groupSizeK; | 119 | basicTiling_.baseK = inputParams_.groupSizeK; |
| 116 | QuantBatchMatmulV3BasicTiling::DoL2CacheTiling(); | 120 | QuantBatchMatmulV3BasicTiling::DoL2CacheTiling(); |
| @@ -158,12 +162,6 @@ ge::graphStatus QuantBatchMatmulV4PergroupArch35Tiling::CheckContext() | |||
| 158 | OPS_CHECK_NULL_WITH_CONTEXT(context_, outputDesc); | 162 | OPS_CHECK_NULL_WITH_CONTEXT(context_, outputDesc); |
| 159 | OPS_CHECK_NULL_WITH_CONTEXT(context_, context_->GetRawTilingData()); | 163 | OPS_CHECK_NULL_WITH_CONTEXT(context_, context_->GetRawTilingData()); |
| 160 | OPS_CHECK_NULL_WITH_CONTEXT(context_, context_->GetRawTilingData()->GetData()); | 164 | OPS_CHECK_NULL_WITH_CONTEXT(context_, context_->GetRawTilingData()->GetData()); |
| 161 | - OP_TILING_CHECK( | ||
| 162 | - context_->GetRawTilingData()->GetCapacity() < tilingDataSize_, | ||
| 163 | - CUBE_INNER_ERR_REPORT( | ||
| 164 | - inputParams_.opName, "context tiling data capacity %zu < actual tiling data size %zu.", | ||
| 165 | - context_->GetRawTilingData()->GetCapacity(), tilingDataSize_), | ||
| 166 | - return ge::GRAPH_FAILED); | ||
| 167 | return ge::GRAPH_SUCCESS; | 165 | return ge::GRAPH_SUCCESS; |
| 168 | } | 166 | } |
| 169 | 167 | ||
Mmatmul/quant_batch_matmul_v4/op_host/op_tiling/arch35/quant_batch_matmul_v4_reg_base_tiling.cpp+35-15
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -54,12 +54,23 @@ bool QuantBatchMatmulV4RegBase::CheckA8W4Params() const | |||
| 54 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | 54 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, |
| 55 | "Invalid params, only support x2 not transpose FORMAT_FRACTAL_NZ."), | 55 | "Invalid params, only support x2 not transpose FORMAT_FRACTAL_NZ."), |
| 56 | return false); | 56 | return false); |
| 57 | - OP_CHECK_IF( | 57 | + |
| 58 | - inputParams_.groupSize <= 0 || inputParams_.kSize < inputParams_.groupSize, | 58 | + if (inputParams_.antiQuantType == QuantType::MX) { |
| 59 | - VECTOR_INNER_ERR_REPORT_TILIING( | 59 | + OP_CHECK_IF( |
| 60 | - inputParams_.opName, | 60 | + inputParams_.groupSize != MX_GROUP_SIZE, |
| 61 | - "Invalid params, groupSize must be greater than 0 and less than kSize, kSize: %lu, groupSize: %lu.", | 61 | + VECTOR_INNER_ERR_REPORT_TILIING( |
| 62 | - inputParams_.kSize, inputParams_.groupSize), return false); | 62 | + inputParams_.opName, |
| 63 | + "Invalid params, groupSize must be 32 for MX quantization, but got %lu.", | ||
| 64 | + inputParams_.groupSize), return false); | ||
| 65 | + } else { | ||
| 66 | + OP_CHECK_IF( | ||
| 67 | + inputParams_.groupSize <= 0 || inputParams_.kSize < inputParams_.groupSize, | ||
| 68 | + VECTOR_INNER_ERR_REPORT_TILIING( | ||
| 69 | + inputParams_.opName, | ||
| 70 | + "Invalid params, groupSize must be greater than 0 and less than kSize, kSize: %lu, groupSize: %lu.", | ||
| 71 | + inputParams_.kSize, inputParams_.groupSize), return false); | ||
| 72 | + } | ||
| 73 | + | ||
| 63 | OP_CHECK_IF(inputParams_.groupSize % GROUP_ALIGN_SIZE > 0, | 74 | OP_CHECK_IF(inputParams_.groupSize % GROUP_ALIGN_SIZE > 0, |
| 64 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | 75 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, |
| 65 | "Invalid params, groupSize must be 32 aligned, groupSize: %lu.", | 76 | "Invalid params, groupSize must be 32 aligned, groupSize: %lu.", |
| @@ -67,19 +78,28 @@ bool QuantBatchMatmulV4RegBase::CheckA8W4Params() const | |||
| 67 | // A8W4 Nz场景要求n为32B对齐 | 78 | // A8W4 Nz场景要求n为32B对齐 |
| 68 | OP_CHECK_IF(inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ && inputParams_.nSize % N_ALIGN_SIZE > 0, | 79 | OP_CHECK_IF(inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ && inputParams_.nSize % N_ALIGN_SIZE > 0, |
| 69 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | 80 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, |
| 70 | - "Invalid params, nSize only support aligned to 64 when weight format is NZ, but nSize is %lu.", | 81 | + "Invalid params, nSize only support aligned to 8 when weight format is NZ, but nSize is %lu.", |
| 71 | inputParams_.nSize), return false); | 82 | inputParams_.nSize), return false); |
| 72 | return true; | 83 | return true; |
| 73 | } | 84 | } |
| 74 | 85 | ||
| 75 | bool QuantBatchMatmulV4RegBase::CustomCheck() const | 86 | bool QuantBatchMatmulV4RegBase::CustomCheck() const |
| 76 | { | 87 | { |
| 77 | - OP_CHECK_IF( | 88 | + if (inputParams_.antiQuantType == QuantType::MX) { |
| 78 | - inputParams_.kSize % K_ALIGN_SIZE > 0 || inputParams_.kSize <= K_ALIGN_SIZE, | 89 | + OP_CHECK_IF( |
| 79 | - VECTOR_INNER_ERR_REPORT_TILIING( | 90 | + inputParams_.kSize % K_ALIGN_SIZE_MX > 0, |
| 80 | - inputParams_.opName, "Invalid params, kSize must be aligned to 32 and greater than 32, but got %lu.", | 91 | + VECTOR_INNER_ERR_REPORT_TILIING( |
| 81 | - inputParams_.kSize), | 92 | + inputParams_.opName, "Invalid params, kSize must be aligned to 8 for MX quantization, but got %lu.", |
| 82 | - return false); | 93 | + inputParams_.kSize), |
| 94 | + return false); | ||
| 95 | + } else { | ||
| 96 | + OP_CHECK_IF( | ||
| 97 | + inputParams_.kSize % K_ALIGN_SIZE > 0 || inputParams_.kSize <= K_ALIGN_SIZE, | ||
| 98 | + VECTOR_INNER_ERR_REPORT_TILIING( | ||
| 99 | + inputParams_.opName, "Invalid params, kSize must be aligned to 32 and greater than 32, but got %lu.", | ||
| 100 | + inputParams_.kSize), | ||
| 101 | + return false); | ||
| 102 | + } | ||
| 83 | 103 | ||
| 84 | OP_CHECK_IF((inputParams_.cDtype != ge::DT_BF16) && (inputParams_.cDtype != ge::DT_FLOAT16), | 104 | OP_CHECK_IF((inputParams_.cDtype != ge::DT_BF16) && (inputParams_.cDtype != ge::DT_FLOAT16), |
| 85 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, "Invalid params, output only support DT_BF16 or DT_FLOAT16."), | 105 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, "Invalid params, output only support DT_BF16 or DT_FLOAT16."), |
| @@ -399,7 +419,7 @@ void QuantBatchMatmulV4RegBase::PrintCVTilingData(const bool debugLevel) const | |||
| 399 | << " AL1Pingpong: " << tilingData_->AL1Pingpong << " BL1Pingpong: " << tilingData_->BL1Pingpong; | 419 | << " AL1Pingpong: " << tilingData_->AL1Pingpong << " BL1Pingpong: " << tilingData_->BL1Pingpong; |
| 400 | if (debugLevel) { | 420 | if (debugLevel) { |
| 401 | OPS_LOG_D(inputParams_.opName, "tiling data: %s", ss.str().c_str()); | 421 | OPS_LOG_D(inputParams_.opName, "tiling data: %s", ss.str().c_str()); |
| 402 | - }else { | 422 | + } else { |
| 403 | OPS_LOG_E(inputParams_.opName, "tiling data: %s", ss.str().c_str()); | 423 | OPS_LOG_E(inputParams_.opName, "tiling data: %s", ss.str().c_str()); |
| 404 | } | 424 | } |
| 405 | PrintMatMulTiling(); | 425 | PrintMatMulTiling(); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -149,30 +149,8 @@ ge::graphStatus QuantBatchMatmulV4TilingBase::GetShapeAttrsInfo() | |||
| 149 | inputParams_.weightNz = inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ; | 149 | inputParams_.weightNz = inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ; |
| 150 | OP_TILING_CHECK(!AnalyzeQuantType() || !AnalyzeAttrs() || !AnalyzeInputs() || !AnalyzeDtype(), | 150 | OP_TILING_CHECK(!AnalyzeQuantType() || !AnalyzeAttrs() || !AnalyzeInputs() || !AnalyzeDtype(), |
| 151 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, "Fail to analyze context info"), return ge::GRAPH_FAILED); | 151 | VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, "Fail to analyze context info"), return ge::GRAPH_FAILED); |
| 152 | - bool maxDimCheck = inputParams_.kSize > MAX_SHAPE_DIM || inputParams_.nSize > MAX_SHAPE_DIM; | 152 | + OP_TILING_CHECK(CheckInputParams() != ge::GRAPH_SUCCESS, |
| 153 | - if (inputParams_.transA) { | 153 | + VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, "invalid input parameters"), |
| 154 | - maxDimCheck |= inputParams_.mSize > MAX_SHAPE_DIM; | ||
| 155 | - } | ||
| 156 | - OP_TILING_CHECK(inputParams_.supportL0c2Out && maxDimCheck, | ||
| 157 | - VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 158 | - "only support MKN in range [1, %lu], get actual value[%lu, %lu, %lu]", | ||
| 159 | - MAX_SHAPE_DIM, inputParams_.mSize, inputParams_.kSize, inputParams_.nSize), | ||
| 160 | - return ge::GRAPH_FAILED); | ||
| 161 | - OP_TILING_CHECK(inputParams_.groupSize > inputParams_.kSize || inputParams_.groupSize % MIN_GROUP_SIZE != 0, | ||
| 162 | - VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 163 | - "Only support group size greater than %lu, less than K and align to %lu, get K[%lu] and group size[%lu]", | ||
| 164 | - MIN_GROUP_SIZE, MIN_GROUP_SIZE, inputParams_.kSize, inputParams_.groupSize), | ||
| 165 | - return ge::GRAPH_FAILED); | ||
| 166 | - OP_TILING_CHECK(inputParams_.supportL0c2Out && !inputParams_.supportL12BtBf16 && | ||
| 167 | - inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ && | ||
| 168 | - (inputParams_.bDtype != ge::DT_INT8 || inputParams_.antiQuantType != QuantType::PER_CHANNEL || | ||
| 169 | - inputParams_.cDtype == ge::DT_INT8), | ||
| 170 | - VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 171 | - "weight Nz only support weight dtype INT8 per-channel scene, and not support quant scale, " | ||
| 172 | - "current input bDtype[%s], antiquantType[%d], cDtype[%s]", | ||
| 173 | - ge::TypeUtils::DataTypeToSerialString(inputParams_.bDtype).c_str(), | ||
| 174 | - static_cast<int>(inputParams_.antiQuantType), | ||
| 175 | - ge::TypeUtils::DataTypeToSerialString(inputParams_.bDtype).c_str()), | ||
| 176 | return ge::GRAPH_FAILED); | 154 | return ge::GRAPH_FAILED); |
| 177 | auto transA_str = inputParams_.transA ? "true" : "false"; | 155 | auto transA_str = inputParams_.transA ? "true" : "false"; |
| 178 | auto transB_str = inputParams_.transB ? "true" : "false"; | 156 | auto transB_str = inputParams_.transB ? "true" : "false"; |
| @@ -226,6 +204,43 @@ ge::graphStatus QuantBatchMatmulV4TilingBase::CheckContext() const | |||
| 226 | return ge::GRAPH_SUCCESS; | 204 | return ge::GRAPH_SUCCESS; |
| 227 | } | 205 | } |
| 228 | 206 | ||
| 207 | +ge::graphStatus QuantBatchMatmulV4TilingBase::CheckInputParams() const | ||
| 208 | +{ | ||
| 209 | + bool maxDimCheck = inputParams_.kSize > MAX_SHAPE_DIM || inputParams_.nSize > MAX_SHAPE_DIM; | ||
| 210 | + if (inputParams_.transA) { | ||
| 211 | + maxDimCheck |= inputParams_.mSize > MAX_SHAPE_DIM; | ||
| 212 | + } | ||
| 213 | + OP_TILING_CHECK(inputParams_.supportL0c2Out && maxDimCheck, | ||
| 214 | + VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 215 | + "only support MKN in range [1, %lu], get actual value[%lu, %lu, %lu]", | ||
| 216 | + MAX_SHAPE_DIM, inputParams_.mSize, inputParams_.kSize, inputParams_.nSize), | ||
| 217 | + return ge::GRAPH_FAILED); | ||
| 218 | + if (inputParams_.antiQuantType == QuantType::MX) { | ||
| 219 | + OP_TILING_CHECK(inputParams_.groupSize != MX_GROUP_SIZE, | ||
| 220 | + VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 221 | + "Group size must be 32 for MX quantization, get group size[%lu]", inputParams_.groupSize), | ||
| 222 | + return ge::GRAPH_FAILED); | ||
| 223 | + } else { | ||
| 224 | + OP_TILING_CHECK(inputParams_.groupSize > inputParams_.kSize || inputParams_.groupSize % MIN_GROUP_SIZE != 0, | ||
| 225 | + VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 226 | + "Only support group size greater than %lu, less than K and align to %lu, get K[%lu] and group size[%lu]", | ||
| 227 | + MIN_GROUP_SIZE, MIN_GROUP_SIZE, inputParams_.kSize, inputParams_.groupSize), | ||
| 228 | + return ge::GRAPH_FAILED); | ||
| 229 | + } | ||
| 230 | + OP_TILING_CHECK(inputParams_.supportL0c2Out && !inputParams_.supportL12BtBf16 && | ||
| 231 | + inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ && | ||
| 232 | + (inputParams_.bDtype != ge::DT_INT8 || inputParams_.antiQuantType != QuantType::PER_CHANNEL || | ||
| 233 | + inputParams_.cDtype == ge::DT_INT8), | ||
| 234 | + VECTOR_INNER_ERR_REPORT_TILIING(inputParams_.opName, | ||
| 235 | + "weight Nz only support weight dtype INT8 per-channel scene, and not support quant scale, " | ||
| 236 | + "current input bDtype[%s], antiquantType[%d], cDtype[%s]", | ||
| 237 | + ge::TypeUtils::DataTypeToSerialString(inputParams_.bDtype).c_str(), | ||
| 238 | + static_cast<int>(inputParams_.antiQuantType), | ||
| 239 | + ge::TypeUtils::DataTypeToSerialString(inputParams_.bDtype).c_str()), | ||
| 240 | + return ge::GRAPH_FAILED); | ||
| 241 | + return ge::GRAPH_SUCCESS; | ||
| 242 | +} | ||
| 243 | + | ||
| 229 | bool QuantBatchMatmulV4TilingBase::AnalyzeDtype() | 244 | bool QuantBatchMatmulV4TilingBase::AnalyzeDtype() |
| 230 | { | 245 | { |
| 231 | inputParams_.aDtype = context_->GetInputDesc(X1_INDEX)->GetDataType(); | 246 | inputParams_.aDtype = context_->GetInputDesc(X1_INDEX)->GetDataType(); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -64,12 +64,14 @@ constexpr size_t VALID_BIAS_MAX_DIM = 2; | |||
| 64 | constexpr uint64_t VEC_INNER_AXIS_ALIGN_UINT = 128UL; | 64 | constexpr uint64_t VEC_INNER_AXIS_ALIGN_UINT = 128UL; |
| 65 | constexpr uint64_t MAX_SHAPE_DIM = 0x7fffffffUL; | 65 | constexpr uint64_t MAX_SHAPE_DIM = 0x7fffffffUL; |
| 66 | constexpr uint64_t MIN_GROUP_SIZE = 32UL; | 66 | constexpr uint64_t MIN_GROUP_SIZE = 32UL; |
| 67 | +constexpr uint64_t MX_GROUP_SIZE = 32UL; | ||
| 67 | constexpr int32_t BASIC_PRIORITY = 1; | 68 | constexpr int32_t BASIC_PRIORITY = 1; |
| 68 | constexpr uint64_t INT4_DTYPE_PARAM = 2; | 69 | constexpr uint64_t INT4_DTYPE_PARAM = 2; |
| 69 | constexpr uint32_t WORKSPACE_SIZE = 16777216; // 16 * 1024 * 1024 | 70 | constexpr uint32_t WORKSPACE_SIZE = 16777216; // 16 * 1024 * 1024 |
| 70 | constexpr int32_t DB_BUFFER = 2; | 71 | constexpr int32_t DB_BUFFER = 2; |
| 71 | constexpr int32_t EXTRA_GROUP_NUM = 2; | 72 | constexpr int32_t EXTRA_GROUP_NUM = 2; |
| 72 | constexpr uint64_t K_ALIGN_SIZE = 32; | 73 | constexpr uint64_t K_ALIGN_SIZE = 32; |
| 74 | +constexpr uint64_t K_ALIGN_SIZE_MX = 8; | ||
| 73 | constexpr uint64_t N_ALIGN_SIZE = 8; | 75 | constexpr uint64_t N_ALIGN_SIZE = 8; |
| 74 | 76 | ||
| 75 | constexpr int64_t B64_BITS = 64; | 77 | constexpr int64_t B64_BITS = 64; |
| @@ -185,6 +187,7 @@ protected: | |||
| 185 | void Reset(); | 187 | void Reset(); |
| 186 | void InitCompileInfo(); | 188 | void InitCompileInfo(); |
| 187 | ge::graphStatus CheckContext() const; | 189 | ge::graphStatus CheckContext() const; |
| 190 | + ge::graphStatus CheckInputParams() const; | ||
| 188 | bool AnalyzeDtype(); | 191 | bool AnalyzeDtype(); |
| 189 | bool AnalyzeBiasDtype(const gert::CompileTimeTensorDesc *biasDesc); | 192 | bool AnalyzeBiasDtype(const gert::CompileTimeTensorDesc *biasDesc); |
| 190 | bool AnalyzeX1scaleDtype(const gert::CompileTimeTensorDesc *x1ScaleDesc); | 193 | bool AnalyzeX1scaleDtype(const gert::CompileTimeTensorDesc *x1ScaleDesc); |
| @@ -175,7 +175,7 @@ __global__ __aicore__ void quant_batch_matmul_v4( | |||
| 175 | tPipe.Destroy(); | 175 | tPipe.Destroy(); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | - REGISTER_TILING_DEFAULT(DequantBmm::QuantBatchMatmulV3TilingDataParams); | 178 | + REGISTER_TILING_DEFAULT(qbmmv4_tiling::QuantBatchMatmulV4TilingDataParams); |
| 179 | if (QUANT_TYPE == QBMMV4_PER_GROUP) { | 179 | if (QUANT_TYPE == QBMMV4_PER_GROUP) { |
| 180 | constexpr bool isTransA = TRANS == QBMMV4_A_TRANS || TRANS == QBMMV4_ALL_TRANS; | 180 | constexpr bool isTransA = TRANS == QBMMV4_A_TRANS || TRANS == QBMMV4_ALL_TRANS; |
| 181 | constexpr bool isTransB = TRANS == QBMMV4_B_TRANS || TRANS == QBMMV4_ALL_TRANS; | 181 | constexpr bool isTransB = TRANS == QBMMV4_B_TRANS || TRANS == QBMMV4_ALL_TRANS; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -628,8 +628,11 @@ QuantBatchMatmulV4RegBaseCommonKernel<xType, wType, biasType, yType, aTrans, bTr | |||
| 628 | ubOffset = ubBufIdx_ * (vecScaleOffsetLen_ / sizeof(scaleType) / tiling_->BL1Pingpong); | 628 | ubOffset = ubBufIdx_ * (vecScaleOffsetLen_ / sizeof(scaleType) / tiling_->BL1Pingpong); |
| 629 | } | 629 | } |
| 630 | } else { // B 矩阵非转置 | 630 | } else { // B 矩阵非转置 |
| 631 | - intriParams.blockLen = bubNLen * sizeof(scaleType); | 631 | + int32_t bubNLenReal = (bubNOffset + bubNLen) > tiling_->nSize ? tiling_->nSize - bubNOffset : bubNLen; |
| 632 | - intriParams.srcStride = (tiling_->nSize - bubNLen) * sizeof(scaleType); | 632 | + intriParams.blockLen = bubNLenReal * sizeof(scaleType); |
| 633 | + intriParams.srcStride = (tiling_->nSize - bubNLenReal) * sizeof(scaleType); | ||
| 634 | + intriParams.dstStride = (bubNLen * sizeof(scaleType) - CeilAlign(intriParams.blockLen, ALIGNED_32_SIZE)) | ||
| 635 | + / ALIGNED_32_SIZE; | ||
| 633 | if constexpr (antiQuantType == QuantType::PER_GROUP) { | 636 | if constexpr (antiQuantType == QuantType::PER_GROUP) { |
| 634 | // k_offset + n_offset | 637 | // k_offset + n_offset |
| 635 | gmOffset = bubKOffset / tiling_->groupSize * tiling_->nSize + bubNOffset; | 638 | gmOffset = bubKOffset / tiling_->groupSize * tiling_->nSize + bubNOffset; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | 22 | ||
| @@ -61,21 +62,24 @@ ASCENDC_TPL_SEL( | |||
| 61 | ASCENDC_TPL_UINT_SEL(QUANT_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_PER_GROUP), | 62 | ASCENDC_TPL_UINT_SEL(QUANT_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_PER_GROUP), |
| 62 | ASCENDC_TPL_UINT_SEL(OPTION_ATTRS, ASCENDC_TPL_UI_LIST, QBMMV4_OPTION_ATTR_NONE), | 63 | ASCENDC_TPL_UINT_SEL(OPTION_ATTRS, ASCENDC_TPL_UI_LIST, QBMMV4_OPTION_ATTR_NONE), |
| 63 | ASCENDC_TPL_UINT_SEL(WEIGHTNZ, ASCENDC_TPL_UI_LIST, QBMMV4_NOT_WEIGHT_NZ), | 64 | ASCENDC_TPL_UINT_SEL(WEIGHTNZ, ASCENDC_TPL_UI_LIST, QBMMV4_NOT_WEIGHT_NZ), |
| 64 | - ASCENDC_TPL_UINT_SEL(KERNEL_TEMPLATE_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_BASIS), ), | 65 | + ASCENDC_TPL_UINT_SEL(KERNEL_TEMPLATE_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_BASIS), |
| 66 | + ASCENDC_TPL_TILING_STRUCT_SEL(qbmmv4_tiling::QuantBatchMatmulV4TilingDataParams), ), | ||
| 65 | ASCENDC_TPL_ARGS_SEL( | 67 | ASCENDC_TPL_ARGS_SEL( |
| 66 | ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), | 68 | ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), |
| 67 | ASCENDC_TPL_UINT_SEL(TRANS, ASCENDC_TPL_UI_LIST, QBMMV4_NOT_TRANS), | 69 | ASCENDC_TPL_UINT_SEL(TRANS, ASCENDC_TPL_UI_LIST, QBMMV4_NOT_TRANS), |
| 68 | ASCENDC_TPL_UINT_SEL(QUANT_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_PER_GROUP), | 70 | ASCENDC_TPL_UINT_SEL(QUANT_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_PER_GROUP), |
| 69 | ASCENDC_TPL_UINT_SEL(OPTION_ATTRS, ASCENDC_TPL_UI_LIST, QBMMV4_OPTION_ATTR_NONE), | 71 | ASCENDC_TPL_UINT_SEL(OPTION_ATTRS, ASCENDC_TPL_UI_LIST, QBMMV4_OPTION_ATTR_NONE), |
| 70 | ASCENDC_TPL_UINT_SEL(WEIGHTNZ, ASCENDC_TPL_UI_LIST, QBMMV4_IS_WEIGHT_NZ), | 72 | ASCENDC_TPL_UINT_SEL(WEIGHTNZ, ASCENDC_TPL_UI_LIST, QBMMV4_IS_WEIGHT_NZ), |
| 71 | - ASCENDC_TPL_UINT_SEL(KERNEL_TEMPLATE_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_BASIS), ), | 73 | + ASCENDC_TPL_UINT_SEL(KERNEL_TEMPLATE_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_BASIS), |
| 74 | + ASCENDC_TPL_TILING_STRUCT_SEL(qbmmv4_tiling::QuantBatchMatmulV4TilingDataParams), ), | ||
| 72 | ASCENDC_TPL_ARGS_SEL( | 75 | ASCENDC_TPL_ARGS_SEL( |
| 73 | ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), | 76 | ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), |
| 74 | ASCENDC_TPL_UINT_SEL(TRANS, ASCENDC_TPL_UI_LIST, QBMMV4_B_TRANS), | 77 | ASCENDC_TPL_UINT_SEL(TRANS, ASCENDC_TPL_UI_LIST, QBMMV4_B_TRANS), |
| 75 | ASCENDC_TPL_UINT_SEL(QUANT_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_MX), | 78 | ASCENDC_TPL_UINT_SEL(QUANT_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_MX), |
| 76 | ASCENDC_TPL_UINT_SEL(OPTION_ATTRS, ASCENDC_TPL_UI_LIST, QBMMV4_OPTION_ATTR_NONE), | 79 | ASCENDC_TPL_UINT_SEL(OPTION_ATTRS, ASCENDC_TPL_UI_LIST, QBMMV4_OPTION_ATTR_NONE), |
| 77 | ASCENDC_TPL_UINT_SEL(WEIGHTNZ, ASCENDC_TPL_UI_LIST, QBMMV4_NOT_WEIGHT_NZ, QBMMV4_IS_WEIGHT_NZ), | 80 | ASCENDC_TPL_UINT_SEL(WEIGHTNZ, ASCENDC_TPL_UI_LIST, QBMMV4_NOT_WEIGHT_NZ, QBMMV4_IS_WEIGHT_NZ), |
| 78 | - ASCENDC_TPL_UINT_SEL(KERNEL_TEMPLATE_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_BASIS), ), | 81 | + ASCENDC_TPL_UINT_SEL(KERNEL_TEMPLATE_TYPE, ASCENDC_TPL_UI_LIST, QBMMV4_BASIS), |
| 82 | + ASCENDC_TPL_TILING_STRUCT_SEL(qbmmv4_tiling::QuantBatchMatmulV4TilingDataParams), ), | ||
| 79 | ASCENDC_TPL_ARGS_SEL( | 83 | ASCENDC_TPL_ARGS_SEL( |
| 80 | ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), | 84 | ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), |
| 81 | ASCENDC_TPL_UINT_SEL( | 85 | ASCENDC_TPL_UINT_SEL( |