已合并
smla perf #9988
郑文惠创建于 26 天前
smla perf #9988
已合并
共 13 个文件变更+1781-859
| @@ -353,9 +353,9 @@ ge::graphStatus SMLAInfoParser::GetNpuInfo() | |||
| 353 | if (npuArch_ != NpuArch::DAV_2201 && npuArch_ != NpuArch::DAV_3510) { | 353 | if (npuArch_ != NpuArch::DAV_2201 && npuArch_ != NpuArch::DAV_3510) { |
| 354 | OP_LOGE(opName_, "Npu Arch Version[%d] is not support.", (int32_t)npuArch_); | 354 | OP_LOGE(opName_, "Npu Arch Version[%d] is not support.", (int32_t)npuArch_); |
| 355 | return ge::GRAPH_FAILED; | 355 | return ge::GRAPH_FAILED; |
| 356 | - } | 356 | + } |
| 357 | - batchConsistency_ = false; | 357 | + batchConsistency_ = false; |
| 358 | - OP_LOGD(opName_, "deterministic_level=%d", context_->GetDeterministicLevel()); | 358 | + OP_LOGD(opName_, "deterministic_level=%d", context_->GetDeterministicLevel()); |
| 359 | 359 | ||
| 360 | return ge::GRAPH_SUCCESS; | 360 | return ge::GRAPH_SUCCESS; |
| 361 | } | 361 | } |
| @@ -889,7 +889,6 @@ ge::graphStatus SMLAInfoParser::GetValueHeadDim() | |||
| 889 | return ge::GRAPH_SUCCESS; | 889 | return ge::GRAPH_SUCCESS; |
| 890 | } | 890 | } |
| 891 | 891 | ||
| 892 | - | ||
| 893 | ge::graphStatus SMLAInfoParser::GetSparseBlockCount() | 892 | ge::graphStatus SMLAInfoParser::GetSparseBlockCount() |
| 894 | { | 893 | { |
| 895 | if (opParamInfo_.oriSparseIndices.tensor != nullptr) { | 894 | if (opParamInfo_.oriSparseIndices.tensor != nullptr) { |
| @@ -1990,7 +1989,7 @@ void SparseFlashMlaTiling::CalcUbBmm(SMLATilingInfo *tilingInfo) | |||
| 1990 | cubeMSize = maxMSize; | 1989 | cubeMSize = maxMSize; |
| 1991 | } | 1990 | } |
| 1992 | mmResUbSize_ = sInnerSizeAlign_ * Align(cubeMSize, 16U); // kernel按照16对齐写出,tiling按照这个原则分配内存 | 1991 | mmResUbSize_ = sInnerSizeAlign_ * Align(cubeMSize, 16U); // kernel按照16对齐写出,tiling按照这个原则分配内存 |
| 1993 | - bmm2ResUbSize_ = headDimAlign_ * Align(cubeMSize, 16U); // kernel按照16对齐写出,tiling按照这个原则分配内存 | 1992 | + bmm2ResUbSize_ = headDimAlign_ * Align(cubeMSize, 16U); // kernel按照16对齐写出,tiling按照这个原则分配内存 |
| 1994 | } | 1993 | } |
| 1995 | 1994 | ||
| 1996 | void SparseFlashMlaTiling::SplitBalanced(SMLATilingInfo *tilingInfo) | 1995 | void SparseFlashMlaTiling::SplitBalanced(SMLATilingInfo *tilingInfo) |
| @@ -2039,6 +2038,63 @@ uint64_t SparseFlashMlaTiling::CalcFdStagingWorkspaceSize(const SMLATilingInfo * | |||
| 2039 | return logicalCoreSlots * FD_MAX_S2_SPLIT_NUM * bytesPerSlot; | 2038 | return logicalCoreSlots * FD_MAX_S2_SPLIT_NUM * bytesPerSlot; |
| 2040 | } | 2039 | } |
| 2041 | 2040 | ||
| 2041 | +uint64_t SparseFlashMlaTiling::CalcVectorizeKvPhyAddrWorkspaceSize(const SMLATilingInfo *tilingInfo, | ||
| 2042 | + uint32_t &vectorizeFlag) const | ||
| 2043 | +{ | ||
| 2044 | + vectorizeFlag = 0U; | ||
| 2045 | + if (tilingInfo->npuArch != NpuArch::DAV_3510) { | ||
| 2046 | + return 0ULL; | ||
| 2047 | + } | ||
| 2048 | + constexpr uint32_t SPARSE_BLOCK_ALIGN_NUM = 128; | ||
| 2049 | + constexpr uint32_t UB_SIZE = 248 * 1024; | ||
| 2050 | + uint32_t alignedOriSparseBlockCount = | ||
| 2051 | + (tilingInfo->oriSparseBlockCount + SPARSE_BLOCK_ALIGN_NUM - 1) / SPARSE_BLOCK_ALIGN_NUM * SPARSE_BLOCK_ALIGN_NUM; | ||
| 2052 | + uint32_t alignedCmpSparseBlockCount = | ||
| 2053 | + (tilingInfo->cmpSparseBlockCount + SPARSE_BLOCK_ALIGN_NUM - 1) / SPARSE_BLOCK_ALIGN_NUM * SPARSE_BLOCK_ALIGN_NUM; | ||
| 2054 | + bool isPa = (tilingInfo->kvLayout == SMLALayout::PA_BBND); | ||
| 2055 | + uint32_t oriBlocksizeFlag = | ||
| 2056 | + static_cast<uint32_t>((tilingInfo->oriBlockSize & (tilingInfo->oriBlockSize - 1)) == 0); | ||
| 2057 | + uint32_t cmpBlocksizeFlag = | ||
| 2058 | + static_cast<uint32_t>((tilingInfo->cmpBlockSize & (tilingInfo->cmpBlockSize - 1)) == 0); | ||
| 2059 | + uint32_t blocksizeFlag = isPa ? ((tilingInfo->perfMode == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE) ? | ||
| 2060 | + oriBlocksizeFlag : | ||
| 2061 | + (oriBlocksizeFlag && cmpBlocksizeFlag)) : | ||
| 2062 | + 1U; | ||
| 2063 | + uint64_t paExtraUb = std::max( | ||
| 2064 | + static_cast<uint64_t>(tilingInfo->oriMaxBlockNumPerBatch) * sizeof(int32_t), | ||
| 2065 | + static_cast<uint64_t>(tilingInfo->cmpMaxBlockNumPerBatch) * sizeof(int32_t)); | ||
| 2066 | + uint64_t cmpUbSize = (isPa ? paExtraUb : 0U) + | ||
| 2067 | + static_cast<uint64_t>(alignedCmpSparseBlockCount) * sizeof(int32_t) + | ||
| 2068 | + static_cast<uint64_t>(alignedCmpSparseBlockCount) * sizeof(int64_t); | ||
| 2069 | + uint64_t oriUbSize = (isPa ? paExtraUb : 0U) + | ||
| 2070 | + static_cast<uint64_t>(alignedOriSparseBlockCount) * sizeof(int32_t) + | ||
| 2071 | + static_cast<uint64_t>(alignedOriSparseBlockCount) * sizeof(int64_t); | ||
| 2072 | + uint64_t vectorizeUbSize = std::max(cmpUbSize, oriUbSize); | ||
| 2073 | + vectorizeFlag = static_cast<uint32_t>( | ||
| 2074 | + (tilingInfo->perfMode == SMLATemplateMode::CSA_TEMPLATE_MODE || | ||
| 2075 | + tilingInfo->perfMode == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 2076 | + tilingInfo->perfMode == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) && | ||
| 2077 | + (vectorizeUbSize <= UB_SIZE) && blocksizeFlag); | ||
| 2078 | + | ||
| 2079 | + if (vectorizeFlag == 0U) { | ||
| 2080 | + return 0ULL; | ||
| 2081 | + } | ||
| 2082 | + uint32_t totalBS1 = (tilingInfo->qLayout == SMLALayout::TND) ? | ||
| 2083 | + tilingInfo->s1Size : | ||
| 2084 | + (tilingInfo->bSize * tilingInfo->s1Size); | ||
| 2085 | + uint64_t oriPhyAddrSize = 0; | ||
| 2086 | + if (tilingInfo->perfMode == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 2087 | + tilingInfo->perfMode == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 2088 | + oriPhyAddrSize = static_cast<uint64_t>(totalBS1) * alignedOriSparseBlockCount * sizeof(int64_t); | ||
| 2089 | + } | ||
| 2090 | + uint64_t cmpPhyAddrSize = 0; | ||
| 2091 | + if (tilingInfo->perfMode == SMLATemplateMode::CSA_TEMPLATE_MODE || | ||
| 2092 | + tilingInfo->perfMode == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 2093 | + cmpPhyAddrSize = static_cast<uint64_t>(totalBS1) * alignedCmpSparseBlockCount * sizeof(int64_t); | ||
| 2094 | + } | ||
| 2095 | + return oriPhyAddrSize + cmpPhyAddrSize; | ||
| 2096 | +} | ||
| 2097 | + | ||
| 2042 | // --------------------------SparseFlashMlaTiling类成员函数定义---------------------- | 2098 | // --------------------------SparseFlashMlaTiling类成员函数定义---------------------- |
| 2043 | ge::graphStatus SparseFlashMlaTiling::DoOpTiling(SMLATilingInfo *tilingInfo) | 2099 | ge::graphStatus SparseFlashMlaTiling::DoOpTiling(SMLATilingInfo *tilingInfo) |
| 2044 | { | 2100 | { |
| @@ -2087,6 +2143,11 @@ ge::graphStatus SparseFlashMlaTiling::DoOpTiling(SMLATilingInfo *tilingInfo) | |||
| 2087 | workspaceSize += MERGE_CACHE_GM_BUF_NUM * 512 * 512 * 2 * aicNum; | 2143 | workspaceSize += MERGE_CACHE_GM_BUF_NUM * 512 * 512 * 2 * aicNum; |
| 2088 | } | 2144 | } |
| 2089 | } | 2145 | } |
| 2146 | + | ||
| 2147 | + // 计算vectorizeFlag (稀疏KV物理地址向量化) | ||
| 2148 | + uint32_t vectorizeFlag = 0U; | ||
| 2149 | + workspaceSize += CalcVectorizeKvPhyAddrWorkspaceSize(tilingInfo, vectorizeFlag); | ||
| 2150 | + | ||
| 2090 | workspaceSize += CalcFdStagingWorkspaceSize(tilingInfo, aicNum); | 2151 | workspaceSize += CalcFdStagingWorkspaceSize(tilingInfo, aicNum); |
| 2091 | size_t *workSpaces = context_->GetWorkspaceSizes(1); | 2152 | size_t *workSpaces = context_->GetWorkspaceSizes(1); |
| 2092 | workSpaces[0] = workspaceSize; | 2153 | workSpaces[0] = workspaceSize; |
| @@ -2147,7 +2208,7 @@ ge::graphStatus SparseFlashMlaTiling::DoOpTiling(SMLATilingInfo *tilingInfo) | |||
| 2147 | splitG = static_cast<uint32_t>(tilingInfo->gSize > 64); | 2208 | splitG = static_cast<uint32_t>(tilingInfo->gSize > 64); |
| 2148 | } | 2209 | } |
| 2149 | tilingKey = GET_TPL_TILING_KEY(0U, qLayout, inputKvLayout, static_cast<uint32_t>(tilingInfo->perfMode), splitG, | 2210 | tilingKey = GET_TPL_TILING_KEY(0U, qLayout, inputKvLayout, static_cast<uint32_t>(tilingInfo->perfMode), splitG, |
| 2150 | - headRatioOne, static_cast<uint32_t>(tilingInfo->batchConsistency)); | 2211 | + headRatioOne, static_cast<uint32_t>(tilingInfo->batchConsistency), vectorizeFlag); |
| 2151 | context_->SetScheduleMode(1); | 2212 | context_->SetScheduleMode(1); |
| 2152 | context_->SetTilingKey(tilingKey); | 2213 | context_->SetTilingKey(tilingKey); |
| 2153 | 2214 | ||
| @@ -313,7 +313,8 @@ public: | |||
| 313 | // -----------算子Tiling入参信息解析及Check类--------------- | 313 | // -----------算子Tiling入参信息解析及Check类--------------- |
| 314 | class SMLATilingCheck { | 314 | class SMLATilingCheck { |
| 315 | public: | 315 | public: |
| 316 | - explicit SMLATilingCheck(const SMLATilingInfo &smlaInfo) : smlaInfo_(smlaInfo) {}; | 316 | + explicit SMLATilingCheck(const SMLATilingInfo &smlaInfo) |
| 317 | + : smlaInfo_(smlaInfo) {}; | ||
| 317 | ~SMLATilingCheck() = default; | 318 | ~SMLATilingCheck() = default; |
| 318 | virtual ge::graphStatus Process(); | 319 | virtual ge::graphStatus Process(); |
| 319 | 320 | ||
| @@ -455,7 +456,8 @@ inline T Align(T num, T rnd) | |||
| 455 | 456 | ||
| 456 | class SMLAInfoParser { | 457 | class SMLAInfoParser { |
| 457 | public: | 458 | public: |
| 458 | - explicit SMLAInfoParser(gert::TilingContext *context) : context_(context) | 459 | + explicit SMLAInfoParser(gert::TilingContext *context) |
| 460 | + : context_(context) | ||
| 459 | { | 461 | { |
| 460 | } | 462 | } |
| 461 | ~SMLAInfoParser() = default; | 463 | ~SMLAInfoParser() = default; |
| @@ -589,7 +591,8 @@ public: | |||
| 589 | // ---------------算子Tiling类--------------- | 591 | // ---------------算子Tiling类--------------- |
| 590 | class SparseFlashMlaTiling { | 592 | class SparseFlashMlaTiling { |
| 591 | public: | 593 | public: |
| 592 | - explicit SparseFlashMlaTiling(gert::TilingContext *context) : context_(context) {}; | 594 | + explicit SparseFlashMlaTiling(gert::TilingContext *context) |
| 595 | + : context_(context) {}; | ||
| 593 | ge::graphStatus DoOpTiling(SMLATilingInfo *tilingInfo); | 596 | ge::graphStatus DoOpTiling(SMLATilingInfo *tilingInfo); |
| 594 | 597 | ||
| 595 | private: | 598 | private: |
| @@ -597,6 +600,7 @@ private: | |||
| 597 | void CalcUbBmm(SMLATilingInfo *tilingInfo); | 600 | void CalcUbBmm(SMLATilingInfo *tilingInfo); |
| 598 | uint32_t CalcFdLogicalSlotCount(const SMLATilingInfo *tilingInfo, uint32_t aicNum) const; | 601 | uint32_t CalcFdLogicalSlotCount(const SMLATilingInfo *tilingInfo, uint32_t aicNum) const; |
| 599 | uint64_t CalcFdStagingWorkspaceSize(const SMLATilingInfo *tilingInfo, uint32_t aicNum) const; | 602 | uint64_t CalcFdStagingWorkspaceSize(const SMLATilingInfo *tilingInfo, uint32_t aicNum) const; |
| 603 | + uint64_t CalcVectorizeKvPhyAddrWorkspaceSize(const SMLATilingInfo *tilingInfo, uint32_t &vectorizeFlag) const; | ||
| 600 | gert::TilingContext *context_ = nullptr; | 604 | gert::TilingContext *context_ = nullptr; |
| 601 | SMLATemplateMode perfMode_ = SMLATemplateMode::SWA_TEMPLATE_MODE; | 605 | SMLATemplateMode perfMode_ = SMLATemplateMode::SWA_TEMPLATE_MODE; |
| 602 | SparseFlashMlaTilingData tilingData_; | 606 | SparseFlashMlaTilingData tilingData_; |
| @@ -21,12 +21,16 @@ | |||
| 21 | constexpr uint64_t BLOCK_BYTE = 32; | 21 | constexpr uint64_t BLOCK_BYTE = 32; |
| 22 | constexpr uint32_t NEGATIVE_MIN_VAULE_FP32 = 0xFF7FFFFF; | 22 | constexpr uint32_t NEGATIVE_MIN_VAULE_FP32 = 0xFF7FFFFF; |
| 23 | 23 | ||
| 24 | -constexpr uint32_t L0AB_SHARED_SIZE_64K = 65536; // 65536表示64*1024 | 24 | +constexpr uint32_t L0AB_SHARED_SIZE_64K = 65536; // 65536表示64*1024 |
| 25 | constexpr uint32_t L0C_SHARED_SIZE_256K = 262144; // 262144表示256 * 1024 | 25 | constexpr uint32_t L0C_SHARED_SIZE_256K = 262144; // 262144表示256 * 1024 |
| 26 | 26 | ||
| 27 | -constexpr uint32_t BUFFER_SIZE_16K = 16384; // 16384表示16 * 1024 | 27 | +constexpr uint32_t BUFFER_SIZE_8K = 8192; // 8192表示8 * 1024 |
| 28 | -constexpr uint32_t BUFFER_SIZE_32K = 32768; // 32768表示32 * 1024 | 28 | +constexpr uint32_t BUFFER_SIZE_16K = 16384; // 16384表示16 * 1024 |
| 29 | +constexpr uint32_t BUFFER_SIZE_32K = 32768; // 32768表示32 * 1024 | ||
| 30 | +constexpr uint32_t BUFFER_SIZE_64K = 65536; // 65536表示64 * 1024 | ||
| 31 | +constexpr uint32_t BUFFER_SIZE_96K = 98304; // 98304表示96 * 1024 | ||
| 29 | constexpr uint32_t BUFFER_SIZE_128K = 131072; // 131072表示128 * 1024 | 32 | constexpr uint32_t BUFFER_SIZE_128K = 131072; // 131072表示128 * 1024 |
| 33 | +constexpr uint32_t BUFFER_SIZE_256K = 262144; // 262144表示256 * 1024 | ||
| 30 | 34 | ||
| 31 | constexpr uint32_t CV_RATIO = 2; | 35 | constexpr uint32_t CV_RATIO = 2; |
| 32 | constexpr uint64_t SYNC_MODE = 4; | 36 | constexpr uint64_t SYNC_MODE = 4; |
| @@ -52,21 +56,23 @@ __aicore__ constexpr uint64_t Align64Func(uint64_t data) | |||
| 52 | { | 56 | { |
| 53 | return (data + 63UL) >> 6UL << 6UL; // 向上64对齐, +63移位6 | 57 | return (data + 63UL) >> 6UL << 6UL; // 向上64对齐, +63移位6 |
| 54 | } | 58 | } |
| 55 | -} | 59 | +} // namespace SMLAKernel |
| 56 | 60 | ||
| 57 | 61 | ||
| 58 | template <typename Q_T, typename KV_T, typename T, typename OUTPUT_T, \ | 62 | template <typename Q_T, typename KV_T, typename T, typename OUTPUT_T, \ |
| 59 | - bool IS_FD, SMLA_LAYOUT LAYOUT_T, \ | 63 | + bool IS_FD, SMLA_LAYOUT LAYOUT_T, \ |
| 60 | - SMLA_LAYOUT KV_LAYOUT_T, SMLATemplateMode TEMPLATE_MODE, bool IS_SPLIT_G, bool IS_BATCH_CONSISTENCY> | 64 | + SMLA_LAYOUT KV_LAYOUT_T, SMLATemplateMode TEMPLATE_MODE, bool IS_SPLIT_G, bool IS_BATCH_CONSISTENCY, \ |
| 65 | + bool IS_VEC_S2PHYADDR> | ||
| 61 | 66 | ||
| 62 | 67 | ||
| 63 | - Q_T, KV_T, T, OUTPUT_T, IS_FD, LAYOUT_T, KV_LAYOUT_T, TEMPLATE_MODE, IS_SPLIT_G, IS_BATCH_CONSISTENCY | 68 | + Q_T, KV_T, T, OUTPUT_T, IS_FD, LAYOUT_T, KV_LAYOUT_T, TEMPLATE_MODE, IS_SPLIT_G, IS_BATCH_CONSISTENCY, \ |
| 69 | + IS_VEC_S2PHYADDR | ||
| 64 | 70 | ||
| 65 | 71 | ||
| 66 | X(Q_T) \ | 72 | X(Q_T) \ |
| 67 | X(KV_T) \ | 73 | X(KV_T) \ |
| 68 | X(T) \ | 74 | X(T) \ |
| 69 | - X(OUTPUT_T) \ | 75 | + X(OUTPUT_T) |
| 70 | 76 | ||
| 71 | 77 | ||
| 72 | X(IS_FD, bool, false) \ | 78 | X(IS_FD, bool, false) \ |
| @@ -75,27 +81,28 @@ __aicore__ constexpr uint64_t Align64Func(uint64_t data) | |||
| 75 | X(TEMPLATE_MODE, SMLATemplateMode, SMLATemplateMode::CSA_TEMPLATE_MODE) \ | 81 | X(TEMPLATE_MODE, SMLATemplateMode, SMLATemplateMode::CSA_TEMPLATE_MODE) \ |
| 76 | X(IS_SPLIT_G, bool, false) \ | 82 | X(IS_SPLIT_G, bool, false) \ |
| 77 | X(IS_BATCH_CONSISTENCY, bool, false) \ | 83 | X(IS_BATCH_CONSISTENCY, bool, false) \ |
| 78 | - | 84 | + X(IS_VEC_S2PHYADDR, bool, false) |
| 79 | 85 | ||
| 80 | /* 1. 生成带默认值的模版Template */ | 86 | /* 1. 生成带默认值的模版Template */ |
| 81 | 87 | ||
| 82 | 88 | ||
| 83 | 89 | ||
| 84 | 90 | ||
| 85 | -template <CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_TYPE_PARAM) \ | 91 | + template <CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_TYPE_PARAM) \ |
| 86 | - CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_CONST_PARAM) bool end = true> | 92 | + CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_CONST_PARAM) bool end = true> |
| 87 | 93 | ||
| 88 | /* 2. 生成不带带默认值的模版Template */ | 94 | /* 2. 生成不带带默认值的模版Template */ |
| 89 | 95 | ||
| 90 | 96 | ||
| 91 | 97 | ||
| 92 | -template <CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_TEMPLATE_TYPE_NODEF) \ | 98 | + template <CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_TEMPLATE_TYPE_NODEF) \ |
| 93 | - CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_TEMPLATE_CONST_NODEF) bool end> | 99 | + CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_TEMPLATE_CONST_NODEF) bool end> |
| 94 | 100 | ||
| 95 | /* 3. 生成有默认值的Args */ | 101 | /* 3. 生成有默认值的Args */ |
| 96 | 102 | ||
| 97 | 103 | ||
| 98 | CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_ARG_NAME) \ | 104 | CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_ARG_NAME) \ |
| 99 | - CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_ARG_NAME) end | 105 | + CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_ARG_NAME) \ |
| 106 | + end | ||
| 100 | 107 | ||
| 101 | 108 | ||
| @@ -80,10 +80,16 @@ public: | |||
| 80 | static constexpr uint32_t s2BaseSize = 128; | 80 | static constexpr uint32_t s2BaseSize = 128; |
| 81 | static constexpr uint32_t dBaseSize = 512; | 81 | static constexpr uint32_t dBaseSize = 512; |
| 82 | static constexpr uint32_t dBaseMatmulSize = 128; | 82 | static constexpr uint32_t dBaseMatmulSize = 128; |
| 83 | + static constexpr uint32_t rightBufNum = 3; | ||
| 84 | + static constexpr uint32_t rightBufSingleSize = s2BaseSize * dBaseSize; | ||
| 85 | + static constexpr uint32_t rightBufTotalSize = rightBufSingleSize * rightBufNum; | ||
| 86 | + static constexpr uint32_t l1QBufNum = 3; // L1 Q 三缓冲 | ||
| 87 | + static constexpr uint32_t l1KBufNum = 3; // L1 K 三缓冲 | ||
| 88 | + static constexpr uint32_t qHalfNum = 2; // Q 沿 d 轴切半 | ||
| 89 | + static constexpr uint32_t crossCoreMte2SyncFlagId = 15; // IS_SPLIT_G 核间 MTE2 同步 flag ID | ||
| 83 | 90 | ||
| 84 | __aicore__ inline CSABlockCube(){}; | 91 | __aicore__ inline CSABlockCube(){}; |
| 85 | - __aicore__ inline void InitCubeBlock(TPipe *pipe, BufferManager<BufferType::L1> &l1BufferManager, | 92 | + __aicore__ inline void InitCubeBlock(TPipe *pipe, __gm__ uint8_t *query); |
| 86 | - __gm__ uint8_t *query); | ||
| 87 | __aicore__ inline void InitCubeInput(__gm__ uint8_t *oriKv, __gm__ uint8_t *cmpKv, __gm__ uint8_t *cmpSparseIndices, | 93 | __aicore__ inline void InitCubeInput(__gm__ uint8_t *oriKv, __gm__ uint8_t *cmpKv, __gm__ uint8_t *cmpSparseIndices, |
| 88 | __gm__ uint8_t *oriBlockTable, __gm__ uint8_t *cmpBlockTable, | 94 | __gm__ uint8_t *oriBlockTable, __gm__ uint8_t *cmpBlockTable, |
| 89 | __gm__ uint8_t *sequsedQ, __gm__ uint8_t *cuSeqlensQ, | 95 | __gm__ uint8_t *sequsedQ, __gm__ uint8_t *cuSeqlensQ, |
| @@ -91,52 +97,39 @@ public: | |||
| 91 | __gm__ uint8_t *seqUsedOriKV, __gm__ uint8_t *seqUsedCmpKV, | 97 | __gm__ uint8_t *seqUsedOriKV, __gm__ uint8_t *seqUsedCmpKV, |
| 92 | const ConstInfo &constInfo); | 98 | const ConstInfo &constInfo); |
| 93 | 99 | ||
| 94 | - // SWA/HCA场景, inputRightBuf是INNER_CORE_SYNC类型 | 100 | + // SWA/HCA场景 |
| 101 | + __aicore__ inline void IterateLoadQK(RunInfo &runInfo, ConstInfo &constInfo, bool isFirstLoop); | ||
| 102 | + | ||
| 103 | + // CSA场景 | ||
| 104 | + __aicore__ inline void IterateLoadQK(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | ||
| 105 | + RunInfo &runInfo, ConstInfo &constInfo, bool isFirstLoop); | ||
| 95 | __aicore__ inline void IterateBmm1(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &output, | 106 | __aicore__ inline void IterateBmm1(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &output, |
| 96 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, | 107 | + bool notLastTwoLoop, RunInfo &runInfoNext, |
| 97 | - const RunInfo &runInfo, const ConstInfo &constInfo); | 108 | + RunInfo &runInfo, ConstInfo &constInfo); |
| 98 | __aicore__ inline void | 109 | __aicore__ inline void |
| 99 | IterateBmm2(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | 110 | IterateBmm2(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, |
| 100 | BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | 111 | BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, |
| 101 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, const RunInfo &runInfo, | 112 | + const RunInfo &runInfo, const ConstInfo &constInfo); |
| 102 | - const ConstInfo &constInfo); | ||
| 103 | - // CSA场景, inputRightBuf是CROSS_CORE_SYNC_FORWARD类型 | ||
| 104 | - __aicore__ inline void IterateBmm1(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &output, | ||
| 105 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, | ||
| 106 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | ||
| 107 | - const RunInfo &runInfo, const ConstInfo &constInfo); | ||
| 108 | - __aicore__ inline void | ||
| 109 | - IterateBmm2(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 110 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | ||
| 111 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, const RunInfo &runInfo, | ||
| 112 | - const ConstInfo &constInfo); | ||
| 113 | 113 | ||
| 114 | private: | 114 | private: |
| 115 | - __aicore__ inline void InitLocalBuffer(BufferManager<BufferType::L1> &l1BufferManager); | 115 | + __aicore__ inline void InitLocalBuffer(); |
| 116 | __aicore__ inline void InitGmTensor(__gm__ uint8_t *cuSeqlensQ, __gm__ uint8_t *sequsedQ, | 116 | __aicore__ inline void InitGmTensor(__gm__ uint8_t *cuSeqlensQ, __gm__ uint8_t *sequsedQ, |
| 117 | __gm__ uint8_t *cuSeqlensOriKv, __gm__ uint8_t *cuSeqlensCmpKv, | 117 | __gm__ uint8_t *cuSeqlensOriKv, __gm__ uint8_t *cuSeqlensCmpKv, |
| 118 | __gm__ uint8_t *seqUsedOriKV, __gm__ uint8_t *seqUsedCmpKV, | 118 | __gm__ uint8_t *seqUsedOriKV, __gm__ uint8_t *seqUsedCmpKV, |
| 119 | const ConstInfo &constInfo); | 119 | const ConstInfo &constInfo); |
| 120 | - __aicore__ inline void CalcS1Coord(const RunInfo &runInfo, const ConstInfo &constInfo); | ||
| 121 | __aicore__ inline void CalcS2Coord(const RunInfo &runInfo, const ConstInfo &constInfo); | 120 | __aicore__ inline void CalcS2Coord(const RunInfo &runInfo, const ConstInfo &constInfo); |
| 122 | - __aicore__ inline void IterateBmm1HCA(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | 121 | + __aicore__ inline void CopyQGmToL1(RunInfo &runInfo, ConstInfo &constInfo); |
| 123 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, | 122 | + __aicore__ inline void LoadKGmToL1(LocalTensor<KV_T> &inputRightTensor, const RunInfo &runInfo, |
| 124 | - const RunInfo &runInfo, const ConstInfo &constInfo); | 123 | + const ConstInfo &constInfo); |
| 125 | - __aicore__ inline void | ||
| 126 | - IterateBmm2HCA(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 127 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | ||
| 128 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, const RunInfo &runInfo, | ||
| 129 | - const ConstInfo &constInfo); | ||
| 130 | 124 | ||
| 131 | - __aicore__ inline void IterateBmm1CSA(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | 125 | + __aicore__ inline void IterateBmm1Impl(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, |
| 132 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, | 126 | + bool notLastTwoLoop, |
| 133 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 127 | + RunInfo &runInfoNext, RunInfo &runInfo, ConstInfo &constInfo); |
| 134 | - const RunInfo &runInfo, const ConstInfo &constInfo); | ||
| 135 | __aicore__ inline void | 128 | __aicore__ inline void |
| 136 | - IterateBmm2CSA(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | 129 | + IterateBmm2Impl(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, |
| 137 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | 130 | + BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, |
| 138 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, const RunInfo &runInfo, | 131 | + const RunInfo &runInfo, const ConstInfo &constInfo); |
| 139 | - const ConstInfo &constInfo); | 132 | + |
| 140 | TPipe *tPipe; | 133 | TPipe *tPipe; |
| 141 | /* =====================GM变量==================== */ | 134 | /* =====================GM变量==================== */ |
| 142 | static constexpr GmFormat Q_FORMAT = GetQueryGmFormat<LAYOUT_T>(); | 135 | static constexpr GmFormat Q_FORMAT = GetQueryGmFormat<LAYOUT_T>(); |
| @@ -157,35 +150,37 @@ private: | |||
| 157 | CubeCoordInfo coordInfo[3]; | 150 | CubeCoordInfo coordInfo[3]; |
| 158 | uint32_t kvCacheBlockSize = 0; | 151 | uint32_t kvCacheBlockSize = 0; |
| 159 | uint32_t maxBlockNumPerBatch = 0; | 152 | uint32_t maxBlockNumPerBatch = 0; |
| 160 | - TEventID mte1ToMte2Id[3]; | 153 | + uint32_t l0CBufId = 0; |
| 161 | - TEventID mte2ToMte1Id[3]; | 154 | + uint32_t l1QBufId = 0; |
| 162 | - | 155 | + uint32_t l1KLoadBufId = 0; |
| 156 | + uint32_t l1KMatmul1BufId = 0; | ||
| 157 | + uint32_t l1KMatmul2BufId = 0; | ||
| 158 | + uint32_t l0CFixToMFlagId = 0; // {0, 1}, 用于L0C | ||
| 159 | + uint32_t l0CMToFixFlagId = 0; // {0, 1}, 用于L0C | ||
| 160 | + uint32_t l1QMte1ToMte2FlagId = 0; // {0, 1, 2}, 用于l1Q | ||
| 161 | + uint32_t l1QMte2ToMte1FlagId = 0; // {0, 1, 2}, 用于l1Q | ||
| 162 | + uint32_t l1KMte1ToMte2FlagId = 3; // {3, 4, 5}, 用于l1K | ||
| 163 | + uint32_t l1KMte2ToMte1FlagId = 3; // {3, 4, 5}, 用于l1K | ||
| 163 | /* =====================LocalBuffer变量==================== */ | 164 | /* =====================LocalBuffer变量==================== */ |
| 164 | BufferManager<BufferType::L0A> l0aBufferManager; | 165 | BufferManager<BufferType::L0A> l0aBufferManager; |
| 165 | BufferManager<BufferType::L0B> l0bBufferManager; | 166 | BufferManager<BufferType::L0B> l0bBufferManager; |
| 166 | - BufferManager<BufferType::L0C> l0cBufferManager; | ||
| 167 | - | ||
| 168 | - // D小于等于256 mm1左矩阵Q,GS1循环内左矩阵复用, | ||
| 169 | - // GS1循环间开pingpong;D大于256使用单块Buffer,S1循环间驻留;fp32场景单块不驻留 | ||
| 170 | - BuffersPolicySingleBuffer<BufferType::L1> l1QBuffers; | ||
| 171 | - | ||
| 172 | - // L0A | ||
| 173 | BuffersPolicyDB<BufferType::L0A> mmL0ABuffers; | 167 | BuffersPolicyDB<BufferType::L0A> mmL0ABuffers; |
| 174 | - // L0B | ||
| 175 | BuffersPolicyDB<BufferType::L0B> mmL0BBuffers; | 168 | BuffersPolicyDB<BufferType::L0B> mmL0BBuffers; |
| 176 | - // L0C | 169 | + TBuf<TPosition::B1> l1RightBuffers; |
| 177 | - BuffersPolicyDB<BufferType::L0C> mmL0CBuffers; | 170 | + TBuf<TPosition::A1> l1QBuffers; |
| 171 | + TBuf<TPosition::CO1> mmL0CBuffers; | ||
| 172 | + LocalTensor<Q_T> l1RightTensor; | ||
| 173 | + LocalTensor<Q_T> l1QTensor; | ||
| 174 | + LocalTensor<T> mmL0CTensor; | ||
| 178 | }; | 175 | }; |
| 179 | 176 | ||
| 180 | TEMPLATES_DEF_NO_DEFAULT | 177 | TEMPLATES_DEF_NO_DEFAULT |
| 181 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::InitCubeBlock(TPipe *pipe, | 178 | +__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::InitCubeBlock(TPipe *pipe, __gm__ uint8_t *query) |
| 182 | - BufferManager<BufferType::L1> &l1BufferManager, | ||
| 183 | - __gm__ uint8_t *query) | ||
| 184 | { | 179 | { |
| 185 | if ASCEND_IS_AIC { | 180 | if ASCEND_IS_AIC { |
| 186 | tPipe = pipe; | 181 | tPipe = pipe; |
| 187 | this->queryGm.gmTensor.SetGlobalBuffer((__gm__ Q_T *)query); | 182 | this->queryGm.gmTensor.SetGlobalBuffer((__gm__ Q_T *)query); |
| 188 | - InitLocalBuffer(l1BufferManager); | 183 | + InitLocalBuffer(); |
| 189 | } | 184 | } |
| 190 | } | 185 | } |
| 191 | 186 | ||
| @@ -211,37 +206,35 @@ __aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::InitCubeInput( | |||
| 211 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE) { | 206 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE) { |
| 212 | this->cmpSparseIndicesGm.SetGlobalBuffer((__gm__ int32_t *)cmpSparseIndices); | 207 | this->cmpSparseIndicesGm.SetGlobalBuffer((__gm__ int32_t *)cmpSparseIndices); |
| 213 | } | 208 | } |
| 214 | - if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | ||
| 215 | - TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 216 | - TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE || IS_SPLIT_G) { | ||
| 217 | - mte1ToMte2Id[0] = GetTPipePtr()->AllocEventID<HardEvent::MTE2_MTE1>(); | ||
| 218 | - mte1ToMte2Id[1] = GetTPipePtr()->AllocEventID<HardEvent::MTE2_MTE1>(); | ||
| 219 | - mte1ToMte2Id[2] = GetTPipePtr()->AllocEventID<HardEvent::MTE2_MTE1>(); | ||
| 220 | - mte2ToMte1Id[0] = GetTPipePtr()->AllocEventID<HardEvent::MTE1_MTE2>(); | ||
| 221 | - mte2ToMte1Id[1] = GetTPipePtr()->AllocEventID<HardEvent::MTE1_MTE2>(); | ||
| 222 | - mte2ToMte1Id[2] = GetTPipePtr()->AllocEventID<HardEvent::MTE1_MTE2>(); | ||
| 223 | - SetFlag<HardEvent::MTE1_MTE2>(mte2ToMte1Id[0]); | ||
| 224 | - SetFlag<HardEvent::MTE1_MTE2>(mte2ToMte1Id[1]); | ||
| 225 | - SetFlag<HardEvent::MTE1_MTE2>(mte2ToMte1Id[2]); | ||
| 226 | - } | ||
| 227 | InitGmTensor(cuSeqlensQ, sequsedQ, cuSeqlensOriKv, cuSeqlensCmpKv, seqUsedOriKV, seqUsedCmpKV, constInfo); | 209 | InitGmTensor(cuSeqlensQ, sequsedQ, cuSeqlensOriKv, cuSeqlensCmpKv, seqUsedOriKV, seqUsedCmpKV, constInfo); |
| 228 | } | 210 | } |
| 229 | } | 211 | } |
| 230 | 212 | ||
| 231 | TEMPLATES_DEF_NO_DEFAULT | 213 | TEMPLATES_DEF_NO_DEFAULT |
| 232 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::InitLocalBuffer(BufferManager<BufferType::L1> &l1BufferManager) | 214 | +__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::InitLocalBuffer() |
| 233 | { | 215 | { |
| 234 | - constexpr uint32_t mm1LeftSize = s1BaseSize * dBaseSize * sizeof(Q_T); | 216 | + tPipe->InitBuffer(l1RightBuffers, rightBufTotalSize * sizeof(Q_T)); |
| 235 | - l1QBuffers.Init((l1BufferManager), mm1LeftSize); | 217 | + l1RightTensor = l1RightBuffers.Get<Q_T>(); |
| 218 | + | ||
| 219 | + tPipe->InitBuffer(l1QBuffers, BUFFER_SIZE_96K); | ||
| 220 | + l1QTensor = l1QBuffers.Get<Q_T>(); | ||
| 236 | 221 | ||
| 237 | - // L0A B C 当前写死,能否通过基础api获取 | ||
| 238 | l0aBufferManager.Init(tPipe, L0AB_SHARED_SIZE_64K); | 222 | l0aBufferManager.Init(tPipe, L0AB_SHARED_SIZE_64K); |
| 239 | l0bBufferManager.Init(tPipe, L0AB_SHARED_SIZE_64K); | 223 | l0bBufferManager.Init(tPipe, L0AB_SHARED_SIZE_64K); |
| 240 | - l0cBufferManager.Init(tPipe, L0C_SHARED_SIZE_256K); | ||
| 241 | 224 | ||
| 242 | - mmL0ABuffers.Init(l0aBufferManager, BUFFER_SIZE_16K); // db类型,填入数值是总大小的一半 | 225 | + mmL0ABuffers.Init(l0aBufferManager, BUFFER_SIZE_16K); |
| 243 | mmL0BBuffers.Init(l0bBufferManager, BUFFER_SIZE_32K); | 226 | mmL0BBuffers.Init(l0bBufferManager, BUFFER_SIZE_32K); |
| 244 | - mmL0CBuffers.Init(l0cBufferManager, BUFFER_SIZE_128K); | 227 | + |
| 228 | + tPipe->InitBuffer(mmL0CBuffers, BUFFER_SIZE_256K); | ||
| 229 | + mmL0CTensor = mmL0CBuffers.Get<T>(); | ||
| 230 | + SetFlag<HardEvent::FIX_M>(l0CFixToMFlagId); // {0, 1}, 用于L0C | ||
| 231 | + SetFlag<HardEvent::FIX_M>(l0CFixToMFlagId + 1); | ||
| 232 | + SetFlag<HardEvent::MTE1_MTE2>(l1QMte1ToMte2FlagId); // {0, 1, 2}, 用于l1Q | ||
| 233 | + SetFlag<HardEvent::MTE1_MTE2>(l1QMte1ToMte2FlagId + 1); | ||
| 234 | + SetFlag<HardEvent::MTE1_MTE2>(l1QMte1ToMte2FlagId + 2); | ||
| 235 | + SetFlag<HardEvent::MTE1_MTE2>(l1KMte1ToMte2FlagId); // {3, 4, 5}, 用于l1K | ||
| 236 | + SetFlag<HardEvent::MTE1_MTE2>(l1KMte1ToMte2FlagId + 1); | ||
| 237 | + SetFlag<HardEvent::MTE1_MTE2>(l1KMte1ToMte2FlagId + 2); | ||
| 245 | } | 238 | } |
| 246 | 239 | ||
| 247 | /* 初始化GmTensor,设置shape信息并计算strides */ | 240 | /* 初始化GmTensor,设置shape信息并计算strides */ |
| @@ -293,13 +286,6 @@ __aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::InitGmTensor(__gm__ uint8_t | |||
| 293 | } | 286 | } |
| 294 | } | 287 | } |
| 295 | 288 | ||
| 296 | -TEMPLATES_DEF_NO_DEFAULT | ||
| 297 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::CalcS1Coord(const RunInfo &runInfo, const ConstInfo &constInfo) | ||
| 298 | -{ | ||
| 299 | - // 计算s1方向偏移 | ||
| 300 | - coordInfo[runInfo.taskIdMod3].s1Coord = runInfo.s1oIdx * runInfo.qSNumInOneBlock; | ||
| 301 | -} | ||
| 302 | - | ||
| 303 | TEMPLATES_DEF_NO_DEFAULT | 289 | TEMPLATES_DEF_NO_DEFAULT |
| 304 | __aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::CalcS2Coord(const RunInfo &runInfo, const ConstInfo &constInfo) | 290 | __aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::CalcS2Coord(const RunInfo &runInfo, const ConstInfo &constInfo) |
| 305 | { | 291 | { |
| @@ -322,57 +308,25 @@ __aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::CalcS2Coord(const RunInfo &r | |||
| 322 | } | 308 | } |
| 323 | 309 | ||
| 324 | TEMPLATES_DEF_NO_DEFAULT | 310 | TEMPLATES_DEF_NO_DEFAULT |
| 325 | -__aicore__ inline void | 311 | +__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::CopyQGmToL1(RunInfo &runInfo, ConstInfo &constInfo) |
| 326 | -CSABlockCube<TEMPLATE_ARGS>::IterateBmm1(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 327 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, | ||
| 328 | - const RunInfo &runInfo, const ConstInfo &constInfo) | ||
| 329 | { | 312 | { |
| 330 | - CalcS1Coord(runInfo, constInfo); | 313 | + uint64_t gmOffset = this->queryGm.offsetCalculator.GetOffset(runInfo.boIdx, runInfo.n2oIdx, runInfo.goIdx, |
| 331 | - CalcS2Coord(runInfo, constInfo); | 314 | + runInfo.s1oIdx * runInfo.qSNumInOneBlock, 0); |
| 332 | - | 315 | + for (uint32_t i = 0; i < qHalfNum; i++) { |
| 333 | - IterateBmm1HCA(outputBuf, inputRightBuf, runInfo, constInfo); | 316 | + uint32_t curL1QBufId = (l1QBufId + i) % l1QBufNum; |
| 334 | -} | 317 | + WaitFlag<HardEvent::MTE1_MTE2>(l1QMte1ToMte2FlagId + curL1QBufId); |
| 335 | - | 318 | + uint64_t curGmOffset = gmOffset + i * (constInfo.dSize >> 1); |
| 336 | -TEMPLATES_DEF_NO_DEFAULT | 319 | + CopyToL1Nd2Nz<Q_T>(l1QTensor[curL1QBufId * BUFFER_SIZE_16K], |
| 337 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::IterateBmm2( | 320 | + this->queryGm.gmTensor[curGmOffset], runInfo.mRealSize, constInfo.dSize >> 1, |
| 338 | - Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 339 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | ||
| 340 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, const RunInfo &runInfo, | ||
| 341 | - const ConstInfo &constInfo) | ||
| 342 | -{ | ||
| 343 | - IterateBmm2HCA(outputBuf, inputLeftBuffers, inputRightBuf, runInfo, constInfo); | ||
| 344 | -} | ||
| 345 | - | ||
| 346 | -TEMPLATES_DEF_NO_DEFAULT | ||
| 347 | -__aicore__ inline void | ||
| 348 | -CSABlockCube<TEMPLATE_ARGS>::IterateBmm1HCA(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 349 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, | ||
| 350 | - const RunInfo &runInfo, const ConstInfo &constInfo) | ||
| 351 | -{ | ||
| 352 | - Buffer<BufferType::L1> inputLeftBuf; | ||
| 353 | - // 左矩阵复用,S2的第一次循环加载左矩阵 | ||
| 354 | - // 加载左矩阵到L1, 全载 | ||
| 355 | - // query对ori_kv, cmp_kv都一样,无需区分 | ||
| 356 | - if (unlikely(runInfo.s2LoopCount == 0)) { // sOuter循环第一个基本块:搬运Q | ||
| 357 | - inputLeftBuf = l1QBuffers.Get(); | ||
| 358 | - inputLeftBuf.Wait<HardEvent::MTE1_MTE2>(); // 占用L1A | ||
| 359 | - LocalTensor<Q_T> inputLeftTensor = inputLeftBuf.GetTensor<Q_T>(); | ||
| 360 | - | ||
| 361 | - uint64_t gmOffset = this->queryGm.offsetCalculator.GetOffset(runInfo.boIdx, runInfo.n2oIdx, runInfo.goIdx, | ||
| 362 | - coordInfo[runInfo.taskIdMod3].s1Coord, 0); | ||
| 363 | - CopyToL1Nd2Nz<Q_T>(inputLeftTensor, this->queryGm.gmTensor[gmOffset], runInfo.mRealSize, constInfo.dSize, | ||
| 364 | constInfo.mm1Ka); | 321 | constInfo.mm1Ka); |
| 365 | - | 322 | + SetFlag<HardEvent::MTE2_MTE1>(l1QMte2ToMte1FlagId + curL1QBufId); |
| 366 | - inputLeftBuf.Set<HardEvent::MTE2_MTE1>(); // 通知 | ||
| 367 | - } else { // 非S2的第一次循环直接复用Q | ||
| 368 | - inputLeftBuf = l1QBuffers.GetPre(); | ||
| 369 | - // 左矩阵复用时,sinner循环内不需要MTE2同步等待 | ||
| 370 | - inputLeftBuf.Set<HardEvent::MTE2_MTE1>(); // 通知 | ||
| 371 | } | 323 | } |
| 324 | +} | ||
| 372 | 325 | ||
| 373 | - // 加载当前轮的右矩阵到L1 | 326 | +TEMPLATES_DEF_NO_DEFAULT |
| 374 | - inputRightBuf.Wait<HardEvent::MTE1_MTE2>(); // 占用L1B | 327 | +__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::LoadKGmToL1(LocalTensor<KV_T> &inputRightTensor, |
| 375 | - LocalTensor<KV_T> inputRightTensor = inputRightBuf.GetTensor<KV_T>(); | 328 | + const RunInfo &runInfo, const ConstInfo &constInfo) |
| 329 | +{ | ||
| 376 | if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | 330 | if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { |
| 377 | Position startPos; | 331 | Position startPos; |
| 378 | startPos.bIdx = runInfo.boIdx; | 332 | startPos.bIdx = runInfo.boIdx; |
| @@ -395,156 +349,36 @@ CSABlockCube<TEMPLATE_ARGS>::IterateBmm1HCA(Buffer<BufferType::UB, SyncType::CRO | |||
| 395 | CopyToL1Nd2Nz<KV_T>(inputRightTensor, curKvGm.gmTensor[keyOffset], runInfo.s2RealSize, constInfo.dSize, | 349 | CopyToL1Nd2Nz<KV_T>(inputRightTensor, curKvGm.gmTensor[keyOffset], runInfo.s2RealSize, constInfo.dSize, |
| 396 | constInfo.mm1Kb); | 350 | constInfo.mm1Kb); |
| 397 | } | 351 | } |
| 398 | - inputRightBuf.Set<HardEvent::MTE2_MTE1>(); // 通知 | ||
| 399 | - inputRightBuf.Wait<HardEvent::MTE2_MTE1>(); // 等待L1B | ||
| 400 | - | ||
| 401 | - inputLeftBuf.Wait<HardEvent::MTE2_MTE1>(); // 等待L1A | ||
| 402 | - Buffer<BufferType::L0C> mm1ResL0C = mmL0CBuffers.Get(); | ||
| 403 | - mm1ResL0C.Wait<HardEvent::FIX_M>(); // 占用 | ||
| 404 | - MMParam param = { | ||
| 405 | - static_cast<uint32_t>(runInfo.mRealSize), // singleM | ||
| 406 | - static_cast<uint32_t>(runInfo.s2RealSize), // singleN | ||
| 407 | - static_cast<uint32_t>(constInfo.dSize), // singleK | ||
| 408 | - 0, // isLeftTranspose | ||
| 409 | - 1 // isRightTranspose | ||
| 410 | - }; | ||
| 411 | - MatmulK<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( // m,n不切,k切128 | ||
| 412 | - inputLeftBuf.GetTensor<Q_T>(), inputRightBuf.GetTensor<Q_T>(), // mm1B直接用tensor的数据 | ||
| 413 | - mmL0ABuffers, mmL0BBuffers, mm1ResL0C.GetTensor<T>(), param); | ||
| 414 | - if (unlikely(runInfo.s2LoopCount == runInfo.s2LoopLimit)) { | ||
| 415 | - inputLeftBuf.Set<HardEvent::MTE1_MTE2>(); // 释放L1A | ||
| 416 | - } | ||
| 417 | - | ||
| 418 | - mm1ResL0C.Set<HardEvent::M_FIX>(); // 通知 | ||
| 419 | - mm1ResL0C.Wait<HardEvent::M_FIX>(); // 等待L0C | ||
| 420 | - | ||
| 421 | - outputBuf.WaitCrossCore(); | ||
| 422 | - FixpipeParamsC310<CO2Layout::ROW_MAJOR> fixpipeParams; // L0C→UB | ||
| 423 | - // L0C上的bmm1结果矩阵N方向的size大小; 同mmadParams.n; 为什么要8个元素对齐(32B对齐) // 128 | ||
| 424 | - fixpipeParams.nSize = Align8Func(runInfo.s2RealSize); | ||
| 425 | - // 有效数据不足16行,只需要输出部分行即可; L0C上的bmm1结果矩阵M方向的size大小(必须为偶数) // 128 | ||
| 426 | - fixpipeParams.mSize = Align2Func(runInfo.mRealSize); | ||
| 427 | - // L0C上bmm1结果相邻连续数据片段间隔(前面一个数据块的头与后面数据块的头的间隔), 单位为16*sizeof(T) | ||
| 428 | - // 源Nz矩阵中相邻大Z排布的起始地址偏移 | ||
| 429 | - fixpipeParams.srcStride = Align16Func(fixpipeParams.mSize); | ||
| 430 | - // mmResUb上两行之间的间隔,单位:element。 // 128:根据比对dump文件得到, ND方案(S1*S2)时脏数据用mask剔除 | ||
| 431 | - fixpipeParams.dstStride = s2BaseSize; | ||
| 432 | - // 双目标模式,按M维度拆分,M / 2 * N写入每个UB, M必须为2的倍数 | ||
| 433 | - fixpipeParams.dualDstCtl = 1; | ||
| 434 | - fixpipeParams.params.ndNum = 1; | ||
| 435 | - fixpipeParams.params.srcNdStride = 0; | ||
| 436 | - fixpipeParams.params.dstNdStride = 0; | ||
| 437 | - | ||
| 438 | - // 将matmul结果从L0C搬运到UB | ||
| 439 | - Fixpipe<T, T, PFA_CFG_ROW_MAJOR_UB>(outputBuf.template GetTensor<T>(), mm1ResL0C.GetTensor<T>(), fixpipeParams); | ||
| 440 | - mm1ResL0C.Set<HardEvent::FIX_M>(); // 释放L0C | ||
| 441 | - outputBuf.SetCrossCore(); | ||
| 442 | -} | ||
| 443 | - | ||
| 444 | -TEMPLATES_DEF_NO_DEFAULT | ||
| 445 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::IterateBmm2HCA( | ||
| 446 | - Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 447 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | ||
| 448 | - Buffer<BufferType::L1, SyncType::INNER_CORE_SYNC> &inputRightBuf, const RunInfo &runInfo, | ||
| 449 | - const ConstInfo &constInfo) | ||
| 450 | -{ | ||
| 451 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> inputLeftBuf = inputLeftBuffers.Get(); // P直接用无需搬运 | ||
| 452 | - inputLeftBuf.WaitCrossCore(); | ||
| 453 | - | ||
| 454 | - Buffer<BufferType::L0C> mm2ResL0C = mmL0CBuffers.Get(); | ||
| 455 | - mm2ResL0C.Wait<HardEvent::FIX_M>(); // 占用 | ||
| 456 | - MMParam param = { | ||
| 457 | - static_cast<uint32_t>(runInfo.mRealSize), // singleM 64 | ||
| 458 | - static_cast<uint32_t>(constInfo.dSizeV), // singleN 512 | ||
| 459 | - static_cast<uint32_t>(runInfo.s2RealSize), // singleK 128 | ||
| 460 | - 0, // isLeftTranspose | ||
| 461 | - 0 // isRightTranspose | ||
| 462 | - }; | ||
| 463 | - MatmulN<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( | ||
| 464 | - inputLeftBuf.GetTensor<Q_T>(), inputRightBuf.GetTensor<Q_T>(), mmL0ABuffers, mmL0BBuffers, | ||
| 465 | - mm2ResL0C.GetTensor<T>(), param); | ||
| 466 | - | ||
| 467 | - inputLeftBuf.SetCrossCore(); | ||
| 468 | - // bmm2才释放KV,在这里释放 | ||
| 469 | - inputRightBuf.Set<HardEvent::MTE1_MTE2>(); | ||
| 470 | - | ||
| 471 | - mm2ResL0C.Set<HardEvent::M_FIX>(); // 通知 | ||
| 472 | - mm2ResL0C.Wait<HardEvent::M_FIX>(); // 等待 | ||
| 473 | - | ||
| 474 | - // 占用 | ||
| 475 | - outputBuf.WaitCrossCore(); | ||
| 476 | - // L0C→UB;FixpipeParamsM300:L0C→UB | ||
| 477 | - FixpipeParamsC310<CO2Layout::ROW_MAJOR> fixpipeParams; | ||
| 478 | - // L0C上的bmm1结果矩阵N方向的size大小, 分档计算且vector2中通过mask筛选出实际有效值 | ||
| 479 | - fixpipeParams.nSize = Align8Func(constInfo.dSizeV); | ||
| 480 | - // 有效数据不足16行,只需要输出部分行即可; L0C上的bmm1结果矩阵M方向的size大小; 同mmadParams.m | ||
| 481 | - fixpipeParams.mSize = Align2Func(runInfo.mRealSize); | ||
| 482 | - // L0C上bmm1结果相邻连续数据片段间隔(前面一个数据块的头与后面数据块的头的间隔) | ||
| 483 | - fixpipeParams.srcStride = Align16Func(fixpipeParams.mSize); | ||
| 484 | - fixpipeParams.dstStride = Align16Func(constInfo.dSizeV); | ||
| 485 | - fixpipeParams.dualDstCtl = 1; | ||
| 486 | - fixpipeParams.params.ndNum = 1; | ||
| 487 | - fixpipeParams.params.srcNdStride = 0; | ||
| 488 | - fixpipeParams.params.dstNdStride = 0; | ||
| 489 | - Fixpipe<T, T, PFA_CFG_ROW_MAJOR_UB>(outputBuf.template GetTensor<T>(), mm2ResL0C.GetTensor<T>(), | ||
| 490 | - fixpipeParams); // 将matmul结果从L0C搬运到UB | ||
| 491 | - mm2ResL0C.Set<HardEvent::FIX_M>(); // 释放 | ||
| 492 | - | ||
| 493 | - outputBuf.SetCrossCore(); | ||
| 494 | } | 352 | } |
| 495 | 353 | ||
| 354 | +// SWA/HCA场景: K从GM直接搬运 | ||
| 496 | TEMPLATES_DEF_NO_DEFAULT | 355 | TEMPLATES_DEF_NO_DEFAULT |
| 497 | __aicore__ inline void | 356 | __aicore__ inline void |
| 498 | -CSABlockCube<TEMPLATE_ARGS>::IterateBmm1(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | 357 | +CSABlockCube<TEMPLATE_ARGS>::IterateLoadQK(RunInfo &runInfo, ConstInfo &constInfo, bool isFirstLoop) |
| 499 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, | ||
| 500 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | ||
| 501 | - const RunInfo &runInfo, const ConstInfo &constInfo) | ||
| 502 | { | 358 | { |
| 503 | - CalcS1Coord(runInfo, constInfo); | 359 | + if (unlikely(isFirstLoop)) { |
| 504 | - CalcS2Coord(runInfo, constInfo); | 360 | + CopyQGmToL1(runInfo, constInfo); |
| 505 | - | ||
| 506 | - IterateBmm1CSA(outputBuf, inputRightBuf, v0ResGm, runInfo, constInfo); | ||
| 507 | -} | ||
| 508 | - | ||
| 509 | -TEMPLATES_DEF_NO_DEFAULT | ||
| 510 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::IterateBmm2( | ||
| 511 | - Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 512 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | ||
| 513 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, const RunInfo &runInfo, | ||
| 514 | - const ConstInfo &constInfo) | ||
| 515 | -{ | ||
| 516 | - IterateBmm2CSA(outputBuf, inputLeftBuffers, inputRightBuf, runInfo, constInfo); | ||
| 517 | -} | ||
| 518 | - | ||
| 519 | -TEMPLATES_DEF_NO_DEFAULT | ||
| 520 | -__aicore__ inline void | ||
| 521 | -CSABlockCube<TEMPLATE_ARGS>::IterateBmm1CSA(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 522 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, | ||
| 523 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | ||
| 524 | - const RunInfo &runInfo, const ConstInfo &constInfo) | ||
| 525 | -{ | ||
| 526 | - Buffer<BufferType::L1> inputLeftBuf; | ||
| 527 | - // 左矩阵复用,S2的第一次循环加载左矩阵 | ||
| 528 | - // 加载左矩阵到L1, 全载 | ||
| 529 | - // query对ori_kv, cmp_kv都一样,无需区分 | ||
| 530 | - if (unlikely(runInfo.s2LoopCount == 0)) { // sOuter循环第一个基本块:搬运Q | ||
| 531 | - inputLeftBuf = l1QBuffers.Get(); | ||
| 532 | - inputLeftBuf.Wait<HardEvent::MTE1_MTE2>(); // 占用L1A | ||
| 533 | - LocalTensor<Q_T> inputLeftTensor = inputLeftBuf.GetTensor<Q_T>(); | ||
| 534 | - | ||
| 535 | - uint64_t gmOffset = this->queryGm.offsetCalculator.GetOffset(runInfo.boIdx, runInfo.n2oIdx, runInfo.goIdx, | ||
| 536 | - coordInfo[runInfo.taskIdMod3].s1Coord, 0); | ||
| 537 | - CopyToL1Nd2Nz<Q_T>(inputLeftTensor, this->queryGm.gmTensor[gmOffset], runInfo.mRealSize, constInfo.dSize, | ||
| 538 | - constInfo.mm1Ka); | ||
| 539 | - | ||
| 540 | - inputLeftBuf.Set<HardEvent::MTE2_MTE1>(); // 通知 | ||
| 541 | - } else { // 非S2的第一次循环直接复用Q | ||
| 542 | - inputLeftBuf = l1QBuffers.GetPre(); | ||
| 543 | - // 左矩阵复用时,sinner循环内不需要MTE2同步等待 | ||
| 544 | - inputLeftBuf.Set<HardEvent::MTE2_MTE1>(); // 通知 | ||
| 545 | } | 361 | } |
| 546 | 362 | ||
| 547 | // 加载当前轮的右矩阵到L1 | 363 | // 加载当前轮的右矩阵到L1 |
| 364 | + CalcS2Coord(runInfo, constInfo); | ||
| 365 | + WaitFlag<HardEvent::MTE1_MTE2>(l1KMte1ToMte2FlagId + l1KLoadBufId); | ||
| 366 | + LocalTensor<KV_T> dst = l1RightTensor[runInfo.taskIdMod3 * rightBufSingleSize]; | ||
| 367 | + LoadKGmToL1(dst, runInfo, constInfo); | ||
| 368 | + SetFlag<HardEvent::MTE2_MTE1>(l1KMte2ToMte1FlagId + l1KLoadBufId); | ||
| 369 | + l1KLoadBufId = (l1KLoadBufId + 1) % l1KBufNum; | ||
| 370 | +} | ||
| 371 | + | ||
| 372 | +// CSA场景: K来源取决于isSparse | ||
| 373 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 374 | +__aicore__ inline void | ||
| 375 | +CSABlockCube<TEMPLATE_ARGS>::IterateLoadQK(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | ||
| 376 | + RunInfo &runInfo, ConstInfo &constInfo, bool isFirstLoop) | ||
| 377 | +{ | ||
| 378 | + if (unlikely(isFirstLoop)) { | ||
| 379 | + CopyQGmToL1(runInfo, constInfo); | ||
| 380 | + } | ||
| 381 | + | ||
| 548 | // ORI_SPARSE、ORI_CMP_SPARSE及CSA的cmpKv为v0稀疏搬运,CSA的oriKv为cube搬运 | 382 | // ORI_SPARSE、ORI_CMP_SPARSE及CSA的cmpKv为v0稀疏搬运,CSA的oriKv为cube搬运 |
| 549 | bool isSparse = false; | 383 | bool isSparse = false; |
| 550 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | 384 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || |
| @@ -554,67 +388,107 @@ CSABlockCube<TEMPLATE_ARGS>::IterateBmm1CSA(Buffer<BufferType::UB, SyncType::CRO | |||
| 554 | isSparse = runInfo.isCmp ? true : false; | 388 | isSparse = runInfo.isCmp ? true : false; |
| 555 | } | 389 | } |
| 556 | 390 | ||
| 391 | + WaitFlag<HardEvent::MTE1_MTE2>(l1KMte1ToMte2FlagId + l1KLoadBufId); | ||
| 392 | + LocalTensor<Q_T> dst = l1RightTensor[runInfo.taskIdMod3 * rightBufSingleSize]; | ||
| 557 | if (!isSparse) { | 393 | if (!isSparse) { |
| 558 | - WaitFlag<HardEvent::MTE1_MTE2>(mte2ToMte1Id[runInfo.taskIdMod3]); | 394 | + if constexpr (IS_SPLIT_G) { |
| 559 | - LocalTensor<KV_T> inputRightTensor = inputRightBuf.GetTensor<KV_T>(); | 395 | + CrossCoreSetFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 560 | - if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | 396 | + CrossCoreWaitFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 561 | - Position startPos; | ||
| 562 | - startPos.bIdx = runInfo.boIdx; | ||
| 563 | - startPos.n2Idx = runInfo.n2oIdx; | ||
| 564 | - startPos.s2Offset = coordInfo[runInfo.taskIdMod3].s2Coord; | ||
| 565 | - startPos.dIdx = 0; | ||
| 566 | - PAShape shape; | ||
| 567 | - shape.blockSize = kvCacheBlockSize; | ||
| 568 | - shape.headNum = constInfo.n2Size; | ||
| 569 | - shape.headDim = constInfo.dSize; | ||
| 570 | - shape.actHeadDim = constInfo.dSize; | ||
| 571 | - shape.maxblockNumPerBatch = maxBlockNumPerBatch; | ||
| 572 | - shape.copyRowNum = runInfo.s2RealSize; | ||
| 573 | - shape.copyRowNumAlign = (runInfo.s2RealSize + 15) >> 4 << 4; | ||
| 574 | - shape.pageStride = runInfo.isCmp ? constInfo.cmpKeyStride0 : constInfo.oriKeyStride0; | ||
| 575 | - GmCopyInToL1PA<KV_T>(inputRightTensor, curKvGm.gmTensor, blockTableGm, KVLAYOUT::BBH, shape, startPos); | ||
| 576 | - } else { | ||
| 577 | - int64_t keyOffset = this->curKvGm.offsetCalculator.GetOffset( | ||
| 578 | - coordInfo[runInfo.taskIdMod3].curBIdx, runInfo.n2oIdx, coordInfo[runInfo.taskIdMod3].s2Coord, 0); | ||
| 579 | - CopyToL1Nd2Nz<KV_T>(inputRightTensor, curKvGm.gmTensor[keyOffset], runInfo.s2RealSize, constInfo.dSize, | ||
| 580 | - constInfo.mm1Kb); | ||
| 581 | } | 397 | } |
| 582 | - SetFlag<HardEvent::MTE2_MTE1>(mte1ToMte2Id[runInfo.taskIdMod3]); | 398 | + // cube直接从kv cache搬运K |
| 583 | - WaitFlag<HardEvent::MTE2_MTE1>(mte1ToMte2Id[runInfo.taskIdMod3]); | 399 | + CalcS2Coord(runInfo, constInfo); |
| 400 | + LoadKGmToL1(dst, runInfo, constInfo); | ||
| 584 | } else { | 401 | } else { |
| 585 | - inputRightBuf.WaitCrossCore(); | ||
| 586 | - WaitFlag<HardEvent::MTE1_MTE2>(mte2ToMte1Id[runInfo.taskIdMod3]); | ||
| 587 | - LocalTensor<Q_T> dst = inputRightBuf.GetTensor<Q_T>(); | ||
| 588 | v0ResGm.WaitCrossCore(); | 402 | v0ResGm.WaitCrossCore(); |
| 403 | + if constexpr (IS_SPLIT_G) { | ||
| 404 | + CrossCoreSetFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); | ||
| 405 | + CrossCoreWaitFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); | ||
| 406 | + } | ||
| 589 | GlobalTensor<Q_T> v0ResGmTensor = v0ResGm.template GetTensor<Q_T>(); | 407 | GlobalTensor<Q_T> v0ResGmTensor = v0ResGm.template GetTensor<Q_T>(); |
| 590 | CopyToL1Nd2Nz<Q_T>(dst, v0ResGmTensor, runInfo.s2RealSize, constInfo.dSize, constInfo.mm1Kb); | 408 | CopyToL1Nd2Nz<Q_T>(dst, v0ResGmTensor, runInfo.s2RealSize, constInfo.dSize, constInfo.mm1Kb); |
| 591 | - SetFlag<HardEvent::MTE2_MTE1>(mte1ToMte2Id[runInfo.taskIdMod3]); | ||
| 592 | - WaitFlag<HardEvent::MTE2_MTE1>(mte1ToMte2Id[runInfo.taskIdMod3]); | ||
| 593 | } | 409 | } |
| 410 | + SetFlag<HardEvent::MTE2_MTE1>(l1KMte2ToMte1FlagId + l1KLoadBufId); | ||
| 411 | + l1KLoadBufId = (l1KLoadBufId + 1) % l1KBufNum; | ||
| 412 | +} | ||
| 413 | + | ||
| 414 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 415 | +__aicore__ inline void | ||
| 416 | +CSABlockCube<TEMPLATE_ARGS>::IterateBmm1(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 417 | + bool notLastTwoLoop, RunInfo &runInfoNext, | ||
| 418 | + RunInfo &runInfo, ConstInfo &constInfo) | ||
| 419 | +{ | ||
| 420 | + IterateBmm1Impl(outputBuf, notLastTwoLoop, runInfoNext, runInfo, constInfo); | ||
| 421 | +} | ||
| 422 | + | ||
| 423 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 424 | +__aicore__ inline void | ||
| 425 | +CSABlockCube<TEMPLATE_ARGS>::IterateBmm2(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 426 | + BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | ||
| 427 | + const RunInfo &runInfo, const ConstInfo &constInfo) | ||
| 428 | +{ | ||
| 429 | + IterateBmm2Impl(outputBuf, inputLeftBuffers, runInfo, constInfo); | ||
| 430 | +} | ||
| 431 | + | ||
| 432 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 433 | +__aicore__ inline void | ||
| 434 | +CSABlockCube<TEMPLATE_ARGS>::IterateBmm1Impl(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | ||
| 435 | + bool notLastTwoLoop, | ||
| 436 | + RunInfo &runInfoNext, RunInfo &runInfo, ConstInfo &constInfo) | ||
| 437 | +{ | ||
| 438 | + LocalTensor<Q_T> curL1RightTensor = l1RightTensor[runInfo.taskIdMod3 * rightBufSingleSize]; | ||
| 439 | + WaitFlag<HardEvent::MTE2_MTE1>(l1KMte2ToMte1FlagId + l1KMatmul1BufId); | ||
| 440 | + l1KMatmul1BufId = (l1KMatmul1BufId + 1) % l1KBufNum; | ||
| 441 | + WaitFlag<HardEvent::FIX_M>(l0CFixToMFlagId + l0CBufId); | ||
| 594 | 442 | ||
| 595 | - inputLeftBuf.Wait<HardEvent::MTE2_MTE1>(); // 等待L1A | ||
| 596 | - Buffer<BufferType::L0C> mm1ResL0C = mmL0CBuffers.Get(); | ||
| 597 | - mm1ResL0C.Wait<HardEvent::FIX_M>(); // 占用 | ||
| 598 | MMParam param = { | 443 | MMParam param = { |
| 599 | - static_cast<uint32_t>(runInfo.mRealSize), // singleM | 444 | + static_cast<uint32_t>(runInfo.mRealSize), // singleM |
| 600 | - static_cast<uint32_t>(runInfo.s2RealSize), // singleN | 445 | + static_cast<uint32_t>(runInfo.s2RealSize), // singleN |
| 601 | - static_cast<uint32_t>(constInfo.dSize), // singleK | 446 | + static_cast<uint32_t>(constInfo.dSize >> 1), // singleK |
| 602 | - 0, // isLeftTranspose | 447 | + 0, // isLeftTranspose |
| 603 | - 1 // isRightTranspose | 448 | + 1 // isRightTranspose |
| 604 | }; | 449 | }; |
| 605 | - MatmulK<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( // m,n不切,k切128 | 450 | + uint32_t curL1QBufId = l1QBufId; |
| 606 | - inputLeftBuf.GetTensor<Q_T>(), inputRightBuf.GetTensor<Q_T>(), // mm1B直接用tensor的数据 | 451 | + if (unlikely(runInfo.s2LoopCount == 0)) { |
| 607 | - mmL0ABuffers, mmL0BBuffers, mm1ResL0C.GetTensor<T>(), param); | 452 | + WaitFlag<HardEvent::MTE2_MTE1>(l1QMte2ToMte1FlagId + curL1QBufId); |
| 608 | - if (unlikely(runInfo.s2LoopCount == runInfo.s2LoopLimit)) { | ||
| 609 | - inputLeftBuf.Set<HardEvent::MTE1_MTE2>(); // 释放L1A | ||
| 610 | } | 453 | } |
| 611 | 454 | ||
| 612 | - mm1ResL0C.Set<HardEvent::M_FIX>(); // 通知 | 455 | + // m,n不切,k切128,mm1B直接用tensor的数据 |
| 613 | - mm1ResL0C.Wait<HardEvent::M_FIX>(); // 等待L0C | 456 | + MatmulK<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( |
| 457 | + l1QTensor[curL1QBufId * BUFFER_SIZE_16K], | ||
| 458 | + curL1RightTensor, | ||
| 459 | + mmL0ABuffers, mmL0BBuffers, | ||
| 460 | + mmL0CTensor[BUFFER_SIZE_32K * l0CBufId], | ||
| 461 | + param); | ||
| 462 | + | ||
| 463 | + curL1QBufId = (curL1QBufId + 1) % l1QBufNum; | ||
| 464 | + if (unlikely(runInfo.s2LoopCount == 0)) { | ||
| 465 | + WaitFlag<HardEvent::MTE2_MTE1>(l1QMte2ToMte1FlagId + curL1QBufId); | ||
| 466 | + } | ||
| 467 | + param.singleK = constInfo.dSize - param.singleK; | ||
| 468 | + param.isOutKFisrt = false; | ||
| 469 | + | ||
| 470 | + // m,n不切,k切128, mm1B直接用tensor的数据 | ||
| 471 | + MatmulK<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( | ||
| 472 | + l1QTensor[curL1QBufId * BUFFER_SIZE_16K], | ||
| 473 | + curL1RightTensor[(constInfo.dSize >> 1) * Align16Func(runInfo.s2RealSize)], | ||
| 474 | + mmL0ABuffers, mmL0BBuffers, | ||
| 475 | + mmL0CTensor[BUFFER_SIZE_32K * l0CBufId], | ||
| 476 | + param); | ||
| 477 | + | ||
| 478 | + if (unlikely(runInfo.s2LoopCount == runInfo.s2LoopLimit)) { | ||
| 479 | + SetFlag<HardEvent::MTE1_MTE2>(l1QMte1ToMte2FlagId + l1QBufId); | ||
| 480 | + SetFlag<HardEvent::MTE1_MTE2>(l1QMte1ToMte2FlagId + curL1QBufId); | ||
| 481 | + l1QBufId = (l1QBufId + qHalfNum) % l1QBufNum; | ||
| 482 | + if (notLastTwoLoop) { | ||
| 483 | + CopyQGmToL1(runInfoNext, constInfo); | ||
| 484 | + } | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + SetFlag<HardEvent::M_FIX>(l0CMToFixFlagId + l0CBufId); | ||
| 488 | + WaitFlag<HardEvent::M_FIX>(l0CMToFixFlagId + l0CBufId); | ||
| 614 | 489 | ||
| 615 | outputBuf.WaitCrossCore(); | 490 | outputBuf.WaitCrossCore(); |
| 616 | - // L0C→UB | 491 | + FixpipeParamsC310<CO2Layout::ROW_MAJOR> fixpipeParams; // L0C→UB |
| 617 | - FixpipeParamsC310<CO2Layout::ROW_MAJOR> fixpipeParams; | ||
| 618 | // L0C上的bmm1结果矩阵N方向的size大小; 同mmadParams.n; 为什么要8个元素对齐(32B对齐) // 128 | 492 | // L0C上的bmm1结果矩阵N方向的size大小; 同mmadParams.n; 为什么要8个元素对齐(32B对齐) // 128 |
| 619 | fixpipeParams.nSize = Align8Func(runInfo.s2RealSize); | 493 | fixpipeParams.nSize = Align8Func(runInfo.s2RealSize); |
| 620 | // 有效数据不足16行,只需要输出部分行即可; L0C上的bmm1结果矩阵M方向的size大小(必须为偶数) // 128 | 494 | // 有效数据不足16行,只需要输出部分行即可; L0C上的bmm1结果矩阵M方向的size大小(必须为偶数) // 128 |
| @@ -631,45 +505,45 @@ CSABlockCube<TEMPLATE_ARGS>::IterateBmm1CSA(Buffer<BufferType::UB, SyncType::CRO | |||
| 631 | fixpipeParams.params.dstNdStride = 0; | 505 | fixpipeParams.params.dstNdStride = 0; |
| 632 | 506 | ||
| 633 | // 将matmul结果从L0C搬运到UB | 507 | // 将matmul结果从L0C搬运到UB |
| 634 | - Fixpipe<T, T, PFA_CFG_ROW_MAJOR_UB>(outputBuf.template GetTensor<T>(), mm1ResL0C.GetTensor<T>(), fixpipeParams); | 508 | + Fixpipe<T, T, PFA_CFG_ROW_MAJOR_UB>(outputBuf.template GetTensor<T>(), |
| 635 | - mm1ResL0C.Set<HardEvent::FIX_M>(); // 释放L0C | 509 | + mmL0CTensor[BUFFER_SIZE_32K * l0CBufId], fixpipeParams); |
| 510 | + SetFlag<HardEvent::FIX_M>(l0CFixToMFlagId + l0CBufId); | ||
| 511 | + l0CBufId ^= 1; | ||
| 636 | outputBuf.SetCrossCore(); | 512 | outputBuf.SetCrossCore(); |
| 637 | } | 513 | } |
| 638 | 514 | ||
| 639 | TEMPLATES_DEF_NO_DEFAULT | 515 | TEMPLATES_DEF_NO_DEFAULT |
| 640 | -__aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::IterateBmm2CSA( | 516 | +__aicore__ inline void |
| 641 | - Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, | 517 | +CSABlockCube<TEMPLATE_ARGS>::IterateBmm2Impl(Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &outputBuf, |
| 642 | - BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, | 518 | + BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputLeftBuffers, |
| 643 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &inputRightBuf, const RunInfo &runInfo, | 519 | + const RunInfo &runInfo, |
| 644 | - const ConstInfo &constInfo) | 520 | + const ConstInfo &constInfo) |
| 645 | { | 521 | { |
| 646 | - Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> inputLeftBuf = inputLeftBuffers.Get(); // P直接用无需搬运 | 522 | + LocalTensor<Q_T> curL1RightTensor = l1RightTensor[runInfo.taskIdMod3 * rightBufSingleSize]; |
| 647 | - inputLeftBuf.WaitCrossCore(); | 523 | + Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> l1PBuffer = inputLeftBuffers.Get(); // P直接用无需搬运 |
| 524 | + l1PBuffer.WaitCrossCore(); | ||
| 648 | 525 | ||
| 649 | - Buffer<BufferType::L0C> mm2ResL0C = mmL0CBuffers.Get(); | 526 | + WaitFlag<HardEvent::FIX_M>(l0CFixToMFlagId + l0CBufId); |
| 650 | - mm2ResL0C.Wait<HardEvent::FIX_M>(); // 占用 | ||
| 651 | MMParam param = { | 527 | MMParam param = { |
| 652 | - static_cast<uint32_t>(runInfo.mRealSize), // singleM 64 | 528 | + static_cast<uint32_t>(runInfo.mRealSize), // singleM |
| 653 | static_cast<uint32_t>(constInfo.dSizeV), // singleN 512 | 529 | static_cast<uint32_t>(constInfo.dSizeV), // singleN 512 |
| 654 | static_cast<uint32_t>(runInfo.s2RealSize), // singleK 128 | 530 | static_cast<uint32_t>(runInfo.s2RealSize), // singleK 128 |
| 655 | 0, // isLeftTranspose | 531 | 0, // isLeftTranspose |
| 656 | 0 // isRightTranspose | 532 | 0 // isRightTranspose |
| 657 | }; | 533 | }; |
| 658 | MatmulN<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( | 534 | MatmulN<Q_T, Q_T, T, s1BaseSize, s2BaseSize, dBaseMatmulSize, ABLayout::MK, ABLayout::KN>( |
| 659 | - inputLeftBuf.GetTensor<Q_T>(), inputRightBuf.GetTensor<Q_T>(), mmL0ABuffers, mmL0BBuffers, | 535 | + l1PBuffer.template GetTensor<Q_T>(), |
| 660 | - mm2ResL0C.GetTensor<T>(), param); | 536 | + curL1RightTensor, |
| 537 | + mmL0ABuffers, mmL0BBuffers, | ||
| 538 | + mmL0CTensor[BUFFER_SIZE_32K * l0CBufId], | ||
| 539 | + param); | ||
| 661 | 540 | ||
| 662 | - if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | 541 | + SetFlag<HardEvent::M_FIX>(l0CMToFixFlagId + l0CBufId); |
| 663 | - TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | 542 | + WaitFlag<HardEvent::M_FIX>(l0CMToFixFlagId + l0CBufId); |
| 664 | - TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | 543 | + SetFlag<HardEvent::MTE1_MTE2>(l1KMte1ToMte2FlagId + l1KMatmul2BufId); |
| 665 | - SetFlag<HardEvent::MTE1_MTE2>(mte2ToMte1Id[runInfo.taskIdMod3]); | 544 | + l1KMatmul2BufId = (l1KMatmul2BufId + 1) % l1KBufNum; |
| 666 | - } | ||
| 667 | 545 | ||
| 668 | - mm2ResL0C.Set<HardEvent::M_FIX>(); // 通知 | 546 | + outputBuf.WaitCrossCore(); // 占用 |
| 669 | - mm2ResL0C.Wait<HardEvent::M_FIX>(); // 等待 | ||
| 670 | - | ||
| 671 | - // 占用 | ||
| 672 | - outputBuf.WaitCrossCore(); | ||
| 673 | // L0C→UB;FixpipeParamsM300:L0C→UB | 547 | // L0C→UB;FixpipeParamsM300:L0C→UB |
| 674 | FixpipeParamsC310<CO2Layout::ROW_MAJOR> fixpipeParams; | 548 | FixpipeParamsC310<CO2Layout::ROW_MAJOR> fixpipeParams; |
| 675 | // L0C上的bmm1结果矩阵N方向的size大小, 分档计算且vector2中通过mask筛选出实际有效值 | 549 | // L0C上的bmm1结果矩阵N方向的size大小, 分档计算且vector2中通过mask筛选出实际有效值 |
| @@ -683,9 +557,10 @@ __aicore__ inline void CSABlockCube<TEMPLATE_ARGS>::IterateBmm2CSA( | |||
| 683 | fixpipeParams.params.ndNum = 1; | 557 | fixpipeParams.params.ndNum = 1; |
| 684 | fixpipeParams.params.srcNdStride = 0; | 558 | fixpipeParams.params.srcNdStride = 0; |
| 685 | fixpipeParams.params.dstNdStride = 0; | 559 | fixpipeParams.params.dstNdStride = 0; |
| 686 | - Fixpipe<T, T, PFA_CFG_ROW_MAJOR_UB>(outputBuf.template GetTensor<T>(), mm2ResL0C.GetTensor<T>(), | 560 | + Fixpipe<T, T, PFA_CFG_ROW_MAJOR_UB>(outputBuf.template GetTensor<T>(), |
| 687 | - fixpipeParams); // 将matmul结果从L0C搬运到UB | 561 | + mmL0CTensor[BUFFER_SIZE_32K * l0CBufId], fixpipeParams); // 将matmul结果从L0C搬运到UB |
| 688 | - mm2ResL0C.Set<HardEvent::FIX_M>(); // 释放 | 562 | + SetFlag<HardEvent::FIX_M>(l0CFixToMFlagId + l0CBufId); |
| 563 | + l0CBufId ^= 1; | ||
| 689 | 564 | ||
| 690 | outputBuf.SetCrossCore(); | 565 | outputBuf.SetCrossCore(); |
| 691 | } | 566 | } |
| @@ -694,10 +569,7 @@ TEMPLATES_DEF | |||
| 694 | class CSABlockCubeDummy { | 569 | class CSABlockCubeDummy { |
| 695 | public: | 570 | public: |
| 696 | __aicore__ inline CSABlockCubeDummy(){}; | 571 | __aicore__ inline CSABlockCubeDummy(){}; |
| 697 | - __aicore__ inline void InitCubeBlock(TPipe *pipe, BufferManager<BufferType::L1> &l1BufferManager, | 572 | + __aicore__ inline void InitCubeBlock(TPipe *pipe, __gm__ uint8_t *query) {} |
| 698 | - __gm__ uint8_t *query) | ||
| 699 | - { | ||
| 700 | - } | ||
| 701 | __aicore__ inline void InitCubeInput(__gm__ uint8_t *oriKv, __gm__ uint8_t *cmpKv, __gm__ uint8_t *cmpSparseIndices, | 573 | __aicore__ inline void InitCubeInput(__gm__ uint8_t *oriKv, __gm__ uint8_t *cmpKv, __gm__ uint8_t *cmpSparseIndices, |
| 702 | __gm__ uint8_t *oriBlockTable, __gm__ uint8_t *cmpBlockTable, | 574 | __gm__ uint8_t *oriBlockTable, __gm__ uint8_t *cmpBlockTable, |
| 703 | __gm__ uint8_t *sequsedQ, __gm__ uint8_t *cuSeqlensQ, | 575 | __gm__ uint8_t *sequsedQ, __gm__ uint8_t *cuSeqlensQ, |
| @@ -715,11 +587,11 @@ struct CubeBlockTraits; // 声明 | |||
| 715 | 587 | ||
| 716 | 588 | ||
| 717 | 589 | ||
| 718 | -#define DEFINE_CUBE_BLOCK_TRAITS(CUBE_BLOCK_CLASS) \ | 590 | +#define DEFINE_CUBE_BLOCK_TRAITS(CUBE_BLOCK_CLASS) \ |
| 719 | - TEMPLATES_DEF_NO_DEFAULT \ | 591 | + TEMPLATES_DEF_NO_DEFAULT \ |
| 720 | - struct CubeBlockTraits<CUBE_BLOCK_CLASS<TEMPLATE_ARGS>> { \ | 592 | + struct CubeBlockTraits<CUBE_BLOCK_CLASS<TEMPLATE_ARGS>> { \ |
| 721 | - CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_TRAIT_TYPE) \ | 593 | + CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_TRAIT_TYPE) \ |
| 722 | - CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_TRAIT_CONST) \ | 594 | + CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_TRAIT_CONST) \ |
| 723 | } | 595 | } |
| 724 | 596 | ||
| 725 | DEFINE_CUBE_BLOCK_TRAITS(CSABlockCube); | 597 | DEFINE_CUBE_BLOCK_TRAITS(CSABlockCube); |
| @@ -728,8 +600,8 @@ DEFINE_CUBE_BLOCK_TRAITS(CSABlockCubeDummy); | |||
| 728 | // /* 生成Arg Traits, kernel中只需要调用ARGS_TRAITS就可以获取所有CubeBlock中的模板参数 */ | 600 | // /* 生成Arg Traits, kernel中只需要调用ARGS_TRAITS就可以获取所有CubeBlock中的模板参数 */ |
| 729 | 601 | ||
| 730 | 602 | ||
| 731 | -#define ARGS_TRAITS \ | 603 | +#define ARGS_TRAITS \ |
| 732 | - CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_ARGS_TYPE) \ | 604 | + CUBE_BLOCK_TRAITS_TYPE_FIELDS(GEN_ARGS_TYPE) \ |
| 733 | CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_ARGS_CONST) | 605 | CUBE_BLOCK_TRAITS_CONST_FIELDS(GEN_ARGS_CONST) |
| 734 | } // namespace SMLAKernel | 606 | } // namespace SMLAKernel |
| 735 | 607 | ||
| @@ -80,6 +80,14 @@ public: | |||
| 80 | static constexpr uint32_t dTemplateAlign64 = Align64Func(dVTemplateType); | 80 | static constexpr uint32_t dTemplateAlign64 = Align64Func(dVTemplateType); |
| 81 | static constexpr float R0 = 1.0f; | 81 | static constexpr float R0 = 1.0f; |
| 82 | 82 | ||
| 83 | + // GetKVPhyAddrForKvType 事件 ID (手动管理, 不通过 AllocEventID) | ||
| 84 | + static constexpr uint32_t blkTableVToMte2FlagId = 3; // block table V→MTE2 | ||
| 85 | + static constexpr uint32_t sparseIdxVToMte2FlagId = 4; // sparse indices V→MTE2 | ||
| 86 | + static constexpr uint32_t phyAddrVToMte3FlagId = 5; // phy addr V→MTE3 | ||
| 87 | + static constexpr uint32_t sparseIdxMte2ToVFlagId = 6; // sparse indices MTE2→V | ||
| 88 | + static constexpr uint32_t phyAddrMte3ToVFlagId = 7; // phy addr MTE3→V | ||
| 89 | + static constexpr uint32_t blkTableMte2ToVFlagId = 8; // block table MTE2→V | ||
| 90 | + | ||
| 83 | // ==================== Functions ====================== | 91 | // ==================== Functions ====================== |
| 84 | __aicore__ inline CSABlockVec(){}; | 92 | __aicore__ inline CSABlockVec(){}; |
| 85 | __aicore__ inline void InitVecBlock(TPipe *pipe, __gm__ uint8_t *cuSeqlensQ, __gm__ uint8_t *cuSeqlensOriKv, | 93 | __aicore__ inline void InitVecBlock(TPipe *pipe, __gm__ uint8_t *cuSeqlensQ, __gm__ uint8_t *cuSeqlensOriKv, |
| @@ -121,13 +129,12 @@ public: | |||
| 121 | __gm__ uint8_t *sequsedOriKv, __gm__ uint8_t *sequsedCmpKv, | 129 | __gm__ uint8_t *sequsedOriKv, __gm__ uint8_t *sequsedCmpKv, |
| 122 | __gm__ uint8_t *cmpResidualKv); | 130 | __gm__ uint8_t *cmpResidualKv); |
| 123 | __aicore__ inline void InitOutputSingleCore(ConstInfo &constInfo); | 131 | __aicore__ inline void InitOutputSingleCore(ConstInfo &constInfo); |
| 124 | - __aicore__ inline void ProcessVec0(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputL1, | 132 | + __aicore__ inline void ProcessVec0(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, |
| 125 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 133 | + const RunInfo &runInfo, ConstInfo &constInfo); |
| 126 | - const RunInfo &runInfo, ConstInfo &constInfo, int32_t startPos); | ||
| 127 | __aicore__ inline void ProcessVec1(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputBuf, | 134 | __aicore__ inline void ProcessVec1(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputBuf, |
| 128 | - Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &bmm1ResBuf, | 135 | + Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH> &bmm1ResBuf, |
| 129 | - RunInfo &runInfo, | 136 | + RunInfo &runInfo, |
| 130 | - ConstInfo &constInfo); | 137 | + ConstInfo &constInfo); |
| 131 | __aicore__ inline void InitS2SplitStaging( | 138 | __aicore__ inline void InitS2SplitStaging( |
| 132 | Buffer<BufferType::GM, SyncType::INNER_CORE_SYNC> &fdStaging) | 139 | Buffer<BufferType::GM, SyncType::INNER_CORE_SYNC> &fdStaging) |
| 133 | { | 140 | { |
| @@ -149,12 +156,23 @@ public: | |||
| 149 | __aicore__ inline void ProcessFlashDecode(FdRunInfo &fdRunInfo, ConstInfo &constInfo); | 156 | __aicore__ inline void ProcessFlashDecode(FdRunInfo &fdRunInfo, ConstInfo &constInfo); |
| 150 | using mm2ResPos = Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH>; | 157 | using mm2ResPos = Buffer<BufferType::UB, SyncType::CROSS_CORE_SYNC_BOTH>; |
| 151 | __aicore__ inline void ProcessVec2(mm2ResPos &bmm2ResBuf, RunInfo &runInfo, ConstInfo &constInfo); | 158 | __aicore__ inline void ProcessVec2(mm2ResPos &bmm2ResBuf, RunInfo &runInfo, ConstInfo &constInfo); |
| 159 | + __aicore__ inline void GetKVPhyAddr(uint32_t hasLoad, uint32_t bN2StartIdx, uint32_t bN2EndIdx, | ||
| 160 | + uint32_t gS1StartIdx, uint32_t nextGs1Idx, bool hasActualSeqQlen, | ||
| 161 | + bool hasCuSeqlensQ, bool hasActualSeqOriKvlen, bool hasCuSeqlensOriKv, | ||
| 162 | + GlobalTensor<int32_t> actualSeqOriKvlenGm, | ||
| 163 | + GlobalTensor<int32_t> cuSeqlensOriKvGm, GlobalTensor<int32_t> oriTopkLengthGm, | ||
| 164 | + bool hasActualSeqCmpKvlen, bool hasCuSeqlensCmpKv, | ||
| 165 | + GlobalTensor<int32_t> actualSeqCmpKvlenGm, | ||
| 166 | + GlobalTensor<int32_t> cuSeqlensCmpKvGm, GlobalTensor<int32_t> cmpTopkLengthGm, | ||
| 167 | + GlobalTensor<int32_t> cmpResidualKvGm, GlobalTensor<int32_t> actualSeqQlenGm, | ||
| 168 | + GlobalTensor<int32_t> cuSeqlensQGm, __gm__ uint8_t *workspace, | ||
| 169 | + ConstInfo &constInfo); | ||
| 152 | 170 | ||
| 153 | private: | 171 | private: |
| 154 | template <bool UPDATE> | 172 | template <bool UPDATE> |
| 155 | __aicore__ inline void ComputeVec1Softmax(LocalTensor<Q_T> &stage1CastTensor, LocalTensor<T> &mmRes, | 173 | __aicore__ inline void ComputeVec1Softmax(LocalTensor<Q_T> &stage1CastTensor, LocalTensor<T> &mmRes, |
| 156 | - LocalTensor<float> &sumUb, LocalTensor<float> &maxUb, LocalTensor<T> &apiTmpBuffer, | 174 | + LocalTensor<float> &sumUb, LocalTensor<float> &maxUb, LocalTensor<T> &apiTmpBuffer, |
| 157 | - RunInfo &runInfo, ConstInfo &constInfo); | 175 | + RunInfo &runInfo, ConstInfo &constInfo); |
| 158 | __aicore__ inline void InitVec1SoftmaxFromSinks( | 176 | __aicore__ inline void InitVec1SoftmaxFromSinks( |
| 159 | LocalTensor<float> &sumUb, LocalTensor<float> &maxUb, RunInfo &runInfo, ConstInfo &constInfo); | 177 | LocalTensor<float> &sumUb, LocalTensor<float> &maxUb, RunInfo &runInfo, ConstInfo &constInfo); |
| 160 | __aicore__ inline void CopyVec1ResultToL1( | 178 | __aicore__ inline void CopyVec1ResultToL1( |
| @@ -216,25 +234,49 @@ private: | |||
| 216 | return stagingMOffset; | 234 | return stagingMOffset; |
| 217 | } | 235 | } |
| 218 | 236 | ||
| 219 | - __aicore__ inline void ProcessSparseKv(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputL1, | 237 | + __aicore__ inline void ProcessSparseKv(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, |
| 220 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 238 | + const RunInfo &runInfo, ConstInfo &constInfo); |
| 221 | - const RunInfo &runInfo, ConstInfo &constInfo, int32_t startPos); | ||
| 222 | __aicore__ inline void CalSparseCalSize(const RunInfo &runInfo, ConstInfo &constInfo); | 239 | __aicore__ inline void CalSparseCalSize(const RunInfo &runInfo, ConstInfo &constInfo); |
| 223 | __aicore__ inline int64_t GetkeyOffset(int64_t s2Idx, const RunInfo &runInfo, ConstInfo &constInfo); | 240 | __aicore__ inline int64_t GetkeyOffset(int64_t s2Idx, const RunInfo &runInfo, ConstInfo &constInfo); |
| 224 | - __aicore__ inline void GetRealCmpS2Idx(int64_t &token0Idx, int64_t &token1Idx, int64_t s2IdxInBase, | 241 | + __aicore__ inline void GetRealCmpS2Idx(int64_t *tokenData, int64_t s2IdxInBase, |
| 225 | const RunInfo &runInfo, ConstInfo &constInfo); | 242 | const RunInfo &runInfo, ConstInfo &constInfo); |
| 226 | - __aicore__ inline uint32_t CopyInKvSparse(LocalTensor<KV_T> kvInUb, int64_t startRow, int64_t token0Idx, | 243 | + __aicore__ inline uint32_t CopyInKvSparse(LocalTensor<KV_T> kvInUb, int64_t startRow, int64_t *tokenData, |
| 227 | - int64_t token1Idx, const RunInfo &runInfo, ConstInfo &constInfo); | 244 | + const RunInfo &runInfo, ConstInfo &constInfo); |
| 228 | __aicore__ inline void CopyToOutUb(LocalTensor<Q_T> kvNzUb, LocalTensor<KV_T> srcTensor, int64_t dealRow, | 245 | __aicore__ inline void CopyToOutUb(LocalTensor<Q_T> kvNzUb, LocalTensor<KV_T> srcTensor, int64_t dealRow, |
| 229 | ConstInfo &constInfo); | 246 | ConstInfo &constInfo); |
| 230 | - __aicore__ inline void CopyOutKvUb2L1(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputL1, | ||
| 231 | - LocalTensor<Q_T> kvNzOutUb, int64_t dealRow, int64_t s2StartIdx, | ||
| 232 | - const RunInfo &runInfo, ConstInfo &constInfo); | ||
| 233 | __aicore__ inline void CopyOutKvUb2Gm(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 247 | __aicore__ inline void CopyOutKvUb2Gm(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, |
| 234 | LocalTensor<Q_T> kvOutUb, int64_t dealRow, int64_t s2StartIdx, | 248 | LocalTensor<Q_T> kvOutUb, int64_t dealRow, int64_t s2StartIdx, |
| 235 | const RunInfo &runInfo, ConstInfo &constInfo); | 249 | const RunInfo &runInfo, ConstInfo &constInfo); |
| 236 | __aicore__ inline void CopyInSingleKv(LocalTensor<KV_T> kvInUb, int64_t startRow, int64_t keyOffset, | 250 | __aicore__ inline void CopyInSingleKv(LocalTensor<KV_T> kvInUb, int64_t startRow, int64_t keyOffset, |
| 237 | ConstInfo &constInfo); | 251 | ConstInfo &constInfo); |
| 252 | + __aicore__ inline void GetRealS2Addr(int64_t *tokenData, int64_t s2IdxInBase, const RunInfo &runInfo, | ||
| 253 | + ConstInfo &constInfo); | ||
| 254 | + __aicore__ inline void GetKVPhyAddrForKvType( | ||
| 255 | + uint32_t bN2StartIdx, uint32_t bN2EndIdx, uint32_t gS1StartIdx, uint32_t nextGs1Idx, bool hasActualSeqQlen, | ||
| 256 | + bool hasCuSeqlensQ, bool hasActualSeqKvlen, bool hasCuSeqlensKv, GlobalTensor<int32_t> actualSeqQlenGm, | ||
| 257 | + GlobalTensor<int32_t> cuSeqlensQGm, GlobalTensor<int32_t> actualSeqKvlenGm, GlobalTensor<int32_t> cuSeqlensKvGm, | ||
| 258 | + GlobalTensor<int32_t> topkLengthGm, GlobalTensor<int32_t> cmpResidualKvGm, ConstInfo &constInfo, | ||
| 259 | + GlobalTensor<int32_t> &blockTableGm, GlobalTensor<int32_t> &sparseIndicesGm, GlobalTensor<uint32_t> &phyAddrGm, | ||
| 260 | + uint32_t kvStride, uint32_t blockSize, uint32_t maxBlockNumPerBatch, uint32_t sparseBlockCount, | ||
| 261 | + uint32_t alignedSparseBlockCount, bool isOriKv); | ||
| 262 | + __aicore__ inline int32_t GetSeqLen(int32_t bIdx, bool hasActualSeq, bool hasCuSeqlens, | ||
| 263 | + GlobalTensor<int32_t> &actualSeqGm, GlobalTensor<int32_t> &cuSeqlensGm, | ||
| 264 | + int64_t defaultSize); | ||
| 265 | + __aicore__ inline int32_t CalcCurValidS2(uint32_t bIdx, int32_t s1Idx, int32_t actualS1Size, bool isOriKv, | ||
| 266 | + bool hasActualSeqKvlen, bool hasCuSeqlensKv, | ||
| 267 | + GlobalTensor<int32_t> &cuSeqlensQGm, | ||
| 268 | + GlobalTensor<int32_t> &actualSeqKvlenGm, | ||
| 269 | + GlobalTensor<int32_t> &cuSeqlensKvGm, GlobalTensor<int32_t> &topkLengthGm, | ||
| 270 | + GlobalTensor<int32_t> &cmpResidualKvGm, ConstInfo &constInfo, | ||
| 271 | + int32_t sparseBlockCount); | ||
| 272 | + __aicore__ inline void CopyPhyAddrToGm(LocalTensor<uint32_t> kvPhyAddrUb, int64_t bS1Idx, int64_t s1Idx, | ||
| 273 | + int64_t validS2, int64_t alignNum, GlobalTensor<uint32_t> &phyAddrGm, | ||
| 274 | + uint32_t alignedSparseBlockCount); | ||
| 275 | + __aicore__ inline void CopyPaTableToUb(LocalTensor<int32_t> blkTableUb, int64_t bIdx, | ||
| 276 | + GlobalTensor<int32_t> &blockTableGm, uint32_t maxBlockNumPerBatch); | ||
| 277 | + __aicore__ inline void CopySparseIdxToUb(LocalTensor<int32_t> sparseIdxUb, int64_t bS1Idx, int64_t s1Idx, | ||
| 278 | + int64_t validS2, GlobalTensor<int32_t> &sparseIndicesGm, | ||
| 279 | + uint32_t sparseBlockCount); | ||
| 238 | /* VEC2_RES_T 表示bmm2ResUb当前的类型,VEC2_RES_T = Q_T那么不需要做Cast。另外,无效行场景当前默认需要做Cast */ | 280 | /* VEC2_RES_T 表示bmm2ResUb当前的类型,VEC2_RES_T = Q_T那么不需要做Cast。另外,无效行场景当前默认需要做Cast */ |
| 239 | template <typename VEC2_RES_T> | 281 | template <typename VEC2_RES_T> |
| 240 | __aicore__ inline void Bmm2DataCopyOut(RunInfo &runInfo, ConstInfo &constInfo, LocalTensor<VEC2_RES_T> &vec2ResUb, | 282 | __aicore__ inline void Bmm2DataCopyOut(RunInfo &runInfo, ConstInfo &constInfo, LocalTensor<VEC2_RES_T> &vec2ResUb, |
| @@ -247,7 +289,7 @@ private: | |||
| 247 | __aicore__ inline void GetExtremeValue(T &negativeScalar); | 289 | __aicore__ inline void GetExtremeValue(T &negativeScalar); |
| 248 | __aicore__ inline void InitSinksBuffer(ConstInfo &constInfo); | 290 | __aicore__ inline void InitSinksBuffer(ConstInfo &constInfo); |
| 249 | __aicore__ inline void ReduceIntraBlockAndStage(RunInfo &runInfo, ConstInfo &constInfo, | 291 | __aicore__ inline void ReduceIntraBlockAndStage(RunInfo &runInfo, ConstInfo &constInfo, |
| 250 | - LocalTensor<T> &vec2ResUb, LocalTensor<T> &partialTmpUb); | 292 | + LocalTensor<T> &vec2ResUb, LocalTensor<T> &partialTmpUb); |
| 251 | 293 | ||
| 252 | TPipe *tPipe; | 294 | TPipe *tPipe; |
| 253 | 295 | ||
| @@ -270,6 +312,8 @@ private: | |||
| 270 | GlobalTensor<int32_t> actualSeqLengthsKVGm; | 312 | GlobalTensor<int32_t> actualSeqLengthsKVGm; |
| 271 | GlobalTensor<int32_t> actualSeqLengthsCmpKVGm; | 313 | GlobalTensor<int32_t> actualSeqLengthsCmpKVGm; |
| 272 | GlobalTensor<int32_t> cmpResidualKVGm; | 314 | GlobalTensor<int32_t> cmpResidualKVGm; |
| 315 | + GlobalTensor<uint32_t> oriKvPhyAddrGm; | ||
| 316 | + GlobalTensor<uint32_t> cmpKvPhyAddrGm; | ||
| 273 | 317 | ||
| 274 | TBuf<> commonTBuf; // common的复用空间 | 318 | TBuf<> commonTBuf; // common的复用空间 |
| 275 | TBuf<> sinksBuf; | 319 | TBuf<> sinksBuf; |
| @@ -327,21 +371,25 @@ private: | |||
| 327 | }; | 371 | }; |
| 328 | 372 | ||
| 329 | TEMPLATES_DEF_NO_DEFAULT | 373 | TEMPLATES_DEF_NO_DEFAULT |
| 330 | -__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetRealCmpS2Idx(int64_t &token0Idx, int64_t &token1Idx, | 374 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetRealCmpS2Idx(int64_t *tokenData, int64_t s2IdxInBase, |
| 331 | - int64_t s2IdxInBase, const RunInfo &runInfo, | 375 | + const RunInfo &runInfo, ConstInfo &constInfo) |
| 332 | - ConstInfo &constInfo) | ||
| 333 | { | 376 | { |
| 334 | int64_t sparseBlockCount = 0; | 377 | int64_t sparseBlockCount = 0; |
| 335 | int64_t curS2LoopCnt = runInfo.s2LoopCount; | 378 | int64_t curS2LoopCnt = runInfo.s2LoopCount; |
| 336 | - // CSA、ORI_SPARSE、ORI_CMP_SPARSE均可通过runInfo.isCmp判断 | 379 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE) { |
| 337 | - if (runInfo.isCmp) { | ||
| 338 | sparseBlockCount = constInfo.cmpSparseBlockCount; | 380 | sparseBlockCount = constInfo.cmpSparseBlockCount; |
| 339 | curS2LoopCnt -= runInfo.oriKvLoopEndIdx; | 381 | curS2LoopCnt -= runInfo.oriKvLoopEndIdx; |
| 340 | - } else { | 382 | + } else if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE) { |
| 341 | sparseBlockCount = constInfo.oriSparseBlockCount; | 383 | sparseBlockCount = constInfo.oriSparseBlockCount; |
| 384 | + } else if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 385 | + if (runInfo.isCmp) { | ||
| 386 | + sparseBlockCount = constInfo.cmpSparseBlockCount; | ||
| 387 | + curS2LoopCnt -= runInfo.oriKvLoopEndIdx; | ||
| 388 | + } else { | ||
| 389 | + sparseBlockCount = constInfo.oriSparseBlockCount; | ||
| 390 | + } | ||
| 342 | } | 391 | } |
| 343 | - | 392 | + uint64_t topkBS1Idx = 0; |
| 344 | - int64_t topkBS1Idx = 0; | ||
| 345 | if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { | 393 | if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { |
| 346 | uint64_t actualSeqQPrefixSum = cuSeqlensQGm.GetValue(runInfo.boIdx); | 394 | uint64_t actualSeqQPrefixSum = cuSeqlensQGm.GetValue(runInfo.boIdx); |
| 347 | topkBS1Idx += (actualSeqQPrefixSum + runInfo.s1oIdx) * sparseBlockCount; // T, N2(1), K | 395 | topkBS1Idx += (actualSeqQPrefixSum + runInfo.s1oIdx) * sparseBlockCount; // T, N2(1), K |
| @@ -350,17 +398,49 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetRealCmpS2Idx(int64_t &toke | |||
| 350 | runInfo.boIdx * constInfo.s1Size * sparseBlockCount + runInfo.s1oIdx * sparseBlockCount; // B, S1, N2(1), K | 398 | runInfo.boIdx * constInfo.s1Size * sparseBlockCount + runInfo.s1oIdx * sparseBlockCount; // B, S1, N2(1), K |
| 351 | } | 399 | } |
| 352 | 400 | ||
| 353 | - int64_t topkKIdx = s2IdxInBase + curS2LoopCnt * constInfo.s2BaseSize; | 401 | + uint64_t topkKIdx = s2IdxInBase + curS2LoopCnt * constInfo.s2BaseSize; |
| 354 | - if (unlikely(topkKIdx >= sparseBlockCount)) { | 402 | + for (uint64_t i = 0; i < 8; ++i) { |
| 355 | - token0Idx = -1; | 403 | + uint64_t idx = topkBS1Idx + runInfo.s2StartIdx + topkKIdx + i; |
| 356 | - } else { | 404 | + if (likely((topkKIdx + i < sparseBlockCount) && (s2IdxInBase + i < sparseS2End))) { |
| 357 | - token0Idx = sparseIndicesGm.GetValue(topkBS1Idx + topkKIdx + runInfo.s2StartIdx); | 405 | + tokenData[i] = sparseIndicesGm.GetValue(idx); |
| 406 | + } else { | ||
| 407 | + break; | ||
| 408 | + } | ||
| 358 | } | 409 | } |
| 359 | - topkKIdx += 1; | 410 | +} |
| 360 | - if (unlikely((topkKIdx >= sparseBlockCount) || (s2IdxInBase + 1 >= sparseS2End))) { | 411 | + |
| 361 | - token1Idx = -1; | 412 | +TEMPLATES_DEF_NO_DEFAULT |
| 413 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetRealS2Addr(int64_t *tokenData, int64_t s2IdxInBase, | ||
| 414 | + const RunInfo &runInfo, ConstInfo &constInfo) | ||
| 415 | +{ | ||
| 416 | + uint32_t sparseBlockCount = runInfo.isCmp ? constInfo.cmpSparseBlockCount : constInfo.oriSparseBlockCount; | ||
| 417 | + uint32_t alignedSparseBlockCount = | ||
| 418 | + runInfo.isCmp ? constInfo.alignedCmpSparseBlockCount : constInfo.alignedOriSparseBlockCount; | ||
| 419 | + int64_t curS2LoopCnt = runInfo.s2LoopCount; | ||
| 420 | + GlobalTensor<int64_t> phyAddrGm64; | ||
| 421 | + if (runInfo.isCmp) { | ||
| 422 | + curS2LoopCnt -= runInfo.oriKvLoopEndIdx; | ||
| 423 | + phyAddrGm64 = cmpKvPhyAddrGm.template ReinterpretCast<int64_t>(); | ||
| 362 | } else { | 424 | } else { |
| 363 | - token1Idx = sparseIndicesGm.GetValue(topkBS1Idx + topkKIdx + runInfo.s2StartIdx); | 425 | + phyAddrGm64 = oriKvPhyAddrGm.template ReinterpretCast<int64_t>(); |
| 426 | + } | ||
| 427 | + | ||
| 428 | + uint64_t topkBS1Idx = 0; | ||
| 429 | + if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { | ||
| 430 | + uint64_t actualSeqQPrefixSum = cuSeqlensQGm.GetValue(runInfo.boIdx); | ||
| 431 | + topkBS1Idx += (actualSeqQPrefixSum + runInfo.s1oIdx) * alignedSparseBlockCount; | ||
| 432 | + } else { | ||
| 433 | + topkBS1Idx += | ||
| 434 | + runInfo.boIdx * constInfo.s1Size * alignedSparseBlockCount + runInfo.s1oIdx * alignedSparseBlockCount; | ||
| 435 | + } | ||
| 436 | + uint64_t topkKIdx = s2IdxInBase + curS2LoopCnt * constInfo.s2BaseSize; | ||
| 437 | + for (uint64_t i = 0; i < 8; ++i) { | ||
| 438 | + uint64_t idx = topkBS1Idx + runInfo.s2StartIdx + topkKIdx + i; | ||
| 439 | + if (likely((topkKIdx + i < sparseBlockCount) && (s2IdxInBase + i < sparseS2End))) { | ||
| 440 | + tokenData[i] = phyAddrGm64.GetValue(idx); | ||
| 441 | + } else { | ||
| 442 | + break; | ||
| 443 | + } | ||
| 364 | } | 444 | } |
| 365 | } | 445 | } |
| 366 | 446 | ||
| @@ -418,42 +498,53 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopyInSingleKv(LocalTensor<KV | |||
| 418 | 498 | ||
| 419 | TEMPLATES_DEF_NO_DEFAULT | 499 | TEMPLATES_DEF_NO_DEFAULT |
| 420 | __aicore__ inline uint32_t CSABlockVec<TEMPLATE_ARGS>::CopyInKvSparse(LocalTensor<KV_T> kvInUb, int64_t startRow, | 500 | __aicore__ inline uint32_t CSABlockVec<TEMPLATE_ARGS>::CopyInKvSparse(LocalTensor<KV_T> kvInUb, int64_t startRow, |
| 421 | - int64_t token0Idx, int64_t token1Idx, | 501 | + int64_t *tokenData, const RunInfo &runInfo, |
| 422 | - const RunInfo &runInfo, ConstInfo &constInfo) | 502 | + ConstInfo &constInfo) |
| 423 | { | 503 | { |
| 424 | - int64_t keyOffset0 = GetkeyOffset(token0Idx, runInfo, constInfo); | 504 | + uint32_t dealRow = 0; |
| 425 | - int64_t keyOffset1 = GetkeyOffset(token1Idx, runInfo, constInfo); | 505 | + for (uint32_t i = 0; i < 8; i += 2) { |
| 426 | - if (unlikely(keyOffset0 < 0 && keyOffset1 < 0)) { | 506 | + int64_t keyOffset0; |
| 427 | - return 0; | 507 | + int64_t keyOffset1; |
| 428 | - } | 508 | + if constexpr (IS_VEC_S2PHYADDR) { |
| 429 | - int64_t combineBytes = constInfo.dSizeVInput * sizeof(KV_T); | 509 | + keyOffset0 = tokenData[i]; |
| 430 | - int64_t keySrcStride = | 510 | + keyOffset1 = tokenData[i + 1]; |
| 431 | - (keyOffset0 > keyOffset1 ? (keyOffset0 - keyOffset1) : (keyOffset1 - keyOffset0)) * sizeof(KV_T) - combineBytes; | 511 | + } else { |
| 432 | - if (unlikely(keyOffset1 < 0)) { | 512 | + keyOffset0 = GetkeyOffset(tokenData[i], runInfo, constInfo); |
| 433 | - CopyInSingleKv(kvInUb, startRow, keyOffset0, constInfo); | 513 | + keyOffset1 = GetkeyOffset(tokenData[i + 1], runInfo, constInfo); |
| 434 | - } else if (unlikely(keySrcStride >= INT32_MAX || keySrcStride < 0) || constInfo.sparseBlockSize > 1) { | ||
| 435 | - // stride溢出、stride为负数、s2超长等异常场景,还原成2条搬运指令 | ||
| 436 | - CopyInSingleKv(kvInUb, startRow, keyOffset0, constInfo); | ||
| 437 | - CopyInSingleKv(kvInUb, startRow + 1, keyOffset1, constInfo); | ||
| 438 | - } else { | ||
| 439 | - DataCopyExtParams intriParams; | ||
| 440 | - intriParams.blockCount = (keyOffset0 >= 0) + (keyOffset1 >= 0); | ||
| 441 | - intriParams.blockLen = combineBytes; | ||
| 442 | - intriParams.dstStride = 0; | ||
| 443 | - intriParams.srcStride = keySrcStride; | ||
| 444 | - DataCopyPadExtParams<KV_T> padParams; | ||
| 445 | - padParams.isPad = true; | ||
| 446 | - padParams.leftPadding = 0; | ||
| 447 | - padParams.rightPadding = (CeilAlign(combineBytes, BUFFER_SIZE_BYTE_32B) - combineBytes) / sizeof(KV_T); | ||
| 448 | - padParams.paddingValue = 0; | ||
| 449 | - | ||
| 450 | - int64_t keyOffset = keyOffset0 > -1 ? keyOffset0 : keyOffset1; | ||
| 451 | - if (keyOffset1 > -1 && keyOffset1 < keyOffset0) { | ||
| 452 | - keyOffset = keyOffset1; | ||
| 453 | } | 514 | } |
| 454 | - DataCopyPad(kvInUb[startRow * constInfo.dSize], keyGm[keyOffset], intriParams, padParams); | 515 | + if (unlikely(keyOffset0 < 0 && keyOffset1 < 0)) { |
| 516 | + return dealRow; | ||
| 517 | + } | ||
| 518 | + int64_t combineBytes = constInfo.dSizeVInput * sizeof(KV_T); | ||
| 519 | + int64_t keySrcStride = | ||
| 520 | + (keyOffset0 > keyOffset1 ? (keyOffset0 - keyOffset1) : (keyOffset1 - keyOffset0)) * sizeof(KV_T) - | ||
| 521 | + combineBytes; | ||
| 522 | + if (unlikely(keySrcStride >= INT32_MAX || keySrcStride < 0) || constInfo.sparseBlockSize > 1) { | ||
| 523 | + // stride溢出、stride为负数、s2超长等异常场景,还原成2条搬运指令 | ||
| 524 | + CopyInSingleKv(kvInUb, startRow, keyOffset0, constInfo); | ||
| 525 | + CopyInSingleKv(kvInUb, startRow + 1, keyOffset1, constInfo); | ||
| 526 | + } else { | ||
| 527 | + DataCopyExtParams intriParams; | ||
| 528 | + intriParams.blockCount = (keyOffset0 >= 0) + (keyOffset1 >= 0); | ||
| 529 | + intriParams.blockLen = combineBytes; | ||
| 530 | + intriParams.dstStride = 0; | ||
| 531 | + intriParams.srcStride = keySrcStride; | ||
| 532 | + DataCopyPadExtParams<KV_T> padParams; | ||
| 533 | + padParams.isPad = true; | ||
| 534 | + padParams.leftPadding = 0; | ||
| 535 | + padParams.rightPadding = (CeilAlign(combineBytes, BUFFER_SIZE_BYTE_32B) - combineBytes) / sizeof(KV_T); | ||
| 536 | + padParams.paddingValue = 0; | ||
| 537 | + | ||
| 538 | + int64_t keyOffset = keyOffset0 > -1 ? keyOffset0 : keyOffset1; | ||
| 539 | + if (keyOffset1 > -1 && keyOffset1 < keyOffset0) { | ||
| 540 | + keyOffset = keyOffset1; | ||
| 541 | + } | ||
| 542 | + DataCopyPad(kvInUb[startRow * constInfo.dSize], keyGm[keyOffset], intriParams, padParams); | ||
| 543 | + } | ||
| 544 | + dealRow += (keyOffset0 >= 0) + (keyOffset1 >= 0); | ||
| 545 | + startRow += 2; | ||
| 455 | } | 546 | } |
| 456 | - return (keyOffset0 > -1) + (keyOffset1 > -1); | 547 | + return dealRow; |
| 457 | } | 548 | } |
| 458 | 549 | ||
| 459 | TEMPLATES_DEF_NO_DEFAULT | 550 | TEMPLATES_DEF_NO_DEFAULT |
| @@ -464,23 +555,6 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopyToOutUb(LocalTensor<Q_T> | |||
| 464 | DataCopy(kvOutUb, kvNdUb, dealRow * constInfo.dSize); | 555 | DataCopy(kvOutUb, kvNdUb, dealRow * constInfo.dSize); |
| 465 | } | 556 | } |
| 466 | 557 | ||
| 467 | -TEMPLATES_DEF_NO_DEFAULT | ||
| 468 | -__aicore__ inline void | ||
| 469 | -CSABlockVec<TEMPLATE_ARGS>::CopyOutKvUb2L1(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputL1, | ||
| 470 | - LocalTensor<Q_T> kvNzOutUb, int64_t dealRow, int64_t s2StartIdx, | ||
| 471 | - const RunInfo &runInfo, ConstInfo &constInfo) | ||
| 472 | -{ | ||
| 473 | - uint64_t blockElementNum = 16; | ||
| 474 | - DataCopyParams dataCopyParams; | ||
| 475 | - dataCopyParams.blockCount = constInfo.dSize / blockElementNum; | ||
| 476 | - dataCopyParams.blockLen = dealRow; | ||
| 477 | - dataCopyParams.srcGap = blockElementNum + 1 - dealRow; | ||
| 478 | - dataCopyParams.dstGap = Align16Func(runInfo.s2RealSize) - dealRow; | ||
| 479 | - | ||
| 480 | - LocalTensor<Q_T> dst = outputL1.GetTensor<Q_T>(); | ||
| 481 | - DataCopy(dst[s2StartIdx * 16], kvNzOutUb, dataCopyParams); | ||
| 482 | -} | ||
| 483 | - | ||
| 484 | TEMPLATES_DEF_NO_DEFAULT | 558 | TEMPLATES_DEF_NO_DEFAULT |
| 485 | __aicore__ inline void | 559 | __aicore__ inline void |
| 486 | CSABlockVec<TEMPLATE_ARGS>::CopyOutKvUb2Gm(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 560 | CSABlockVec<TEMPLATE_ARGS>::CopyOutKvUb2Gm(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, |
| @@ -527,16 +601,11 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CalSparseCalSize(const RunInf | |||
| 527 | 601 | ||
| 528 | TEMPLATES_DEF_NO_DEFAULT | 602 | TEMPLATES_DEF_NO_DEFAULT |
| 529 | __aicore__ inline void | 603 | __aicore__ inline void |
| 530 | -CSABlockVec<TEMPLATE_ARGS>::ProcessVec0(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputL1, | 604 | +CSABlockVec<TEMPLATE_ARGS>::ProcessVec0(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, |
| 531 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 605 | + const RunInfo &runInfo, ConstInfo &constInfo) |
| 532 | - const RunInfo &runInfo, ConstInfo &constInfo, int32_t startPos) | ||
| 533 | { | 606 | { |
| 534 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE) { | 607 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE) { |
| 535 | if (runInfo.s2LoopCount < runInfo.oriKvLoopEndIdx) { | 608 | if (runInfo.s2LoopCount < runInfo.oriKvLoopEndIdx) { |
| 536 | - if constexpr (IS_SPLIT_G) { | ||
| 537 | - CrossCoreSetFlag<0, PIPE_MTE3>(15); | ||
| 538 | - CrossCoreWaitFlag<0, PIPE_MTE3>(15); | ||
| 539 | - } | ||
| 540 | return; | 609 | return; |
| 541 | } | 610 | } |
| 542 | keyGm = cmpKVGm; | 611 | keyGm = cmpKVGm; |
| @@ -548,12 +617,7 @@ CSABlockVec<TEMPLATE_ARGS>::ProcessVec0(Buffer<BufferType::L1, SyncType::CROSS_C | |||
| 548 | maxBlockNumPerBatch = constInfo.cmpMaxBlockNumPerBatch; | 617 | maxBlockNumPerBatch = constInfo.cmpMaxBlockNumPerBatch; |
| 549 | } | 618 | } |
| 550 | CalSparseCalSize(runInfo, constInfo); | 619 | CalSparseCalSize(runInfo, constInfo); |
| 551 | - ProcessSparseKv(outputL1, v0ResGm, runInfo, constInfo, startPos); | 620 | + ProcessSparseKv(v0ResGm, runInfo, constInfo); |
| 552 | - if constexpr (IS_SPLIT_G) { | ||
| 553 | - CrossCoreSetFlag<0, PIPE_MTE3>(15); | ||
| 554 | - CrossCoreWaitFlag<0, PIPE_MTE3>(15); | ||
| 555 | - } | ||
| 556 | - outputL1.SetCrossCore(); | ||
| 557 | v0ResGm.SetCrossCore(); | 621 | v0ResGm.SetCrossCore(); |
| 558 | } else if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | 622 | } else if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || |
| 559 | TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | 623 | TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { |
| @@ -577,21 +641,15 @@ CSABlockVec<TEMPLATE_ARGS>::ProcessVec0(Buffer<BufferType::L1, SyncType::CROSS_C | |||
| 577 | } | 641 | } |
| 578 | } | 642 | } |
| 579 | CalSparseCalSize(runInfo, constInfo); | 643 | CalSparseCalSize(runInfo, constInfo); |
| 580 | - ProcessSparseKv(outputL1, v0ResGm, runInfo, constInfo, startPos); | 644 | + ProcessSparseKv(v0ResGm, runInfo, constInfo); |
| 581 | - if constexpr (IS_SPLIT_G) { | ||
| 582 | - CrossCoreSetFlag<0, PIPE_MTE3>(15); | ||
| 583 | - CrossCoreWaitFlag<0, PIPE_MTE3>(15); | ||
| 584 | - } | ||
| 585 | - outputL1.SetCrossCore(); | ||
| 586 | v0ResGm.SetCrossCore(); | 645 | v0ResGm.SetCrossCore(); |
| 587 | } | 646 | } |
| 588 | } | 647 | } |
| 589 | 648 | ||
| 590 | TEMPLATES_DEF_NO_DEFAULT | 649 | TEMPLATES_DEF_NO_DEFAULT |
| 591 | __aicore__ inline void | 650 | __aicore__ inline void |
| 592 | -CSABlockVec<TEMPLATE_ARGS>::ProcessSparseKv(Buffer<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> &outputL1, | 651 | +CSABlockVec<TEMPLATE_ARGS>::ProcessSparseKv(Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, |
| 593 | - Buffer<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> &v0ResGm, | 652 | + const RunInfo &runInfo, ConstInfo &constInfo) |
| 594 | - const RunInfo &runInfo, ConstInfo &constInfo, int32_t startPos) | ||
| 595 | { | 653 | { |
| 596 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | 654 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || |
| 597 | TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | 655 | TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || |
| @@ -602,22 +660,26 @@ CSABlockVec<TEMPLATE_ARGS>::ProcessSparseKv(Buffer<BufferType::L1, SyncType::CRO | |||
| 602 | bool meetEnd = false; | 660 | bool meetEnd = false; |
| 603 | int64_t s2Start = sparseS2Start; | 661 | int64_t s2Start = sparseS2Start; |
| 604 | int64_t s2 = sparseS2Start; | 662 | int64_t s2 = sparseS2Start; |
| 605 | - int64_t token0Idx; | ||
| 606 | - int64_t token1Idx; | ||
| 607 | uint32_t pingPong = 0; | 663 | uint32_t pingPong = 0; |
| 608 | while ((s2 < sparseS2End) && !meetEnd) { | 664 | while ((s2 < sparseS2End) && !meetEnd) { |
| 609 | int64_t dealRow = 0; | 665 | int64_t dealRow = 0; |
| 610 | LocalTensor<Q_T> stage0OutUb = this->stage0OutBuf[pingPong].template Get<Q_T>(); | 666 | LocalTensor<Q_T> stage0OutUb = this->stage0OutBuf[pingPong].template Get<Q_T>(); |
| 611 | WaitFlag<HardEvent::MTE3_MTE2>(mte3ToMte2[pingPong]); | 667 | WaitFlag<HardEvent::MTE3_MTE2>(mte3ToMte2[pingPong]); |
| 612 | while (dealRow < Min(16, sparseCalSize) && s2 < sparseS2End) { | 668 | while (dealRow < Min(16, sparseCalSize) && s2 < sparseS2End) { |
| 613 | - GetRealCmpS2Idx(token0Idx, token1Idx, s2, runInfo, constInfo); | 669 | + int64_t tokenData[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; |
| 614 | - s2 += 2; | 670 | + if constexpr (IS_VEC_S2PHYADDR) { |
| 615 | - if (token0Idx == -1 && token1Idx == -1) { | 671 | + GetRealS2Addr(tokenData, s2, runInfo, constInfo); |
| 672 | + } else { | ||
| 673 | + GetRealCmpS2Idx(tokenData, s2, runInfo, constInfo); | ||
| 674 | + } | ||
| 675 | + s2 += 8; | ||
| 676 | + if (tokenData[0] == -1 && tokenData[1] == -1 && tokenData[2] == -1 && tokenData[3] == -1 && | ||
| 677 | + tokenData[4] == -1 && tokenData[5] == -1 && tokenData[6] == -1 && tokenData[7] == -1) { | ||
| 616 | meetEnd = true; | 678 | meetEnd = true; |
| 617 | break; | 679 | break; |
| 618 | } | 680 | } |
| 619 | - dealRow += CopyInKvSparse(stage0OutUb, dealRow, token0Idx, token1Idx, runInfo, constInfo); | 681 | + dealRow += CopyInKvSparse(stage0OutUb, dealRow, tokenData, runInfo, constInfo); |
| 620 | - if (token1Idx == -1) { | 682 | + if (tokenData[7] == -1) { |
| 621 | meetEnd = true; | 683 | meetEnd = true; |
| 622 | break; | 684 | break; |
| 623 | } | 685 | } |
| @@ -650,13 +712,13 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ComputeVec1Softmax( | |||
| 650 | negativeFloatScalar); | 712 | negativeFloatScalar); |
| 651 | } else if (runInfo.s2RealSize <= 64) { | 713 | } else if (runInfo.s2RealSize <= 64) { |
| 652 | ProcessVec1Vf<T, Q_T, UPDATE, s1BaseSize, s2BaseSize, | 714 | ProcessVec1Vf<T, Q_T, UPDATE, s1BaseSize, s2BaseSize, |
| 653 | - FaVectorApi::OriginNRange::GT_0_AND_LTE_64_SFA>( | 715 | + FaVectorApi::OriginNRange::GT_0_AND_LTE_64_SFA>( |
| 654 | stage1CastTensor, mmRes, sumUb, maxUb, maxUb, apiTmpBuffer, vselrIndexesBuf, | 716 | stage1CastTensor, mmRes, sumUb, maxUb, maxUb, apiTmpBuffer, vselrIndexesBuf, |
| 655 | runInfo.halfMRealSize, runInfo.s2RealSizeUpdate, static_cast<T>(constInfo.softmaxScale), | 717 | runInfo.halfMRealSize, runInfo.s2RealSizeUpdate, static_cast<T>(constInfo.softmaxScale), |
| 656 | negativeFloatScalar); | 718 | negativeFloatScalar); |
| 657 | } else if (runInfo.s2RealSize < 128 || runInfo.s2RealSizeUpdate < 128) { | 719 | } else if (runInfo.s2RealSize < 128 || runInfo.s2RealSizeUpdate < 128) { |
| 658 | ProcessVec1Vf<T, Q_T, UPDATE, s1BaseSize, s2BaseSize, | 720 | ProcessVec1Vf<T, Q_T, UPDATE, s1BaseSize, s2BaseSize, |
| 659 | - FaVectorApi::OriginNRange::GT_64_AND_LTE_128_SFA>( | 721 | + FaVectorApi::OriginNRange::GT_64_AND_LTE_128_SFA>( |
| 660 | stage1CastTensor, mmRes, sumUb, maxUb, maxUb, apiTmpBuffer, vselrIndexesBuf, | 722 | stage1CastTensor, mmRes, sumUb, maxUb, maxUb, apiTmpBuffer, vselrIndexesBuf, |
| 661 | runInfo.halfMRealSize, runInfo.s2RealSizeUpdate, static_cast<T>(constInfo.softmaxScale), | 723 | runInfo.halfMRealSize, runInfo.s2RealSizeUpdate, static_cast<T>(constInfo.softmaxScale), |
| 662 | negativeFloatScalar); | 724 | negativeFloatScalar); |
| @@ -700,10 +762,11 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopyVec1ResultToL1( | |||
| 700 | LocalTensor<Q_T> mm2AL1Tensor = outputBuf.GetTensor<Q_T>(); | 762 | LocalTensor<Q_T> mm2AL1Tensor = outputBuf.GetTensor<Q_T>(); |
| 701 | if (likely(runInfo.halfMRealSize != 0)) { | 763 | if (likely(runInfo.halfMRealSize != 0)) { |
| 702 | DataCopy(mm2AL1Tensor[constInfo.subBlockIdx * (BLOCK_BYTE / sizeof(Q_T)) * | 764 | DataCopy(mm2AL1Tensor[constInfo.subBlockIdx * (BLOCK_BYTE / sizeof(Q_T)) * |
| 703 | - (runInfo.mRealSize - runInfo.halfMRealSize)], stage1CastTensor, | 765 | + (runInfo.mRealSize - runInfo.halfMRealSize)], |
| 704 | - {s2BaseSize / 16, static_cast<uint16_t>(runInfo.halfMRealSize), | 766 | + stage1CastTensor, |
| 705 | - static_cast<uint16_t>(vec1Srcstride - runInfo.halfMRealSize), | 767 | + {s2BaseSize / 16, static_cast<uint16_t>(runInfo.halfMRealSize), |
| 706 | - static_cast<uint16_t>(Align16Func(runInfo.mRealSize) - runInfo.halfMRealSize)}); | 768 | + static_cast<uint16_t>(vec1Srcstride - runInfo.halfMRealSize), |
| 769 | + static_cast<uint16_t>(Align16Func(runInfo.mRealSize) - runInfo.halfMRealSize)}); | ||
| 707 | } | 770 | } |
| 708 | this->stage1OutQue[stage1Offset].template FreeTensor(stage1CastTensor); | 771 | this->stage1OutQue[stage1Offset].template FreeTensor(stage1CastTensor); |
| 709 | outputBuf.SetCrossCore(); | 772 | outputBuf.SetCrossCore(); |
| @@ -714,12 +777,12 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::StageCrossCoreVec1Lse( | |||
| 714 | LocalTensor<float> &maxUb, LocalTensor<float> &sumUb, RunInfo &runInfo, ConstInfo &constInfo) | 777 | LocalTensor<float> &maxUb, LocalTensor<float> &sumUb, RunInfo &runInfo, ConstInfo &constInfo) |
| 715 | { | 778 | { |
| 716 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, dTemplateAlign64, | 779 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, dTemplateAlign64, |
| 717 | - GetStagingSlotNum(false), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 780 | + GetStagingSlotNum(false), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 718 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 781 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 719 | LocalTensor<float> tmpUb = this->batchReduceTmpBuf.template Get<float>(); | 782 | LocalTensor<float> tmpUb = this->batchReduceTmpBuf.template Get<float>(); |
| 720 | AttentionCommon::StageVec1Lse(stagingLayout, crossCoreCombineBase, GetCrossCoreWorkspaceIdx(runInfo), | 783 | AttentionCommon::StageVec1Lse(stagingLayout, crossCoreCombineBase, GetCrossCoreWorkspaceIdx(runInfo), |
| 721 | - GetFaStagingMOffset(runInfo, constInfo), runInfo.halfMRealSize, maxUb, sumUb, tmpUb, | 784 | + GetFaStagingMOffset(runInfo, constInfo), runInfo.halfMRealSize, maxUb, sumUb, tmpUb, |
| 722 | - vToMte3AttnOutId, stageMte3ToVId); | 785 | + vToMte3AttnOutId, stageMte3ToVId); |
| 723 | } | 786 | } |
| 724 | 787 | ||
| 725 | TEMPLATES_DEF_NO_DEFAULT | 788 | TEMPLATES_DEF_NO_DEFAULT |
| @@ -741,14 +804,14 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::StageBatchConsistencyVec1Lse( | |||
| 741 | if (runInfo.isCrossCoreSplit && !runInfo.isFirstS2SplitCore) { | 804 | if (runInfo.isCrossCoreSplit && !runInfo.isFirstS2SplitCore) { |
| 742 | StageCrossCoreVec1Lse(maxUb, sumUb, runInfo, constInfo); | 805 | StageCrossCoreVec1Lse(maxUb, sumUb, runInfo, constInfo); |
| 743 | } else if (runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0 && | 806 | } else if (runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0 && |
| 744 | - runInfo.s2LoopCount < runInfo.s2LoopLimit) { | 807 | + runInfo.s2LoopCount < runInfo.s2LoopLimit) { |
| 745 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, dTemplateAlign64, | 808 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, dTemplateAlign64, |
| 746 | - GetStagingSlotNum(true), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 809 | + GetStagingSlotNum(true), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 747 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 810 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 748 | LocalTensor<float> tmpUb = this->batchReduceTmpBuf.template Get<float>(); | 811 | LocalTensor<float> tmpUb = this->batchReduceTmpBuf.template Get<float>(); |
| 749 | AttentionCommon::StageVec1Lse(stagingLayout, intraCoreCombineBase, | 812 | AttentionCommon::StageVec1Lse(stagingLayout, intraCoreCombineBase, |
| 750 | - GetIntraCoreWorkspaceIdx(runInfo, constInfo), GetFaStagingMOffset(runInfo, constInfo), | 813 | + GetIntraCoreWorkspaceIdx(runInfo, constInfo), GetFaStagingMOffset(runInfo, constInfo), |
| 751 | - runInfo.halfMRealSize, maxUb, sumUb, tmpUb, vToMte3AttnOutId, stageMte3ToVId); | 814 | + runInfo.halfMRealSize, maxUb, sumUb, tmpUb, vToMte3AttnOutId, stageMte3ToVId); |
| 752 | SetFlag<HardEvent::MTE3_MTE2>(intraLseMte3ToMte2Id[runInfo.multiCoreIdxMod2]); | 815 | SetFlag<HardEvent::MTE3_MTE2>(intraLseMte3ToMte2Id[runInfo.multiCoreIdxMod2]); |
| 753 | } else if (runInfo.isCrossCoreSplit && runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0) { | 816 | } else if (runInfo.isCrossCoreSplit && runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0) { |
| 754 | StageCrossCoreVec1Lse(maxUb, sumUb, runInfo, constInfo); | 817 | StageCrossCoreVec1Lse(maxUb, sumUb, runInfo, constInfo); |
| @@ -764,12 +827,12 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::StageLegacyVec1Lse( | |||
| 764 | return; | 827 | return; |
| 765 | } | 828 | } |
| 766 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, dTemplateAlign64, | 829 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, dTemplateAlign64, |
| 767 | - GetStagingSlotNum(), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 830 | + GetStagingSlotNum(), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 768 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 831 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 769 | LocalTensor<float> tmpUb = this->stage2OutBuf.template Get<float>(); | 832 | LocalTensor<float> tmpUb = this->stage2OutBuf.template Get<float>(); |
| 770 | AttentionCommon::StageVec1Lse(stagingLayout, fdStagingBase, GetCrossCoreWorkspaceIdx(runInfo), | 833 | AttentionCommon::StageVec1Lse(stagingLayout, fdStagingBase, GetCrossCoreWorkspaceIdx(runInfo), |
| 771 | - GetFaStagingMOffset(runInfo, constInfo), static_cast<uint32_t>(runInfo.halfMRealSize), | 834 | + GetFaStagingMOffset(runInfo, constInfo), static_cast<uint32_t>(runInfo.halfMRealSize), |
| 772 | - maxUb, sumUb, tmpUb, vToMte3AttnOutId, stageMte3ToVId); | 835 | + maxUb, sumUb, tmpUb, vToMte3AttnOutId, stageMte3ToVId); |
| 773 | } | 836 | } |
| 774 | 837 | ||
| 775 | TEMPLATES_DEF_NO_DEFAULT | 838 | TEMPLATES_DEF_NO_DEFAULT |
| @@ -777,7 +840,7 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopyOutVec1Lse( | |||
| 777 | LocalTensor<float> &maxUb, LocalTensor<float> &sumUb, RunInfo &runInfo, ConstInfo &constInfo) | 840 | LocalTensor<float> &maxUb, LocalTensor<float> &sumUb, RunInfo &runInfo, ConstInfo &constInfo) |
| 778 | { | 841 | { |
| 779 | bool copyOutLse = constInfo.returnSoftmaxLse && runInfo.halfMRealSize > 0 && | 842 | bool copyOutLse = constInfo.returnSoftmaxLse && runInfo.halfMRealSize > 0 && |
| 780 | - runInfo.s2LoopCount == runInfo.s2LoopLimit; | 843 | + runInfo.s2LoopCount == runInfo.s2LoopLimit; |
| 781 | if constexpr (IS_BATCH_CONSISTENCY) { | 844 | if constexpr (IS_BATCH_CONSISTENCY) { |
| 782 | copyOutLse = copyOutLse && !runInfo.isCrossCoreSplit && !runInfo.needReduce; | 845 | copyOutLse = copyOutLse && !runInfo.isCrossCoreSplit && !runInfo.needReduce; |
| 783 | } | 846 | } |
| @@ -848,11 +911,11 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ReduceIntraBlockAndStage( | |||
| 848 | RunInfo &runInfo, ConstInfo &constInfo, LocalTensor<T> &vec2ResUb, LocalTensor<T> &partialTmpUb) | 911 | RunInfo &runInfo, ConstInfo &constInfo, LocalTensor<T> &vec2ResUb, LocalTensor<T> &partialTmpUb) |
| 849 | { | 912 | { |
| 850 | AttentionCommon::S2SplitFdStagingLayout intraLayout = {constInfo.gSize, dTemplateAlign64, | 913 | AttentionCommon::S2SplitFdStagingLayout intraLayout = {constInfo.gSize, dTemplateAlign64, |
| 851 | - GetStagingSlotNum(true), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 914 | + GetStagingSlotNum(true), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 852 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 915 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 853 | AttentionCommon::S2SplitFdStagingLayout crossLayout = {constInfo.gSize, dTemplateAlign64, | 916 | AttentionCommon::S2SplitFdStagingLayout crossLayout = {constInfo.gSize, dTemplateAlign64, |
| 854 | - GetStagingSlotNum(false), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 917 | + GetStagingSlotNum(false), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 855 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 918 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 856 | uint32_t intraWorkspaceIdx = GetIntraCoreWorkspaceIdx(runInfo, constInfo); | 919 | uint32_t intraWorkspaceIdx = GetIntraCoreWorkspaceIdx(runInfo, constInfo); |
| 857 | uint32_t crossWorkspaceIdx = static_cast<uint32_t>( | 920 | uint32_t crossWorkspaceIdx = static_cast<uint32_t>( |
| 858 | runInfo.firstFdDataWorkspaceIdx + runInfo.s2SplitIdx - runInfo.reduceBlockId); | 921 | runInfo.firstFdDataWorkspaceIdx + runInfo.s2SplitIdx - runInfo.reduceBlockId); |
| @@ -867,7 +930,7 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ReduceIntraBlockAndStage( | |||
| 867 | LocalTensor<float> sumUb = | 930 | LocalTensor<float> sumUb = |
| 868 | this->softmaxFinalSumBuf[runInfo.taskIdMod2].template Get<float>(); | 931 | this->softmaxFinalSumBuf[runInfo.taskIdMod2].template Get<float>(); |
| 869 | bool copyOutMergedLse = constInfo.returnSoftmaxLse && !runInfo.isCrossCoreSplit && | 932 | bool copyOutMergedLse = constInfo.returnSoftmaxLse && !runInfo.isCrossCoreSplit && |
| 870 | - runInfo.s2LoopCount == runInfo.s2LoopLimit; | 933 | + runInfo.s2LoopCount == runInfo.s2LoopLimit; |
| 871 | 934 | ||
| 872 | WaitFlag<HardEvent::MTE3_MTE2>(intraLseMte3ToMte2Id[runInfo.multiCoreIdxMod2]); | 935 | WaitFlag<HardEvent::MTE3_MTE2>(intraLseMte3ToMte2Id[runInfo.multiCoreIdxMod2]); |
| 873 | WaitFlag<HardEvent::MTE3_MTE2>(intraAttnOutMte3ToMte2Id[runInfo.multiCoreIdxMod2]); | 936 | WaitFlag<HardEvent::MTE3_MTE2>(intraAttnOutMte3ToMte2Id[runInfo.multiCoreIdxMod2]); |
| @@ -884,14 +947,14 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ReduceIntraBlockAndStage( | |||
| 884 | WaitFlag<HardEvent::MTE3_V>(mte3ToVLseOutId); | 947 | WaitFlag<HardEvent::MTE3_V>(mte3ToVLseOutId); |
| 885 | } | 948 | } |
| 886 | AttentionCommon::MergeStagedAndCurrentChunk<T, dTemplateAlign64>(intraLayout, | 949 | AttentionCommon::MergeStagedAndCurrentChunk<T, dTemplateAlign64>(intraLayout, |
| 887 | - intraCoreCombineBase, intraWorkspaceIdx, stagingMOffset + startRow, | 950 | + intraCoreCombineBase, intraWorkspaceIdx, stagingMOffset + startRow, |
| 888 | - dealRowCount, static_cast<int64_t>(constInfo.dSizeV), chunkMaxUb, chunkSumUb, | 951 | + dealRowCount, static_cast<int64_t>(constInfo.dSizeV), chunkMaxUb, chunkSumUb, |
| 889 | - chunkCurrent, blockMaxUb, blockSumUb, partialTmpUb, lseBroadcastUb, sumBroadcastUb, | 952 | + chunkCurrent, blockMaxUb, blockSumUb, partialTmpUb, lseBroadcastUb, sumBroadcastUb, |
| 890 | - reduceMaxSumVToMte2Id, intraPartialOVToMte2Id, reduceMte2ToVId); | 953 | + reduceMaxSumVToMte2Id, intraPartialOVToMte2Id, reduceMte2ToVId); |
| 891 | 954 | ||
| 892 | AttentionCommon::StageBroadcastMaxSum(intraLayout, intraCoreCombineBase, intraWorkspaceIdx, | 955 | AttentionCommon::StageBroadcastMaxSum(intraLayout, intraCoreCombineBase, intraWorkspaceIdx, |
| 893 | - stagingMOffset + startRow, dealRowCount, lseBroadcastUb, sumBroadcastUb, | 956 | + stagingMOffset + startRow, dealRowCount, lseBroadcastUb, sumBroadcastUb, |
| 894 | - vToMte3AttnOutId, stageMte3ToVId); | 957 | + vToMte3AttnOutId, stageMte3ToVId); |
| 895 | if (copyOutMergedLse) { | 958 | if (copyOutMergedLse) { |
| 896 | DataCopyExtParams lseParams; | 959 | DataCopyExtParams lseParams; |
| 897 | lseParams.blockCount = static_cast<uint16_t>(dealRowCount); | 960 | lseParams.blockCount = static_cast<uint16_t>(dealRowCount); |
| @@ -901,24 +964,24 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ReduceIntraBlockAndStage( | |||
| 901 | SetFlag<HardEvent::V_MTE3>(vToMte3LseOutId); | 964 | SetFlag<HardEvent::V_MTE3>(vToMte3LseOutId); |
| 902 | WaitFlag<HardEvent::V_MTE3>(vToMte3LseOutId); | 965 | WaitFlag<HardEvent::V_MTE3>(vToMte3LseOutId); |
| 903 | DataCopyPad(this->softmaxLseGm[runInfo.softmaxLseOffset + startRow], | 966 | DataCopyPad(this->softmaxLseGm[runInfo.softmaxLseOffset + startRow], |
| 904 | - lseBroadcastUb, lseParams); | 967 | + lseBroadcastUb, lseParams); |
| 905 | SetFlag<HardEvent::MTE3_V>(mte3ToVLseOutId); | 968 | SetFlag<HardEvent::MTE3_V>(mte3ToVLseOutId); |
| 906 | } | 969 | } |
| 907 | if (runInfo.isCrossCoreSplit && runInfo.s2LoopCount == runInfo.s2LoopLimit) { | 970 | if (runInfo.isCrossCoreSplit && runInfo.s2LoopCount == runInfo.s2LoopLimit) { |
| 908 | AttentionCommon::StageBroadcastMaxSum(crossLayout, crossCoreCombineBase, crossWorkspaceIdx, | 971 | AttentionCommon::StageBroadcastMaxSum(crossLayout, crossCoreCombineBase, crossWorkspaceIdx, |
| 909 | - stagingMOffset + startRow, dealRowCount, lseBroadcastUb, sumBroadcastUb, | 972 | + stagingMOffset + startRow, dealRowCount, lseBroadcastUb, sumBroadcastUb, |
| 910 | - vToMte3AttnOutId, stageMte3ToVId); | 973 | + vToMte3AttnOutId, stageMte3ToVId); |
| 911 | } | 974 | } |
| 912 | startRow += intraLayout.chunkRows; | 975 | startRow += intraLayout.chunkRows; |
| 913 | } | 976 | } |
| 914 | 977 | ||
| 915 | AttentionCommon::StageVec2PartialOAndWait<T>(intraLayout, intraCoreCombineGm, intraWorkspaceIdx, | 978 | AttentionCommon::StageVec2PartialOAndWait<T>(intraLayout, intraCoreCombineGm, intraWorkspaceIdx, |
| 916 | - stagingMOffset, runInfo.vec2MRealSize, static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, | 979 | + stagingMOffset, runInfo.vec2MRealSize, static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, |
| 917 | - vToMte3AttnOutId, stageMte3ToVId); | 980 | + vToMte3AttnOutId, stageMte3ToVId); |
| 918 | if (runInfo.isCrossCoreSplit && runInfo.s2LoopCount == runInfo.s2LoopLimit) { | 981 | if (runInfo.isCrossCoreSplit && runInfo.s2LoopCount == runInfo.s2LoopLimit) { |
| 919 | AttentionCommon::StageVec2PartialOAndWait<T>(crossLayout, crossCoreCombineGm, crossWorkspaceIdx, | 982 | AttentionCommon::StageVec2PartialOAndWait<T>(crossLayout, crossCoreCombineGm, crossWorkspaceIdx, |
| 920 | - stagingMOffset, runInfo.vec2MRealSize, static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, | 983 | + stagingMOffset, runInfo.vec2MRealSize, static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, |
| 921 | - vToMte3AttnOutId, stageMte3ToVId); | 984 | + vToMte3AttnOutId, stageMte3ToVId); |
| 922 | } | 985 | } |
| 923 | if (runInfo.s2LoopCount < runInfo.s2LoopLimit) { | 986 | if (runInfo.s2LoopCount < runInfo.s2LoopLimit) { |
| 924 | SetFlag<HardEvent::MTE3_MTE2>(intraLseMte3ToMte2Id[runInfo.multiCoreIdxMod2]); | 987 | SetFlag<HardEvent::MTE3_MTE2>(intraLseMte3ToMte2Id[runInfo.multiCoreIdxMod2]); |
| @@ -1016,27 +1079,27 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ProcessVec2( | |||
| 1016 | if (runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0 && | 1079 | if (runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0 && |
| 1017 | runInfo.s2LoopCount < runInfo.s2LoopLimit) { | 1080 | runInfo.s2LoopCount < runInfo.s2LoopLimit) { |
| 1018 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, | 1081 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, |
| 1019 | - dTemplateAlign64, GetStagingSlotNum(true), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 1082 | + dTemplateAlign64, GetStagingSlotNum(true), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 1020 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 1083 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 1021 | int64_t stagingMOffset = GetFaStagingMOffset(runInfo, constInfo); | 1084 | int64_t stagingMOffset = GetFaStagingMOffset(runInfo, constInfo); |
| 1022 | AttentionCommon::StageVec2PartialOAndWait<T>(stagingLayout, intraCoreCombineGm, | 1085 | AttentionCommon::StageVec2PartialOAndWait<T>(stagingLayout, intraCoreCombineGm, |
| 1023 | - GetIntraCoreWorkspaceIdx(runInfo, constInfo), stagingMOffset, runInfo.vec2MRealSize, | 1086 | + GetIntraCoreWorkspaceIdx(runInfo, constInfo), stagingMOffset, runInfo.vec2MRealSize, |
| 1024 | - static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, | 1087 | + static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, |
| 1025 | - vToMte3AttnOutId, stageMte3ToVId); | 1088 | + vToMte3AttnOutId, stageMte3ToVId); |
| 1026 | SetFlag<HardEvent::MTE3_MTE2>(intraAttnOutMte3ToMte2Id[runInfo.multiCoreIdxMod2]); | 1089 | SetFlag<HardEvent::MTE3_MTE2>(intraAttnOutMte3ToMte2Id[runInfo.multiCoreIdxMod2]); |
| 1027 | } | 1090 | } |
| 1028 | if (runInfo.isCrossCoreSplit && (!runInfo.isFirstS2SplitCore || | 1091 | if (runInfo.isCrossCoreSplit && (!runInfo.isFirstS2SplitCore || |
| 1029 | - (runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0 && | 1092 | + (runInfo.isFirstS2SplitCore && runInfo.reduceBlockId == 0 && |
| 1030 | - runInfo.s2LoopCount == runInfo.s2LoopLimit))) { | 1093 | + runInfo.s2LoopCount == runInfo.s2LoopLimit))) { |
| 1031 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, | 1094 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, |
| 1032 | - dTemplateAlign64, GetStagingSlotNum(false), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 1095 | + dTemplateAlign64, GetStagingSlotNum(false), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 1033 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 1096 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 1034 | uint32_t workspaceIdx = GetCrossCoreWorkspaceIdx(runInfo); | 1097 | uint32_t workspaceIdx = GetCrossCoreWorkspaceIdx(runInfo); |
| 1035 | int64_t stagingMOffset = GetFaStagingMOffset(runInfo, constInfo); | 1098 | int64_t stagingMOffset = GetFaStagingMOffset(runInfo, constInfo); |
| 1036 | AttentionCommon::StageVec2PartialOAndWait<T>(stagingLayout, crossCoreCombineGm, | 1099 | AttentionCommon::StageVec2PartialOAndWait<T>(stagingLayout, crossCoreCombineGm, |
| 1037 | - workspaceIdx, stagingMOffset, runInfo.vec2MRealSize, | 1100 | + workspaceIdx, stagingMOffset, runInfo.vec2MRealSize, |
| 1038 | - static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, | 1101 | + static_cast<uint32_t>(constInfo.dSizeV), vec2ResUb, |
| 1039 | - vToMte3AttnOutId, stageMte3ToVId); | 1102 | + vToMte3AttnOutId, stageMte3ToVId); |
| 1040 | } else if (!runInfo.isCrossCoreSplit && runInfo.s2LoopCount == runInfo.s2LoopLimit) { | 1103 | } else if (!runInfo.isCrossCoreSplit && runInfo.s2LoopCount == runInfo.s2LoopLimit) { |
| 1041 | this->CopyOutAttentionOut(runInfo, constInfo, vec2ResUb, 0, vec2CalcSize); | 1104 | this->CopyOutAttentionOut(runInfo, constInfo, vec2ResUb, 0, vec2CalcSize); |
| 1042 | } | 1105 | } |
| @@ -1086,14 +1149,15 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ProcessFlashDecode(FdRunInfo | |||
| 1086 | seqOffset = fdRunInfo.bn2Idx * constInfo.s1Size; | 1149 | seqOffset = fdRunInfo.bn2Idx * constInfo.s1Size; |
| 1087 | } | 1150 | } |
| 1088 | int64_t attentionOutOffset = seqOffset * constInfo.n2GDv + | 1151 | int64_t attentionOutOffset = seqOffset * constInfo.n2GDv + |
| 1089 | - fdRunInfo.mIdx * constInfo.n2GDv + | 1152 | + fdRunInfo.mIdx * constInfo.n2GDv + |
| 1090 | - fdRunInfo.mStartIdx * constInfo.dSizeV; | 1153 | + fdRunInfo.mStartIdx * constInfo.dSizeV; |
| 1091 | int64_t softmaxLseOffset = 0; | 1154 | int64_t softmaxLseOffset = 0; |
| 1092 | if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { | 1155 | if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { |
| 1093 | softmaxLseOffset = (seqOffset + fdRunInfo.mIdx) * constInfo.gSize + fdRunInfo.mStartIdx; | 1156 | softmaxLseOffset = (seqOffset + fdRunInfo.mIdx) * constInfo.gSize + fdRunInfo.mStartIdx; |
| 1094 | } else { | 1157 | } else { |
| 1095 | softmaxLseOffset = (fdRunInfo.bn2Idx * constInfo.s1Size + fdRunInfo.mIdx) * | 1158 | softmaxLseOffset = (fdRunInfo.bn2Idx * constInfo.s1Size + fdRunInfo.mIdx) * |
| 1096 | - constInfo.gSize + fdRunInfo.mStartIdx; | 1159 | + constInfo.gSize + |
| 1160 | + fdRunInfo.mStartIdx; | ||
| 1097 | } | 1161 | } |
| 1098 | LocalTensor<T> accumulatedO = this->fdBuffers.accumOut.template Get<T>(); | 1162 | LocalTensor<T> accumulatedO = this->fdBuffers.accumOut.template Get<T>(); |
| 1099 | LocalTensor<float> lseExpUb = this->fdBuffers.lseExp.template Get<float>(); | 1163 | LocalTensor<float> lseExpUb = this->fdBuffers.lseExp.template Get<float>(); |
| @@ -1101,10 +1165,10 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ProcessFlashDecode(FdRunInfo | |||
| 1101 | LocalTensor<float> blockSumUb = this->fdBuffers.blockSum.template Get<float>(); | 1165 | LocalTensor<float> blockSumUb = this->fdBuffers.blockSum.template Get<float>(); |
| 1102 | LocalTensor<T> partialOFp32 = this->fdBuffers.partialO.template Get<T>(); | 1166 | LocalTensor<T> partialOFp32 = this->fdBuffers.partialO.template Get<T>(); |
| 1103 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, | 1167 | AttentionCommon::S2SplitFdStagingLayout stagingLayout = {constInfo.gSize, |
| 1104 | - dTemplateAlign64, GetStagingSlotNum(), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, | 1168 | + dTemplateAlign64, GetStagingSlotNum(), AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW, |
| 1105 | - AttentionCommon::FD_REDUCE_CHUNK_ROWS}; | 1169 | + AttentionCommon::FD_REDUCE_CHUNK_ROWS}; |
| 1106 | int64_t attentionOutRowStride = static_cast<int64_t>(constInfo.dSizeV) + | 1170 | int64_t attentionOutRowStride = static_cast<int64_t>(constInfo.dSizeV) + |
| 1107 | - static_cast<int64_t>(constInfo.attentionOutStride) / sizeof(OUTPUT_T); | 1171 | + static_cast<int64_t>(constInfo.attentionOutStride) / sizeof(OUTPUT_T); |
| 1108 | int64_t startRow = 0; | 1172 | int64_t startRow = 0; |
| 1109 | while (startRow < fdRunInfo.mNum) { | 1173 | while (startRow < fdRunInfo.mNum) { |
| 1110 | int64_t dealRowCount = AttentionCommon::FD_REDUCE_CHUNK_ROWS; | 1174 | int64_t dealRowCount = AttentionCommon::FD_REDUCE_CHUNK_ROWS; |
| @@ -1113,13 +1177,13 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::ProcessFlashDecode(FdRunInfo | |||
| 1113 | } | 1177 | } |
| 1114 | WaitFlag<HardEvent::MTE3_V>(fdMte3ToVId); | 1178 | WaitFlag<HardEvent::MTE3_V>(fdMte3ToVId); |
| 1115 | AttentionCommon::ReduceWithLse<T, dTemplateAlign64>(stagingLayout, fdStagingBase, | 1179 | AttentionCommon::ReduceWithLse<T, dTemplateAlign64>(stagingLayout, fdStagingBase, |
| 1116 | - fdRunInfo.workspaceIdx, fdRunInfo.workspaceNum, | 1180 | + fdRunInfo.workspaceIdx, fdRunInfo.workspaceNum, |
| 1117 | - static_cast<uint32_t>(fdRunInfo.mStartIdx + startRow), dealRowCount, | 1181 | + static_cast<uint32_t>(fdRunInfo.mStartIdx + startRow), dealRowCount, |
| 1118 | - static_cast<uint32_t>(constInfo.dSizeV), | 1182 | + static_cast<uint32_t>(constInfo.dSizeV), |
| 1119 | - accumulatedO, lseExpUb, blockMaxUb, blockSumUb, partialOFp32, | 1183 | + accumulatedO, lseExpUb, blockMaxUb, blockSumUb, partialOFp32, |
| 1120 | - constInfo.returnSoftmaxLse, softmaxLseGm, softmaxLseOffset + startRow, | 1184 | + constInfo.returnSoftmaxLse, softmaxLseGm, softmaxLseOffset + startRow, |
| 1121 | - fdVToMte2Id[0], fdVToMte2Id[1], fdMte2ToVId, | 1185 | + fdVToMte2Id[0], fdVToMte2Id[1], fdMte2ToVId, |
| 1122 | - vToMte3LseOutId, mte3ToVLseOutId); | 1186 | + vToMte3LseOutId, mte3ToVLseOutId); |
| 1123 | RunInfo runInfo; | 1187 | RunInfo runInfo; |
| 1124 | runInfo.vec2MRealSize = dealRowCount; | 1188 | runInfo.vec2MRealSize = dealRowCount; |
| 1125 | runInfo.attentionOutOffset = attentionOutOffset + startRow * attentionOutRowStride; | 1189 | runInfo.attentionOutOffset = attentionOutOffset + startRow * attentionOutRowStride; |
| @@ -1373,6 +1437,773 @@ __aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetExtremeValue(T &negativeSc | |||
| 1373 | negativeScalar = *((float *)&tmp1); | 1437 | negativeScalar = *((float *)&tmp1); |
| 1374 | } | 1438 | } |
| 1375 | 1439 | ||
| 1440 | +template <typename T> | ||
| 1441 | +__simd_vf__ void GetKVPhyAddrVFPaImpl(__ubuf__ uint32_t *kvPhyAddrUb, __ubuf__ int32_t *sparseIdxUb, | ||
| 1442 | + __ubuf__ int32_t *blkTableUb, const uint16_t s2Loop, uint32_t s2Tail, | ||
| 1443 | + const uint32_t blockSize, const int16_t shiftRightNum, | ||
| 1444 | + const uint32_t sparseBlockSize, const uint32_t kvDim, const uint32_t kvStride) | ||
| 1445 | +{ | ||
| 1446 | + static const uint16_t s2_num_per_loop = 128; | ||
| 1447 | + static const uint16_t s2_num_per_reg = 64; | ||
| 1448 | + static const uint16_t out_offset_per_loop = 256; | ||
| 1449 | + static const uint16_t out_offset_per_reg = 128; | ||
| 1450 | + static const uint32_t invalid_value = 0xFFFFFFFF; | ||
| 1451 | + MicroAPI::MaskReg preg_all_b32 = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 1452 | + MicroAPI::MaskReg add_carry_l_1; | ||
| 1453 | + MicroAPI::MaskReg add_carry_h_1; | ||
| 1454 | + MicroAPI::MaskReg add_carry_l_2; | ||
| 1455 | + MicroAPI::MaskReg add_carry_h_2; | ||
| 1456 | + MicroAPI::MaskReg preg_tail_neg_1_b32; | ||
| 1457 | + MicroAPI::MaskReg preg_tail_neg_2_b32; | ||
| 1458 | + | ||
| 1459 | + MicroAPI::RegTensor<uint32_t> vreg_kv_stride; | ||
| 1460 | + MicroAPI::RegTensor<uint32_t> vreg_sparse_idx_1; | ||
| 1461 | + MicroAPI::RegTensor<uint32_t> vreg_sparse_idx_2; | ||
| 1462 | + MicroAPI::RegTensor<uint32_t> vreg_block_size; | ||
| 1463 | + MicroAPI::RegTensor<uint32_t> vreg_shift_rights_num; | ||
| 1464 | + MicroAPI::RegTensor<uint32_t> vreg_pa_blk_idx_1; | ||
| 1465 | + MicroAPI::RegTensor<uint32_t> vreg_pa_blk_idx_2; | ||
| 1466 | + MicroAPI::RegTensor<uint32_t> vreg_pa_tmp_1; | ||
| 1467 | + MicroAPI::RegTensor<uint32_t> vreg_pa_tmp_2; | ||
| 1468 | + MicroAPI::RegTensor<uint32_t> vreg_pa_offset_1; | ||
| 1469 | + MicroAPI::RegTensor<uint32_t> vreg_pa_offset_2; | ||
| 1470 | + MicroAPI::RegTensor<uint32_t> vreg_phy_offset_1; | ||
| 1471 | + MicroAPI::RegTensor<uint32_t> vreg_phy_offset_2; | ||
| 1472 | + MicroAPI::RegTensor<uint32_t> vreg_phy_blk_idx_1; | ||
| 1473 | + MicroAPI::RegTensor<uint32_t> vreg_phy_blk_idx_2; | ||
| 1474 | + | ||
| 1475 | + MicroAPI::RegTensor<uint32_t> vreg_blk_id_mul_stride_h_1; | ||
| 1476 | + MicroAPI::RegTensor<uint32_t> vreg_blk_id_mul_stride_tmp_h_1; | ||
| 1477 | + MicroAPI::RegTensor<uint32_t> vreg_blk_id_mul_stride_l_1; | ||
| 1478 | + MicroAPI::RegTensor<uint32_t> vreg_mul_overflow_l_1; | ||
| 1479 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_l_1; | ||
| 1480 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_h_1; | ||
| 1481 | + | ||
| 1482 | + MicroAPI::RegTensor<uint32_t> vreg_blk_id_mul_stride_h_2; | ||
| 1483 | + MicroAPI::RegTensor<uint32_t> vreg_blk_id_mul_stride_tmp_h_2; | ||
| 1484 | + MicroAPI::RegTensor<uint32_t> vreg_blk_id_mul_stride_l_2; | ||
| 1485 | + MicroAPI::RegTensor<uint32_t> vreg_mul_overflow_l_2; | ||
| 1486 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_l_2; | ||
| 1487 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_h_2; | ||
| 1488 | + | ||
| 1489 | + MicroAPI::RegTensor<uint32_t> vreg_zero; | ||
| 1490 | + MicroAPI::Duplicate(vreg_zero, 0); | ||
| 1491 | + MicroAPI::Duplicate(vreg_kv_stride, kvStride); | ||
| 1492 | + | ||
| 1493 | + for (; s2Loop > 1;) { | ||
| 1494 | + for (uint16_t i = 0; i < s2Loop - 1; i++) { | ||
| 1495 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>( | ||
| 1496 | + (MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_1, sparseIdxUb + i * s2_num_per_loop); | ||
| 1497 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>( | ||
| 1498 | + (MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_2, sparseIdxUb + s2_num_per_reg + i * s2_num_per_loop); | ||
| 1499 | + // * sparseBlockSize | ||
| 1500 | + MicroAPI::Muls(vreg_sparse_idx_1, vreg_sparse_idx_1, sparseBlockSize, preg_all_b32); | ||
| 1501 | + MicroAPI::Muls(vreg_sparse_idx_2, vreg_sparse_idx_2, sparseBlockSize, preg_all_b32); | ||
| 1502 | + // 计算右移位数 | ||
| 1503 | + // 右移 -> 除blockSize 得到paBlockIdx,vreg_sparse_idx - pa_idx * blocksize -> pa offset | ||
| 1504 | + MicroAPI::ShiftRights(vreg_pa_blk_idx_1, vreg_sparse_idx_1, shiftRightNum, preg_all_b32); | ||
| 1505 | + MicroAPI::ShiftRights(vreg_pa_blk_idx_2, vreg_sparse_idx_2, shiftRightNum, preg_all_b32); | ||
| 1506 | + | ||
| 1507 | + MicroAPI::Muls(vreg_pa_tmp_1, vreg_pa_blk_idx_1, blockSize, preg_all_b32); | ||
| 1508 | + MicroAPI::Muls(vreg_pa_tmp_2, vreg_pa_blk_idx_2, blockSize, preg_all_b32); | ||
| 1509 | + // offset | ||
| 1510 | + MicroAPI::Sub(vreg_pa_offset_1, vreg_sparse_idx_1, vreg_pa_tmp_1, preg_all_b32); | ||
| 1511 | + MicroAPI::Sub(vreg_pa_offset_2, vreg_sparse_idx_2, vreg_pa_tmp_2, preg_all_b32); | ||
| 1512 | + // 物理页内offset | ||
| 1513 | + MicroAPI::Muls(vreg_phy_offset_1, vreg_pa_offset_1, kvDim, preg_all_b32); | ||
| 1514 | + MicroAPI::Muls(vreg_phy_offset_2, vreg_pa_offset_2, kvDim, preg_all_b32); | ||
| 1515 | + | ||
| 1516 | + // int32 paBlockId -> 物理id | ||
| 1517 | + DataCopyGather(vreg_phy_blk_idx_1, blkTableUb, vreg_pa_blk_idx_1, preg_all_b32); | ||
| 1518 | + DataCopyGather(vreg_phy_blk_idx_2, blkTableUb, vreg_pa_blk_idx_2, preg_all_b32); | ||
| 1519 | + | ||
| 1520 | + // 分高低32位计算int64物理地址 -- 乘 stride | ||
| 1521 | + // 低位乘 带进位 | ||
| 1522 | + MicroAPI::Mull(vreg_blk_id_mul_stride_l_1, vreg_mul_overflow_l_1, vreg_phy_blk_idx_1, vreg_kv_stride, | ||
| 1523 | + preg_all_b32); | ||
| 1524 | + MicroAPI::Mull(vreg_blk_id_mul_stride_l_2, vreg_mul_overflow_l_2, vreg_phy_blk_idx_2, vreg_kv_stride, | ||
| 1525 | + preg_all_b32); | ||
| 1526 | + | ||
| 1527 | + // 分高低32位计算int64物理地址 -- 加 offset | ||
| 1528 | + MicroAPI::Add(add_carry_l_1, vreg_total_offset_l_1, vreg_blk_id_mul_stride_l_1, vreg_phy_offset_1, | ||
| 1529 | + preg_all_b32); | ||
| 1530 | + MicroAPI::Add(add_carry_l_2, vreg_total_offset_l_2, vreg_blk_id_mul_stride_l_2, vreg_phy_offset_2, | ||
| 1531 | + preg_all_b32); | ||
| 1532 | + | ||
| 1533 | + MicroAPI::AddC(add_carry_h_1, vreg_total_offset_h_1, vreg_mul_overflow_l_1, vreg_zero, add_carry_l_1, | ||
| 1534 | + preg_all_b32); | ||
| 1535 | + MicroAPI::AddC(add_carry_h_2, vreg_total_offset_h_2, vreg_mul_overflow_l_2, vreg_zero, add_carry_l_2, | ||
| 1536 | + preg_all_b32); | ||
| 1537 | + | ||
| 1538 | + // 搬出 由于拆分为了int32类型,元素个数翻倍 | ||
| 1539 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1540 | + kvPhyAddrUb + i * out_offset_per_loop, vreg_total_offset_l_1, vreg_total_offset_h_1, preg_all_b32); | ||
| 1541 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1542 | + kvPhyAddrUb + out_offset_per_reg + i * out_offset_per_loop, vreg_total_offset_l_2, | ||
| 1543 | + vreg_total_offset_h_2, preg_all_b32); | ||
| 1544 | + } | ||
| 1545 | + break; | ||
| 1546 | + } | ||
| 1547 | + | ||
| 1548 | + for (uint16_t i = s2Loop - 1; i < s2Loop; i++) { | ||
| 1549 | + MicroAPI::MaskReg preg_tail_1_b32 = MicroAPI::UpdateMask<int32_t>(s2Tail); | ||
| 1550 | + MicroAPI::MaskReg preg_tail_2_b32 = MicroAPI::UpdateMask<int32_t>(s2Tail); | ||
| 1551 | + MicroAPI::Not(preg_tail_neg_1_b32, preg_tail_1_b32, preg_all_b32); | ||
| 1552 | + MicroAPI::Not(preg_tail_neg_2_b32, preg_tail_2_b32, preg_all_b32); | ||
| 1553 | + | ||
| 1554 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>((MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_1, | ||
| 1555 | + sparseIdxUb + i * s2_num_per_loop); | ||
| 1556 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>((MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_2, | ||
| 1557 | + sparseIdxUb + s2_num_per_reg + i * s2_num_per_loop); | ||
| 1558 | + // * sparseBlockSize | ||
| 1559 | + MicroAPI::Muls(vreg_sparse_idx_1, vreg_sparse_idx_1, sparseBlockSize, preg_tail_1_b32); | ||
| 1560 | + MicroAPI::Muls(vreg_sparse_idx_2, vreg_sparse_idx_2, sparseBlockSize, preg_tail_2_b32); | ||
| 1561 | + // 计算右移位数 | ||
| 1562 | + // 右移 -> 除blockSize 得到paBlockIdx,vreg_sparse_idx - pa_idx * blocksize -> pa offset | ||
| 1563 | + MicroAPI::ShiftRights(vreg_pa_blk_idx_1, vreg_sparse_idx_1, shiftRightNum, preg_tail_1_b32); | ||
| 1564 | + MicroAPI::ShiftRights(vreg_pa_blk_idx_2, vreg_sparse_idx_2, shiftRightNum, preg_tail_2_b32); | ||
| 1565 | + | ||
| 1566 | + MicroAPI::Muls(vreg_pa_tmp_1, vreg_pa_blk_idx_1, blockSize, preg_tail_1_b32); | ||
| 1567 | + MicroAPI::Muls(vreg_pa_tmp_2, vreg_pa_blk_idx_2, blockSize, preg_tail_2_b32); | ||
| 1568 | + // offset | ||
| 1569 | + MicroAPI::Sub(vreg_pa_offset_1, vreg_sparse_idx_1, vreg_pa_tmp_1, preg_tail_1_b32); | ||
| 1570 | + MicroAPI::Sub(vreg_pa_offset_2, vreg_sparse_idx_2, vreg_pa_tmp_2, preg_tail_2_b32); | ||
| 1571 | + // 物理页内offset | ||
| 1572 | + MicroAPI::Muls(vreg_phy_offset_1, vreg_pa_offset_1, kvDim, preg_tail_1_b32); | ||
| 1573 | + MicroAPI::Muls(vreg_phy_offset_2, vreg_pa_offset_2, kvDim, preg_tail_2_b32); | ||
| 1574 | + | ||
| 1575 | + // int32 paBlockId -> 物理id | ||
| 1576 | + DataCopyGather(vreg_phy_blk_idx_1, blkTableUb, vreg_pa_blk_idx_1, preg_tail_1_b32); | ||
| 1577 | + DataCopyGather(vreg_phy_blk_idx_2, blkTableUb, vreg_pa_blk_idx_2, preg_tail_2_b32); | ||
| 1578 | + | ||
| 1579 | + // 分高低32位计算int64物理地址 -- 乘 stride | ||
| 1580 | + // 低位乘 带进位 | ||
| 1581 | + MicroAPI::Mull(vreg_blk_id_mul_stride_l_1, vreg_mul_overflow_l_1, vreg_phy_blk_idx_1, vreg_kv_stride, | ||
| 1582 | + preg_tail_1_b32); | ||
| 1583 | + MicroAPI::Mull(vreg_blk_id_mul_stride_l_2, vreg_mul_overflow_l_2, vreg_phy_blk_idx_2, vreg_kv_stride, | ||
| 1584 | + preg_tail_2_b32); | ||
| 1585 | + | ||
| 1586 | + // 分高低32位计算int64物理地址 -- 加 offset | ||
| 1587 | + MicroAPI::Add(add_carry_l_1, vreg_total_offset_l_1, vreg_blk_id_mul_stride_l_1, vreg_phy_offset_1, | ||
| 1588 | + preg_tail_1_b32); | ||
| 1589 | + MicroAPI::Add(add_carry_l_2, vreg_total_offset_l_2, vreg_blk_id_mul_stride_l_2, vreg_phy_offset_2, | ||
| 1590 | + preg_tail_2_b32); | ||
| 1591 | + | ||
| 1592 | + MicroAPI::AddC(add_carry_h_1, vreg_total_offset_h_1, vreg_mul_overflow_l_1, vreg_zero, add_carry_l_1, | ||
| 1593 | + preg_tail_1_b32); | ||
| 1594 | + MicroAPI::AddC(add_carry_h_2, vreg_total_offset_h_2, vreg_mul_overflow_l_2, vreg_zero, add_carry_l_2, | ||
| 1595 | + preg_tail_2_b32); | ||
| 1596 | + | ||
| 1597 | + // 无效值填充-1(0xFFFFFFFF) | ||
| 1598 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_l_1, invalid_value, | ||
| 1599 | + preg_tail_neg_1_b32); | ||
| 1600 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_h_1, invalid_value, | ||
| 1601 | + preg_tail_neg_1_b32); | ||
| 1602 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_l_2, invalid_value, | ||
| 1603 | + preg_tail_neg_2_b32); | ||
| 1604 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_h_2, invalid_value, | ||
| 1605 | + preg_tail_neg_2_b32); | ||
| 1606 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1607 | + kvPhyAddrUb + i * out_offset_per_loop, vreg_total_offset_l_1, vreg_total_offset_h_1, preg_all_b32); | ||
| 1608 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1609 | + kvPhyAddrUb + out_offset_per_reg + i * out_offset_per_loop, vreg_total_offset_l_2, | ||
| 1610 | + vreg_total_offset_h_2, preg_all_b32); | ||
| 1611 | + } | ||
| 1612 | +} | ||
| 1613 | + | ||
| 1614 | +template <typename T> | ||
| 1615 | +__aicore__ inline void GetKVPhyAddrVFPa(LocalTensor<uint32_t> kvPhyAddrTensor, LocalTensor<int32_t> sparseIdxTensor, | ||
| 1616 | + LocalTensor<int32_t> blkTableTensor, const uint16_t s2Loop, const uint32_t s2Tail, | ||
| 1617 | + const uint32_t blockSize, const int16_t shiftRightNum, | ||
| 1618 | + const uint32_t sparseBlockSize, const uint32_t kvDim, const uint32_t kvStride) | ||
| 1619 | +{ | ||
| 1620 | + __ubuf__ uint32_t *kv_phy_addr_ub = (__ubuf__ uint32_t *)(kvPhyAddrTensor.GetPhyAddr()); | ||
| 1621 | + __ubuf__ int32_t *sparse_idx_ub = (__ubuf__ int32_t *)(sparseIdxTensor.GetPhyAddr()); | ||
| 1622 | + __ubuf__ int32_t *blk_table_ub = (__ubuf__ int32_t *)(blkTableTensor.GetPhyAddr()); | ||
| 1623 | + GetKVPhyAddrVFPaImpl<uint32_t>(kv_phy_addr_ub, sparse_idx_ub, blk_table_ub, s2Loop, s2Tail, blockSize, shiftRightNum, | ||
| 1624 | + sparseBlockSize, kvDim, kvStride); | ||
| 1625 | +} | ||
| 1626 | + | ||
| 1627 | +template <typename T> | ||
| 1628 | +__simd_vf__ void GetKVPhyAddrVFTndImpl(__ubuf__ uint32_t *kvPhyAddrUb, __ubuf__ int32_t *sparseIdxUb, | ||
| 1629 | + const uint16_t s2Loop, uint32_t s2Tail, | ||
| 1630 | + const uint32_t sparseBlockSize, const uint32_t kvDim, | ||
| 1631 | + const uint32_t kvPrefix) | ||
| 1632 | +{ | ||
| 1633 | + static const uint16_t s2_num_per_loop = 128; | ||
| 1634 | + static const uint16_t s2_num_per_reg = 64; | ||
| 1635 | + static const uint16_t out_offset_per_loop = 256; | ||
| 1636 | + static const uint16_t out_offset_per_reg = 128; | ||
| 1637 | + static const uint32_t invalid_value = 0xFFFFFFFF; | ||
| 1638 | + MicroAPI::MaskReg preg_all_b32 = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 1639 | + MicroAPI::MaskReg preg_tail_neg_1_b32; | ||
| 1640 | + MicroAPI::MaskReg preg_tail_neg_2_b32; | ||
| 1641 | + | ||
| 1642 | + MicroAPI::RegTensor<uint32_t> vreg_sparse_idx_1; | ||
| 1643 | + MicroAPI::RegTensor<uint32_t> vreg_sparse_idx_2; | ||
| 1644 | + MicroAPI::RegTensor<uint32_t> vreg_kv_prefix; | ||
| 1645 | + MicroAPI::RegTensor<uint32_t> vreg_kv_dim; | ||
| 1646 | + MicroAPI::RegTensor<uint32_t> vreg_sum_1; | ||
| 1647 | + MicroAPI::RegTensor<uint32_t> vreg_sum_2; | ||
| 1648 | + MicroAPI::RegTensor<uint32_t> vreg_mul_overflow_l_1; | ||
| 1649 | + MicroAPI::RegTensor<uint32_t> vreg_mul_overflow_l_2; | ||
| 1650 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_l_1; | ||
| 1651 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_h_1; | ||
| 1652 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_l_2; | ||
| 1653 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_h_2; | ||
| 1654 | + | ||
| 1655 | + MicroAPI::Duplicate(vreg_kv_prefix, kvPrefix); | ||
| 1656 | + MicroAPI::Duplicate(vreg_kv_dim, kvDim); | ||
| 1657 | + | ||
| 1658 | + for (; s2Loop > 1;) { | ||
| 1659 | + for (uint16_t i = 0; i < s2Loop - 1; i++) { | ||
| 1660 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>( | ||
| 1661 | + (MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_1, sparseIdxUb + i * s2_num_per_loop); | ||
| 1662 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>( | ||
| 1663 | + (MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_2, sparseIdxUb + s2_num_per_reg + i * s2_num_per_loop); | ||
| 1664 | + // * sparseBlockSize | ||
| 1665 | + MicroAPI::Muls(vreg_sparse_idx_1, vreg_sparse_idx_1, sparseBlockSize, preg_all_b32); | ||
| 1666 | + MicroAPI::Muls(vreg_sparse_idx_2, vreg_sparse_idx_2, sparseBlockSize, preg_all_b32); | ||
| 1667 | + // (kvPrefix + sparseIdx) * kvDim -> int64 物理地址 | ||
| 1668 | + MicroAPI::Add(vreg_sum_1, vreg_sparse_idx_1, vreg_kv_prefix, preg_all_b32); | ||
| 1669 | + MicroAPI::Add(vreg_sum_2, vreg_sparse_idx_2, vreg_kv_prefix, preg_all_b32); | ||
| 1670 | + // 带进位乘法 | ||
| 1671 | + MicroAPI::Mull(vreg_total_offset_l_1, vreg_total_offset_h_1, vreg_sum_1, vreg_kv_dim, preg_all_b32); | ||
| 1672 | + MicroAPI::Mull(vreg_total_offset_l_2, vreg_total_offset_h_2, vreg_sum_2, vreg_kv_dim, preg_all_b32); | ||
| 1673 | + // 搬出 | ||
| 1674 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1675 | + kvPhyAddrUb + i * out_offset_per_loop, vreg_total_offset_l_1, vreg_total_offset_h_1, preg_all_b32); | ||
| 1676 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1677 | + kvPhyAddrUb + out_offset_per_reg + i * out_offset_per_loop, vreg_total_offset_l_2, | ||
| 1678 | + vreg_total_offset_h_2, preg_all_b32); | ||
| 1679 | + } | ||
| 1680 | + break; | ||
| 1681 | + } | ||
| 1682 | + | ||
| 1683 | + for (uint16_t i = s2Loop - 1; i < s2Loop; i++) { | ||
| 1684 | + MicroAPI::MaskReg preg_tail_1_b32 = MicroAPI::UpdateMask<int32_t>(s2Tail); | ||
| 1685 | + MicroAPI::MaskReg preg_tail_2_b32 = MicroAPI::UpdateMask<int32_t>(s2Tail); | ||
| 1686 | + MicroAPI::Not(preg_tail_neg_1_b32, preg_tail_1_b32, preg_all_b32); | ||
| 1687 | + MicroAPI::Not(preg_tail_neg_2_b32, preg_tail_2_b32, preg_all_b32); | ||
| 1688 | + | ||
| 1689 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>((MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_1, | ||
| 1690 | + sparseIdxUb + i * s2_num_per_loop); | ||
| 1691 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>((MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_2, | ||
| 1692 | + sparseIdxUb + s2_num_per_reg + i * s2_num_per_loop); | ||
| 1693 | + // * sparseBlockSize | ||
| 1694 | + MicroAPI::Muls(vreg_sparse_idx_1, vreg_sparse_idx_1, sparseBlockSize, preg_tail_1_b32); | ||
| 1695 | + MicroAPI::Muls(vreg_sparse_idx_2, vreg_sparse_idx_2, sparseBlockSize, preg_tail_2_b32); | ||
| 1696 | + // (kvPrefix + sparseIdx) * kvDim -> int64 物理地址 | ||
| 1697 | + MicroAPI::Add(vreg_sum_1, vreg_sparse_idx_1, vreg_kv_prefix, preg_tail_1_b32); | ||
| 1698 | + MicroAPI::Add(vreg_sum_2, vreg_sparse_idx_2, vreg_kv_prefix, preg_tail_2_b32); | ||
| 1699 | + // 带进位乘法 | ||
| 1700 | + MicroAPI::Mull(vreg_total_offset_l_1, vreg_total_offset_h_1, vreg_sum_1, vreg_kv_dim, preg_tail_1_b32); | ||
| 1701 | + MicroAPI::Mull(vreg_total_offset_l_2, vreg_total_offset_h_2, vreg_sum_2, vreg_kv_dim, preg_tail_2_b32); | ||
| 1702 | + // 无效值填充-1(0xFFFFFFFF) | ||
| 1703 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_l_1, invalid_value, | ||
| 1704 | + preg_tail_neg_1_b32); | ||
| 1705 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_h_1, invalid_value, | ||
| 1706 | + preg_tail_neg_1_b32); | ||
| 1707 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_l_2, invalid_value, | ||
| 1708 | + preg_tail_neg_2_b32); | ||
| 1709 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_h_2, invalid_value, | ||
| 1710 | + preg_tail_neg_2_b32); | ||
| 1711 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1712 | + kvPhyAddrUb + i * out_offset_per_loop, vreg_total_offset_l_1, vreg_total_offset_h_1, preg_all_b32); | ||
| 1713 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1714 | + kvPhyAddrUb + out_offset_per_reg + i * out_offset_per_loop, vreg_total_offset_l_2, | ||
| 1715 | + vreg_total_offset_h_2, preg_all_b32); | ||
| 1716 | + } | ||
| 1717 | +} | ||
| 1718 | + | ||
| 1719 | +template <typename T> | ||
| 1720 | +__aicore__ inline void GetKVPhyAddrVFTnd(LocalTensor<uint32_t> kvPhyAddrTensor, LocalTensor<int32_t> sparseIdxTensor, | ||
| 1721 | + const uint16_t s2Loop, const uint32_t s2Tail, | ||
| 1722 | + const uint32_t sparseBlockSize, const uint32_t kvDim, | ||
| 1723 | + const uint32_t kvPrefix) | ||
| 1724 | +{ | ||
| 1725 | + __ubuf__ uint32_t *kv_phy_addr_ub = (__ubuf__ uint32_t *)(kvPhyAddrTensor.GetPhyAddr()); | ||
| 1726 | + __ubuf__ int32_t *sparse_idx_ub = (__ubuf__ int32_t *)(sparseIdxTensor.GetPhyAddr()); | ||
| 1727 | + GetKVPhyAddrVFTndImpl<uint32_t>(kv_phy_addr_ub, sparse_idx_ub, s2Loop, s2Tail, | ||
| 1728 | + sparseBlockSize, kvDim, kvPrefix); | ||
| 1729 | +} | ||
| 1730 | + | ||
| 1731 | +template <typename T> | ||
| 1732 | +__simd_vf__ void GetKVPhyAddrVFBsndImpl(__ubuf__ uint32_t *kvPhyAddrUb, __ubuf__ int32_t *sparseIdxUb, | ||
| 1733 | + const uint16_t s2Loop, uint32_t s2Tail, | ||
| 1734 | + const uint32_t sparseBlockSize, const uint32_t kvDim, | ||
| 1735 | + const uint32_t bS2BaseLow, const uint32_t bS2BaseHigh) | ||
| 1736 | +{ | ||
| 1737 | + static const uint16_t s2_num_per_loop = 128; | ||
| 1738 | + static const uint16_t s2_num_per_reg = 64; | ||
| 1739 | + static const uint16_t out_offset_per_loop = 256; | ||
| 1740 | + static const uint16_t out_offset_per_reg = 128; | ||
| 1741 | + static const uint32_t invalid_value = 0xFFFFFFFF; | ||
| 1742 | + MicroAPI::MaskReg preg_all_b32 = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 1743 | + MicroAPI::MaskReg add_carry_l_1; | ||
| 1744 | + MicroAPI::MaskReg add_carry_h_1; | ||
| 1745 | + MicroAPI::MaskReg add_carry_l_2; | ||
| 1746 | + MicroAPI::MaskReg add_carry_h_2; | ||
| 1747 | + MicroAPI::MaskReg preg_tail_neg_1_b32; | ||
| 1748 | + MicroAPI::MaskReg preg_tail_neg_2_b32; | ||
| 1749 | + | ||
| 1750 | + MicroAPI::RegTensor<uint32_t> vreg_sparse_idx_1; | ||
| 1751 | + MicroAPI::RegTensor<uint32_t> vreg_sparse_idx_2; | ||
| 1752 | + MicroAPI::RegTensor<uint32_t> vreg_kv_dim; | ||
| 1753 | + MicroAPI::RegTensor<uint32_t> vreg_b_s2_base_low; | ||
| 1754 | + MicroAPI::RegTensor<uint32_t> vreg_b_s2_base_high; | ||
| 1755 | + MicroAPI::RegTensor<uint32_t> vreg_s2_offset_l_1; | ||
| 1756 | + MicroAPI::RegTensor<uint32_t> vreg_s2_offset_l_2; | ||
| 1757 | + MicroAPI::RegTensor<uint32_t> vreg_mul_overflow_l_1; | ||
| 1758 | + MicroAPI::RegTensor<uint32_t> vreg_mul_overflow_l_2; | ||
| 1759 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_l_1; | ||
| 1760 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_h_1; | ||
| 1761 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_l_2; | ||
| 1762 | + MicroAPI::RegTensor<uint32_t> vreg_total_offset_h_2; | ||
| 1763 | + MicroAPI::RegTensor<uint32_t> vreg_zero; | ||
| 1764 | + | ||
| 1765 | + MicroAPI::Duplicate(vreg_zero, 0); | ||
| 1766 | + MicroAPI::Duplicate(vreg_kv_dim, kvDim); | ||
| 1767 | + MicroAPI::Duplicate(vreg_b_s2_base_low, bS2BaseLow); | ||
| 1768 | + MicroAPI::Duplicate(vreg_b_s2_base_high, bS2BaseHigh); | ||
| 1769 | + | ||
| 1770 | + for (; s2Loop > 1;) { | ||
| 1771 | + for (uint16_t i = 0; i < s2Loop - 1; i++) { | ||
| 1772 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>( | ||
| 1773 | + (MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_1, sparseIdxUb + i * s2_num_per_loop); | ||
| 1774 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>( | ||
| 1775 | + (MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_2, sparseIdxUb + s2_num_per_reg + i * s2_num_per_loop); | ||
| 1776 | + // * sparseBlockSize | ||
| 1777 | + MicroAPI::Muls(vreg_sparse_idx_1, vreg_sparse_idx_1, sparseBlockSize, preg_all_b32); | ||
| 1778 | + MicroAPI::Muls(vreg_sparse_idx_2, vreg_sparse_idx_2, sparseBlockSize, preg_all_b32); | ||
| 1779 | + // sparseIdx * kvDim (带进位乘法) | ||
| 1780 | + MicroAPI::Mull(vreg_s2_offset_l_1, vreg_mul_overflow_l_1, vreg_sparse_idx_1, vreg_kv_dim, preg_all_b32); | ||
| 1781 | + MicroAPI::Mull(vreg_s2_offset_l_2, vreg_mul_overflow_l_2, vreg_sparse_idx_2, vreg_kv_dim, preg_all_b32); | ||
| 1782 | + // s2_offset + bS2Base (int64 + int64) | ||
| 1783 | + MicroAPI::Add(add_carry_l_1, vreg_total_offset_l_1, vreg_s2_offset_l_1, vreg_b_s2_base_low, preg_all_b32); | ||
| 1784 | + MicroAPI::Add(add_carry_l_2, vreg_total_offset_l_2, vreg_s2_offset_l_2, vreg_b_s2_base_low, preg_all_b32); | ||
| 1785 | + MicroAPI::AddC(add_carry_h_1, vreg_total_offset_h_1, vreg_mul_overflow_l_1, vreg_b_s2_base_high, | ||
| 1786 | + add_carry_l_1, preg_all_b32); | ||
| 1787 | + MicroAPI::AddC(add_carry_h_2, vreg_total_offset_h_2, vreg_mul_overflow_l_2, vreg_b_s2_base_high, | ||
| 1788 | + add_carry_l_2, preg_all_b32); | ||
| 1789 | + // 搬出 | ||
| 1790 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1791 | + kvPhyAddrUb + i * out_offset_per_loop, vreg_total_offset_l_1, vreg_total_offset_h_1, preg_all_b32); | ||
| 1792 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1793 | + kvPhyAddrUb + out_offset_per_reg + i * out_offset_per_loop, vreg_total_offset_l_2, | ||
| 1794 | + vreg_total_offset_h_2, preg_all_b32); | ||
| 1795 | + } | ||
| 1796 | + break; | ||
| 1797 | + } | ||
| 1798 | + | ||
| 1799 | + for (uint16_t i = s2Loop - 1; i < s2Loop; i++) { | ||
| 1800 | + MicroAPI::MaskReg preg_tail_1_b32 = MicroAPI::UpdateMask<int32_t>(s2Tail); | ||
| 1801 | + MicroAPI::MaskReg preg_tail_2_b32 = MicroAPI::UpdateMask<int32_t>(s2Tail); | ||
| 1802 | + MicroAPI::Not(preg_tail_neg_1_b32, preg_tail_1_b32, preg_all_b32); | ||
| 1803 | + MicroAPI::Not(preg_tail_neg_2_b32, preg_tail_2_b32, preg_all_b32); | ||
| 1804 | + | ||
| 1805 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>((MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_1, | ||
| 1806 | + sparseIdxUb + i * s2_num_per_loop); | ||
| 1807 | + MicroAPI::LoadAlign<int32_t, MicroAPI::LoadDist::DIST_NORM>((MicroAPI::RegTensor<int32_t> &)vreg_sparse_idx_2, | ||
| 1808 | + sparseIdxUb + s2_num_per_reg + i * s2_num_per_loop); | ||
| 1809 | + // * sparseBlockSize | ||
| 1810 | + MicroAPI::Muls(vreg_sparse_idx_1, vreg_sparse_idx_1, sparseBlockSize, preg_tail_1_b32); | ||
| 1811 | + MicroAPI::Muls(vreg_sparse_idx_2, vreg_sparse_idx_2, sparseBlockSize, preg_tail_2_b32); | ||
| 1812 | + // sparseIdx * kvDim (带进位乘法) | ||
| 1813 | + MicroAPI::Mull(vreg_s2_offset_l_1, vreg_mul_overflow_l_1, vreg_sparse_idx_1, vreg_kv_dim, preg_tail_1_b32); | ||
| 1814 | + MicroAPI::Mull(vreg_s2_offset_l_2, vreg_mul_overflow_l_2, vreg_sparse_idx_2, vreg_kv_dim, preg_tail_2_b32); | ||
| 1815 | + // s2_offset + bS2Base (int64 + int64) | ||
| 1816 | + MicroAPI::Add(add_carry_l_1, vreg_total_offset_l_1, vreg_s2_offset_l_1, vreg_b_s2_base_low, preg_tail_1_b32); | ||
| 1817 | + MicroAPI::Add(add_carry_l_2, vreg_total_offset_l_2, vreg_s2_offset_l_2, vreg_b_s2_base_low, preg_tail_2_b32); | ||
| 1818 | + MicroAPI::AddC(add_carry_h_1, vreg_total_offset_h_1, vreg_mul_overflow_l_1, vreg_b_s2_base_high, | ||
| 1819 | + add_carry_l_1, preg_tail_1_b32); | ||
| 1820 | + MicroAPI::AddC(add_carry_h_2, vreg_total_offset_h_2, vreg_mul_overflow_l_2, vreg_b_s2_base_high, | ||
| 1821 | + add_carry_l_2, preg_tail_2_b32); | ||
| 1822 | + // 无效值填充-1(0xFFFFFFFF) | ||
| 1823 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_l_1, invalid_value, | ||
| 1824 | + preg_tail_neg_1_b32); | ||
| 1825 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_h_1, invalid_value, | ||
| 1826 | + preg_tail_neg_1_b32); | ||
| 1827 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_l_2, invalid_value, | ||
| 1828 | + preg_tail_neg_2_b32); | ||
| 1829 | + MicroAPI::Duplicate<uint32_t, MicroAPI::MaskMergeMode::MERGING>(vreg_total_offset_h_2, invalid_value, | ||
| 1830 | + preg_tail_neg_2_b32); | ||
| 1831 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1832 | + kvPhyAddrUb + i * out_offset_per_loop, vreg_total_offset_l_1, vreg_total_offset_h_1, preg_all_b32); | ||
| 1833 | + MicroAPI::StoreAlign<uint32_t, MicroAPI::StoreDist::DIST_INTLV_B32>( | ||
| 1834 | + kvPhyAddrUb + out_offset_per_reg + i * out_offset_per_loop, vreg_total_offset_l_2, | ||
| 1835 | + vreg_total_offset_h_2, preg_all_b32); | ||
| 1836 | + } | ||
| 1837 | +} | ||
| 1838 | + | ||
| 1839 | +template <typename T> | ||
| 1840 | +__aicore__ inline void GetKVPhyAddrVFBsnd(LocalTensor<uint32_t> kvPhyAddrTensor, LocalTensor<int32_t> sparseIdxTensor, | ||
| 1841 | + const uint16_t s2Loop, const uint32_t s2Tail, | ||
| 1842 | + const uint32_t sparseBlockSize, const uint32_t kvDim, | ||
| 1843 | + const uint32_t bS2BaseLow, const uint32_t bS2BaseHigh) | ||
| 1844 | +{ | ||
| 1845 | + __ubuf__ uint32_t *kv_phy_addr_ub = (__ubuf__ uint32_t *)(kvPhyAddrTensor.GetPhyAddr()); | ||
| 1846 | + __ubuf__ int32_t *sparse_idx_ub = (__ubuf__ int32_t *)(sparseIdxTensor.GetPhyAddr()); | ||
| 1847 | + GetKVPhyAddrVFBsndImpl<uint32_t>(kv_phy_addr_ub, sparse_idx_ub, s2Loop, s2Tail, | ||
| 1848 | + sparseBlockSize, kvDim, bS2BaseLow, bS2BaseHigh); | ||
| 1849 | +} | ||
| 1850 | + | ||
| 1851 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 1852 | +__aicore__ inline int32_t CSABlockVec<TEMPLATE_ARGS>::GetSeqLen(int32_t bIdx, bool hasActualSeq, bool hasCuSeqlens, | ||
| 1853 | + GlobalTensor<int32_t> &actualSeqGm, | ||
| 1854 | + GlobalTensor<int32_t> &cuSeqlensGm, int64_t defaultSize) | ||
| 1855 | +{ | ||
| 1856 | + if (hasActualSeq) { | ||
| 1857 | + return actualSeqGm.GetValue(bIdx); | ||
| 1858 | + } else if (hasCuSeqlens) { | ||
| 1859 | + return cuSeqlensGm.GetValue(bIdx + 1) - cuSeqlensGm.GetValue(bIdx); | ||
| 1860 | + } else { | ||
| 1861 | + return defaultSize; | ||
| 1862 | + } | ||
| 1863 | +} | ||
| 1864 | + | ||
| 1865 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 1866 | +__aicore__ inline int32_t CSABlockVec<TEMPLATE_ARGS>::CalcCurValidS2( | ||
| 1867 | + uint32_t bIdx, int32_t s1Idx, int32_t actualS1Size, bool isOriKv, bool hasActualSeqKvlen, bool hasCuSeqlensKv, | ||
| 1868 | + GlobalTensor<int32_t> &cuSeqlensQGm, GlobalTensor<int32_t> &actualSeqKvlenGm, | ||
| 1869 | + GlobalTensor<int32_t> &cuSeqlensKvGm, GlobalTensor<int32_t> &topkLengthGm, | ||
| 1870 | + GlobalTensor<int32_t> &cmpResidualKvGm, ConstInfo &constInfo, int32_t sparseBlockCount) | ||
| 1871 | +{ | ||
| 1872 | + int32_t curValidS2 = 0; | ||
| 1873 | + if (isOriKv) { | ||
| 1874 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 1875 | + TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 1876 | + uint64_t topkIdx = (LAYOUT_T == SMLA_LAYOUT::TND) ? (cuSeqlensQGm.GetValue(bIdx) + s1Idx) : | ||
| 1877 | + (bIdx * constInfo.s1Size + s1Idx); | ||
| 1878 | + int32_t topkLen = constInfo.hasOriTopkLength ? topkLengthGm.GetValue(topkIdx) : sparseBlockCount; | ||
| 1879 | + curValidS2 = Min(topkLen, sparseBlockCount); | ||
| 1880 | + } | ||
| 1881 | + } else { | ||
| 1882 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE) { | ||
| 1883 | + if (constInfo.cmpMaskMode == 0) { | ||
| 1884 | + uint64_t topkIdx = (LAYOUT_T == SMLA_LAYOUT::TND) ? (cuSeqlensQGm.GetValue(bIdx) + s1Idx) : | ||
| 1885 | + (bIdx * constInfo.s1Size + s1Idx); | ||
| 1886 | + int32_t topkLen = constInfo.hasCmpTopkLength ? topkLengthGm.GetValue(topkIdx) : sparseBlockCount; | ||
| 1887 | + curValidS2 = Min(topkLen, sparseBlockCount); | ||
| 1888 | + } else { | ||
| 1889 | + int32_t actualCmpS2Size = GetSeqLen(bIdx, hasActualSeqKvlen, hasCuSeqlensKv, actualSeqKvlenGm, | ||
| 1890 | + cuSeqlensKvGm, constInfo.s2Size); | ||
| 1891 | + int32_t cmpRestoredSize = | ||
| 1892 | + actualCmpS2Size * static_cast<int32_t>(constInfo.cmpRatio) + cmpResidualKvGm.GetValue(bIdx); | ||
| 1893 | + int32_t numerator = cmpRestoredSize - actualS1Size + 1 + s1Idx; | ||
| 1894 | + curValidS2 = | ||
| 1895 | + (numerator > 0) ? Min(sparseBlockCount, numerator / static_cast<int32_t>(constInfo.cmpRatio)) : 0; | ||
| 1896 | + } | ||
| 1897 | + } else if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 1898 | + uint64_t topkIdx = (LAYOUT_T == SMLA_LAYOUT::TND) ? (cuSeqlensQGm.GetValue(bIdx) + s1Idx) : | ||
| 1899 | + (bIdx * constInfo.s1Size + s1Idx); | ||
| 1900 | + int32_t topkLen = constInfo.hasCmpTopkLength ? topkLengthGm.GetValue(topkIdx) : sparseBlockCount; | ||
| 1901 | + curValidS2 = Min(topkLen, sparseBlockCount); | ||
| 1902 | + } | ||
| 1903 | + } | ||
| 1904 | + return curValidS2; | ||
| 1905 | +} | ||
| 1906 | + | ||
| 1907 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 1908 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopyPhyAddrToGm(LocalTensor<uint32_t> kvPhyAddrUb, int64_t bS1Idx, | ||
| 1909 | + int64_t s1Idx, int64_t validS2, int64_t alignNum, | ||
| 1910 | + GlobalTensor<uint32_t> &phyAddrGm, | ||
| 1911 | + uint32_t alignedSparseBlockCount) | ||
| 1912 | +{ | ||
| 1913 | + constexpr int64_t numPerBlock = 32; | ||
| 1914 | + DataCopyParams dataCopyParams; | ||
| 1915 | + dataCopyParams.blockCount = 1U; | ||
| 1916 | + dataCopyParams.blockLen = ((validS2 + alignNum - 1) / alignNum * alignNum) * sizeof(int64_t) / numPerBlock; | ||
| 1917 | + dataCopyParams.srcGap = 0U; | ||
| 1918 | + dataCopyParams.dstGap = 0U; | ||
| 1919 | + DataCopy(phyAddrGm[(bS1Idx + s1Idx) * alignedSparseBlockCount * 2], kvPhyAddrUb, dataCopyParams); | ||
| 1920 | +} | ||
| 1921 | + | ||
| 1922 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 1923 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopyPaTableToUb(LocalTensor<int32_t> blkTableUb, int64_t bIdx, | ||
| 1924 | + GlobalTensor<int32_t> &blockTableGm, | ||
| 1925 | + uint32_t maxBlockNumPerBatch) | ||
| 1926 | +{ | ||
| 1927 | + DataCopyExtParams dataCopyParams; | ||
| 1928 | + dataCopyParams.blockCount = 1U; | ||
| 1929 | + dataCopyParams.blockLen = maxBlockNumPerBatch * sizeof(int32_t); | ||
| 1930 | + dataCopyParams.srcStride = 0U; | ||
| 1931 | + dataCopyParams.dstStride = 0U; | ||
| 1932 | + DataCopyPadExtParams<int32_t> padParams; | ||
| 1933 | + DataCopyPad(blkTableUb, blockTableGm[bIdx * maxBlockNumPerBatch], dataCopyParams, padParams); | ||
| 1934 | +} | ||
| 1935 | + | ||
| 1936 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 1937 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::CopySparseIdxToUb(LocalTensor<int32_t> sparseIdxUb, int64_t bS1Idx, | ||
| 1938 | + int64_t s1Idx, int64_t validS2, | ||
| 1939 | + GlobalTensor<int32_t> &sparseIndicesGm, | ||
| 1940 | + uint32_t sparseBlockCount) | ||
| 1941 | +{ | ||
| 1942 | + DataCopyExtParams dataCopyParams; | ||
| 1943 | + dataCopyParams.blockCount = 1U; | ||
| 1944 | + dataCopyParams.blockLen = validS2 * sizeof(int32_t); | ||
| 1945 | + dataCopyParams.srcStride = 0U; | ||
| 1946 | + dataCopyParams.dstStride = 0U; | ||
| 1947 | + DataCopyPadExtParams<int32_t> padParams; | ||
| 1948 | + DataCopyPad(sparseIdxUb, sparseIndicesGm[(bS1Idx + s1Idx) * sparseBlockCount], dataCopyParams, padParams); | ||
| 1949 | +} | ||
| 1950 | + | ||
| 1951 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 1952 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetKVPhyAddrForKvType( | ||
| 1953 | + uint32_t bN2StartIdx, uint32_t bN2EndIdx, uint32_t gS1StartIdx, uint32_t nextGs1Idx, bool hasActualSeqQlen, | ||
| 1954 | + bool hasCuSeqlensQ, bool hasActualSeqKvlen, bool hasCuSeqlensKv, GlobalTensor<int32_t> actualSeqQlenGm, | ||
| 1955 | + GlobalTensor<int32_t> cuSeqlensQGm, GlobalTensor<int32_t> actualSeqKvlenGm, GlobalTensor<int32_t> cuSeqlensKvGm, | ||
| 1956 | + GlobalTensor<int32_t> topkLengthGm, GlobalTensor<int32_t> cmpResidualKvGm, ConstInfo &constInfo, | ||
| 1957 | + GlobalTensor<int32_t> &blockTableGm, GlobalTensor<int32_t> &sparseIndicesGm, GlobalTensor<uint32_t> &phyAddrGm, | ||
| 1958 | + uint32_t kvStride, uint32_t blockSize, uint32_t maxBlockNumPerBatch, uint32_t sparseBlockCount, | ||
| 1959 | + uint32_t alignedSparseBlockCount, bool isOriKv) | ||
| 1960 | +{ | ||
| 1961 | + static constexpr uint16_t s2NumPerLoop = 128; | ||
| 1962 | + static constexpr uint32_t vecCoreNum = IS_SPLIT_G ? 4 : 2; | ||
| 1963 | + uint32_t vecCoreIdx = IS_SPLIT_G ? constInfo.aivIdx % 4 : constInfo.aivIdx % 2; | ||
| 1964 | + TBuf<> blkTableBuf; | ||
| 1965 | + TBuf<> sparseIdxBuf; | ||
| 1966 | + TBuf<> kvPhyAddrBuf; | ||
| 1967 | + int16_t shiftRightNum = 0; | ||
| 1968 | + LocalTensor<int32_t> blkTableUb; | ||
| 1969 | + | ||
| 1970 | + if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | ||
| 1971 | + int32_t blkSize = static_cast<int32_t>(blockSize); | ||
| 1972 | + while (blkSize > 1) { | ||
| 1973 | + blkSize >>= 1; | ||
| 1974 | + shiftRightNum++; | ||
| 1975 | + } | ||
| 1976 | + tPipe->InitBuffer(blkTableBuf, maxBlockNumPerBatch * sizeof(int32_t)); | ||
| 1977 | + blkTableUb = blkTableBuf.template Get<int32_t>(); | ||
| 1978 | + } | ||
| 1979 | + tPipe->InitBuffer(sparseIdxBuf, alignedSparseBlockCount * sizeof(int32_t)); | ||
| 1980 | + tPipe->InitBuffer(kvPhyAddrBuf, alignedSparseBlockCount * sizeof(int64_t)); | ||
| 1981 | + LocalTensor<int32_t> sparseIdxUb = sparseIdxBuf.template Get<int32_t>(); | ||
| 1982 | + LocalTensor<uint32_t> kvPhyAddrUb = kvPhyAddrBuf.template Get<uint32_t>(); | ||
| 1983 | + | ||
| 1984 | + // 第一遍: 统计totalValidS1 | ||
| 1985 | + int64_t totalValidS1 = 0; | ||
| 1986 | + uint32_t tmpGS1Start = gS1StartIdx; | ||
| 1987 | + for (uint32_t bIdx = bN2StartIdx; bIdx < bN2EndIdx; ++bIdx) { | ||
| 1988 | + bool lastBN = (bIdx == bN2EndIdx - 1); | ||
| 1989 | + int32_t actualS1Size = | ||
| 1990 | + GetSeqLen(bIdx, hasActualSeqQlen, hasCuSeqlensQ, actualSeqQlenGm, cuSeqlensQGm, constInfo.s1Size); | ||
| 1991 | + int32_t s1End = actualS1Size; | ||
| 1992 | + if (lastBN && nextGs1Idx != 0) { | ||
| 1993 | + s1End = nextGs1Idx; | ||
| 1994 | + } | ||
| 1995 | + | ||
| 1996 | + int64_t bS1IdxBase = 0; | ||
| 1997 | + if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { | ||
| 1998 | + bS1IdxBase = hasCuSeqlensQ ? cuSeqlensQGm.GetValue(bIdx) : constInfo.s1Size * bIdx; | ||
| 1999 | + } else { | ||
| 2000 | + bS1IdxBase = constInfo.s1Size * bIdx; | ||
| 2001 | + } | ||
| 2002 | + | ||
| 2003 | + for (int32_t s1Idx = tmpGS1Start; s1Idx < s1End; ++s1Idx) { | ||
| 2004 | + int32_t curValidS2 = CalcCurValidS2(bIdx, s1Idx, actualS1Size, isOriKv, hasActualSeqKvlen, | ||
| 2005 | + hasCuSeqlensKv, cuSeqlensQGm, actualSeqKvlenGm, cuSeqlensKvGm, | ||
| 2006 | + topkLengthGm, cmpResidualKvGm, constInfo, | ||
| 2007 | + static_cast<int32_t>(sparseBlockCount)); | ||
| 2008 | + if (curValidS2 > 0) { | ||
| 2009 | + totalValidS1++; | ||
| 2010 | + } | ||
| 2011 | + } | ||
| 2012 | + tmpGS1Start = 0; | ||
| 2013 | + } | ||
| 2014 | + | ||
| 2015 | + int64_t s1PerVecCore = totalValidS1 / vecCoreNum; | ||
| 2016 | + int64_t s1Tail = totalValidS1 % vecCoreNum; | ||
| 2017 | + int64_t curStart = s1PerVecCore * vecCoreIdx + Min((int64_t)vecCoreIdx, s1Tail); | ||
| 2018 | + int64_t curCount = s1PerVecCore + (vecCoreIdx < (uint32_t)s1Tail ? 1 : 0); | ||
| 2019 | + | ||
| 2020 | + if (curCount == 0) { | ||
| 2021 | + return; | ||
| 2022 | + } | ||
| 2023 | + | ||
| 2024 | + // 第二遍: 实际计算 | ||
| 2025 | + int64_t validCounter = 0; | ||
| 2026 | + int64_t processedCount = 0; | ||
| 2027 | + tmpGS1Start = gS1StartIdx; | ||
| 2028 | + bool done = false; | ||
| 2029 | + | ||
| 2030 | + if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | ||
| 2031 | + SetFlag<AscendC::HardEvent::V_MTE2>(blkTableVToMte2FlagId); | ||
| 2032 | + } | ||
| 2033 | + SetFlag<AscendC::HardEvent::V_MTE2>(sparseIdxVToMte2FlagId); | ||
| 2034 | + SetFlag<AscendC::HardEvent::MTE3_V>(phyAddrMte3ToVFlagId); | ||
| 2035 | + for (uint32_t bIdx = bN2StartIdx; bIdx < bN2EndIdx && !done; ++bIdx) { | ||
| 2036 | + bool lastBN = (bIdx == bN2EndIdx - 1); | ||
| 2037 | + int32_t actualS1Size = | ||
| 2038 | + GetSeqLen(bIdx, hasActualSeqQlen, hasCuSeqlensQ, actualSeqQlenGm, cuSeqlensQGm, constInfo.s1Size); | ||
| 2039 | + int64_t bS1Idx = 0; | ||
| 2040 | + if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { | ||
| 2041 | + bS1Idx = hasCuSeqlensQ ? cuSeqlensQGm.GetValue(bIdx) : constInfo.s1Size * bIdx; | ||
| 2042 | + } else { | ||
| 2043 | + bS1Idx = constInfo.s1Size * bIdx; | ||
| 2044 | + } | ||
| 2045 | + | ||
| 2046 | + int32_t s1End = actualS1Size; | ||
| 2047 | + if (lastBN && nextGs1Idx != 0) { | ||
| 2048 | + s1End = nextGs1Idx; | ||
| 2049 | + } | ||
| 2050 | + | ||
| 2051 | + // per-batch 参数预计算 | ||
| 2052 | + uint32_t kvPrefix = 0; | ||
| 2053 | + uint32_t bS2BaseLow = 0; | ||
| 2054 | + uint32_t bS2BaseHigh = 0; | ||
| 2055 | + if constexpr (LAYOUT_T == SMLA_LAYOUT::TND) { | ||
| 2056 | + kvPrefix = static_cast<uint32_t>(cuSeqlensKvGm.GetValue(bIdx)); | ||
| 2057 | + } else { | ||
| 2058 | + uint32_t s2Size = isOriKv ? static_cast<uint32_t>(constInfo.s2Size) : | ||
| 2059 | + static_cast<uint32_t>(constInfo.cmpS2Size); | ||
| 2060 | + uint64_t bS2Base = static_cast<uint64_t>(bIdx) * s2Size * | ||
| 2061 | + static_cast<uint64_t>(constInfo.dSize); | ||
| 2062 | + bS2BaseLow = static_cast<uint32_t>(bS2Base); | ||
| 2063 | + bS2BaseHigh = static_cast<uint32_t>(bS2Base >> 32U); | ||
| 2064 | + } | ||
| 2065 | + | ||
| 2066 | + if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | ||
| 2067 | + WaitFlag<AscendC::HardEvent::V_MTE2>(blkTableVToMte2FlagId); | ||
| 2068 | + CopyPaTableToUb(blkTableUb, bIdx, blockTableGm, maxBlockNumPerBatch); | ||
| 2069 | + SetFlag<AscendC::HardEvent::MTE2_V>(blkTableMte2ToVFlagId); | ||
| 2070 | + WaitFlag<AscendC::HardEvent::MTE2_V>(blkTableMte2ToVFlagId); | ||
| 2071 | + } | ||
| 2072 | + | ||
| 2073 | + for (int32_t s1Idx = tmpGS1Start; s1Idx < s1End; ++s1Idx) { | ||
| 2074 | + int32_t curValidS2 = CalcCurValidS2(bIdx, s1Idx, actualS1Size, isOriKv, hasActualSeqKvlen, | ||
| 2075 | + hasCuSeqlensKv, cuSeqlensQGm, actualSeqKvlenGm, cuSeqlensKvGm, | ||
| 2076 | + topkLengthGm, cmpResidualKvGm, constInfo, | ||
| 2077 | + static_cast<int32_t>(sparseBlockCount)); | ||
| 2078 | + if (curValidS2 <= 0) { | ||
| 2079 | + continue; | ||
| 2080 | + } | ||
| 2081 | + | ||
| 2082 | + if (validCounter < curStart || validCounter >= curStart + curCount) { | ||
| 2083 | + validCounter++; | ||
| 2084 | + continue; | ||
| 2085 | + } | ||
| 2086 | + validCounter++; | ||
| 2087 | + | ||
| 2088 | + uint16_t s2Loop = (curValidS2 + s2NumPerLoop - 1) / s2NumPerLoop; | ||
| 2089 | + int32_t s2Tail = curValidS2 - (s2Loop - 1) * s2NumPerLoop; | ||
| 2090 | + WaitFlag<AscendC::HardEvent::V_MTE2>(sparseIdxVToMte2FlagId); | ||
| 2091 | + CopySparseIdxToUb(sparseIdxUb, bS1Idx, s1Idx, curValidS2, sparseIndicesGm, sparseBlockCount); | ||
| 2092 | + SetFlag<AscendC::HardEvent::MTE2_V>(sparseIdxMte2ToVFlagId); | ||
| 2093 | + | ||
| 2094 | + WaitFlag<AscendC::HardEvent::MTE2_V>(sparseIdxMte2ToVFlagId); | ||
| 2095 | + WaitFlag<AscendC::HardEvent::MTE3_V>(phyAddrMte3ToVFlagId); | ||
| 2096 | + if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | ||
| 2097 | + GetKVPhyAddrVFPa<uint32_t>(kvPhyAddrUb, sparseIdxUb, blkTableUb, s2Loop, s2Tail, blockSize, | ||
| 2098 | + shiftRightNum, constInfo.sparseBlockSize, | ||
| 2099 | + static_cast<uint32_t>(constInfo.dSize), kvStride); | ||
| 2100 | + } else if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::TND) { | ||
| 2101 | + GetKVPhyAddrVFTnd<uint32_t>(kvPhyAddrUb, sparseIdxUb, s2Loop, s2Tail, | ||
| 2102 | + constInfo.sparseBlockSize, | ||
| 2103 | + static_cast<uint32_t>(constInfo.dSize), kvPrefix); | ||
| 2104 | + } else { | ||
| 2105 | + GetKVPhyAddrVFBsnd<uint32_t>(kvPhyAddrUb, sparseIdxUb, s2Loop, s2Tail, | ||
| 2106 | + constInfo.sparseBlockSize, | ||
| 2107 | + static_cast<uint32_t>(constInfo.dSize), | ||
| 2108 | + bS2BaseLow, bS2BaseHigh); | ||
| 2109 | + } | ||
| 2110 | + SetFlag<AscendC::HardEvent::V_MTE2>(sparseIdxVToMte2FlagId); | ||
| 2111 | + SetFlag<AscendC::HardEvent::V_MTE3>(phyAddrVToMte3FlagId); | ||
| 2112 | + WaitFlag<AscendC::HardEvent::V_MTE3>(phyAddrVToMte3FlagId); | ||
| 2113 | + CopyPhyAddrToGm(kvPhyAddrUb, bS1Idx, s1Idx, curValidS2, s2NumPerLoop, phyAddrGm, | ||
| 2114 | + alignedSparseBlockCount); | ||
| 2115 | + SetFlag<AscendC::HardEvent::MTE3_V>(phyAddrMte3ToVFlagId); | ||
| 2116 | + | ||
| 2117 | + processedCount++; | ||
| 2118 | + if (processedCount >= curCount) { | ||
| 2119 | + done = true; | ||
| 2120 | + break; | ||
| 2121 | + } | ||
| 2122 | + } | ||
| 2123 | + if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | ||
| 2124 | + SetFlag<AscendC::HardEvent::V_MTE2>(blkTableVToMte2FlagId); | ||
| 2125 | + } | ||
| 2126 | + tmpGS1Start = 0; | ||
| 2127 | + } | ||
| 2128 | + if constexpr (KV_LAYOUT_T == SMLA_LAYOUT::PA_BBND) { | ||
| 2129 | + WaitFlag<AscendC::HardEvent::V_MTE2>(blkTableVToMte2FlagId); | ||
| 2130 | + } | ||
| 2131 | + WaitFlag<AscendC::HardEvent::V_MTE2>(sparseIdxVToMte2FlagId); | ||
| 2132 | + WaitFlag<AscendC::HardEvent::MTE3_V>(phyAddrMte3ToVFlagId); | ||
| 2133 | +} | ||
| 2134 | + | ||
| 2135 | +TEMPLATES_DEF_NO_DEFAULT | ||
| 2136 | +__aicore__ inline void CSABlockVec<TEMPLATE_ARGS>::GetKVPhyAddr( | ||
| 2137 | + uint32_t hasLoad, uint32_t bN2StartIdx, uint32_t bN2EndIdx, uint32_t gS1StartIdx, uint32_t nextGs1Idx, | ||
| 2138 | + bool hasActualSeqQlen, bool hasCuSeqlensQ, bool hasActualSeqOriKvlen, bool hasCuSeqlensOriKv, | ||
| 2139 | + GlobalTensor<int32_t> actualSeqOriKvlenGm, GlobalTensor<int32_t> cuSeqlensOriKvGm, | ||
| 2140 | + GlobalTensor<int32_t> oriTopkLengthGm, bool hasActualSeqCmpKvlen, bool hasCuSeqlensCmpKv, | ||
| 2141 | + GlobalTensor<int32_t> actualSeqCmpKvlenGm, GlobalTensor<int32_t> cuSeqlensCmpKvGm, | ||
| 2142 | + GlobalTensor<int32_t> cmpTopkLengthGm, GlobalTensor<int32_t> cmpResidualKvGm, GlobalTensor<int32_t> actualSeqQlenGm, | ||
| 2143 | + GlobalTensor<int32_t> cuSeqlensQGm, __gm__ uint8_t *workspace, ConstInfo &constInfo) | ||
| 2144 | +{ | ||
| 2145 | + if (hasLoad == 0) { | ||
| 2146 | + SyncAll(); | ||
| 2147 | + tPipe->Reset(); | ||
| 2148 | + return; | ||
| 2149 | + } | ||
| 2150 | + | ||
| 2151 | + // GM分配: ori在前, cmp在后 | ||
| 2152 | + int64_t v0TotalOffset = 0; | ||
| 2153 | + uint32_t v0ResSize = constInfo.s2BaseSize * constInfo.dSize * sizeof(Q_T); | ||
| 2154 | + if constexpr (IS_SPLIT_G) { | ||
| 2155 | + v0TotalOffset = v0ResSize * 3 * (GetBlockNum() >> 1U); | ||
| 2156 | + } else { | ||
| 2157 | + v0TotalOffset = v0ResSize * 3 * GetBlockNum(); | ||
| 2158 | + } | ||
| 2159 | + | ||
| 2160 | + // SMLA特有: 加上s2RealBuf大小 | ||
| 2161 | + constexpr uint32_t TRIPLE_BUFFER_NUM = 3; | ||
| 2162 | + constexpr uint32_t S2_REAL_BUF_LEN = 128; | ||
| 2163 | + v0TotalOffset += TRIPLE_BUFFER_NUM * S2_REAL_BUF_LEN * sizeof(int32_t) * GetBlockNum(); | ||
| 2164 | + | ||
| 2165 | + uint32_t totalBS1 = (LAYOUT_T == SMLA_LAYOUT::TND) ? constInfo.s1Size : (constInfo.bSize * constInfo.s1Size); | ||
| 2166 | + | ||
| 2167 | + uint64_t oriPhyAddrSize = 0; | ||
| 2168 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 2169 | + TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 2170 | + oriPhyAddrSize = static_cast<uint64_t>(totalBS1) * constInfo.alignedOriSparseBlockCount * sizeof(int64_t); | ||
| 2171 | + this->oriKvPhyAddrGm.SetGlobalBuffer((__gm__ uint32_t *)(workspace + v0TotalOffset)); | ||
| 2172 | + } | ||
| 2173 | + | ||
| 2174 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | ||
| 2175 | + TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 2176 | + uint64_t cmpPhyAddrSize = | ||
| 2177 | + static_cast<uint64_t>(totalBS1) * constInfo.alignedCmpSparseBlockCount * sizeof(int64_t); | ||
| 2178 | + this->cmpKvPhyAddrGm.SetGlobalBuffer((__gm__ uint32_t *)(workspace + v0TotalOffset + oriPhyAddrSize)); | ||
| 2179 | + } | ||
| 2180 | + | ||
| 2181 | + // ori部分 (先计算) | ||
| 2182 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 2183 | + TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 2184 | + GetKVPhyAddrForKvType(bN2StartIdx, bN2EndIdx, gS1StartIdx, nextGs1Idx, hasActualSeqQlen, hasCuSeqlensQ, | ||
| 2185 | + hasActualSeqOriKvlen, hasCuSeqlensOriKv, actualSeqQlenGm, cuSeqlensQGm, | ||
| 2186 | + actualSeqOriKvlenGm, cuSeqlensOriKvGm, oriTopkLengthGm, cmpResidualKvGm, constInfo, | ||
| 2187 | + oriBlockTableGm, oriSparseIndicesGm, oriKvPhyAddrGm, constInfo.oriKeyStride0, | ||
| 2188 | + constInfo.oriBlockSize, constInfo.oriMaxBlockNumPerBatch, constInfo.oriSparseBlockCount, | ||
| 2189 | + constInfo.alignedOriSparseBlockCount, true); | ||
| 2190 | + } | ||
| 2191 | + | ||
| 2192 | + // cmp部分 (后计算) | ||
| 2193 | + if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | ||
| 2194 | + TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | ||
| 2195 | + GetKVPhyAddrForKvType(bN2StartIdx, bN2EndIdx, gS1StartIdx, nextGs1Idx, hasActualSeqQlen, hasCuSeqlensQ, | ||
| 2196 | + hasActualSeqCmpKvlen, hasCuSeqlensCmpKv, actualSeqQlenGm, cuSeqlensQGm, | ||
| 2197 | + actualSeqCmpKvlenGm, cuSeqlensCmpKvGm, cmpTopkLengthGm, cmpResidualKvGm, constInfo, | ||
| 2198 | + cmpBlockTableGm, cmpSparseIndicesGm, cmpKvPhyAddrGm, constInfo.cmpKeyStride0, | ||
| 2199 | + constInfo.cmpBlockSize, constInfo.cmpMaxBlockNumPerBatch, constInfo.cmpSparseBlockCount, | ||
| 2200 | + constInfo.alignedCmpSparseBlockCount, false); | ||
| 2201 | + } | ||
| 2202 | + | ||
| 2203 | + SyncAll(); | ||
| 2204 | + tPipe->Reset(); | ||
| 2205 | +} | ||
| 2206 | + | ||
| 1376 | TEMPLATES_DEF | 2207 | TEMPLATES_DEF |
| 1377 | class CSABlockVecDummy { | 2208 | class CSABlockVecDummy { |
| 1378 | public: | 2209 | public: |
| @@ -1381,12 +2212,12 @@ public: | |||
| 1381 | { | 2212 | { |
| 1382 | } | 2213 | } |
| 1383 | __aicore__ inline void InitGlobalBuffer(__gm__ uint8_t *oriKV, __gm__ uint8_t *cmpKV, | 2214 | __aicore__ inline void InitGlobalBuffer(__gm__ uint8_t *oriKV, __gm__ uint8_t *cmpKV, |
| 1384 | - __gm__ uint8_t *oriSparseIndices, __gm__ uint8_t *cmpSparseIndices, __gm__ uint8_t *oriBlockTable, | 2215 | + __gm__ uint8_t *oriSparseIndices, __gm__ uint8_t *cmpSparseIndices, __gm__ uint8_t *oriBlockTable, |
| 1385 | - __gm__ uint8_t *cmpBlockTable, __gm__ uint8_t *sequsedQ, __gm__ uint8_t *sinks, | 2216 | + __gm__ uint8_t *cmpBlockTable, __gm__ uint8_t *sequsedQ, __gm__ uint8_t *sinks, |
| 1386 | - __gm__ uint8_t *sequsedOriKv, __gm__ uint8_t *sequsedCmpKv, __gm__ uint8_t *cmpResidualKv) {} | 2217 | + __gm__ uint8_t *sequsedOriKv, __gm__ uint8_t *sequsedCmpKv, __gm__ uint8_t *cmpResidualKv) {} |
| 1387 | __aicore__ inline void InitVecBlock(TPipe *pipe, __gm__ uint8_t *cuSeqlensQ, | 2218 | __aicore__ inline void InitVecBlock(TPipe *pipe, __gm__ uint8_t *cuSeqlensQ, |
| 1388 | - __gm__ uint8_t *cuSeqlensOriKv, __gm__ uint8_t *cuSeqlensCmpKv, __gm__ uint8_t *seqUsedOriKV, | 2219 | + __gm__ uint8_t *cuSeqlensOriKv, __gm__ uint8_t *cuSeqlensCmpKv, __gm__ uint8_t *seqUsedOriKV, |
| 1389 | - __gm__ uint8_t *seqUsedCmpKV, __gm__ uint8_t *cmpResidualKV) {}; | 2220 | + __gm__ uint8_t *seqUsedCmpKV, __gm__ uint8_t *cmpResidualKV) {}; |
| 1390 | __aicore__ inline void InitS2SplitStaging( | 2221 | __aicore__ inline void InitS2SplitStaging( |
| 1391 | Buffer<BufferType::GM, SyncType::INNER_CORE_SYNC> &fdStaging) {} | 2222 | Buffer<BufferType::GM, SyncType::INNER_CORE_SYNC> &fdStaging) {} |
| 1392 | __aicore__ inline void InitS2SplitStaging( | 2223 | __aicore__ inline void InitS2SplitStaging( |
| @@ -37,6 +37,9 @@ | |||
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + | ||
| 40 | 43 | ||
| 41 | 44 | ||
| 42 | 45 | ||
| @@ -104,7 +107,9 @@ private: | |||
| 104 | const SparseFlashMlaTilingData *__restrict tilingData; | 107 | const SparseFlashMlaTilingData *__restrict tilingData; |
| 105 | /* 编译期常量的基本块信息 */ | 108 | /* 编译期常量的基本块信息 */ |
| 106 | static constexpr uint64_t SYNC_MODE = 4; | 109 | static constexpr uint64_t SYNC_MODE = 4; |
| 107 | - static constexpr uint32_t PRELOAD_NUM = 2; | 110 | + static constexpr uint32_t PRELOAD_NUM = 3; |
| 111 | + static constexpr uint32_t crossCoreMte2SyncFlagId = 15; // IS_SPLIT_G 核间 MTE2 同步 flag ID | ||
| 112 | + static constexpr uint32_t SPARSE_BLOCK_ALIGN_NUM = 128; | ||
| 108 | 113 | ||
| 109 | uint32_t crossCoreSyncBufId = 0; | 114 | uint32_t crossCoreSyncBufId = 0; |
| 110 | /* 核间通道 */ | 115 | /* 核间通道 */ |
| @@ -117,7 +122,6 @@ private: | |||
| 117 | // mm2左矩阵P | 122 | // mm2左矩阵P |
| 118 | BufferManager<BufferType::L1> l1BufferManager; | 123 | BufferManager<BufferType::L1> l1BufferManager; |
| 119 | BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> l1PBuffers; | 124 | BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> l1PBuffers; |
| 120 | - BuffersPolicy3buff<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> l1RightBuffers; | ||
| 121 | GlobalTensor<uint32_t> metadataGm; | 125 | GlobalTensor<uint32_t> metadataGm; |
| 122 | GlobalTensor<int32_t> cuSeqlensQGm; | 126 | GlobalTensor<int32_t> cuSeqlensQGm; |
| 123 | GlobalTensor<int32_t> cuSeqlensOriKvGm; | 127 | GlobalTensor<int32_t> cuSeqlensOriKvGm; |
| @@ -136,7 +140,7 @@ private: | |||
| 136 | bool hasActualSeqOriKvlen = false; | 140 | bool hasActualSeqOriKvlen = false; |
| 137 | bool hasActualSeqCmpKvlen = false; | 141 | bool hasActualSeqCmpKvlen = false; |
| 138 | /* workspace 空间 */ | 142 | /* workspace 空间 */ |
| 139 | - BuffersPolicy3buff<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> v0ResGmBuffers; | 143 | + BuffersPolicy3buffSFA<BufferType::GM, SyncType::CROSS_CORE_SYNC_BACKWARD> v0ResGmBuffers; |
| 140 | BufferManager<BufferType::GM> fdStagingBufferManager; | 144 | BufferManager<BufferType::GM> fdStagingBufferManager; |
| 141 | BuffersPolicySingleBuffer<BufferType::GM> fdStagingBuffer; | 145 | BuffersPolicySingleBuffer<BufferType::GM> fdStagingBuffer; |
| 142 | BuffersPolicySingleBuffer<BufferType::GM> intraCoreCombineBuffer; | 146 | BuffersPolicySingleBuffer<BufferType::GM> intraCoreCombineBuffer; |
| @@ -144,6 +148,13 @@ private: | |||
| 144 | /* 核Index信息 */ | 148 | /* 核Index信息 */ |
| 145 | int32_t aicIdx; | 149 | int32_t aicIdx; |
| 146 | 150 | ||
| 151 | + /* Init阶段metadata解析结果 */ | ||
| 152 | + uint32_t bN2StartIdx; | ||
| 153 | + uint32_t gS1StartIdx; | ||
| 154 | + uint32_t bN2EndIdx; | ||
| 155 | + uint32_t nextGs1Idx; | ||
| 156 | + uint32_t hasLoad; | ||
| 157 | + | ||
| 147 | /* 初始化后不变的信息 */ | 158 | /* 初始化后不变的信息 */ |
| 148 | ConstInfo constInfo; | 159 | ConstInfo constInfo; |
| 149 | 160 | ||
| @@ -187,18 +198,42 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 187 | cmpResidualKV); | 198 | cmpResidualKV); |
| 188 | vecBlock.InitVecBlock(tPipe, cuSeqlensQ, cuSeqlensOriKv, cuSeqlensCmpKv, seqUsedOriKV, seqUsedCmpKV, cmpResidualKV); | 199 | vecBlock.InitVecBlock(tPipe, cuSeqlensQ, cuSeqlensOriKv, cuSeqlensCmpKv, seqUsedOriKV, seqUsedCmpKV, cmpResidualKV); |
| 189 | vecBlock.CleanOutput(attentionOut, softmaxLse, constInfo); | 200 | vecBlock.CleanOutput(attentionOut, softmaxLse, constInfo); |
| 201 | + | ||
| 202 | + // 从meta data解析分核信息 | ||
| 203 | + bN2StartIdx = metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_BN2_START_INDEX, false)); | ||
| 204 | + gS1StartIdx = metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_M_START_INDEX, false)); | ||
| 205 | + bN2EndIdx = metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_BN2_END_INDEX, false)); | ||
| 206 | + nextGs1Idx = metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_M_END_INDEX, false)); | ||
| 207 | + hasLoad = metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_CORE_ENABLE_INDEX, false)); | ||
| 208 | + if (nextGs1Idx != 0) { | ||
| 209 | + bN2EndIdx++; | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + this->InitGlobalBuffer(query, oriKV, cmpKV, oriSparseIndices, cmpSparseIndices, oriBlockTable, cmpBlockTable, | ||
| 213 | + cuSeqlensQ, cuSeqlensOriKv, cuSeqlensCmpKv, sequsedQ, seqUsedOriKV, seqUsedCmpKV, | ||
| 214 | + cmpResidualKV, oriTopkLength, cmpTopkLength, sinks, workspace, tiling, tPipe); // gm设置 | ||
| 215 | + | ||
| 216 | + if ASCEND_IS_AIV { | ||
| 217 | + if constexpr ((TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | ||
| 218 | + TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | ||
| 219 | + TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) && | ||
| 220 | + IS_VEC_S2PHYADDR) { | ||
| 221 | + this->vecBlock.GetKVPhyAddr(hasLoad, bN2StartIdx, bN2EndIdx, gS1StartIdx, nextGs1Idx, hasActualSeqQlen, | ||
| 222 | + hasCuSeqlensQ, hasActualSeqOriKvlen, hasCuSeqlensOriKv, actualSeqOriKvlenGm, | ||
| 223 | + cuSeqlensOriKvGm, oriTopkLengthGm, hasActualSeqCmpKvlen, hasCuSeqlensCmpKv, | ||
| 224 | + actualSeqCmpKvlenGm, cuSeqlensCmpKvGm, cmpTopkLengthGm, cmpResidualKvGm, | ||
| 225 | + actualSeqQlenGm, cuSeqlensQGm, workspace, constInfo); | ||
| 226 | + } | ||
| 227 | + } | ||
| 228 | + | ||
| 190 | InitMMResBuf(workspace); | 229 | InitMMResBuf(workspace); |
| 191 | if constexpr (IS_BATCH_CONSISTENCY) { | 230 | if constexpr (IS_BATCH_CONSISTENCY) { |
| 192 | vecBlock.InitS2SplitStaging(intraCoreCombineBuffer.Get(), crossCoreCombineBuffer.Get()); | 231 | vecBlock.InitS2SplitStaging(intraCoreCombineBuffer.Get(), crossCoreCombineBuffer.Get()); |
| 193 | } else { | 232 | } else { |
| 194 | vecBlock.InitS2SplitStaging(fdStagingBuffer.Get()); | 233 | vecBlock.InitS2SplitStaging(fdStagingBuffer.Get()); |
| 195 | } | 234 | } |
| 196 | - cubeBlock.InitCubeBlock(pipe, l1BufferManager, query); | 235 | + cubeBlock.InitCubeBlock(pipe, query); |
| 197 | this->ComputeConstexpr(); | 236 | this->ComputeConstexpr(); |
| 198 | - | ||
| 199 | - this->InitGlobalBuffer(query, oriKV, cmpKV, oriSparseIndices, cmpSparseIndices, oriBlockTable, cmpBlockTable, | ||
| 200 | - cuSeqlensQ, cuSeqlensOriKv, cuSeqlensCmpKv, sequsedQ, seqUsedOriKV, seqUsedCmpKV, | ||
| 201 | - cmpResidualKV, oriTopkLength, cmpTopkLength, sinks, workspace, tiling, tPipe); // gm设置 | ||
| 202 | this->InitLocalBuffer(); | 237 | this->InitLocalBuffer(); |
| 203 | } | 238 | } |
| 204 | 239 | ||
| @@ -232,6 +267,10 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Par | |||
| 232 | constInfo.cmpS2Size = sparseFlashMLACmpParams.cmpKvSeqSize; | 267 | constInfo.cmpS2Size = sparseFlashMLACmpParams.cmpKvSeqSize; |
| 233 | constInfo.oriSparseBlockCount = sparseFlashMLABaseParams.oriSparseBlockCount; | 268 | constInfo.oriSparseBlockCount = sparseFlashMLABaseParams.oriSparseBlockCount; |
| 234 | constInfo.cmpSparseBlockCount = sparseFlashMLACmpParams.cmpSparseBlockCount; | 269 | constInfo.cmpSparseBlockCount = sparseFlashMLACmpParams.cmpSparseBlockCount; |
| 270 | + constInfo.alignedOriSparseBlockCount = | ||
| 271 | + (constInfo.oriSparseBlockCount + SPARSE_BLOCK_ALIGN_NUM - 1) / SPARSE_BLOCK_ALIGN_NUM * SPARSE_BLOCK_ALIGN_NUM; | ||
| 272 | + constInfo.alignedCmpSparseBlockCount = | ||
| 273 | + (constInfo.cmpSparseBlockCount + SPARSE_BLOCK_ALIGN_NUM - 1) / SPARSE_BLOCK_ALIGN_NUM * SPARSE_BLOCK_ALIGN_NUM; | ||
| 235 | constInfo.cmpRatio = sparseFlashMLACmpParams.cmpRatio; | 274 | constInfo.cmpRatio = sparseFlashMLACmpParams.cmpRatio; |
| 236 | constInfo.oriMaskMode = sparseFlashMLABaseParams.oriMaskMode; | 275 | constInfo.oriMaskMode = sparseFlashMLABaseParams.oriMaskMode; |
| 237 | constInfo.cmpMaskMode = sparseFlashMLACmpParams.cmpMaskMode; | 276 | constInfo.cmpMaskMode = sparseFlashMLACmpParams.cmpMaskMode; |
| @@ -372,8 +411,7 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 372 | uint32_t mm1ResultSize = constInfo.s1BaseSize / CV_RATIO * constInfo.s2BaseSize * sizeof(T); | 411 | uint32_t mm1ResultSize = constInfo.s1BaseSize / CV_RATIO * constInfo.s2BaseSize * sizeof(T); |
| 373 | uint32_t mm2ResultSize = constInfo.s1BaseSize / CV_RATIO * 512 * sizeof(T); | 412 | uint32_t mm2ResultSize = constInfo.s1BaseSize / CV_RATIO * 512 * sizeof(T); |
| 374 | uint32_t mm2LeftSize = constInfo.s1BaseSize * constInfo.s2BaseSize * sizeof(Q_T); | 413 | uint32_t mm2LeftSize = constInfo.s1BaseSize * constInfo.s2BaseSize * sizeof(Q_T); |
| 375 | - uint32_t mm1RightSize = constInfo.s2BaseSize * 512 * sizeof(Q_T); | 414 | + l1BufferManager.Init(pipe, mm2LeftSize * 2); |
| 376 | - l1BufferManager.Init(pipe, 524288); // 512 * 1024 | ||
| 377 | // 保存p结果的L1内存必须放在第一个L1 policy上,保证和vec申请的地址相同 | 415 | // 保存p结果的L1内存必须放在第一个L1 policy上,保证和vec申请的地址相同 |
| 378 | l1PBuffers.Init(l1BufferManager, mm2LeftSize); | 416 | l1PBuffers.Init(l1BufferManager, mm2LeftSize); |
| 379 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | 417 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); |
| @@ -381,14 +419,6 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 381 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | 419 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); |
| 382 | crossCoreSyncBufId++; | 420 | crossCoreSyncBufId++; |
| 383 | 421 | ||
| 384 | - l1RightBuffers.Init(l1BufferManager, mm1RightSize); | ||
| 385 | - l1RightBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | ||
| 386 | - crossCoreSyncBufId++; | ||
| 387 | - l1RightBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | ||
| 388 | - crossCoreSyncBufId++; | ||
| 389 | - l1RightBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | ||
| 390 | - crossCoreSyncBufId++; | ||
| 391 | - | ||
| 392 | ubBufferManager.Init(pipe, mm1ResultSize * 2 + mm2ResultSize); | 422 | ubBufferManager.Init(pipe, mm1ResultSize * 2 + mm2ResultSize); |
| 393 | bmm2Buffers.Init(ubBufferManager, mm2ResultSize); | 423 | bmm2Buffers.Init(ubBufferManager, mm2ResultSize); |
| 394 | bmm2Buffers.Get().SetCrossCoreID(crossCoreSyncBufId, crossCoreSyncBufId); | 424 | bmm2Buffers.Get().SetCrossCoreID(crossCoreSyncBufId, crossCoreSyncBufId); |
| @@ -438,17 +468,17 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 438 | constexpr uint32_t FD_MAX_SUM_REGION_NUM = 2U; | 468 | constexpr uint32_t FD_MAX_SUM_REGION_NUM = 2U; |
| 439 | uint32_t gSize = static_cast<uint32_t>(constInfo.gSize); | 469 | uint32_t gSize = static_cast<uint32_t>(constInfo.gSize); |
| 440 | uint32_t combineElemSize = gSize * constInfo.dSize + FD_MAX_SUM_REGION_NUM * gSize * | 470 | uint32_t combineElemSize = gSize * constInfo.dSize + FD_MAX_SUM_REGION_NUM * gSize * |
| 441 | - static_cast<uint32_t>(AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW); | 471 | + static_cast<uint32_t>(AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW); |
| 442 | if constexpr (IS_BATCH_CONSISTENCY) { | 472 | if constexpr (IS_BATCH_CONSISTENCY) { |
| 443 | uint32_t intraCoreSlotNum = IS_SPLIT_G ? GetBlockNum() : (GetBlockNum() << 1U); | 473 | uint32_t intraCoreSlotNum = IS_SPLIT_G ? GetBlockNum() : (GetBlockNum() << 1U); |
| 444 | uint32_t intraCoreCombineSize = intraCoreSlotNum * combineElemSize * sizeof(float); | 474 | uint32_t intraCoreCombineSize = intraCoreSlotNum * combineElemSize * sizeof(float); |
| 445 | uint32_t crossCoreCombineSize = GetBlockNum() * BATCH_CONSISTENCY_MAX_REDUCE_BLOCK_NUM * | 475 | uint32_t crossCoreCombineSize = GetBlockNum() * BATCH_CONSISTENCY_MAX_REDUCE_BLOCK_NUM * |
| 446 | - combineElemSize * sizeof(float); | 476 | + combineElemSize * sizeof(float); |
| 447 | intraCoreCombineBuffer.Init(fdStagingBufferManager, intraCoreCombineSize); | 477 | intraCoreCombineBuffer.Init(fdStagingBufferManager, intraCoreCombineSize); |
| 448 | crossCoreCombineBuffer.Init(fdStagingBufferManager, crossCoreCombineSize); | 478 | crossCoreCombineBuffer.Init(fdStagingBufferManager, crossCoreCombineSize); |
| 449 | } else { | 479 | } else { |
| 450 | uint32_t fdSlotCount = static_cast<uint32_t>(AttentionCommon::FD_MAX_S2_SPLIT_NUM) * | 480 | uint32_t fdSlotCount = static_cast<uint32_t>(AttentionCommon::FD_MAX_S2_SPLIT_NUM) * |
| 451 | - (IS_SPLIT_G ? (GetBlockNum() >> 1U) : GetBlockNum()); | 481 | + (IS_SPLIT_G ? (GetBlockNum() >> 1U) : GetBlockNum()); |
| 452 | fdStagingBuffer.Init(fdStagingBufferManager, fdSlotCount * combineElemSize * sizeof(float)); | 482 | fdStagingBuffer.Init(fdStagingBufferManager, fdSlotCount * combineElemSize * sizeof(float)); |
| 453 | } | 483 | } |
| 454 | } | 484 | } |
| @@ -527,11 +557,11 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 527 | maxS2LoopCnt = static_cast<int64_t>(metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_S2_MAX_NUM, false))); | 557 | maxS2LoopCnt = static_cast<int64_t>(metadataGm.GetValue(GetAttrAbsIndex(aicIdx, FA_S2_MAX_NUM, false))); |
| 528 | } | 558 | } |
| 529 | if (hasLoad == 0) { | 559 | if (hasLoad == 0) { |
| 530 | - if ASCEND_IS_AIV { | 560 | + if ASCEND_IS_AIC { |
| 531 | if constexpr (IS_SPLIT_G) { | 561 | if constexpr (IS_SPLIT_G) { |
| 532 | for (int64_t loopCnt = 0; loopCnt < maxS2LoopCnt; loopCnt++) { | 562 | for (int64_t loopCnt = 0; loopCnt < maxS2LoopCnt; loopCnt++) { |
| 533 | - CrossCoreSetFlag<0, PIPE_MTE3>(15); | 563 | + CrossCoreSetFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 534 | - CrossCoreWaitFlag<0, PIPE_MTE3>(15); | 564 | + CrossCoreWaitFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 535 | } | 565 | } |
| 536 | } | 566 | } |
| 537 | } | 567 | } |
| @@ -556,7 +586,8 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 556 | 586 | ||
| 557 | int64_t taskId = 0; | 587 | int64_t taskId = 0; |
| 558 | bool notLast = true; | 588 | bool notLast = true; |
| 559 | - RunInfo runInfo[3]; | 589 | + bool isFirstLoop = true; |
| 590 | + RunInfo runInfo[4]; | ||
| 560 | RunParamStr runParam; | 591 | RunParamStr runParam; |
| 561 | runParam.firstFdDataWorkspaceIdx = firstFdDataWorkspaceIdx; | 592 | runParam.firstFdDataWorkspaceIdx = firstFdDataWorkspaceIdx; |
| 562 | int64_t multiCoreInnerIdx = 1; | 593 | int64_t multiCoreInnerIdx = 1; |
| @@ -573,22 +604,28 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 573 | 604 | ||
| 574 | int64_t gS1LoopEnd = lastBN ? (runParam.gs1LoopEndIdx + PRELOAD_NUM) : runParam.gs1LoopEndIdx; | 605 | int64_t gS1LoopEnd = lastBN ? (runParam.gs1LoopEndIdx + PRELOAD_NUM) : runParam.gs1LoopEndIdx; |
| 575 | for (int64_t gS1Index = runParam.gs1LoopStartIdx; gS1Index < gS1LoopEnd; gS1Index++) { | 606 | for (int64_t gS1Index = runParam.gs1LoopStartIdx; gS1Index < gS1LoopEnd; gS1Index++) { |
| 607 | + bool notLastThreeLoop = true; | ||
| 576 | bool notLastTwoLoop = true; | 608 | bool notLastTwoLoop = true; |
| 577 | if (lastBN) { | 609 | if (lastBN) { |
| 578 | int32_t extraGS1 = gS1Index - runParam.gs1LoopEndIdx; | 610 | int32_t extraGS1 = gS1Index - runParam.gs1LoopEndIdx; |
| 579 | switch (extraGS1) { | 611 | switch (extraGS1) { |
| 580 | case 0: | 612 | case 0: |
| 581 | - notLastTwoLoop = false; | 613 | + notLastThreeLoop = false; |
| 582 | break; | 614 | break; |
| 583 | case 1: | 615 | case 1: |
| 616 | + notLastTwoLoop = false; | ||
| 617 | + notLastThreeLoop = false; | ||
| 618 | + break; | ||
| 619 | + case 2: | ||
| 584 | notLast = false; | 620 | notLast = false; |
| 585 | notLastTwoLoop = false; | 621 | notLastTwoLoop = false; |
| 622 | + notLastThreeLoop = false; | ||
| 586 | break; | 623 | break; |
| 587 | default: | 624 | default: |
| 588 | break; | 625 | break; |
| 589 | } | 626 | } |
| 590 | } | 627 | } |
| 591 | - if (notLastTwoLoop) { | 628 | + if (notLastThreeLoop) { |
| 592 | this->ComputeAxisIdxByBnAndGs1(bnIdx, gS1Index, runParam); | 629 | this->ComputeAxisIdxByBnAndGs1(bnIdx, gS1Index, runParam); |
| 593 | bool s1NoNeedCalc = | 630 | bool s1NoNeedCalc = |
| 594 | ComputeParamS1<TEMPLATE_INTF_ARGS>(runParam, this->constInfo, gS1Index, this->cuSeqlensQGm); | 631 | ComputeParamS1<TEMPLATE_INTF_ARGS>(runParam, this->constInfo, gS1Index, this->cuSeqlensQGm); |
| @@ -637,7 +674,8 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 637 | for (int64_t s2LoopCount = 0; s2LoopCount <= s2LoopLimit; ++s2LoopCount) { | 674 | for (int64_t s2LoopCount = 0; s2LoopCount <= s2LoopLimit; ++s2LoopCount) { |
| 638 | if constexpr (IS_BATCH_CONSISTENCY) { | 675 | if constexpr (IS_BATCH_CONSISTENCY) { |
| 639 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? | 676 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? |
| 640 | - runParam.baseBlockNumPerReductionBlock : 1LL; | 677 | + runParam.baseBlockNumPerReductionBlock : |
| 678 | + 1LL; | ||
| 641 | if (runParam.isCrossCoreSplit && s2LoopCount % safeBaseBlockNum == 0) { | 679 | if (runParam.isCrossCoreSplit && s2LoopCount % safeBaseBlockNum == 0) { |
| 642 | runParam.s2SplitIdx = s2SplitIdxCounter++; | 680 | runParam.s2SplitIdx = s2SplitIdxCounter++; |
| 643 | } | 681 | } |
| @@ -645,42 +683,50 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 645 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || | 683 | if constexpr (TEMPLATE_MODE == SMLATemplateMode::CSA_TEMPLATE_MODE || |
| 646 | TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || | 684 | TEMPLATE_MODE == SMLATemplateMode::ORI_SPARSE_TEMPLATE_MODE || |
| 647 | TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { | 685 | TEMPLATE_MODE == SMLATemplateMode::ORI_CMP_SPARSE_TEMPLATE_MODE) { |
| 648 | - if (notLastTwoLoop) { | 686 | + if (notLastThreeLoop) { |
| 649 | - RunInfo &runInfo1 = runInfo[taskId % 3]; | 687 | + RunInfo &runInfo1 = runInfo[taskId % 4]; |
| 650 | this->SetRunInfo(runInfo1, runParam, taskId, s2LoopCount, s2LoopLimit, multiCoreInnerIdx); | 688 | this->SetRunInfo(runInfo1, runParam, taskId, s2LoopCount, s2LoopLimit, multiCoreInnerIdx); |
| 651 | - if ASCEND_IS_AIC { | 689 | + } |
| 652 | - this->cubeBlock.IterateBmm1(this->bmm1Buffers.Get(), this->l1RightBuffers.Get(), | 690 | + if ASCEND_IS_AIV { |
| 653 | - v0ResGmBuffers.Get(), runInfo1, this->constInfo); | 691 | + if (notLastThreeLoop) { |
| 654 | - } else { | 692 | + RunInfo &runInfo1 = runInfo[taskId % 4]; |
| 655 | - this->vecBlock.ProcessVec0(this->l1RightBuffers.Get(), v0ResGmBuffers.Get(), runInfo1, | 693 | + this->vecBlock.ProcessVec0(this->v0ResGmBuffers.Get(runInfo1.taskIdMod3), runInfo1, |
| 656 | - this->constInfo, 0); | 694 | + this->constInfo); |
| 695 | + } | ||
| 696 | + if (taskId > 1 && notLast) { | ||
| 697 | + auto &runInfo2 = runInfo[(taskId + 2) % 4]; | ||
| 698 | + this->vecBlock.ProcessVec1(this->l1PBuffers.Get(), this->bmm1Buffers.Get(), runInfo2, | ||
| 699 | + this->constInfo); | ||
| 700 | + } | ||
| 701 | + if (taskId > 2) { | ||
| 702 | + RunInfo &runInfo3 = runInfo[(taskId + 1) % 4]; | ||
| 703 | + this->vecBlock.ProcessVec2(this->bmm2Buffers.Get(), runInfo3, this->constInfo); | ||
| 657 | } | 704 | } |
| 658 | } else { | 705 | } else { |
| 659 | - if ASCEND_IS_AIV { | 706 | + if (taskId > 0 && notLastTwoLoop) { |
| 707 | + RunInfo &runInfo1 = runInfo[(taskId + 3) % 4]; | ||
| 708 | + this->cubeBlock.IterateLoadQK(this->v0ResGmBuffers.Get(runInfo1.taskIdMod3), | ||
| 709 | + runInfo1, this->constInfo, isFirstLoop); | ||
| 710 | + isFirstLoop = false; | ||
| 711 | + } else { | ||
| 660 | if constexpr (IS_SPLIT_G) { | 712 | if constexpr (IS_SPLIT_G) { |
| 661 | - if (maxS2LoopCnt > 0) { | 713 | + if (taskId > 0 && maxS2LoopCnt > 0) { |
| 662 | maxS2LoopCnt--; | 714 | maxS2LoopCnt--; |
| 663 | - CrossCoreSetFlag<0, PIPE_MTE3>(15); | 715 | + CrossCoreSetFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 664 | - CrossCoreWaitFlag<0, PIPE_MTE3>(15); | 716 | + CrossCoreWaitFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 665 | } | 717 | } |
| 666 | } | 718 | } |
| 667 | } | 719 | } |
| 668 | - } | 720 | + if (taskId > 1 && notLast) { |
| 669 | - if (taskId > 0 && notLast) { | 721 | + auto &runInfo2 = runInfo[(taskId + 2) % 4]; |
| 670 | - auto &runInfo2 = runInfo[(taskId + 2) % 3]; | 722 | + RunInfo &runInfoNext = runInfo[(taskId + 3) % 4]; |
| 671 | - if ASCEND_IS_AIV { | 723 | + this->cubeBlock.IterateBmm1(this->bmm1Buffers.Get(), |
| 672 | - this->vecBlock.ProcessVec1(this->l1PBuffers.Get(), this->bmm1Buffers.Get(), runInfo2, | 724 | + notLastTwoLoop, runInfoNext, runInfo2, this->constInfo); |
| 673 | - this->constInfo); | ||
| 674 | - } else { | ||
| 675 | - RunInfo &runInfo2 = runInfo[(taskId + 2) % 3]; | ||
| 676 | - this->cubeBlock.IterateBmm2(this->bmm2Buffers.Get(), this->l1PBuffers, | ||
| 677 | - this->l1RightBuffers.GetReused(), runInfo2, this->constInfo); | ||
| 678 | } | 725 | } |
| 679 | - } | 726 | + if (taskId > 2) { |
| 680 | - if (taskId > 1) { | 727 | + RunInfo &runInfo3 = runInfo[(taskId + 1) % 4]; |
| 681 | - if ASCEND_IS_AIV { | 728 | + this->cubeBlock.IterateBmm2(this->bmm2Buffers.Get(), this->l1PBuffers, |
| 682 | - RunInfo &runInfo3 = runInfo[(taskId + 1) % 3]; | 729 | + runInfo3, this->constInfo); |
| 683 | - this->vecBlock.ProcessVec2(this->bmm2Buffers.Get(), runInfo3, this->constInfo); | ||
| 684 | } | 730 | } |
| 685 | } | 731 | } |
| 686 | } | 732 | } |
| @@ -690,11 +736,11 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 690 | } | 736 | } |
| 691 | gS1StartIdx = 0; | 737 | gS1StartIdx = 0; |
| 692 | } | 738 | } |
| 693 | - if ASCEND_IS_AIV { | 739 | + if ASCEND_IS_AIC { |
| 694 | if constexpr (IS_SPLIT_G) { | 740 | if constexpr (IS_SPLIT_G) { |
| 695 | for (int64_t loopCnt = 0; loopCnt < maxS2LoopCnt; loopCnt++) { | 741 | for (int64_t loopCnt = 0; loopCnt < maxS2LoopCnt; loopCnt++) { |
| 696 | - CrossCoreSetFlag<0, PIPE_MTE3>(15); | 742 | + CrossCoreSetFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 697 | - CrossCoreWaitFlag<0, PIPE_MTE3>(15); | 743 | + CrossCoreWaitFlag<0, PIPE_MTE2>(crossCoreMte2SyncFlagId); |
| 698 | } | 744 | } |
| 699 | } | 745 | } |
| 700 | } | 746 | } |
| @@ -752,12 +798,13 @@ __aicore__ inline void SparseFlashMlaCsaKernel<CubeBlockType, VecBlockType>::Set | |||
| 752 | runInfo.s2SplitIdx = runParam.s2SplitIdx; | 798 | runInfo.s2SplitIdx = runParam.s2SplitIdx; |
| 753 | runInfo.isFirstS2SplitCore = runParam.isFirstS2SplitCore; | 799 | runInfo.isFirstS2SplitCore = runParam.isFirstS2SplitCore; |
| 754 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? | 800 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? |
| 755 | - runParam.baseBlockNumPerReductionBlock : 1LL; | 801 | + runParam.baseBlockNumPerReductionBlock : |
| 802 | + 1LL; | ||
| 756 | int64_t baseBlockIdInReduceBlock = s2LoopCount % safeBaseBlockNum; | 803 | int64_t baseBlockIdInReduceBlock = s2LoopCount % safeBaseBlockNum; |
| 757 | runInfo.reduceBlockId = s2LoopCount / safeBaseBlockNum; | 804 | runInfo.reduceBlockId = s2LoopCount / safeBaseBlockNum; |
| 758 | runInfo.isFirstBase = baseBlockIdInReduceBlock == 0; | 805 | runInfo.isFirstBase = baseBlockIdInReduceBlock == 0; |
| 759 | runInfo.isLastBase = baseBlockIdInReduceBlock == safeBaseBlockNum - 1LL || | 806 | runInfo.isLastBase = baseBlockIdInReduceBlock == safeBaseBlockNum - 1LL || |
| 760 | - s2LoopCount == s2LoopLimit; | 807 | + s2LoopCount == s2LoopLimit; |
| 761 | runInfo.needReduce = runInfo.reduceBlockId > 0; | 808 | runInfo.needReduce = runInfo.reduceBlockId > 0; |
| 762 | this->ComputeBmm1Tail(runInfo, runParam); | 809 | this->ComputeBmm1Tail(runInfo, runParam); |
| 763 | InitUniqueRunInfo(runParam, runInfo); | 810 | InitUniqueRunInfo(runParam, runInfo); |
| @@ -27,6 +27,9 @@ | |||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 30 | 33 | ||
| 31 | 34 | ||
| 32 | 35 | ||
| @@ -116,7 +119,6 @@ private: | |||
| 116 | // mm2左矩阵P | 119 | // mm2左矩阵P |
| 117 | BufferManager<BufferType::L1> l1BufferManager; | 120 | BufferManager<BufferType::L1> l1BufferManager; |
| 118 | BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> l1PBuffers; | 121 | BuffersPolicyDB<BufferType::L1, SyncType::CROSS_CORE_SYNC_FORWARD> l1PBuffers; |
| 119 | - BuffersPolicy3buff<BufferType::L1, SyncType::INNER_CORE_SYNC> l1RightBuffers; | ||
| 120 | /* GM信息 */ | 122 | /* GM信息 */ |
| 121 | GlobalTensor<uint32_t> metadataGm; | 123 | GlobalTensor<uint32_t> metadataGm; |
| 122 | GlobalTensor<int32_t> cuSeqlensQGm; | 124 | GlobalTensor<int32_t> cuSeqlensQGm; |
| @@ -191,7 +193,7 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 191 | } else { | 193 | } else { |
| 192 | vecBlock.InitS2SplitStaging(fdStagingBuffer.Get()); | 194 | vecBlock.InitS2SplitStaging(fdStagingBuffer.Get()); |
| 193 | } | 195 | } |
| 194 | - cubeBlock.InitCubeBlock(pipe, l1BufferManager, query); | 196 | + cubeBlock.InitCubeBlock(pipe, query); |
| 195 | this->ComputeConstexpr(); | 197 | this->ComputeConstexpr(); |
| 196 | this->InitGlobalBuffer(query, oriKV, cmpKV, oriSparseIndices, cmpSparseIndices, oriBlockTable, cmpBlockTable, | 198 | this->InitGlobalBuffer(query, oriKV, cmpKV, oriSparseIndices, cmpSparseIndices, oriBlockTable, cmpBlockTable, |
| 197 | cuSeqlensQ, cuSeqlensOriKv, cuSeqlensCmpKv, sequsedQ, seqUsedOriKv, seqUsedCmpKv, | 199 | cuSeqlensQ, cuSeqlensOriKv, cuSeqlensCmpKv, sequsedQ, seqUsedOriKv, seqUsedCmpKv, |
| @@ -344,8 +346,7 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 344 | uint32_t mm1ResultSize = constInfo.s1BaseSize / CV_RATIO * constInfo.s2BaseSize * sizeof(T); | 346 | uint32_t mm1ResultSize = constInfo.s1BaseSize / CV_RATIO * constInfo.s2BaseSize * sizeof(T); |
| 345 | uint32_t mm2ResultSize = constInfo.s1BaseSize / CV_RATIO * 512 * sizeof(T); | 347 | uint32_t mm2ResultSize = constInfo.s1BaseSize / CV_RATIO * 512 * sizeof(T); |
| 346 | uint32_t mm2LeftSize = constInfo.s1BaseSize * constInfo.s2BaseSize * sizeof(Q_T); | 348 | uint32_t mm2LeftSize = constInfo.s1BaseSize * constInfo.s2BaseSize * sizeof(Q_T); |
| 347 | - uint32_t mm1RightSize = constInfo.s2BaseSize * 512 * sizeof(Q_T); | 349 | + l1BufferManager.Init(pipe, mm2LeftSize * 2); |
| 348 | - l1BufferManager.Init(pipe, 524288); // 512 * 1024 | ||
| 349 | // 保存p结果的L1内存必须放在第一个L1 policy上,保证和vec申请的地址相同 | 350 | // 保存p结果的L1内存必须放在第一个L1 policy上,保证和vec申请的地址相同 |
| 350 | l1PBuffers.Init(l1BufferManager, mm2LeftSize); | 351 | l1PBuffers.Init(l1BufferManager, mm2LeftSize); |
| 351 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | 352 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); |
| @@ -353,7 +354,6 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 353 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); | 354 | l1PBuffers.Get().SetCrossCoreID(crossCoreSyncBufId, INVALID_CROSS_CORE_EVENT_ID); |
| 354 | crossCoreSyncBufId++; | 355 | crossCoreSyncBufId++; |
| 355 | if ASCEND_IS_AIC { | 356 | if ASCEND_IS_AIC { |
| 356 | - l1RightBuffers.Init(l1BufferManager, mm1RightSize); | ||
| 357 | l1PBuffers.Get().SetCrossCore(); | 357 | l1PBuffers.Get().SetCrossCore(); |
| 358 | l1PBuffers.Get().SetCrossCore(); | 358 | l1PBuffers.Get().SetCrossCore(); |
| 359 | } | 359 | } |
| @@ -385,17 +385,17 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Ini | |||
| 385 | constexpr uint32_t FD_MAX_SUM_REGION_NUM = 2U; | 385 | constexpr uint32_t FD_MAX_SUM_REGION_NUM = 2U; |
| 386 | uint32_t gSize = static_cast<uint32_t>(constInfo.gSize); | 386 | uint32_t gSize = static_cast<uint32_t>(constInfo.gSize); |
| 387 | uint32_t combineElemSize = gSize * constInfo.dSize + FD_MAX_SUM_REGION_NUM * gSize * | 387 | uint32_t combineElemSize = gSize * constInfo.dSize + FD_MAX_SUM_REGION_NUM * gSize * |
| 388 | - static_cast<uint32_t>(AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW); | 388 | + static_cast<uint32_t>(AttentionCommon::FD_BROADCAST_ELEMS_PER_ROW); |
| 389 | if constexpr (IS_BATCH_CONSISTENCY) { | 389 | if constexpr (IS_BATCH_CONSISTENCY) { |
| 390 | uint32_t intraCoreSlotNum = IS_SPLIT_G ? GetBlockNum() : (GetBlockNum() << 1U); | 390 | uint32_t intraCoreSlotNum = IS_SPLIT_G ? GetBlockNum() : (GetBlockNum() << 1U); |
| 391 | uint32_t intraCoreCombineSize = intraCoreSlotNum * combineElemSize * sizeof(float); | 391 | uint32_t intraCoreCombineSize = intraCoreSlotNum * combineElemSize * sizeof(float); |
| 392 | uint32_t crossCoreCombineSize = GetBlockNum() * BATCH_CONSISTENCY_MAX_REDUCE_BLOCK_NUM * | 392 | uint32_t crossCoreCombineSize = GetBlockNum() * BATCH_CONSISTENCY_MAX_REDUCE_BLOCK_NUM * |
| 393 | - combineElemSize * sizeof(float); | 393 | + combineElemSize * sizeof(float); |
| 394 | intraCoreCombineBuffer.Init(fdStagingBufferManager, intraCoreCombineSize); | 394 | intraCoreCombineBuffer.Init(fdStagingBufferManager, intraCoreCombineSize); |
| 395 | crossCoreCombineBuffer.Init(fdStagingBufferManager, crossCoreCombineSize); | 395 | crossCoreCombineBuffer.Init(fdStagingBufferManager, crossCoreCombineSize); |
| 396 | } else { | 396 | } else { |
| 397 | uint32_t fdSlotCount = static_cast<uint32_t>(AttentionCommon::FD_MAX_S2_SPLIT_NUM) * | 397 | uint32_t fdSlotCount = static_cast<uint32_t>(AttentionCommon::FD_MAX_S2_SPLIT_NUM) * |
| 398 | - (IS_SPLIT_G ? (GetBlockNum() >> 1U) : GetBlockNum()); | 398 | + (IS_SPLIT_G ? (GetBlockNum() >> 1U) : GetBlockNum()); |
| 399 | fdStagingBuffer.Init(fdStagingBufferManager, fdSlotCount * combineElemSize * sizeof(float)); | 399 | fdStagingBuffer.Init(fdStagingBufferManager, fdSlotCount * combineElemSize * sizeof(float)); |
| 400 | } | 400 | } |
| 401 | } | 401 | } |
| @@ -487,6 +487,7 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 487 | 487 | ||
| 488 | int64_t taskId = 0; | 488 | int64_t taskId = 0; |
| 489 | bool notLast = true; | 489 | bool notLast = true; |
| 490 | + bool isFirstLoop = true; | ||
| 490 | RunInfo runInfo[3]; | 491 | RunInfo runInfo[3]; |
| 491 | RunParamStr runParam; | 492 | RunParamStr runParam; |
| 492 | runParam.firstFdDataWorkspaceIdx = firstFdDataWorkspaceIdx; | 493 | runParam.firstFdDataWorkspaceIdx = firstFdDataWorkspaceIdx; |
| @@ -566,7 +567,8 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 566 | for (int64_t s2LoopCount = 0; s2LoopCount <= s2LoopLimit; ++s2LoopCount) { | 567 | for (int64_t s2LoopCount = 0; s2LoopCount <= s2LoopLimit; ++s2LoopCount) { |
| 567 | if constexpr (IS_BATCH_CONSISTENCY) { | 568 | if constexpr (IS_BATCH_CONSISTENCY) { |
| 568 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? | 569 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? |
| 569 | - runParam.baseBlockNumPerReductionBlock : 1LL; | 570 | + runParam.baseBlockNumPerReductionBlock : |
| 571 | + 1LL; | ||
| 570 | if (runParam.isCrossCoreSplit && s2LoopCount % safeBaseBlockNum == 0) { | 572 | if (runParam.isCrossCoreSplit && s2LoopCount % safeBaseBlockNum == 0) { |
| 571 | runParam.s2SplitIdx = s2SplitIdxCounter++; | 573 | runParam.s2SplitIdx = s2SplitIdxCounter++; |
| 572 | } | 574 | } |
| @@ -575,8 +577,8 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 575 | RunInfo &runInfo1 = runInfo[taskId % 3]; | 577 | RunInfo &runInfo1 = runInfo[taskId % 3]; |
| 576 | this->SetRunInfo(runInfo1, runParam, taskId, s2LoopCount, s2LoopLimit, multiCoreInnerIdx); | 578 | this->SetRunInfo(runInfo1, runParam, taskId, s2LoopCount, s2LoopLimit, multiCoreInnerIdx); |
| 577 | if ASCEND_IS_AIC { | 579 | if ASCEND_IS_AIC { |
| 578 | - this->cubeBlock.IterateBmm1(this->bmm1Buffers.Get(), this->l1RightBuffers.Get(), runInfo1, | 580 | + this->cubeBlock.IterateLoadQK(runInfo1, this->constInfo, isFirstLoop); |
| 579 | - this->constInfo); | 581 | + isFirstLoop = false; |
| 580 | } | 582 | } |
| 581 | } | 583 | } |
| 582 | if (taskId > 0 && notLast) { | 584 | if (taskId > 0 && notLast) { |
| @@ -585,15 +587,18 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Pro | |||
| 585 | this->vecBlock.ProcessVec1(this->l1PBuffers.Get(), this->bmm1Buffers.Get(), runInfo2, | 587 | this->vecBlock.ProcessVec1(this->l1PBuffers.Get(), this->bmm1Buffers.Get(), runInfo2, |
| 586 | this->constInfo); | 588 | this->constInfo); |
| 587 | } else { | 589 | } else { |
| 588 | - RunInfo &runInfo2 = runInfo[(taskId + 2) % 3]; | 590 | + RunInfo &runInfoNext = runInfo[taskId % 3]; |
| 589 | - this->cubeBlock.IterateBmm2(this->bmm2Buffers.Get(), this->l1PBuffers, | 591 | + this->cubeBlock.IterateBmm1(this->bmm1Buffers.Get(), |
| 590 | - this->l1RightBuffers.GetReused(), runInfo2, this->constInfo); | 592 | + notLastTwoLoop, runInfoNext, runInfo2, this->constInfo); |
| 591 | } | 593 | } |
| 592 | } | 594 | } |
| 593 | if (taskId > 1) { | 595 | if (taskId > 1) { |
| 596 | + RunInfo &runInfo3 = runInfo[(taskId + 1) % 3]; | ||
| 594 | if ASCEND_IS_AIV { | 597 | if ASCEND_IS_AIV { |
| 595 | - RunInfo &runInfo3 = runInfo[(taskId + 1) % 3]; | ||
| 596 | this->vecBlock.ProcessVec2(this->bmm2Buffers.Get(), runInfo3, this->constInfo); | 598 | this->vecBlock.ProcessVec2(this->bmm2Buffers.Get(), runInfo3, this->constInfo); |
| 599 | + } else { | ||
| 600 | + this->cubeBlock.IterateBmm2(this->bmm2Buffers.Get(), this->l1PBuffers, | ||
| 601 | + runInfo3, this->constInfo); | ||
| 597 | } | 602 | } |
| 598 | } | 603 | } |
| 599 | ++taskId; | 604 | ++taskId; |
| @@ -656,12 +661,13 @@ __aicore__ inline void SparseFlashMlaSwaKernel<CubeBlockType, VecBlockType>::Set | |||
| 656 | runInfo.s2SplitIdx = runParam.s2SplitIdx; | 661 | runInfo.s2SplitIdx = runParam.s2SplitIdx; |
| 657 | runInfo.isFirstS2SplitCore = runParam.isFirstS2SplitCore; | 662 | runInfo.isFirstS2SplitCore = runParam.isFirstS2SplitCore; |
| 658 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? | 663 | int64_t safeBaseBlockNum = runParam.baseBlockNumPerReductionBlock > 0 ? |
| 659 | - runParam.baseBlockNumPerReductionBlock : 1LL; | 664 | + runParam.baseBlockNumPerReductionBlock : |
| 665 | + 1LL; | ||
| 660 | int64_t baseBlockIdInReduceBlock = s2LoopCount % safeBaseBlockNum; | 666 | int64_t baseBlockIdInReduceBlock = s2LoopCount % safeBaseBlockNum; |
| 661 | runInfo.reduceBlockId = s2LoopCount / safeBaseBlockNum; | 667 | runInfo.reduceBlockId = s2LoopCount / safeBaseBlockNum; |
| 662 | runInfo.isFirstBase = baseBlockIdInReduceBlock == 0; | 668 | runInfo.isFirstBase = baseBlockIdInReduceBlock == 0; |
| 663 | runInfo.isLastBase = baseBlockIdInReduceBlock == safeBaseBlockNum - 1LL || | 669 | runInfo.isLastBase = baseBlockIdInReduceBlock == safeBaseBlockNum - 1LL || |
| 664 | - s2LoopCount == s2LoopLimit; | 670 | + s2LoopCount == s2LoopLimit; |
| 665 | runInfo.needReduce = runInfo.reduceBlockId > 0; | 671 | runInfo.needReduce = runInfo.reduceBlockId > 0; |
| 666 | this->ComputeBmm1Tail(runInfo, runParam); | 672 | this->ComputeBmm1Tail(runInfo, runParam); |
| 667 | InitUniqueRunInfo(runParam, runInfo); | 673 | InitUniqueRunInfo(runParam, runInfo); |
| @@ -34,37 +34,37 @@ using namespace optiling::detail; | |||
| 34 | using namespace SMLAKernel; | 34 | using namespace SMLAKernel; |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | -#define SMLA_OP_IMPL(templateClass, tilingdataClass, ...) \ | 37 | +#define SMLA_OP_IMPL(templateClass, tilingdataClass, ...) \ |
| 38 | - do { \ | 38 | + do { \ |
| 39 | - using CubeBlockType = \ | 39 | + using CubeBlockType = \ |
| 40 | - typename std::conditional<g_coreType == AscendC::AIC, SMLAKernel::CSABlockCube<__VA_ARGS__>, \ | 40 | + typename std::conditional<g_coreType == AscendC::AIC, SMLAKernel::CSABlockCube<__VA_ARGS__>, \ |
| 41 | - SMLAKernel::CSABlockCubeDummy<__VA_ARGS__>>::type; \ | 41 | + SMLAKernel::CSABlockCubeDummy<__VA_ARGS__>>::type; \ |
| 42 | - using VecBlockType = \ | 42 | + using VecBlockType = \ |
| 43 | - typename std::conditional<g_coreType == AscendC::AIC, SMLAKernel::CSABlockVecDummy<__VA_ARGS__>, \ | 43 | + typename std::conditional<g_coreType == AscendC::AIC, SMLAKernel::CSABlockVecDummy<__VA_ARGS__>, \ |
| 44 | - SMLAKernel::CSABlockVec<__VA_ARGS__>>::type; \ | 44 | + SMLAKernel::CSABlockVec<__VA_ARGS__>>::type; \ |
| 45 | - templateClass<CubeBlockType, VecBlockType> op; \ | 45 | + templateClass<CubeBlockType, VecBlockType> op; \ |
| 46 | - GET_TILING_DATA_WITH_STRUCT(tilingdataClass, tilingDataIn, tiling); \ | 46 | + GET_TILING_DATA_WITH_STRUCT(tilingdataClass, tilingDataIn, tiling); \ |
| 47 | - const tilingdataClass *__restrict tilingData = &tilingDataIn; \ | 47 | + const tilingdataClass *__restrict tilingData = &tilingDataIn; \ |
| 48 | - op.Init(query, oriKV, cmpKV, oriSparseIndices, cmpSparseIndices, oriBlockTable, cmpBlockTable, cuSeqlensQ, \ | 48 | + op.Init(query, oriKV, cmpKV, oriSparseIndices, cmpSparseIndices, oriBlockTable, cmpBlockTable, cuSeqlensQ, \ |
| 49 | - cuSeqlensOriKv, cuSeqlensCmpKv, seqUsedQ, seqUsedOriKV, seqUsedCmpKV, cmpResidualKV, oriTopkLength, \ | 49 | + cuSeqlensOriKv, cuSeqlensCmpKv, seqUsedQ, seqUsedOriKV, seqUsedCmpKV, cmpResidualKV, oriTopkLength, \ |
| 50 | - cmpTopkLength, sinks, metadata, attentionOut, softmaxLse, user, tilingData, &tPipe); \ | 50 | + cmpTopkLength, sinks, metadata, attentionOut, softmaxLse, user, tilingData, &tPipe); \ |
| 51 | - op.Process(); \ | 51 | + op.Process(); \ |
| 52 | } while (0) | 52 | } while (0) |
| 53 | 53 | ||
| 54 | -#define SMLA_OP_IMPL(templateClass, tilingdataClass, ...) \ | 54 | +#define SMLA_OP_IMPL(templateClass, tilingdataClass, ...) \ |
| 55 | - do { \ | 55 | + do { \ |
| 56 | - templateClass<SMLAType<__VA_ARGS__>> op; \ | 56 | + templateClass<SMLAType<__VA_ARGS__>> op; \ |
| 57 | - GET_TILING_DATA_WITH_STRUCT(tilingdataClass, tiling_data_in, tiling); \ | 57 | + GET_TILING_DATA_WITH_STRUCT(tilingdataClass, tiling_data_in, tiling); \ |
| 58 | - const tilingdataClass *__restrict tiling_data = &tiling_data_in; \ | 58 | + const tilingdataClass *__restrict tiling_data = &tiling_data_in; \ |
| 59 | - op.Init(query, oriKV, cmpKV, cmpSparseIndices, oriBlockTable, cmpBlockTable, cuSeqlensQ, cuSeqlensOriKv, \ | 59 | + op.Init(query, oriKV, cmpKV, cmpSparseIndices, oriBlockTable, cmpBlockTable, cuSeqlensQ, cuSeqlensOriKv, \ |
| 60 | - cuSeqlensCmpKv, seqUsedQ, seqUsedOriKV, seqUsedCmpKV, cmpResidualKV, sinks, metadata, attentionOut, \ | 60 | + cuSeqlensCmpKv, seqUsedQ, seqUsedOriKV, seqUsedCmpKV, cmpResidualKV, sinks, metadata, attentionOut, \ |
| 61 | - softmaxLse, user, tiling_data, tiling, &tPipe); \ | 61 | + softmaxLse, user, tiling_data, tiling, &tPipe); \ |
| 62 | - op.Process(); \ | 62 | + op.Process(); \ |
| 63 | } while (0) | 63 | } while (0) |
| 64 | 64 | ||
| 65 | 65 | ||
| 66 | template <int FLASH_DECODE, int LAYOUT_T, int KV_LAYOUT_T, int TEMPLATE_MODE, int SPLIT_G, int HEAD_RATIO_ONE, | 66 | template <int FLASH_DECODE, int LAYOUT_T, int KV_LAYOUT_T, int TEMPLATE_MODE, int SPLIT_G, int HEAD_RATIO_ONE, |
| 67 | - int BATCH_CONSISTENCY> | 67 | + int BATCH_CONSISTENCY, int IS_VEC_S2PHYADDR> |
| 68 | __global__ __aicore__ void | 68 | __global__ __aicore__ void |
| 69 | sparse_flash_mla(__gm__ uint8_t *query, __gm__ uint8_t *oriKV, __gm__ uint8_t *cmpKV, __gm__ uint8_t *oriSparseIndices, | 69 | sparse_flash_mla(__gm__ uint8_t *query, __gm__ uint8_t *oriKV, __gm__ uint8_t *cmpKV, __gm__ uint8_t *oriSparseIndices, |
| 70 | __gm__ uint8_t *cmpSparseIndices, __gm__ uint8_t *oriBlockTable, __gm__ uint8_t *cmpBlockTable, | 70 | __gm__ uint8_t *cmpSparseIndices, __gm__ uint8_t *oriBlockTable, __gm__ uint8_t *cmpBlockTable, |
| @@ -85,11 +85,11 @@ sparse_flash_mla(__gm__ uint8_t *query, __gm__ uint8_t *oriKV, __gm__ uint8_t *c | |||
| 85 | TEMPLATE_MODE == ORI_CMP_SPARSE_TEMPLATE) { | 85 | TEMPLATE_MODE == ORI_CMP_SPARSE_TEMPLATE) { |
| 86 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaCsaKernel, SparseFlashMlaTilingData, half, half, float, half, | 86 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaCsaKernel, SparseFlashMlaTilingData, half, half, float, half, |
| 87 | FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), | 87 | FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), |
| 88 | - static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, BATCH_CONSISTENCY); | 88 | + static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, BATCH_CONSISTENCY, IS_VEC_S2PHYADDR); |
| 89 | } else { | 89 | } else { |
| 90 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaSwaKernel, SparseFlashMlaTilingData, half, half, float, half, | 90 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaSwaKernel, SparseFlashMlaTilingData, half, half, float, half, |
| 91 | FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), | 91 | FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), |
| 92 | - static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, BATCH_CONSISTENCY); | 92 | + static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, BATCH_CONSISTENCY, IS_VEC_S2PHYADDR); |
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | if constexpr (ORIG_DTYPE_Q == DT_BF16 && ORIG_DTYPE_ORI_KV == DT_BF16 && ORIG_DTYPE_ATTN_OUT == DT_BF16) { | 95 | if constexpr (ORIG_DTYPE_Q == DT_BF16 && ORIG_DTYPE_ORI_KV == DT_BF16 && ORIG_DTYPE_ATTN_OUT == DT_BF16) { |
| @@ -98,12 +98,12 @@ sparse_flash_mla(__gm__ uint8_t *query, __gm__ uint8_t *oriKV, __gm__ uint8_t *c | |||
| 98 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaCsaKernel, SparseFlashMlaTilingData, bfloat16_t, bfloat16_t, float, | 98 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaCsaKernel, SparseFlashMlaTilingData, bfloat16_t, bfloat16_t, float, |
| 99 | bfloat16_t, FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), | 99 | bfloat16_t, FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), |
| 100 | static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, | 100 | static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, |
| 101 | - BATCH_CONSISTENCY); | 101 | + BATCH_CONSISTENCY, IS_VEC_S2PHYADDR); |
| 102 | } else { | 102 | } else { |
| 103 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaSwaKernel, SparseFlashMlaTilingData, bfloat16_t, bfloat16_t, float, | 103 | SMLA_OP_IMPL(SMLAKernel::SparseFlashMlaSwaKernel, SparseFlashMlaTilingData, bfloat16_t, bfloat16_t, float, |
| 104 | bfloat16_t, FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), | 104 | bfloat16_t, FLASH_DECODE, static_cast<SMLA_LAYOUT>(LAYOUT_T), |
| 105 | static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, | 105 | static_cast<SMLA_LAYOUT>(KV_LAYOUT_T), static_cast<SMLATemplateMode>(TEMPLATE_MODE), SPLIT_G, |
| 106 | - BATCH_CONSISTENCY); | 106 | + BATCH_CONSISTENCY, IS_VEC_S2PHYADDR); |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | 109 | ||
| @@ -40,7 +40,8 @@ ASCENDC_TPL_ARGS_DECL(SparseFlashMla, // 算子OpType | |||
| 40 | HCA_TEMPLATE, CSA_TEMPLATE, ORI_SPARSE_TEMPLATE, ORI_CMP_SPARSE_TEMPLATE), | 40 | HCA_TEMPLATE, CSA_TEMPLATE, ORI_SPARSE_TEMPLATE, ORI_CMP_SPARSE_TEMPLATE), |
| 41 | ASCENDC_TPL_BOOL_DECL(SPLIT_G, 0, 1), | 41 | ASCENDC_TPL_BOOL_DECL(SPLIT_G, 0, 1), |
| 42 | ASCENDC_TPL_BOOL_DECL(HEAD_RATIO_ONE, 0, 1), | 42 | ASCENDC_TPL_BOOL_DECL(HEAD_RATIO_ONE, 0, 1), |
| 43 | - ASCENDC_TPL_BOOL_DECL(BATCH_CONSISTENCY, 0, 1),); | 43 | + ASCENDC_TPL_BOOL_DECL(BATCH_CONSISTENCY, 0, 1), |
| 44 | + ASCENDC_TPL_BOOL_DECL(IS_VEC_S2PHYADDR, 0, 1)); | ||
| 44 | 45 | ||
| 45 | // 支持的模板参数组合 | 46 | // 支持的模板参数组合 |
| 46 | // 用于调用GET_TPL_TILING_KEY获取TilingKey时,接口内部校验TilingKey是否合法 | 47 | // 用于调用GET_TPL_TILING_KEY获取TilingKey时,接口内部校验TilingKey是否合法 |
| @@ -50,7 +51,9 @@ ASCENDC_TPL_SEL(ASCENDC_TPL_ARGS_SEL( | |||
| 50 | ASCENDC_TPL_UINT_SEL(KV_LAYOUT_T, ASCENDC_TPL_UI_LIST, SMLA_LAYOUT_BSND, SMLA_LAYOUT_TND, SMLA_LAYOUT_PA_BBND), | 51 | ASCENDC_TPL_UINT_SEL(KV_LAYOUT_T, ASCENDC_TPL_UI_LIST, SMLA_LAYOUT_BSND, SMLA_LAYOUT_TND, SMLA_LAYOUT_PA_BBND), |
| 51 | ASCENDC_TPL_UINT_SEL(TEMPLATE_MODE, ASCENDC_TPL_UI_LIST, SWA_TEMPLATE, HCA_TEMPLATE, CSA_TEMPLATE, | 52 | ASCENDC_TPL_UINT_SEL(TEMPLATE_MODE, ASCENDC_TPL_UI_LIST, SWA_TEMPLATE, HCA_TEMPLATE, CSA_TEMPLATE, |
| 52 | ORI_SPARSE_TEMPLATE, ORI_CMP_SPARSE_TEMPLATE), | 53 | ORI_SPARSE_TEMPLATE, ORI_CMP_SPARSE_TEMPLATE), |
| 53 | - ASCENDC_TPL_BOOL_SEL(SPLIT_G, 0, 1), ASCENDC_TPL_BOOL_SEL(HEAD_RATIO_ONE, 0, 1), | 54 | + ASCENDC_TPL_BOOL_SEL(SPLIT_G, 0, 1), |
| 54 | - ASCENDC_TPL_BOOL_SEL(BATCH_CONSISTENCY, 0, 1),)); | 55 | + ASCENDC_TPL_BOOL_SEL(HEAD_RATIO_ONE, 0, 1), |
| 56 | + ASCENDC_TPL_BOOL_SEL(BATCH_CONSISTENCY, 0, 1), | ||
| 57 | + ASCENDC_TPL_BOOL_SEL(IS_VEC_S2PHYADDR, 0, 1))); | ||
| 55 | 58 | ||
| 56 | 59 | ||
| @@ -626,6 +626,78 @@ TEST_PARAMS = { | |||
| 626 | "ori_sparse_indices_mode": ["full"], | 626 | "ori_sparse_indices_mode": ["full"], |
| 627 | "cmp_sparse_indices_mode": ["full"], | 627 | "cmp_sparse_indices_mode": ["full"], |
| 628 | }, | 628 | }, |
| 629 | + "smla_prefill_pro": { | ||
| 630 | + "testcase_name": [None], | ||
| 631 | + "layout_q": ["TND"], | ||
| 632 | + "layout_kv": ["TND"], | ||
| 633 | + "q_type": [torch.bfloat16], | ||
| 634 | + "ori_kv_type": [torch.bfloat16], | ||
| 635 | + "cmp_kv_type": [torch.bfloat16], | ||
| 636 | + "B": [1], | ||
| 637 | + "S1": [4096], | ||
| 638 | + "S2": [8192], | ||
| 639 | + "T1": [4096], | ||
| 640 | + "T2": [8192], | ||
| 641 | + "T3": [2048], | ||
| 642 | + "N1": [128], | ||
| 643 | + "N2": [1], | ||
| 644 | + "D": [512], | ||
| 645 | + "K": [1024], | ||
| 646 | + "block_num1": [None], | ||
| 647 | + "block_num2": [None], | ||
| 648 | + "block_size1": [128], | ||
| 649 | + "block_size2": [128], | ||
| 650 | + "cu_seqlens_q": [None], | ||
| 651 | + "seqused_ori_kv": [None], | ||
| 652 | + "seqused_cmp_kv": [None], | ||
| 653 | + "cmp_residual_kv": [None], | ||
| 654 | + "softmax_scale": [0.04419417], | ||
| 655 | + "cmp_ratio": [4], | ||
| 656 | + "return_softmax_lse": [False], | ||
| 657 | + "ori_mask_mode": [4], | ||
| 658 | + "cmp_mask_mode": [3], | ||
| 659 | + "ori_win_left": [127], | ||
| 660 | + "ori_win_right": [0], | ||
| 661 | + "template_mode": ["CSA"], | ||
| 662 | + "cmp_kv_topk_mode": ["fullK"], | ||
| 663 | + "cmp_sparse_indices_mode": ["full"], | ||
| 664 | + }, | ||
| 665 | + "smla_prefill_flash": { | ||
| 666 | + "testcase_name": [None], | ||
| 667 | + "layout_q": ["TND"], | ||
| 668 | + "layout_kv": ["TND"], | ||
| 669 | + "q_type": [torch.bfloat16], | ||
| 670 | + "ori_kv_type": [torch.bfloat16], | ||
| 671 | + "cmp_kv_type": [torch.bfloat16], | ||
| 672 | + "B": [1], | ||
| 673 | + "S1": [4096], | ||
| 674 | + "S2": [8192], | ||
| 675 | + "T1": [4096], | ||
| 676 | + "T2": [8192], | ||
| 677 | + "T3": [2048], | ||
| 678 | + "N1": [64], | ||
| 679 | + "N2": [1], | ||
| 680 | + "D": [512], | ||
| 681 | + "K": [512], | ||
| 682 | + "block_num1": [None], | ||
| 683 | + "block_num2": [None], | ||
| 684 | + "block_size1": [128], | ||
| 685 | + "block_size2": [128], | ||
| 686 | + "cu_seqlens_q": [None], | ||
| 687 | + "seqused_ori_kv": [None], | ||
| 688 | + "seqused_cmp_kv": [None], | ||
| 689 | + "cmp_residual_kv": [None], | ||
| 690 | + "softmax_scale": [0.04419417], | ||
| 691 | + "cmp_ratio": [4], | ||
| 692 | + "return_softmax_lse": [False], | ||
| 693 | + "ori_mask_mode": [4], | ||
| 694 | + "cmp_mask_mode": [3], | ||
| 695 | + "ori_win_left": [127], | ||
| 696 | + "ori_win_right": [0], | ||
| 697 | + "template_mode": ["CSA"], | ||
| 698 | + "cmp_kv_topk_mode": ["fullK"], | ||
| 699 | + "cmp_sparse_indices_mode": ["full"], | ||
| 700 | + }, | ||
| 629 | } | 701 | } |
| 630 | 702 | ||
| 631 | # 按需选择要启用的测试参数(例如默认启用所有) | 703 | # 按需选择要启用的测试参数(例如默认启用所有) |
| @@ -23,9 +23,11 @@ import numpy as np | |||
| 23 | import os | 23 | import os |
| 24 | 24 | ||
| 25 | pt_dir = os.getenv("SMLA_PT_LOAD_PATH", "./data") | 25 | pt_dir = os.getenv("SMLA_PT_LOAD_PATH", "./data") |
| 26 | -result_path = Path(os.getenv("SMLA_RESULT_SAVE_PATH", './result/smla_result.xlsx')) | 26 | +result_path = Path(os.getenv("SMLA_RESULT_SAVE_PATH", "./result/smla_result.xlsx")) |
| 27 | batch_test_mode = int(os.environ.get("SMLA_BATCH_TEST_MODE", 0)) | 27 | batch_test_mode = int(os.environ.get("SMLA_BATCH_TEST_MODE", 0)) |
| 28 | -excel_path = os.environ.get("SMLA_EXCEL_PATH", os.path.join(os.path.dirname(__file__), "excel", "example.xlsx")) | 28 | +excel_path = os.environ.get( |
| 29 | + "SMLA_EXCEL_PATH", os.path.join(os.path.dirname(__file__), "excel", "example.xlsx") | ||
| 30 | +) | ||
| 29 | excel_sheet = os.environ.get("SMLA_EXCEL_SHEET", "CSA") | 31 | excel_sheet = os.environ.get("SMLA_EXCEL_SHEET", "CSA") |
| 30 | 32 | ||
| 31 | _single_case_path = os.environ.get("QSAS_TESTCASE_PATH", "").strip() | 33 | _single_case_path = os.environ.get("QSAS_TESTCASE_PATH", "").strip() |
| @@ -33,19 +35,27 @@ _single_case_path = os.environ.get("QSAS_TESTCASE_PATH", "").strip() | |||
| 33 | locals()["testcase_files"] = [] | 35 | locals()["testcase_files"] = [] |
| 34 | if _single_case_path: | 36 | if _single_case_path: |
| 35 | if not os.path.isfile(_single_case_path): | 37 | if not os.path.isfile(_single_case_path): |
| 36 | - print(f"错误: 环境变量 QSAS_TESTCASE_PATH 指定的用例文件不存在: {_single_case_path}") | 38 | + print( |
| 39 | + f"错误: 环境变量 QSAS_TESTCASE_PATH 指定的用例文件不存在: {_single_case_path}" | ||
| 40 | + ) | ||
| 37 | else: | 41 | else: |
| 38 | print(f"单用例隔离模式, 仅执行: {_single_case_path}") | 42 | print(f"单用例隔离模式, 仅执行: {_single_case_path}") |
| 39 | locals()["testcase_files"].append(_single_case_path) | 43 | locals()["testcase_files"].append(_single_case_path) |
| 40 | elif os.path.isdir(pt_dir): | 44 | elif os.path.isdir(pt_dir): |
| 41 | - pt_files = [f for f in os.listdir(pt_dir) if f.endswith('.pt')] | 45 | + pt_files = [f for f in os.listdir(pt_dir) if f.endswith(".pt")] |
| 42 | if not pt_files: | 46 | if not pt_files: |
| 43 | print(f"错误: 目录中没有找到.pt文件: {pt_dir}") | 47 | print(f"错误: 目录中没有找到.pt文件: {pt_dir}") |
| 44 | elif batch_test_mode == 1: | 48 | elif batch_test_mode == 1: |
| 45 | df = pd.read_excel(excel_path, sheet_name=excel_sheet) | 49 | df = pd.read_excel(excel_path, sheet_name=excel_sheet) |
| 46 | - target_names = [str(name) for name in df['testcase_name'].dropna().tolist() if str(name) != 'None'] | 50 | + target_names = [ |
| 51 | + str(name) | ||
| 52 | + for name in df["testcase_name"].dropna().tolist() | ||
| 53 | + if str(name) != "None" | ||
| 54 | + ] | ||
| 47 | if not target_names: | 55 | if not target_names: |
| 48 | - print(f"错误: 表格中没有有效的testcase_name: {excel_path} sheet: {excel_sheet}") | 56 | + print( |
| 57 | + f"错误: 表格中没有有效的testcase_name: {excel_path} sheet: {excel_sheet}" | ||
| 58 | + ) | ||
| 49 | else: | 59 | else: |
| 50 | print(f"从表格[{excel_sheet}]中读取到 {len(target_names)} 个目标用例名") | 60 | print(f"从表格[{excel_sheet}]中读取到 {len(target_names)} 个目标用例名") |
| 51 | for target_name in target_names: | 61 | for target_name in target_names: |
| @@ -68,6 +78,7 @@ else: | |||
| 68 | 78 | ||
| 69 | print("files:", locals()["testcase_files"]) | 79 | print("files:", locals()["testcase_files"]) |
| 70 | 80 | ||
| 81 | + | ||
| 71 | 82 | ||
| 72 | 83 | ||
| 73 | def test_sparse_flash_mla(testcase_files): | 84 | def test_sparse_flash_mla(testcase_files): |
| @@ -78,22 +89,26 @@ def test_sparse_flash_mla(testcase_files): | |||
| 78 | try: | 89 | try: |
| 79 | npu_result, softmax_lse = sparse_flash_mla_process.call_npu(test_data) | 90 | npu_result, softmax_lse = sparse_flash_mla_process.call_npu(test_data) |
| 80 | except Exception as e: | 91 | except Exception as e: |
| 81 | - utils.save_result('Exception', 0, test_data['params'], result_path) | 92 | + utils.save_result("Exception", 0, test_data["params"], result_path) |
| 82 | pytest.fail(f"NPU执行异常: {e}") | 93 | pytest.fail(f"NPU执行异常: {e}") |
| 83 | 94 | ||
| 84 | global_failed = False | 95 | global_failed = False |
| 85 | fulfill_percent = 0 | 96 | fulfill_percent = 0 |
| 86 | if npu_result is not None: | 97 | if npu_result is not None: |
| 87 | - result, fulfill_percent = result_compare_method.check_result(test_data['cpu_output'], npu_result) | 98 | + result, fulfill_percent = result_compare_method.check_result( |
| 99 | + test_data["cpu_output"], npu_result | ||
| 100 | + ) | ||
| 88 | if result == "Failed": | 101 | if result == "Failed": |
| 89 | global_failed = True | 102 | global_failed = True |
| 90 | else: | 103 | else: |
| 91 | global_failed = True | 104 | global_failed = True |
| 92 | fulfill_percent = 0 | 105 | fulfill_percent = 0 |
| 93 | 106 | ||
| 94 | - if test_data['params'].get('return_softmax_lse'): | 107 | + if test_data["params"].get("return_softmax_lse"): |
| 95 | print("return_softmax_lse is true!!!") | 108 | print("return_softmax_lse is true!!!") |
| 96 | - lse_result, lse_percent = result_compare_method.check_result(test_data['softmax_lse'], softmax_lse) | 109 | + lse_result, lse_percent = result_compare_method.check_result( |
| 110 | + test_data["softmax_lse"], softmax_lse | ||
| 111 | + ) | ||
| 97 | if lse_result == "Failed": | 112 | if lse_result == "Failed": |
| 98 | global_failed = True | 113 | global_failed = True |
| 99 | fulfill_percent = min(fulfill_percent, lse_percent) | 114 | fulfill_percent = min(fulfill_percent, lse_percent) |
| @@ -103,6 +118,8 @@ def test_sparse_flash_mla(testcase_files): | |||
| 103 | else: | 118 | else: |
| 104 | final_result = "Passed" | 119 | final_result = "Passed" |
| 105 | 120 | ||
| 106 | - utils.save_result(final_result, fulfill_percent, test_data['params'], result_path) | 121 | + utils.save_result(final_result, fulfill_percent, test_data["params"], result_path) |
| 107 | if final_result not in ("Passed", "passed", "Pass", "pass"): | 122 | if final_result not in ("Passed", "passed", "Pass", "pass"): |
| 108 | - pytest.fail(f"用例结果校验失败: result={final_result}, fulfill_percent={fulfill_percent}") | 123 | + pytest.fail( |
| 124 | + f"用例结果校验失败: result={final_result}, fulfill_percent={fulfill_percent}" | ||
| 125 | + ) | ||
| @@ -217,24 +217,24 @@ def save_result( | |||
| 217 | # 检查文件是否存在 | 217 | # 检查文件是否存在 |
| 218 | result_path.parent.mkdir(parents=True, exist_ok=True) | 218 | result_path.parent.mkdir(parents=True, exist_ok=True) |
| 219 | if result_path.exists(): | 219 | if result_path.exists(): |
| 220 | - # 读取现有数据 | ||
| 221 | df = pd.read_excel(result_path) | 220 | df = pd.read_excel(result_path) |
| 222 | - | ||
| 223 | - # 检查列名是否一致 | ||
| 224 | if set(df.columns) != set(row_data.keys()): | 221 | if set(df.columns) != set(row_data.keys()): |
| 225 | - print("警告:变量名与Excel列名不匹配!") | 222 | + print("信息:列名不一致,将自动对齐(缺失填NaN,新增列自动扩展)") |
| 226 | print(f"Excel列名: {list(df.columns)}") | 223 | print(f"Excel列名: {list(df.columns)}") |
| 227 | print(f"变量名: {list(row_data.keys())}") | 224 | print(f"变量名: {list(row_data.keys())}") |
| 228 | - print("请检查变量名或Excel文件") | ||
| 229 | - return False | ||
| 230 | - | ||
| 231 | # 追加新行 | 225 | # 追加新行 |
| 232 | new_df = pd.DataFrame([row_data]) | 226 | new_df = pd.DataFrame([row_data]) |
| 233 | - df = pd.concat([df, new_df], ignore_index=True) | 227 | + df = pd.concat([df, new_df], ignore_index=True, sort=False) |
| 234 | else: | 228 | else: |
| 235 | # 文件不存在,创建新的DataFrame | 229 | # 文件不存在,创建新的DataFrame |
| 236 | df = pd.DataFrame([row_data]) | 230 | df = pd.DataFrame([row_data]) |
| 237 | 231 | ||
| 232 | + # ---------- 新增:固定最后两列 ---------- | ||
| 233 | + # 取出除 result 和 fulfill_percent 外的所有列(保持原有顺序) | ||
| 234 | + other_cols = [col for col in df.columns if col not in ("result", "fulfill_percent")] | ||
| 235 | + # 重新排列:其他列在前,最后两列固定 | ||
| 236 | + df = df[other_cols + ["result", "fulfill_percent"]] | ||
| 237 | + # ------------------------------------- | ||
| 238 | # 保存到Excel | 238 | # 保存到Excel |
| 239 | df.to_excel(result_path, index=False) | 239 | df.to_excel(result_path, index=False) |
| 240 | 240 | ||