已合并
matmul v3 增加vector nz2nd模板 #5356
zhengyuhao3创建于 5月28日
matmul v3 增加vector nz2nd模板 #5356
已合并
共 10 个文件变更+826-419
| @@ -119,10 +119,7 @@ static inline bool CheckMMV3NzNzNdSupport(MmOpInfo& mmOpInfo) | |||
| 119 | ALIGN_UNIT_MAP.find(mmOpInfo.support_info.self_dtype) == ALIGN_UNIT_MAP.end()) { | 119 | ALIGN_UNIT_MAP.find(mmOpInfo.support_info.self_dtype) == ALIGN_UNIT_MAP.end()) { |
| 120 | return false; | 120 | return false; |
| 121 | } | 121 | } |
| 122 | - auto it = ALIGN_UNIT_MAP.find(mmOpInfo.support_info.self_dtype); | 122 | + return op::GetCurrentPlatformInfo().GetCurNpuArch() == NpuArch::DAV_2201; |
| 123 | - uint64_t alignUnit = it->second; | ||
| 124 | - return (op::GetCurrentPlatformInfo().GetCurNpuArch() == NpuArch::DAV_2201) && | ||
| 125 | - (mmOpInfo.shapeInfo.nDim % alignUnit == 0); | ||
| 126 | } | 123 | } |
| 127 | 124 | ||
| 128 | static bool CheckDtypeValid( | 125 | static bool CheckDtypeValid( |
| @@ -631,6 +631,22 @@ void MatmulV3BaseTiling::CalL1Tiling() | |||
| 631 | runInfo_.singleCoreN = runInfo_.baseN; | 631 | runInfo_.singleCoreN = runInfo_.baseN; |
| 632 | return; | 632 | return; |
| 633 | } | 633 | } |
| 634 | +bool MatmulV3BaseTiling::CheckNzNzNdSupport() { | ||
| 635 | + bool isDAV2201 = (compileInfo_.npuArch == NpuArch::DAV_2201); | ||
| 636 | + if (isDAV2201 && | ||
| 637 | + (args_.aFormat == ge::FORMAT_FRACTAL_NZ) && | ||
| 638 | + (args_.bFormat == ge::FORMAT_FRACTAL_NZ) && | ||
| 639 | + (args_.outFormat == ge::FORMAT_ND) && | ||
| 640 | + (args_.nValue % BASIC_ALIGN_256 != 0)) { | ||
| 641 | + return true; | ||
| 642 | + } | ||
| 643 | + return false; | ||
| 644 | +} | ||
| 645 | +void MatmulV3BaseTiling::DoNzNzNdVectorTiling() { | ||
| 646 | + if (CheckNzNzNdSupport()) { | ||
| 647 | + tilingEnable_.tilingEnableFixOpti = TilingEnableFixOpti::VEC_NZ2ND_UNALIGNOUT; | ||
| 648 | + } | ||
| 649 | +} | ||
| 634 | 650 | ||
| 635 | void MatmulV3BaseTiling::DoBasicTiling() | 651 | void MatmulV3BaseTiling::DoBasicTiling() |
| 636 | { | 652 | { |
| @@ -673,6 +689,7 @@ void MatmulV3BaseTiling::DoBasicTiling() | |||
| 673 | DoSelectTiling(); | 689 | DoSelectTiling(); |
| 674 | // add nd2nz tiling here | 690 | // add nd2nz tiling here |
| 675 | DoNd2NzVectorTiling(); | 691 | DoNd2NzVectorTiling(); |
| 692 | + DoNzNzNdVectorTiling(); | ||
| 676 | if (args_.hasBias) { | 693 | if (args_.hasBias) { |
| 677 | runInfo_.baseN = std::min(256UL, runInfo_.baseN); // 有bias时 baseN 小于256 | 694 | runInfo_.baseN = std::min(256UL, runInfo_.baseN); // 有bias时 baseN 小于256 |
| 678 | if (tilingEnable_.tilingEnableSplitCore == TilingEnableSplitCore::BASE && | 695 | if (tilingEnable_.tilingEnableSplitCore == TilingEnableSplitCore::BASE && |
| @@ -2761,6 +2778,18 @@ uint64_t MatmulV3BaseTiling::GetDeterministicSplitKWorkspaceSize(uint64_t aligne | |||
| 2761 | RPC_WORKSIZE * MB_SIZE; | 2778 | RPC_WORKSIZE * MB_SIZE; |
| 2762 | } | 2779 | } |
| 2763 | 2780 | ||
| 2781 | +void MatmulV3BaseTiling::GetVecNz2ndUnAlignedOutWorkspaceSize() | ||
| 2782 | +{ | ||
| 2783 | + if(CheckNzNzNdSupport()) | ||
| 2784 | + { | ||
| 2785 | + workspaceSize_ += tilingData_.matmulTiling.baseN * tilingData_.matmulTiling.baseM * | ||
| 2786 | + tilingData_.matmulTiling.usedCoreNum * NUMBER_TWO * cDtypeSize_; | ||
| 2787 | + }else{ | ||
| 2788 | + workspaceSize_ += ops::CeilAlign(args_.nValue, N_ALIGNED) * tilingData_.matmulTiling.baseM * | ||
| 2789 | + tilingData_.matmulTiling.usedCoreNum * NUMBER_TWO * cDtypeSize_; | ||
| 2790 | + } | ||
| 2791 | +} | ||
| 2792 | + | ||
| 2764 | ge::graphStatus MatmulV3BaseTiling::GetWorkspaceSize() | 2793 | ge::graphStatus MatmulV3BaseTiling::GetWorkspaceSize() |
| 2765 | { | 2794 | { |
| 2766 | uint64_t align256Byte = 256 / aDtypeSize_; // 256B 对齐shape | 2795 | uint64_t align256Byte = 256 / aDtypeSize_; // 256B 对齐shape |
| @@ -2785,9 +2814,9 @@ ge::graphStatus MatmulV3BaseTiling::GetWorkspaceSize() | |||
| 2785 | tilingData_.matmulTiling.usedCoreNum * NUMBER_TWO * cDtypeSize_; | 2814 | tilingData_.matmulTiling.usedCoreNum * NUMBER_TWO * cDtypeSize_; |
| 2786 | } | 2815 | } |
| 2787 | if (tilingEnable_.tilingEnableFixOpti == TilingEnableFixOpti::VEC_NZ2ND_UNALIGNOUT) { | 2816 | if (tilingEnable_.tilingEnableFixOpti == TilingEnableFixOpti::VEC_NZ2ND_UNALIGNOUT) { |
| 2788 | - workspaceSize_ += ops::CeilAlign(args_.nValue, N_ALIGNED) * tilingData_.matmulTiling.baseM * | 2817 | + GetVecNz2ndUnAlignedOutWorkspaceSize(); |
| 2789 | - tilingData_.matmulTiling.usedCoreNum * NUMBER_TWO * cDtypeSize_; | ||
| 2790 | } | 2818 | } |
| 2819 | + | ||
| 2791 | if (!compileInfo_.supportL0c2out) { | 2820 | if (!compileInfo_.supportL0c2out) { |
| 2792 | return ge::GRAPH_SUCCESS; | 2821 | return ge::GRAPH_SUCCESS; |
| 2793 | } | 2822 | } |
| @@ -76,6 +76,7 @@ protected: | |||
| 76 | ge::graphStatus SelectNZTiling(); | 76 | ge::graphStatus SelectNZTiling(); |
| 77 | void DoTilingKey(); | 77 | void DoTilingKey(); |
| 78 | uint64_t GetDeterministicSplitKWorkspaceSize(uint64_t alignedM, uint64_t alignedN); | 78 | uint64_t GetDeterministicSplitKWorkspaceSize(uint64_t alignedM, uint64_t alignedN); |
| 79 | + void GetVecNz2ndUnAlignedOutWorkspaceSize(); | ||
| 79 | void DoBasicTiling(); | 80 | void DoBasicTiling(); |
| 80 | void FormulaicBaseBlockTiling(); | 81 | void FormulaicBaseBlockTiling(); |
| 81 | void FormulaicTilingNoTrans(); | 82 | void FormulaicTilingNoTrans(); |
| @@ -142,6 +143,8 @@ protected: | |||
| 142 | const std::vector<uint64_t> supportNd2nzList) const; | 143 | const std::vector<uint64_t> supportNd2nzList) const; |
| 143 | bool NeedNd2NzVnchw(uint64_t outerSize, uint64_t innerSize, bool supportNd2NzOnTheWay, | 144 | bool NeedNd2NzVnchw(uint64_t outerSize, uint64_t innerSize, bool supportNd2NzOnTheWay, |
| 144 | uint64_t dtypeSize, ge::Format matFormat) const; | 145 | uint64_t dtypeSize, ge::Format matFormat) const; |
| 146 | + bool CheckNzNzNdSupport(); | ||
| 147 | + void DoNzNzNdVectorTiling(); | ||
| 145 | private: | 148 | private: |
| 146 | MatmulTilingData tilingDataSelf_{}; | 149 | MatmulTilingData tilingDataSelf_{}; |
| 147 | protected: | 150 | protected: |
| @@ -0,0 +1,200 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file mat_mul_base_fixpipe_kernel.h | ||
| 13 | + * \brief Intermediate base class for fixpipe-based matmul kernels with AIC+AIV cooperation. | ||
| 14 | + * Extracts common code from MatmulBaseVectorNz2NdKernel and MatmulBaseUnalignedNKernel. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + using namespace AscendC; | ||
| 23 | + using namespace matmul; | ||
| 24 | + | ||
| 25 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock, | ||
| 26 | + const MatmulConfig &MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>> | ||
| 27 | + class MatmulBaseFixPipeKernel : public MatmulBaseKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB> { | ||
| 28 | + public: | ||
| 29 | + using C_T = typename C_TYPE::T; | ||
| 30 | + __aicore__ inline MatmulBaseFixPipeKernel() {} | ||
| 31 | + | ||
| 32 | + __aicore__ inline void AicProcess(GlobalTensor<C_T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, | ||
| 33 | + uint8_t pingPongId); | ||
| 34 | + __aicore__ inline void UpdateOffsetC(bool isNd); | ||
| 35 | + | ||
| 36 | + // AicProcess 的两段公共实现,拆分点即派生类可注入差异(如切换 orgM)的位置: | ||
| 37 | + // - AicLoadAndIterate: 设置 single shape、A/B/bias,执行 Iterate,并按需等待 AIV; | ||
| 38 | + // - AicStoreC: 将结果写出(GetTensorC)并发起 AIC->AIV 同步。 | ||
| 39 | + __aicore__ inline void AicLoadAndIterate(bool aicNeedWaitAiv, uint8_t pingPongId); | ||
| 40 | + __aicore__ inline void AicStoreC(GlobalTensor<C_T>& cTensor, uint8_t enAtomic, uint8_t pingPongId); | ||
| 41 | + | ||
| 42 | + // 计算 AIV 侧 NZ2ND 转换所需的公共块参数,返回 false 表示本核无需处理。 | ||
| 43 | + __aicore__ inline bool PrepareNz2NdConversion(uint8_t pingPongId, LocalTensor<C_T>& tensorNZ, | ||
| 44 | + LocalTensor<C_T>& tensorND, uint64_t& ubProcessMNum, uint64_t& srcGmOffset, uint64_t& dstGmOffset); | ||
| 45 | + | ||
| 46 | + // AIV 侧 NZ2ND 的公共拷入与转换流程。 | ||
| 47 | + __aicore__ inline void Nz2NdCopyAndConvert(GlobalTensor<C_T> cNzGlobal, LocalTensor<C_T> tensorNZ, | ||
| 48 | + LocalTensor<C_T> tensorND, uint64_t ubProcessMNum, uint64_t srcGmOffset, uint8_t pingPongId, | ||
| 49 | + uint64_t gatherNBlocks); | ||
| 50 | + | ||
| 51 | + // 公共的两级 tiling 主调度循环(AIC+AIV 混合)。DERIVED 为派生 kernel 类型, | ||
| 52 | + // 循环内通过 static_cast<DERIVED*> 直接调用派生类的 AicProcess 与 AivStep, | ||
| 53 | + template <class DERIVED> | ||
| 54 | + __aicore__ inline void RunFixpipeTileLoop(uint64_t index, uint8_t enAtomic); | ||
| 55 | + | ||
| 56 | + protected: | ||
| 57 | + GlobalTensor<C_T> tempCGlobal_; | ||
| 58 | + GatherMaskParams params_; | ||
| 59 | + uint64_t baseSize_ = 0UL; | ||
| 60 | + uint64_t alignedN_ = 0UL; | ||
| 61 | + uint64_t c0Size_ = BLOCK_SIZE; | ||
| 62 | + }; | ||
| 63 | + | ||
| 64 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 65 | + class MM_CB> | ||
| 66 | + __aicore__ inline void MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::AicLoadAndIterate( | ||
| 67 | + bool aicNeedWaitAiv, uint8_t pingPongId) | ||
| 68 | + { | ||
| 69 | + this->mm_.SetSingleShape(this->block_.params_.singleCoreM, this->block_.params_.singleCoreN, | ||
| 70 | + this->block_.matmulTilingData_->matmulTiling.singleCoreK); | ||
| 71 | + this->mm_.SetTensorA(this->aGlobal_[this->block_.offset_.offsetA], A_TYPE::isTrans); | ||
| 72 | + this->mm_.SetTensorB(this->bGlobal_[this->block_.offset_.offsetB], B_TYPE::isTrans); | ||
| 73 | + if (this->block_.matmulTilingData_->matmulTiling.isBias) { | ||
| 74 | + this->mm_.SetBias(this->biasGlobal_[this->block_.offset_.offsetBias]); | ||
| 75 | + } | ||
| 76 | + this->mm_.Iterate(); | ||
| 77 | + if (aicNeedWaitAiv) { | ||
| 78 | + CrossCoreWaitFlag(AIC_SYNC_AIV_FLAG + pingPongId); | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 83 | + class MM_CB> | ||
| 84 | + __aicore__ inline void MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::AicStoreC( | ||
| 85 | + GlobalTensor<C_T>& cTensor, uint8_t enAtomic, uint8_t pingPongId) | ||
| 86 | + { | ||
| 87 | + this->mm_.GetTensorC(cTensor, enAtomic); | ||
| 88 | + | ||
| 89 | + CrossCoreSetFlag<0x2, PIPE_FIX>(AIV_SYNC_AIC_FLAG + pingPongId); | ||
| 90 | + | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 94 | + class MM_CB> | ||
| 95 | + __aicore__ inline void MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::AicProcess( | ||
| 96 | + GlobalTensor<typename C_TYPE::T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, uint8_t pingPongId) | ||
| 97 | + { | ||
| 98 | + if ASCEND_IS_AIC { | ||
| 99 | + this->AicLoadAndIterate(aicNeedWaitAiv, pingPongId); | ||
| 100 | + this->AicStoreC(cTensor, enAtomic, pingPongId); | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 105 | + class MM_CB> | ||
| 106 | + __aicore__ inline void MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::UpdateOffsetC( | ||
| 107 | + bool isNd) | ||
| 108 | + { | ||
| 109 | + Nz2NdUpdateOffsetC(this->block_.params_, this->block_.offset_, this->block_.matmulTilingData_, isNd); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 113 | + class MM_CB> | ||
| 114 | + __aicore__ inline bool MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, | ||
| 115 | + MM_CB>::PrepareNz2NdConversion(uint8_t pingPongId, LocalTensor<C_T>& tensorNZ, LocalTensor<C_T>& tensorND, | ||
| 116 | + uint64_t& ubProcessMNum, uint64_t& srcGmOffset, uint64_t& dstGmOffset) | ||
| 117 | + { | ||
| 118 | + uint32_t vBlockIndex = GetBlockIdx(); | ||
| 119 | + if (vBlockIndex >= (this->block_.matmulTilingData_->matmulTiling.usedCoreNum * NUM_TWO)) { | ||
| 120 | + return false; | ||
| 121 | + } | ||
| 122 | + CrossCoreWaitFlag(AIV_SYNC_AIC_FLAG + pingPongId); | ||
| 123 | + LocalTensor<C_T> ubTensor = this->ubBuf_.template Get<C_T>(); | ||
| 124 | + uint64_t cDtypeSize = sizeof(C_T); | ||
| 125 | + ubProcessMNum = min(MMV3CeilAlign(this->block_.params_.singleCoreM / NUM_TWO, this->c0Size_), | ||
| 126 | + static_cast<uint64_t>(this->block_.params_.singleCoreM)); | ||
| 127 | + int64_t subIdx = GetSubBlockIdx(); | ||
| 128 | + srcGmOffset = 0UL; | ||
| 129 | + dstGmOffset = 0UL; | ||
| 130 | + if (subIdx == 1) { | ||
| 131 | + srcGmOffset = ubProcessMNum * ALIGNED_H; | ||
| 132 | + dstGmOffset = ubProcessMNum * this->block_.matmulTilingData_->matmulTiling.N; | ||
| 133 | + ubProcessMNum = this->block_.params_.singleCoreM - ubProcessMNum; | ||
| 134 | + } | ||
| 135 | + uint64_t ndOffset = (TOTAL_UB_SIZE >> 2) / cDtypeSize; | ||
| 136 | + uint64_t pingpongOffset = (TOTAL_UB_SIZE >> 1) / cDtypeSize; | ||
| 137 | + tensorNZ = ubTensor[pingPongId * pingpongOffset]; | ||
| 138 | + tensorND = ubTensor[pingPongId * pingpongOffset + ndOffset]; | ||
| 139 | + return true; | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 143 | + class MM_CB> | ||
| 144 | + __aicore__ inline void MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, | ||
| 145 | + MM_CB>::Nz2NdCopyAndConvert(GlobalTensor<C_T> cNzGlobal, LocalTensor<C_T> tensorNZ, LocalTensor<C_T> tensorND, | ||
| 146 | + uint64_t ubProcessMNum, uint64_t srcGmOffset, uint8_t pingPongId, uint64_t gatherNBlocks) | ||
| 147 | + { | ||
| 148 | + Nz2NdCopyInWithNz<C_T>(tensorNZ, cNzGlobal[srcGmOffset], ubProcessMNum, pingPongId, | ||
| 149 | + this->alignedN_, this->block_.matmulTilingData_->matmulTiling.baseM); | ||
| 150 | + CrossCoreSetFlag<0x2, PIPE_MTE2>(AIC_SYNC_AIV_FLAG + pingPongId); | ||
| 151 | + Nz2NdMulsAndGatherMask<C_T>(tensorND, tensorNZ, ubProcessMNum, pingPongId, | ||
| 152 | + this->alignedN_, this->c0Size_, gatherNBlocks, this->params_); | ||
| 153 | + this->UpdateOffsetC(true); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 157 | + class MM_CB> | ||
| 158 | + template <class DERIVED> | ||
| 159 | + __aicore__ inline void MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, | ||
| 160 | + MM_CB>::RunFixpipeTileLoop(uint64_t index, uint8_t enAtomic) | ||
| 161 | + { | ||
| 162 | + int8_t pingPongId = 0; | ||
| 163 | + bool aicNeedWaitAiv = false; | ||
| 164 | + bool reverse = true; | ||
| 165 | + GlobalTensor<C_T> tempCGlobal = this->tempCGlobal_; | ||
| 166 | + for (uint64_t mTileIndex = 0; mTileIndex < this->block_.params_.mTileCntL2; mTileIndex++) { | ||
| 167 | + reverse = !reverse; | ||
| 168 | + for (uint64_t nTileIndexTemp = 0; nTileIndexTemp < this->block_.params_.nTileCntL2; nTileIndexTemp++) { | ||
| 169 | + uint64_t nTileIndex = reverse ? (this->block_.params_.nTileCntL2 - nTileIndexTemp - 1) : nTileIndexTemp; | ||
| 170 | + this->block_.UpdateBlockCnt(mTileIndex, nTileIndex); | ||
| 171 | + this->block_.InitBlockIndex(index); | ||
| 172 | + SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG)); | ||
| 173 | + SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + 1)); | ||
| 174 | + for (uint64_t j = 0; j < this->block_.params_.realRound; j++) { | ||
| 175 | + tempCGlobal = this->tempCGlobal_[this->baseSize_ * (GetCurrentBlockIdx() * 2 + pingPongId)]; | ||
| 176 | + if (this->block_.params_.rowOrder == 0) { | ||
| 177 | + this->block_.UpdateBasicIndex(j); | ||
| 178 | + } | ||
| 179 | + if (this->block_.params_.index < this->block_.params_.totalTileCnt) { | ||
| 180 | + this->block_.UpdateBlockParams(mTileIndex, nTileIndex); | ||
| 181 | + this->block_.template CalcGMOffset<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(mTileIndex, nTileIndex); | ||
| 182 | + static_cast<DERIVED*>(this)->AicProcess(tempCGlobal, enAtomic, aicNeedWaitAiv, pingPongId); | ||
| 183 | + static_cast<DERIVED*>(this)->AivStep(tempCGlobal, pingPongId); | ||
| 184 | + aicNeedWaitAiv = aicNeedWaitAiv || bool(pingPongId); | ||
| 185 | + pingPongId = (pingPongId + 1) & 1; | ||
| 186 | + } | ||
| 187 | + this->block_.UpdateBlockIndex(); | ||
| 188 | + } | ||
| 189 | + WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG)); | ||
| 190 | + WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + 1)); | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + if (this->block_.params_.isHf32) { | ||
| 194 | + this->mm_.SetHF32(false, 0); | ||
| 195 | + } | ||
| 196 | + PipeBarrier<PIPE_ALL>(); | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + | ||
| 200 | + | ||
| @@ -0,0 +1,173 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/* ! | ||
| 12 | + * \file mat_mul_base_vector_nz2nd_kernel.h | ||
| 13 | + * \brief Matmul kernel with AIV-based NZ2ND conversion for half/bfloat16 output | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + using namespace AscendC; | ||
| 21 | + using namespace matmul; | ||
| 22 | + | ||
| 23 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock, | ||
| 24 | + const MatmulConfig &MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>> | ||
| 25 | + class MatmulBaseVectorNz2NdKernel | ||
| 26 | + : public MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB> { | ||
| 27 | + public: | ||
| 28 | + using C_T = typename C_TYPE::T; | ||
| 29 | + __aicore__ inline MatmulBaseVectorNz2NdKernel() {} | ||
| 30 | + | ||
| 31 | + __aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, | ||
| 32 | + GM_ADDR workspaceGM, const void *tilingData, TPipe *pipe); | ||
| 33 | + | ||
| 34 | + __aicore__ inline void AivNz2NdProcess(GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId); | ||
| 35 | + | ||
| 36 | + // 读 A 与写 C 的 orgM 取值不同,需在 Iterate 与 GetTensorC 之间切换 orgM。 | ||
| 37 | + __aicore__ inline void AicProcess(GlobalTensor<C_T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, | ||
| 38 | + uint8_t pingPongId); | ||
| 39 | + | ||
| 40 | + // 供基类 RunFixpipeTileLoop 回调的每块 AIV 处理步骤。 | ||
| 41 | + __aicore__ inline void AivStep(GlobalTensor<C_T>& cTensor, uint8_t pingPongId) | ||
| 42 | + { | ||
| 43 | + AivNz2NdProcess(cTensor, pingPongId); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + __aicore__ inline void UpdateGlobalTensor(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, | ||
| 47 | + GM_ADDR workspaceGM); | ||
| 48 | + | ||
| 49 | + __aicore__ inline void Process(uint64_t index = 0, uint8_t enAtomic = 0); | ||
| 50 | + }; | ||
| 51 | + | ||
| 52 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 53 | + class MM_CB> | ||
| 54 | + __aicore__ inline void MatmulBaseVectorNz2NdKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::Init( | ||
| 55 | + GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, | ||
| 56 | + GM_ADDR workspaceGM, const void *tilingData, TPipe *pipe) | ||
| 57 | + { | ||
| 58 | + GetSizeC0<C_T>(this->c0Size_); | ||
| 59 | + this->block_.template Init<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(tilingData); | ||
| 60 | + this->pipe_ = pipe; | ||
| 61 | + this->InitInputs(aGM, bGM, cGM, biasGM); | ||
| 62 | + | ||
| 63 | + this->pipe_->InitBuffer(this->ubBuf_, TOTAL_UB_SIZE); | ||
| 64 | + | ||
| 65 | + int64_t originShapeM = this->block_.matmulTilingData_->matmulTiling.baseM; | ||
| 66 | + | ||
| 67 | + this->baseSize_ = this->block_.matmulTilingData_->matmulTiling.baseN * | ||
| 68 | + this->block_.matmulTilingData_->matmulTiling.baseM; | ||
| 69 | + | ||
| 70 | + this->tempCGlobal_.SetGlobalBuffer(reinterpret_cast<__gm__ C_T*>(workspaceGM), | ||
| 71 | + this->baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum); | ||
| 72 | + this->mm_.SetSubBlockIdx(0); | ||
| 73 | + this->mm_.Init(&this->block_.matmulTilingData_->matmulTiling, pipe); | ||
| 74 | + this->mm_.SetUserDefInfo(reinterpret_cast<uint64_t>(tilingData)); | ||
| 75 | + | ||
| 76 | + this->mm_.SetOrgShape(this->block_.params_.alignedOriM, this->block_.params_.alignedOriN, | ||
| 77 | + this->block_.params_.alignedKaSize, this->block_.params_.alignedKbSize, | ||
| 78 | + AlignUp(this->block_.matmulTilingData_->matmulTiling.N, BLOCK_SIZE)); | ||
| 79 | + | ||
| 80 | + if (this->block_.params_.isHf32) { | ||
| 81 | + this->mm_.SetHF32(true, 1); | ||
| 82 | + } else { | ||
| 83 | + this->mm_.SetHF32(false, 0); | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + | ||
| 88 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 89 | + class MM_CB> | ||
| 90 | + __aicore__ inline void MatmulBaseVectorNz2NdKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::AicProcess( | ||
| 91 | + GlobalTensor<C_T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, uint8_t pingPongId) | ||
| 92 | + { | ||
| 93 | + if ASCEND_IS_AIC { | ||
| 94 | + // 读 A 阶段:A 为整块 FRACTAL_NZ,沿 K 方向跨步使用 orgM,需用 alignedOriM | ||
| 95 | + this->mm_.SetOrgShape(this->block_.params_.alignedOriM, this->block_.params_.alignedOriN, | ||
| 96 | + this->block_.params_.alignedKaSize, this->block_.params_.alignedKbSize, | ||
| 97 | + AlignUp(this->block_.matmulTilingData_->matmulTiling.N, BLOCK_SIZE)); | ||
| 98 | + this->AicLoadAndIterate(aicNeedWaitAiv, pingPongId); | ||
| 99 | + // 写 C 阶段:C 写入每个 base 块独立的 NZ workspace,N 分形跨步使用 orgM,需用 baseM | ||
| 100 | + this->mm_.SetOrgShape(this->block_.matmulTilingData_->matmulTiling.baseM, this->block_.params_.alignedOriN, | ||
| 101 | + this->block_.params_.alignedKaSize, this->block_.params_.alignedKbSize, | ||
| 102 | + AlignUp(this->block_.params_.singleCoreN, BLOCK_SIZE)); | ||
| 103 | + this->AicStoreC(cTensor, enAtomic, pingPongId); | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + | ||
| 108 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 109 | + class MM_CB> | ||
| 110 | + __aicore__ inline void MatmulBaseVectorNz2NdKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::AivNz2NdProcess( | ||
| 111 | + GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId) | ||
| 112 | + { | ||
| 113 | + if ASCEND_IS_AIV { | ||
| 114 | + uint64_t nBlocks = this->block_.params_.singleCoreN; | ||
| 115 | + this->alignedN_ = AlignUp(nBlocks, BLOCK_SIZE); | ||
| 116 | + | ||
| 117 | + LocalTensor<C_T> tensorNZ; | ||
| 118 | + LocalTensor<C_T> tensorND; | ||
| 119 | + uint64_t ubProcessMNum = 0UL; | ||
| 120 | + uint64_t srcGmOffset = 0UL; | ||
| 121 | + uint64_t dstGmOffset = 0UL; | ||
| 122 | + if (!this->PrepareNz2NdConversion(pingPongId, tensorNZ, tensorND, ubProcessMNum, srcGmOffset, dstGmOffset)) { | ||
| 123 | + return; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + if (ubProcessMNum == 0UL) { | ||
| 127 | + //补充同步信号 | ||
| 128 | + WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); | ||
| 129 | + CrossCoreSetFlag<0x2, PIPE_MTE2>(AIC_SYNC_AIV_FLAG + pingPongId); | ||
| 130 | + SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); | ||
| 131 | + return; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); | ||
| 135 | + if (std::is_same_v<C_T, bfloat16_t> || std::is_same_v<C_T, half>) { | ||
| 136 | + this->Nz2NdCopyAndConvert(cNzGlobal, tensorNZ, tensorND, ubProcessMNum, srcGmOffset, pingPongId, | ||
| 137 | + this->alignedN_); | ||
| 138 | + | ||
| 139 | + DataCopyExtParams dataCopyExtParams; | ||
| 140 | + dataCopyExtParams.blockCount = ubProcessMNum; | ||
| 141 | + dataCopyExtParams.blockLen = static_cast<uint32_t>(nBlocks * sizeof(C_T)); | ||
| 142 | + dataCopyExtParams.srcStride = 0; | ||
| 143 | + dataCopyExtParams.dstStride = static_cast<uint32_t>((this->block_.matmulTilingData_->matmulTiling.N - nBlocks) * sizeof(C_T)); | ||
| 144 | + dataCopyExtParams.rsv = 0; | ||
| 145 | + DataCopyPad(this->cGlobal_[this->block_.offset_.offsetC + dstGmOffset], tensorND, dataCopyExtParams); | ||
| 146 | + } else { | ||
| 147 | + CrossCoreSetFlag<0x2, PIPE_MTE2>(AIC_SYNC_AIV_FLAG + pingPongId); | ||
| 148 | + } | ||
| 149 | + SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + | ||
| 154 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 155 | + class MM_CB> | ||
| 156 | + __aicore__ inline void MatmulBaseVectorNz2NdKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, | ||
| 157 | + MM_CB>::UpdateGlobalTensor(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, | ||
| 158 | + GM_ADDR workspaceGM) | ||
| 159 | + { | ||
| 160 | + this->InitInputs(aGM, bGM, cGM, biasGM); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + | ||
| 164 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig &MM_CFG, | ||
| 165 | + class MM_CB> | ||
| 166 | + __aicore__ inline void MatmulBaseVectorNz2NdKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::Process( | ||
| 167 | + uint64_t index, uint8_t enAtomic) | ||
| 168 | + { | ||
| 169 | + this->template RunFixpipeTileLoop< | ||
| 170 | + MatmulBaseVectorNz2NdKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>>(index, enAtomic); | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + | ||
| @@ -0,0 +1,28 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file mat_mul_nz2nd.h | ||
| 13 | + * \brief NZ2ND process utilities for AIV-based NZ to ND format conversion. | ||
| 14 | + * Provides low-level utility functions that can be reused by different kernel templates. | ||
| 15 | + * Refer to mat_mul_nd2nz.h for the ND2NZ counterpart pattern. | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +using namespace AscendC; | ||
| 24 | +using namespace matmul; | ||
| 25 | + | ||
| 26 | +const uint8_t AIV_DB_SYNC_FLAG = 0x2; | ||
| 27 | + | ||
| 28 | + | ||
| @@ -0,0 +1,122 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file mat_mul_nz2nd_util.h | ||
| 13 | + * \brief NZ2ND utility functions for vector-based NZ to ND format conversion | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +using namespace AscendC; | ||
| 22 | +using namespace matmul; | ||
| 23 | + | ||
| 24 | +__aicore__ inline void Nz2NdUpdateOffsetC(BaseBlockArgs& params, BlockOffset& offset, | ||
| 25 | + const MatmulTilingData* tilingData, bool isNd) | ||
| 26 | +{ | ||
| 27 | + uint64_t mCntIndex = params.index / params.nCntUse; | ||
| 28 | + uint64_t nCntIndex = params.index % params.nCntUse; | ||
| 29 | + if (isNd) { | ||
| 30 | + offset.offsetC = | ||
| 31 | + (nCntIndex * tilingData->matmulTiling.singleCoreN + | ||
| 32 | + mCntIndex * tilingData->matmulTiling.singleCoreM * | ||
| 33 | + tilingData->matmulTiling.N + | ||
| 34 | + (params.mTileAddrOffset * tilingData->matmulTiling.N + | ||
| 35 | + params.nTileAddrOffset)); | ||
| 36 | + } else { | ||
| 37 | + offset.offsetC = | ||
| 38 | + (nCntIndex * tilingData->matmulTiling.singleCoreN * | ||
| 39 | + tilingData->matmulTiling.M + | ||
| 40 | + mCntIndex * tilingData->matmulTiling.singleCoreM * BLOCK_SIZE + | ||
| 41 | + (params.mTileAddrOffset * BLOCK_SIZE + | ||
| 42 | + params.nTileAddrOffset * tilingData->matmulTiling.M)); | ||
| 43 | + } | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +template <class C_T> | ||
| 47 | +__aicore__ inline void Nz2NdCopyInWithNz(LocalTensor<C_T> tensorNZ, GlobalTensor<C_T> cNzGlobal, | ||
| 48 | + uint64_t ubProcessM, uint8_t pingPongId, uint64_t alignedN, uint64_t baseM) | ||
| 49 | +{ | ||
| 50 | + size_t NfractualNum = alignedN / BLOCK_SIZE; | ||
| 51 | + DataCopyParams copyParams; | ||
| 52 | + copyParams.blockCount = NfractualNum; | ||
| 53 | + if constexpr (std::is_same_v<C_T, float>) { | ||
| 54 | + copyParams.blockLen = ubProcessM * NUM_TWO; | ||
| 55 | + copyParams.srcStride = (baseM - ubProcessM) * NUM_TWO; | ||
| 56 | + } else { | ||
| 57 | + copyParams.blockLen = ubProcessM; | ||
| 58 | + copyParams.srcStride = baseM - ubProcessM; | ||
| 59 | + } | ||
| 60 | + copyParams.dstStride = 0; | ||
| 61 | + DataCopy(tensorNZ, cNzGlobal, copyParams); | ||
| 62 | + SetFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); | ||
| 63 | + WaitFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +template <class C_T> | ||
| 67 | +__aicore__ inline void Nz2NdMulsAndGatherMask(LocalTensor<C_T> tensorND, LocalTensor<C_T> tensorNZ, | ||
| 68 | + uint64_t ubProcessM, uint8_t pingPongId, uint64_t alignedN, uint64_t c0Size, | ||
| 69 | + uint64_t nBlocks, GatherMaskParams& params) | ||
| 70 | +{ | ||
| 71 | + size_t NfractalNum = alignedN / BLOCK_SIZE; | ||
| 72 | + uint8_t repeatTimes = MMV3DivCeil(ubProcessM, 8); | ||
| 73 | + uint64_t mask[2] = {UINT64_MAX, UINT64_MAX}; | ||
| 74 | + UnaryRepeatParams mulsRepeatParams; | ||
| 75 | + | ||
| 76 | + if constexpr (std::is_same_v<C_T, float>) { | ||
| 77 | + mulsRepeatParams.srcBlkStride = 2; | ||
| 78 | + mulsRepeatParams.dstBlkStride = alignedN / c0Size; | ||
| 79 | + mulsRepeatParams.dstRepStride = alignedN; | ||
| 80 | + mulsRepeatParams.srcRepStride = 16; | ||
| 81 | + for (size_t inLoop = 0; inLoop < NfractalNum; inLoop++) { | ||
| 82 | + Muls(tensorND[inLoop * BLOCK_SIZE], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE], static_cast<C_T>(1.0), mask, | ||
| 83 | + repeatTimes, mulsRepeatParams); | ||
| 84 | + Muls(tensorND[inLoop * BLOCK_SIZE + c0Size], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE + c0Size], | ||
| 85 | + static_cast<C_T>(1.0), mask, repeatTimes, mulsRepeatParams); | ||
| 86 | + } | ||
| 87 | + } else if constexpr (std::is_same_v<C_T, half>) { | ||
| 88 | + mulsRepeatParams.srcBlkStride = 1; | ||
| 89 | + mulsRepeatParams.dstBlkStride = alignedN / c0Size; | ||
| 90 | + mulsRepeatParams.dstRepStride = alignedN / NUM_TWO; | ||
| 91 | + mulsRepeatParams.srcRepStride = 8; | ||
| 92 | + for (size_t inLoop = 0; inLoop < NfractalNum; inLoop++) { | ||
| 93 | + Muls(tensorND[inLoop * BLOCK_SIZE], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE], static_cast<half>(1.0), mask, | ||
| 94 | + repeatTimes, mulsRepeatParams); | ||
| 95 | + } | ||
| 96 | + } else if constexpr (std::is_same_v<C_T, bfloat16_t>) { | ||
| 97 | + mulsRepeatParams.srcBlkStride = 1; | ||
| 98 | + mulsRepeatParams.dstBlkStride = alignedN / c0Size; | ||
| 99 | + mulsRepeatParams.dstRepStride = alignedN / NUM_TWO; | ||
| 100 | + mulsRepeatParams.srcRepStride = 8; | ||
| 101 | + LocalTensor<half> tensorNDInterpretCast = tensorND.template ReinterpretCast<half>(); | ||
| 102 | + LocalTensor<half> tensorNZInterpretCast = tensorNZ.template ReinterpretCast<half>(); | ||
| 103 | + for (size_t inLoop = 0; inLoop < NfractalNum; inLoop++) { | ||
| 104 | + Muls(tensorNDInterpretCast[inLoop * BLOCK_SIZE], tensorNZInterpretCast[inLoop * ubProcessM * BLOCK_SIZE], | ||
| 105 | + static_cast<half>(1.0), mask, repeatTimes, mulsRepeatParams); | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + PipeBarrier<PIPE_V>(); | ||
| 110 | + | ||
| 111 | + uint64_t rsvdCnt = 0; | ||
| 112 | + params.src0BlockStride = 1; | ||
| 113 | + params.src0RepeatStride = alignedN / c0Size; | ||
| 114 | + params.src1RepeatStride = 0; | ||
| 115 | + params.repeatTimes = ubProcessM; | ||
| 116 | + GatherMask(tensorND, tensorND, 7, true, nBlocks, params, rsvdCnt); | ||
| 117 | + | ||
| 118 | + SetFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); | ||
| 119 | + WaitFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | + | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | * Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -10,415 +10,253 @@ | |||
| 10 | 10 | ||
| 11 | /*! | 11 | /*! |
| 12 | * \file mat_mul_optimized_fixpipe_algorithm.h | 12 | * \file mat_mul_optimized_fixpipe_algorithm.h |
| 13 | - * \brief | 13 | + * \brief Optimized fixpipe algorithm kernels with AIC+AIV cooperation. |
| 14 | + * MatmulBaseUnalignedNKernel inherits from MatmulBaseFixPipeKernel for shared AIC processing | ||
| 15 | + * and NZ2ND utilities. Supports both aligned output (AivProcess) and NZ2ND unaligned output | ||
| 16 | + * (AivNz2NdProcess) via FIXPIPE_OPT template parameter. | ||
| 14 | */ | 17 | */ |
| 15 | -#ifndef __OP_KERNEL_MATMUL_V3_OPTIMIZED_FIXPIPE_ALGORITHM_H__ | 18 | + #ifndef __OP_KERNEL_MATMUL_V3_OPTIMIZED_FIXPIPE_ALGORITHM_H__ |
| 16 | -#define __OP_KERNEL_MATMUL_V3_OPTIMIZED_FIXPIPE_ALGORITHM_H__ | 19 | + #define __OP_KERNEL_MATMUL_V3_OPTIMIZED_FIXPIPE_ALGORITHM_H__ |
| 17 | - | 20 | + |
| 18 | -#include "mat_mul_base_block.h" | 21 | + #include "mat_mul_base_fixpipe_kernel.h" |
| 19 | -#include "mat_mul_base_kernel.h" | 22 | + #include "mat_mul_l1_full_load.h" |
| 20 | -#include "mat_mul_l1_full_load.h" | 23 | + |
| 21 | - | 24 | + using namespace AscendC; |
| 22 | -using namespace AscendC; | 25 | + using namespace matmul; |
| 23 | -using namespace matmul; | 26 | + using namespace MatmulV3; |
| 24 | -using namespace MatmulV3; | 27 | + |
| 25 | - | 28 | + #if defined(__CCE_KT_TEST__) |
| 26 | -#if defined(__CCE_KT_TEST__) | 29 | + using namespace std; |
| 27 | -using namespace std; | 30 | + #endif |
| 28 | -#endif | 31 | + |
| 29 | -// 512 byte | 32 | + const uint32_t MM_ALIGN_SIZE = 512; |
| 30 | -const uint32_t MM_ALIGN_SIZE = 512; | 33 | + |
| 31 | -const uint8_t AIV_DB_SYNC_FLAG = 0x2; | 34 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock, |
| 32 | - | 35 | + const MatmulConfig& MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>, |
| 33 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock, | 36 | + FIXPIPE_OPT_SELECT FIXPIPE_OPT = FIXPIPE_OPT_SELECT::BASE_ENABLE_ALIGNOUT> |
| 34 | - const MatmulConfig& MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>, | 37 | + class MatmulBaseUnalignedNKernel : public MatmulBaseFixPipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, |
| 35 | - FIXPIPE_OPT_SELECT FIXPIPE_OPT = FIXPIPE_OPT_SELECT::BASE_ENABLE_ALIGNOUT> | 38 | + BLOCK_TYPE, MM_CFG, MM_CB> { |
| 36 | -class MatmulBaseUnalignedNKernel : public MatmulBaseKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, | 39 | + public: |
| 37 | - BLOCK_TYPE, MM_CFG, MM_CB> { | 40 | + using C_T = typename C_TYPE::T; |
| 38 | -public: | 41 | + __aicore__ inline MatmulBaseUnalignedNKernel() {} |
| 39 | - using C_T = typename C_TYPE::T; | 42 | + __aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, |
| 40 | - __aicore__ inline MatmulBaseUnalignedNKernel() {} | 43 | + GM_ADDR workspaceGM, const void* tilingData, TPipe* pipe); |
| 41 | - __aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, | 44 | + __aicore__ inline void AivProcess(GlobalTensor<C_T>& cTensor, uint8_t pingPongId); |
| 42 | - GM_ADDR workspaceGM, const void* tilingData, TPipe* pipe); | 45 | + __aicore__ inline void Process(uint64_t index = 0UL, uint8_t enAtomic = 0UL); |
| 43 | - __aicore__ inline void AicProcess(GlobalTensor<C_T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, | 46 | + __aicore__ inline void AivNz2NdProcess(GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId); |
| 44 | - uint8_t pingPongId); | 47 | + |
| 45 | - __aicore__ inline void AivProcess(GlobalTensor<C_T>& cTensor, uint8_t pingPongId); | 48 | + // 供基类 RunFixpipeTileLoop 回调的每块 AIV 处理步骤:按 FIXPIPE_OPT 选择 NZ2ND 或对齐输出路径。 |
| 46 | - __aicore__ inline void Process(uint64_t index = 0UL, uint8_t enAtomic = 0UL); | 49 | + __aicore__ inline void AivStep(GlobalTensor<C_T>& cTensor, uint8_t pingPongId) |
| 47 | - __aicore__ inline void AivNz2NdProcess(GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId); | 50 | + { |
| 48 | - __aicore__ inline void CopyInWithNz(LocalTensor<C_T> tensorNZ, GlobalTensor<C_T> cNzGlobal, uint64_t ubProcessM, | 51 | + if constexpr (FIXPIPE_OPT == FIXPIPE_OPT_SELECT::VEC_NZ2ND_UNALIGNOUT) { |
| 49 | - uint8_t pingPongId); | 52 | + AivNz2NdProcess(cTensor, pingPongId); |
| 50 | - __aicore__ inline void Nz2NdAndGatherMask(LocalTensor<C_T> tensorND, LocalTensor<C_T> tensorNZ, uint64_t ubProcessM, | 53 | + } else { |
| 51 | - uint8_t pingPongId); | 54 | + AivProcess(cTensor, pingPongId); |
| 52 | - __aicore__ inline void UpdateOffsetC(bool isNd); | 55 | + } |
| 53 | - | 56 | + } |
| 54 | -protected: | 57 | + }; |
| 55 | - GlobalTensor<C_T> tempCGlobal_; | 58 | + |
| 56 | - GatherMaskParams params_; | 59 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, |
| 57 | - uint64_t baseSize_ = 0UL; | 60 | + class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> |
| 58 | - uint64_t alignedN_ = 0UL; | 61 | + __aicore__ inline void |
| 59 | - uint64_t c0Size_ = BLOCK_SIZE; | 62 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init( |
| 60 | -}; | 63 | + GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, GM_ADDR workspaceGM, |
| 61 | - | 64 | + const void* tilingData, TPipe* pipe) |
| 62 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 65 | + { |
| 63 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 66 | + GetSizeC0<C_T>(this->c0Size_); |
| 64 | -__aicore__ inline void | 67 | + uint64_t cDtypeSize = sizeof(C_T); |
| 65 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init( | 68 | + this->block_.template Init<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(tilingData); |
| 66 | - GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, GM_ADDR workspaceGM, | 69 | + this->InitInputs(aGM, bGM, cGM, biasGM); |
| 67 | - const void* tilingData, TPipe* pipe) | 70 | + |
| 68 | -{ | 71 | + this->pipe_ = pipe; |
| 69 | - GetSizeC0<C_T>(c0Size_); | 72 | + this->pipe_->InitBuffer(this->ubBuf_, TOTAL_UB_SIZE); |
| 70 | - uint64_t cDtypeSize = sizeof(C_T); | 73 | + |
| 71 | - this->block_.template Init<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(tilingData); | 74 | + int64_t originShapeM = 0; |
| 72 | - this->InitInputs(aGM, bGM, cGM, biasGM); | 75 | + if constexpr (FIXPIPE_OPT == FIXPIPE_OPT_SELECT::VEC_NZ2ND_UNALIGNOUT) { |
| 73 | - | 76 | + this->alignedN_ = AlignUp(this->block_.matmulTilingData_->matmulTiling.N, BLOCK_SIZE); |
| 74 | - this->pipe_ = pipe; | 77 | + originShapeM = this->block_.matmulTilingData_->matmulTiling.baseM; |
| 75 | - this->pipe_->InitBuffer(this->ubBuf_, TOTAL_UB_SIZE); | 78 | + } else { |
| 76 | - | 79 | + this->alignedN_ = AlignUp(this->block_.matmulTilingData_->matmulTiling.N, MM_ALIGN_SIZE / cDtypeSize); |
| 77 | - int64_t originShapeM = 0; | 80 | + originShapeM = this->block_.matmulTilingData_->matmulTiling.M; |
| 78 | - if constexpr (FIXPIPE_OPT == FIXPIPE_OPT_SELECT::VEC_NZ2ND_UNALIGNOUT) { | 81 | + } |
| 79 | - alignedN_ = AlignUp(this->block_.matmulTilingData_->matmulTiling.N, BLOCK_SIZE); | 82 | + this->baseSize_ = this->alignedN_ * this->block_.matmulTilingData_->matmulTiling.baseM; |
| 80 | - // for MatMul highlevel API copyout NZ format consecutively | 83 | + this->params_.src0BlockStride = 1; |
| 81 | - originShapeM = this->block_.matmulTilingData_->matmulTiling.baseM; | 84 | + this->params_.src0RepeatStride = this->alignedN_ / this->c0Size_; |
| 82 | - } else { | 85 | + this->params_.src1RepeatStride = 0; |
| 83 | - alignedN_ = AlignUp(this->block_.matmulTilingData_->matmulTiling.N, MM_ALIGN_SIZE / cDtypeSize); | 86 | + |
| 84 | - originShapeM = this->block_.matmulTilingData_->matmulTiling.M; | 87 | + this->tempCGlobal_.SetGlobalBuffer(reinterpret_cast<__gm__ C_T*>(workspaceGM), |
| 85 | - } | 88 | + this->baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum); |
| 86 | - baseSize_ = alignedN_ * this->block_.matmulTilingData_->matmulTiling.baseM; | 89 | + this->mm_.SetSubBlockIdx(0); |
| 87 | - params_.src0BlockStride = 1; | 90 | + this->mm_.Init(&this->block_.matmulTilingData_->matmulTiling, pipe); |
| 88 | - params_.src0RepeatStride = alignedN_ / c0Size_; | 91 | + this->mm_.SetUserDefInfo(reinterpret_cast<uint64_t>(tilingData)); |
| 89 | - params_.src1RepeatStride = 0; | 92 | + this->mm_.SetOrgShape(originShapeM, this->block_.params_.alignedOriN, |
| 90 | - | 93 | + this->block_.matmulTilingData_->matmulTiling.singleCoreK, this->block_.params_.alignedKbSize, |
| 91 | - tempCGlobal_.SetGlobalBuffer(reinterpret_cast<__gm__ C_T*>(workspaceGM), | 94 | + this->alignedN_); |
| 92 | - baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum); | 95 | + if (this->block_.params_.isHf32) { |
| 93 | - this->mm_.SetSubBlockIdx(0); | 96 | + this->mm_.SetHF32(true, 1); |
| 94 | - this->mm_.Init(&this->block_.matmulTilingData_->matmulTiling, pipe); | 97 | + } else { |
| 95 | - this->mm_.SetUserDefInfo(reinterpret_cast<uint64_t>(tilingData)); | 98 | + this->mm_.SetHF32(false, 0); |
| 96 | - this->mm_.SetOrgShape(originShapeM, this->block_.params_.alignedOriN, | 99 | + } |
| 97 | - this->block_.matmulTilingData_->matmulTiling.singleCoreK, this->block_.params_.alignedKbSize, | 100 | + } |
| 98 | - this->alignedN_); | 101 | + |
| 99 | - if (this->block_.params_.isHf32) { | 102 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, |
| 100 | - this->mm_.SetHF32(true, 1); | 103 | + class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> |
| 101 | - } else { | 104 | + __aicore__ inline void |
| 102 | - this->mm_.SetHF32(false, 0); | 105 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AivProcess( |
| 103 | - } | 106 | + GlobalTensor<C_T>& cTensor, uint8_t pingPongId) |
| 104 | -} | 107 | + { |
| 105 | - | 108 | + if ASCEND_IS_AIV { |
| 106 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 109 | + uint32_t vBlockIndex = GetBlockIdx(); |
| 107 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 110 | + if (vBlockIndex >= (this->block_.matmulTilingData_->matmulTiling.usedCoreNum * NUM_TWO)) { |
| 108 | -__aicore__ inline void | 111 | + return; |
| 109 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AivProcess( | 112 | + } |
| 110 | - GlobalTensor<C_T>& cTensor, uint8_t pingPongId) | 113 | + CrossCoreWaitFlag(AIV_SYNC_AIC_FLAG + pingPongId); |
| 111 | -{ | 114 | + |
| 112 | - if ASCEND_IS_AIV { | 115 | + uint64_t cDtypeSize = sizeof(C_T); |
| 113 | - uint32_t vBlockIndex = GetBlockIdx(); | 116 | + LocalTensor<C_T> ubTensor = this->ubBuf_.template Get<C_T>(); |
| 114 | - if (vBlockIndex >= (this->block_.matmulTilingData_->matmulTiling.usedCoreNum * NUM_TWO)) { | 117 | + uint64_t vecM = min(MMV3CeilAlign(this->block_.params_.singleCoreM / NUM_TWO, this->c0Size_), |
| 115 | - return; | 118 | + static_cast<uint64_t>(this->block_.params_.singleCoreM)); |
| 116 | - } | 119 | + uint64_t subIdx = GetSubBlockIdx(); |
| 117 | - CrossCoreWaitFlag(0x4 + pingPongId); | 120 | + uint64_t srcOffset = 0UL; |
| 118 | - | 121 | + uint64_t dstOffset = 0UL; |
| 119 | - uint64_t cDtypeSize = sizeof(C_T); | 122 | + if (subIdx == 1) { |
| 120 | - LocalTensor<C_T> ubTensor = this->ubBuf_.template Get<C_T>(); | 123 | + srcOffset = this->alignedN_ * vecM; |
| 121 | - // aic : aiv is 1 : 2, singlecore cal half of baseM. | 124 | + dstOffset = vecM * this->block_.matmulTilingData_->matmulTiling.N; |
| 122 | - uint64_t vecM = min(MMV3CeilAlign(this->block_.params_.singleCoreM / NUM_TWO, c0Size_), | 125 | + vecM = this->block_.params_.singleCoreM - vecM; |
| 123 | - static_cast<uint64_t>(this->block_.params_.singleCoreM)); | 126 | + } |
| 124 | - uint64_t subIdx = GetSubBlockIdx(); | 127 | + if (vecM == 0UL) { |
| 125 | - uint64_t srcOffset = 0UL; | 128 | + return; |
| 126 | - uint64_t dstOffset = 0UL; | 129 | + } |
| 127 | - if (subIdx == 1) { | 130 | + uint64_t ubOffset = (pingPongId * TOTAL_UB_SIZE >> 1) / cDtypeSize; |
| 128 | - srcOffset = alignedN_ * vecM; | 131 | + DataCopy<C_T>(ubTensor[ubOffset], cTensor[srcOffset], vecM * this->alignedN_); |
| 129 | - dstOffset = vecM * this->block_.matmulTilingData_->matmulTiling.N; | 132 | + CrossCoreSetFlag<0x2, PIPE_MTE2>(AIC_SYNC_AIV_FLAG + pingPongId); |
| 130 | - vecM = this->block_.params_.singleCoreM - vecM; | 133 | + |
| 131 | - } | 134 | + SetFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); |
| 132 | - if (vecM == 0UL) { | 135 | + WaitFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); |
| 133 | - return; | 136 | + this->params_.repeatTimes = vecM; |
| 134 | - } | 137 | + uint64_t rsvdCnt = 0UL; |
| 135 | - uint64_t ubOffset = (pingPongId * TOTAL_UB_SIZE >> 1) / cDtypeSize; | 138 | + GatherMask(ubTensor[ubOffset], ubTensor[ubOffset], 7, true, this->block_.matmulTilingData_->matmulTiling.N, |
| 136 | - DataCopy<C_T>(ubTensor[ubOffset], cTensor[srcOffset], vecM * alignedN_); | 139 | + this->params_, rsvdCnt); |
| 137 | - CrossCoreSetFlag<0x2, PIPE_MTE2>(0x6 + pingPongId); | 140 | + SetFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); |
| 138 | - | 141 | + WaitFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); |
| 139 | - SetFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); | 142 | + DataCopy<C_T>(this->cGlobal_[this->block_.offset_.offsetC + dstOffset], ubTensor[ubOffset], |
| 140 | - WaitFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); | 143 | + AlignUp(vecM * this->block_.matmulTilingData_->matmulTiling.N, this->c0Size_)); |
| 141 | - params_.repeatTimes = vecM; | 144 | + SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(pingPongId)); |
| 142 | - uint64_t rsvdCnt = 0UL; | 145 | + WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(pingPongId)); |
| 143 | - // src1Pattern is 7; mask is this->block_.matmulTilingData_->matmulTiling.N; | 146 | + } |
| 144 | - GatherMask(ubTensor[ubOffset], ubTensor[ubOffset], 7, true, this->block_.matmulTilingData_->matmulTiling.N, | 147 | + } |
| 145 | - params_, rsvdCnt); | 148 | + |
| 146 | - SetFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); | 149 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, |
| 147 | - WaitFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); | 150 | + class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> |
| 148 | - DataCopy<C_T>(this->cGlobal_[this->block_.offset_.offsetC + dstOffset], ubTensor[ubOffset], | 151 | + __aicore__ inline void |
| 149 | - AlignUp(vecM * this->block_.matmulTilingData_->matmulTiling.N, c0Size_)); | 152 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AivNz2NdProcess( |
| 150 | - SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(pingPongId)); | 153 | + GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId) |
| 151 | - WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(pingPongId)); | 154 | + { |
| 152 | - } | 155 | + if ASCEND_IS_AIV { |
| 153 | -} | 156 | + LocalTensor<C_T> tensorNZ; |
| 154 | - | 157 | + LocalTensor<C_T> tensorND; |
| 155 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 158 | + uint64_t ubProcessMNum = 0UL; |
| 156 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 159 | + uint64_t srcGmOffset = 0UL; |
| 157 | -__aicore__ inline void | 160 | + uint64_t dstGmOffset = 0UL; |
| 158 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AicProcess( | 161 | + if (!this->PrepareNz2NdConversion(pingPongId, tensorNZ, tensorND, ubProcessMNum, srcGmOffset, dstGmOffset)) { |
| 159 | - GlobalTensor<typename C_TYPE::T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, uint8_t pingPongId) | 162 | + return; |
| 160 | -{ | 163 | + } |
| 161 | - if ASCEND_IS_AIC { | 164 | + if (ubProcessMNum == 0UL) { |
| 162 | - this->mm_.SetSingleShape(this->block_.params_.singleCoreM, this->block_.params_.singleCoreN, | 165 | + return; |
| 163 | - this->block_.matmulTilingData_->matmulTiling.singleCoreK); | 166 | + } |
| 164 | - this->mm_.SetTensorA(this->aGlobal_[this->block_.offset_.offsetA], A_TYPE::isTrans); | 167 | + |
| 165 | - this->mm_.SetTensorB(this->bGlobal_[this->block_.offset_.offsetB], B_TYPE::isTrans); | 168 | + WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); |
| 166 | - if (this->block_.matmulTilingData_->matmulTiling.isBias) { | 169 | + this->Nz2NdCopyAndConvert(cNzGlobal, tensorNZ, tensorND, ubProcessMNum, srcGmOffset, pingPongId, |
| 167 | - this->mm_.SetBias(this->biasGlobal_[this->block_.offset_.offsetBias]); | 170 | + this->block_.matmulTilingData_->matmulTiling.N); |
| 168 | - } | 171 | + |
| 169 | - this->mm_.Iterate(); | 172 | + DataCopy(this->cGlobal_[this->block_.offset_.offsetC + dstGmOffset], tensorND, |
| 170 | - if (aicNeedWaitAiv) { | 173 | + AlignUp(ubProcessMNum * this->block_.matmulTilingData_->matmulTiling.N, this->c0Size_)); |
| 171 | - CrossCoreWaitFlag(0x6 + pingPongId); | 174 | + SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); |
| 172 | - } | 175 | + } |
| 173 | - this->mm_.GetTensorC(cTensor, enAtomic); | 176 | + } |
| 174 | -#if defined(__CCE_AICORE__) && __CCE_AICORE__ == 220 | 177 | + |
| 175 | - CrossCoreSetFlag<0x2, PIPE_FIX>(0x4 + pingPongId); | 178 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, |
| 176 | -#endif | 179 | + class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> |
| 177 | - } | 180 | + __aicore__ inline void |
| 178 | -} | 181 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process( |
| 179 | - | 182 | + uint64_t index, uint8_t enAtomic) |
| 180 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 183 | + { |
| 181 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 184 | + ctx.isFirst = true; |
| 182 | -__aicore__ inline void | 185 | + ctx.inputDtypeSize = sizeof(typename A_TYPE::T); |
| 183 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::CopyInWithNz( | 186 | + this->template RunFixpipeTileLoop< |
| 184 | - LocalTensor<C_T> tensorNZ, GlobalTensor<C_T> cNzGlobal, uint64_t ubProcessM, uint8_t pingPongId) | 187 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>>( |
| 185 | -{ | 188 | + index, enAtomic); |
| 186 | - // AIV cNzGlobal start address has updated | 189 | + } |
| 187 | - size_t NfractualNum = alignedN_ / BLOCK_SIZE; | 190 | + |
| 188 | - DataCopyParams copyParams; | 191 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock, |
| 189 | - copyParams.blockCount = NfractualNum; | 192 | + const MatmulConfig& MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>, |
| 190 | - copyParams.blockLen = ubProcessM * NUM_TWO; | 193 | + FIXPIPE_OPT_SELECT FIXPIPE_OPT = FIXPIPE_OPT_SELECT::BASE_ENABLE_ALIGNOUT> |
| 191 | - copyParams.srcStride = (this->block_.matmulTilingData_->matmulTiling.baseM - ubProcessM) * NUM_TWO; | 194 | + class MatmulBaseAToNZWithBL1FixpipeKernel |
| 192 | - copyParams.dstStride = 0; | 195 | + : public MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT> { |
| 193 | - DataCopy(tensorNZ, cNzGlobal, copyParams); | 196 | + struct BaseUnAlignedNKernelParams { |
| 194 | - SetFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); | 197 | + GM_ADDR aGMNZ; |
| 195 | - WaitFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId)); | 198 | + GM_ADDR workspaceGMNZ; |
| 196 | -} | 199 | + uint64_t baseAN; |
| 197 | - | 200 | + uint64_t baseAD; |
| 198 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 201 | + }; |
| 199 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 202 | + |
| 200 | -__aicore__ inline void | 203 | + public: |
| 201 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::UpdateOffsetC( | 204 | + __aicore__ inline MatmulBaseAToNZWithBL1FixpipeKernel() {} |
| 202 | - bool isNd) | 205 | + |
| 203 | -{ | 206 | + __aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, |
| 204 | - uint64_t mCntIndex = this->block_.params_.index / this->block_.params_.nCntUse; | 207 | + GM_ADDR workspaceGM, const MatmulTilingData* tilingData, TPipe* pipe); |
| 205 | - uint64_t nCntIndex = this->block_.params_.index % this->block_.params_.nCntUse; | 208 | + |
| 206 | - if (isNd) { | 209 | + __aicore__ inline void Process(uint64_t index = 0, uint8_t enAtomic = 0); |
| 207 | - this->block_.offset_.offsetC = | 210 | + |
| 208 | - (nCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreN + | 211 | + protected: |
| 209 | - mCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreM * | 212 | + using C_T = typename C_TYPE::T; |
| 210 | - this->block_.matmulTilingData_->matmulTiling.N + | 213 | + BaseUnAlignedNKernelParams fixpipeInnerParams_; |
| 211 | - (this->block_.params_.mTileAddrOffset * this->block_.matmulTilingData_->matmulTiling.N + | 214 | + }; |
| 212 | - this->block_.params_.nTileAddrOffset)); | 215 | + |
| 213 | - } else { | 216 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, |
| 214 | - this->block_.offset_.offsetC = | 217 | + class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> |
| 215 | - (nCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreN * | 218 | + __aicore__ inline void |
| 216 | - this->block_.matmulTilingData_->matmulTiling.M + | 219 | + MatmulBaseAToNZWithBL1FixpipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init( |
| 217 | - mCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreM * BLOCK_SIZE + | 220 | + GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, GM_ADDR workspaceGM, |
| 218 | - (this->block_.params_.mTileAddrOffset * BLOCK_SIZE + | 221 | + const MatmulTilingData* matmulTilingData, TPipe* pipe) |
| 219 | - this->block_.params_.nTileAddrOffset * this->block_.matmulTilingData_->matmulTiling.M)); | 222 | + { |
| 220 | - } | 223 | + GetSizeC0<C_T>(this->c0Size_); |
| 221 | -} | 224 | + uint64_t cDtypeSize = sizeof(C_T); |
| 222 | - | 225 | + uint64_t alignedN = AlignUp(matmulTilingData->matmulTiling.N, MM_ALIGN_SIZE / cDtypeSize); |
| 223 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 226 | + uint64_t baseSize = alignedN * matmulTilingData->matmulTiling.baseM; |
| 224 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 227 | + |
| 225 | -__aicore__ inline void | 228 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init( |
| 226 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, | 229 | + workspaceGM + baseSize * NUM_TWO * matmulTilingData->matmulTiling.usedCoreNum * cDtypeSize, bGM, cGM, biasGM, |
| 227 | - FIXPIPE_OPT>::Nz2NdAndGatherMask(LocalTensor<C_T> tensorND, LocalTensor<C_T> tensorNZ, | 230 | + offsetWGM, workspaceGM, matmulTilingData, pipe); |
| 228 | - uint64_t ubProcessM, uint8_t pingPongId) | 231 | + this->fixpipeInnerParams_.baseAN = this->block_.matmulTilingData_->baseAN; |
| 229 | -{ | 232 | + this->fixpipeInnerParams_.baseAD = this->block_.matmulTilingData_->baseAD; |
| 230 | - size_t NfractalNum = alignedN_ / BLOCK_SIZE; | 233 | + this->fixpipeInnerParams_.aGMNZ = aGM; |
| 231 | - uint8_t repeatTimes = MMV3DivCeil(ubProcessM, 8); // ub calc 8 row every repeat | 234 | + this->fixpipeInnerParams_.workspaceGMNZ = |
| 232 | - uint64_t mask[2] = {UINT64_MAX, UINT64_MAX}; | 235 | + workspaceGM + this->baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum * cDtypeSize; |
| 233 | - UnaryRepeatParams mulsRepeatParams; | 236 | + this->mm_.SetOrgShape(this->block_.params_.alignedOriM, this->block_.matmulTilingData_->matmulTiling.N, |
| 234 | - mulsRepeatParams.srcBlkStride = 2; | 237 | + this->block_.params_.alignedKaSize, this->block_.matmulTilingData_->matmulTiling.Kb, |
| 235 | - mulsRepeatParams.dstBlkStride = alignedN_ / c0Size_; | 238 | + this->alignedN_); |
| 236 | - mulsRepeatParams.dstRepStride = alignedN_; | 239 | + } |
| 237 | - mulsRepeatParams.srcRepStride = 16; | 240 | + |
| 238 | - // float calc 2 cols per loop | 241 | + template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, |
| 239 | - if constexpr (std::is_same_v<typename A_TYPE::T, float>) { | 242 | + class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> |
| 240 | - for (size_t inLoop = 0; inLoop < NfractalNum; inLoop++) { | 243 | + __aicore__ inline void |
| 241 | - Muls(tensorND[inLoop * BLOCK_SIZE], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE], static_cast<C_T>(1.0), mask, | 244 | + MatmulBaseAToNZWithBL1FixpipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process( |
| 242 | - repeatTimes, mulsRepeatParams); | 245 | + uint64_t index, uint8_t enAtomic) |
| 243 | - Muls(tensorND[inLoop * BLOCK_SIZE + c0Size_], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE + c0Size_], | 246 | + { |
| 244 | - static_cast<C_T>(1.0), mask, repeatTimes, mulsRepeatParams); | 247 | + if ASCEND_IS_AIV { |
| 245 | - } | 248 | + MatrixAtoNZV2<typename A_TYPE::T>(this->fixpipeInnerParams_.workspaceGMNZ, this->fixpipeInnerParams_.aGMNZ, |
| 246 | - } | 249 | + this->block_.matmulTilingData_->matmulTiling, A_TYPE::isTrans, this->ubBuf_, |
| 247 | - PipeBarrier<PIPE_V>(); | 250 | + this->fixpipeInnerParams_.baseAN, this->fixpipeInnerParams_.baseAD); |
| 248 | - // GatherMask | 251 | + SyncAll(); |
| 249 | - uint64_t rsvdCnt = 0; | 252 | + CrossCoreSetFlag<0x2, PIPE_MTE3>(CV_FLAG); |
| 250 | - params_.repeatTimes = ubProcessM; | 253 | + } |
| 251 | - GatherMask(tensorND, tensorND, 7, true, this->block_.matmulTilingData_->matmulTiling.N, params_, rsvdCnt); | 254 | + if ASCEND_IS_AIC { |
| 252 | - SetFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); | 255 | + CrossCoreWaitFlag(CV_FLAG); |
| 253 | - WaitFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId)); | 256 | + } |
| 254 | -} | 257 | + MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process( |
| 255 | - | 258 | + index, enAtomic); |
| 256 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | 259 | + } |
| 257 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | 260 | + |
| 258 | -__aicore__ inline void | 261 | + #endif |
| 259 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AivNz2NdProcess( | 262 | + |
| 260 | - GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId) | ||
| 261 | -{ | ||
| 262 | - if ASCEND_IS_AIV { | ||
| 263 | - uint32_t vBlockIndex = GetBlockIdx(); | ||
| 264 | - if (vBlockIndex >= (this->block_.matmulTilingData_->matmulTiling.usedCoreNum * NUM_TWO)) { | ||
| 265 | - return; | ||
| 266 | - } | ||
| 267 | - CrossCoreWaitFlag(0x4 + pingPongId); | ||
| 268 | - LocalTensor<C_T> ubTensor = this->ubBuf_.template Get<C_T>(); | ||
| 269 | - uint64_t cDtypeSize = sizeof(C_T); | ||
| 270 | - uint64_t ubProcessMNum = min(MMV3CeilAlign(this->block_.params_.singleCoreM / NUM_TWO, c0Size_), | ||
| 271 | - static_cast<uint64_t>(this->block_.params_.singleCoreM)); | ||
| 272 | - int64_t subIdx = GetSubBlockIdx(); | ||
| 273 | - uint64_t srcGmOffset = 0UL; | ||
| 274 | - uint64_t dstGmOffset = 0UL; | ||
| 275 | - | ||
| 276 | - if (subIdx == 1) { | ||
| 277 | - srcGmOffset = ubProcessMNum * ALIGNED_H; // for aiv 1 offset | ||
| 278 | - dstGmOffset = ubProcessMNum * this->block_.matmulTilingData_->matmulTiling.N; | ||
| 279 | - ubProcessMNum = this->block_.params_.singleCoreM - ubProcessMNum; | ||
| 280 | - } | ||
| 281 | - if (ubProcessMNum == 0UL) { | ||
| 282 | - return; | ||
| 283 | - } | ||
| 284 | - uint64_t ndOffset = (TOTAL_UB_SIZE >> 2) / cDtypeSize; | ||
| 285 | - uint64_t pingpongOffset = (TOTAL_UB_SIZE >> 1) / cDtypeSize; | ||
| 286 | - | ||
| 287 | - size_t NfractalNum = alignedN_ / ALIGNED_H; | ||
| 288 | - | ||
| 289 | - LocalTensor<C_T> tensorNZ = ubTensor[pingPongId * pingpongOffset]; | ||
| 290 | - LocalTensor<C_T> tensorND = ubTensor[pingPongId * pingpongOffset + ndOffset]; | ||
| 291 | - WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); | ||
| 292 | - CopyInWithNz(tensorNZ, cNzGlobal[srcGmOffset], ubProcessMNum, pingPongId); | ||
| 293 | - CrossCoreSetFlag<0x2, PIPE_MTE2>(0x6 + pingPongId); // 通知AIC MTE2可进行搬运 | ||
| 294 | - Nz2NdAndGatherMask(tensorND, tensorNZ, ubProcessMNum, pingPongId); | ||
| 295 | - this->UpdateOffsetC(true); | ||
| 296 | - | ||
| 297 | - DataCopy(this->cGlobal_[this->block_.offset_.offsetC + dstGmOffset], tensorND, | ||
| 298 | - AlignUp(ubProcessMNum * this->block_.matmulTilingData_->matmulTiling.N, c0Size_)); | ||
| 299 | - SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId)); | ||
| 300 | - } | ||
| 301 | -} | ||
| 302 | - | ||
| 303 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | ||
| 304 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | ||
| 305 | -__aicore__ inline void | ||
| 306 | -MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process( | ||
| 307 | - uint64_t index, uint8_t enAtomic) | ||
| 308 | -{ | ||
| 309 | - bool reverse = true; | ||
| 310 | - int8_t pingPongId = 0; | ||
| 311 | - bool aicNeedWaitAiv = false; | ||
| 312 | - ctx.isFirst = true; | ||
| 313 | - ctx.inputDtypeSize = sizeof(typename A_TYPE::T); | ||
| 314 | - GlobalTensor<C_T> tempCGlobal = tempCGlobal_; | ||
| 315 | - for (uint64_t mTileIndex = 0; mTileIndex < this->block_.params_.mTileCntL2; mTileIndex++) { | ||
| 316 | - reverse = !reverse; | ||
| 317 | - for (uint64_t nTileIndexTemp = 0; nTileIndexTemp < this->block_.params_.nTileCntL2; nTileIndexTemp++) { | ||
| 318 | - uint64_t nTileIndex = reverse ? (this->block_.params_.nTileCntL2 - nTileIndexTemp - 1) : nTileIndexTemp; | ||
| 319 | - this->block_.UpdateBlockCnt(mTileIndex, nTileIndex); | ||
| 320 | - this->block_.InitBlockIndex(index); | ||
| 321 | - SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG)); | ||
| 322 | - SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + 1)); | ||
| 323 | - for (uint64_t j = 0; j < this->block_.params_.realRound; j++) { | ||
| 324 | - tempCGlobal = tempCGlobal_[baseSize_ * (GetCurrentBlockIdx() * 2 + pingPongId)]; | ||
| 325 | - if (this->block_.params_.rowOrder == 0) { | ||
| 326 | - this->block_.UpdateBasicIndex(j); // 使能错位分核更新Index | ||
| 327 | - } | ||
| 328 | - if (this->block_.params_.index < this->block_.params_.totalTileCnt) { | ||
| 329 | - this->block_.UpdateBlockParams(mTileIndex, nTileIndex); | ||
| 330 | - this->block_.template CalcGMOffset<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(mTileIndex, nTileIndex); | ||
| 331 | - AicProcess(tempCGlobal, enAtomic, aicNeedWaitAiv, pingPongId); | ||
| 332 | - if constexpr (FIXPIPE_OPT == FIXPIPE_OPT_SELECT::VEC_NZ2ND_UNALIGNOUT) { | ||
| 333 | - AivNz2NdProcess(tempCGlobal, pingPongId); | ||
| 334 | - } else { | ||
| 335 | - AivProcess(tempCGlobal, pingPongId); | ||
| 336 | - } | ||
| 337 | - aicNeedWaitAiv = aicNeedWaitAiv || bool(pingPongId); | ||
| 338 | - pingPongId = (pingPongId + 1) & 1; | ||
| 339 | - } | ||
| 340 | - this->block_.UpdateBlockIndex(); | ||
| 341 | - } | ||
| 342 | - WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG)); | ||
| 343 | - WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + 1)); | ||
| 344 | - } | ||
| 345 | - } | ||
| 346 | - if (this->block_.params_.isHf32) { | ||
| 347 | - this->mm_.SetHF32(false, 0); | ||
| 348 | - } | ||
| 349 | - PipeBarrier<PIPE_ALL>(); | ||
| 350 | - return; | ||
| 351 | -} | ||
| 352 | - | ||
| 353 | -// Current Kernel support only nd2nzA. No need to do nd2nz for B. | ||
| 354 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock, | ||
| 355 | - const MatmulConfig& MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>, | ||
| 356 | - FIXPIPE_OPT_SELECT FIXPIPE_OPT = FIXPIPE_OPT_SELECT::BASE_ENABLE_ALIGNOUT> | ||
| 357 | -class MatmulBaseAToNZWithBL1FixpipeKernel | ||
| 358 | - : public MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT> { | ||
| 359 | - struct BaseUnAlignedNKernelParams { | ||
| 360 | - GM_ADDR aGMNZ; | ||
| 361 | - GM_ADDR workspaceGMNZ; | ||
| 362 | - uint64_t baseAN; | ||
| 363 | - uint64_t baseAD; | ||
| 364 | - }; | ||
| 365 | - | ||
| 366 | -public: | ||
| 367 | - __aicore__ inline MatmulBaseAToNZWithBL1FixpipeKernel() {} | ||
| 368 | - | ||
| 369 | - __aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, | ||
| 370 | - GM_ADDR workspaceGM, const MatmulTilingData* tilingData, TPipe* pipe); | ||
| 371 | - | ||
| 372 | - __aicore__ inline void Process(uint64_t index = 0, uint8_t enAtomic = 0); | ||
| 373 | - | ||
| 374 | -protected: | ||
| 375 | - using C_T = typename C_TYPE::T; | ||
| 376 | - BaseUnAlignedNKernelParams fixpipeInnerParams_; | ||
| 377 | -}; | ||
| 378 | - | ||
| 379 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | ||
| 380 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | ||
| 381 | -__aicore__ inline void | ||
| 382 | -MatmulBaseAToNZWithBL1FixpipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init( | ||
| 383 | - GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, GM_ADDR workspaceGM, | ||
| 384 | - const MatmulTilingData* matmulTilingData, TPipe* pipe) | ||
| 385 | -{ | ||
| 386 | - GetSizeC0<C_T>(this->c0Size_); | ||
| 387 | - uint64_t cDtypeSize = sizeof(C_T); | ||
| 388 | - uint64_t alignedN = AlignUp(matmulTilingData->matmulTiling.N, MM_ALIGN_SIZE / cDtypeSize); | ||
| 389 | - uint64_t baseSize = alignedN * matmulTilingData->matmulTiling.baseM; | ||
| 390 | - | ||
| 391 | - MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::Init( | ||
| 392 | - workspaceGM + baseSize * NUM_TWO * matmulTilingData->matmulTiling.usedCoreNum * cDtypeSize, bGM, cGM, biasGM, | ||
| 393 | - offsetWGM, workspaceGM, matmulTilingData, pipe); | ||
| 394 | - this->fixpipeInnerParams_.baseAN = this->block_.matmulTilingData_->baseAN; | ||
| 395 | - this->fixpipeInnerParams_.baseAD = this->block_.matmulTilingData_->baseAD; | ||
| 396 | - this->fixpipeInnerParams_.aGMNZ = aGM; | ||
| 397 | - this->fixpipeInnerParams_.workspaceGMNZ = | ||
| 398 | - workspaceGM + this->baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum * cDtypeSize; | ||
| 399 | - this->mm_.SetOrgShape(this->block_.params_.alignedOriM, this->block_.matmulTilingData_->matmulTiling.N, | ||
| 400 | - this->block_.params_.alignedKaSize, this->block_.matmulTilingData_->matmulTiling.Kb, | ||
| 401 | - this->alignedN_); | ||
| 402 | -} | ||
| 403 | - | ||
| 404 | -template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG, | ||
| 405 | - class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT> | ||
| 406 | -__aicore__ inline void | ||
| 407 | -MatmulBaseAToNZWithBL1FixpipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process( | ||
| 408 | - uint64_t index, uint8_t enAtomic) | ||
| 409 | -{ | ||
| 410 | - if ASCEND_IS_AIV { | ||
| 411 | - MatrixAtoNZV2<typename A_TYPE::T>(this->fixpipeInnerParams_.workspaceGMNZ, this->fixpipeInnerParams_.aGMNZ, | ||
| 412 | - this->block_.matmulTilingData_->matmulTiling, A_TYPE::isTrans, this->ubBuf_, | ||
| 413 | - this->fixpipeInnerParams_.baseAN, this->fixpipeInnerParams_.baseAD); | ||
| 414 | - SyncAll(); | ||
| 415 | - CrossCoreSetFlag<0x2, PIPE_MTE3>(CV_FLAG); | ||
| 416 | - } | ||
| 417 | - if ASCEND_IS_AIC { | ||
| 418 | - CrossCoreWaitFlag(CV_FLAG); | ||
| 419 | - } | ||
| 420 | - MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process( | ||
| 421 | - index, enAtomic); | ||
| 422 | -} | ||
| 423 | - | ||
| 424 | - | ||
| @@ -24,10 +24,13 @@ | |||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | - | ||
| 28 | 27 | ||
| 29 | 28 | ||
| 30 | 29 | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 31 | 34 | ||
| 32 | 35 | ||
| 33 | 36 | ||
| @@ -206,6 +209,12 @@ __global__ __aicore__ void mat_mul_v3( | |||
| 206 | MMV3_IMPL_CLASS( | 209 | MMV3_IMPL_CLASS( |
| 207 | MatmulBaseKernel, format_x1, MatmulBaseBlock, MM_CFG_NO_PRELOAD | 210 | MatmulBaseKernel, format_x1, MatmulBaseBlock, MM_CFG_NO_PRELOAD |
| 208 | ); | 211 | ); |
| 212 | + } else if constexpr ( | ||
| 213 | + LOADMODE == MAT_MUL_V3_BASE_FULLLOAD && SPLITCOREMODE == MAT_MUL_V3_BASE_SPLIT_K && | ||
| 214 | + FIXOPTI == MAT_MUL_V3_VEC_NZ2ND_UNALIGNOUT && MIXND2NZ == MAT_MUL_V3_MIXND2NZ_FALSE) { | ||
| 215 | + MMV3_IMPL_C_CLASS( | ||
| 216 | + MatmulBaseVectorNz2NdKernel, format_x1, CubeFormat::NZ, MatmulBaseBlock, MM_CFG_NO_PRELOAD | ||
| 217 | + ); | ||
| 209 | } | 218 | } |
| 210 | 219 | ||
| 211 | if constexpr ( | 220 | if constexpr ( |
| @@ -98,6 +98,14 @@ ASCENDC_TPL_SEL( | |||
| 98 | ASCENDC_TPL_UINT_SEL(MIXND2NZ, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_MIXND2NZ_FALSE), | 98 | ASCENDC_TPL_UINT_SEL(MIXND2NZ, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_MIXND2NZ_FALSE), |
| 99 | ASCENDC_TPL_UINT_SEL(SPECIALOPT, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_K_SHIFT, MAT_MUL_V3_K_NOT_SHIFT), | 99 | ASCENDC_TPL_UINT_SEL(SPECIALOPT, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_K_SHIFT, MAT_MUL_V3_K_NOT_SHIFT), |
| 100 | ASCENDC_TPL_UINT_SEL(FP32ADDMM, ASCENDC_TPL_UI_LIST, FP32_ADDMM_DISABLE)), | 100 | ASCENDC_TPL_UINT_SEL(FP32ADDMM, ASCENDC_TPL_UI_LIST, FP32_ADDMM_DISABLE)), |
| 101 | + ASCENDC_TPL_ARGS_SEL( | ||
| 102 | + ASCENDC_TPL_KERNEL_TYPE_SEL(ASCENDC_TPL_MIX_AIC_1_2), | ||
| 103 | + ASCENDC_TPL_UINT_SEL(LOADMODE, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_BASE_FULLLOAD), | ||
| 104 | + ASCENDC_TPL_UINT_SEL(SPLITCOREMODE, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_BASE_SPLIT_K), | ||
| 105 | + ASCENDC_TPL_UINT_SEL(FIXOPTI, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_VEC_NZ2ND_UNALIGNOUT), | ||
| 106 | + ASCENDC_TPL_UINT_SEL(MIXND2NZ, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_MIXND2NZ_FALSE), | ||
| 107 | + ASCENDC_TPL_UINT_SEL(SPECIALOPT, ASCENDC_TPL_UI_LIST, MAT_MUL_V3_K_NOT_SHIFT), | ||
| 108 | + ASCENDC_TPL_UINT_SEL(FP32ADDMM, ASCENDC_TPL_UI_LIST, FP32_ADDMM_DISABLE)), | ||
| 101 | ); | 109 | ); |
| 102 | 110 | ||
| 103 | ASCENDC_TPL_SEL( | 111 | ASCENDC_TPL_SEL( |