* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
* \file mat_mul_optimized_fixpipe_algorithm.h
* \brief
*/
#ifndef __OP_KERNEL_MATMUL_V3_OPTIMIZED_FIXPIPE_ALGORITHM_H__
#define __OP_KERNEL_MATMUL_V3_OPTIMIZED_FIXPIPE_ALGORITHM_H__
#include "mat_mul_base_block.h"
#include "mat_mul_base_kernel.h"
#include "mat_mul_l1_full_load.h"
using namespace AscendC;
using namespace matmul;
using namespace MatmulV3;
#if defined(__CCE_KT_TEST__)
using namespace std;
#endif
const uint32_t MM_ALIGN_SIZE = 512;
const uint8_t AIV_DB_SYNC_FLAG = 0x2;
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock,
const MatmulConfig& MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>,
FIXPIPE_OPT_SELECT FIXPIPE_OPT = FIXPIPE_OPT_SELECT::BASE_ENABLE_ALIGNOUT>
class MatmulBaseUnalignedNKernel : public MatmulBaseKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE,
BLOCK_TYPE, MM_CFG, MM_CB> {
public:
using C_T = typename C_TYPE::T;
__aicore__ inline MatmulBaseUnalignedNKernel() {}
__aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM,
GM_ADDR workspaceGM, const void* tilingData, TPipe* pipe);
__aicore__ inline void AicProcess(GlobalTensor<C_T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv,
uint8_t pingPongId);
__aicore__ inline void AivProcess(GlobalTensor<C_T>& cTensor, uint8_t pingPongId);
__aicore__ inline void Process(uint64_t index = 0UL, uint8_t enAtomic = 0UL);
__aicore__ inline void AivNz2NdProcess(GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId);
__aicore__ inline void CopyInWithNz(LocalTensor<C_T> tensorNZ, GlobalTensor<C_T> cNzGlobal, uint64_t ubProcessM,
uint8_t pingPongId);
__aicore__ inline void Nz2NdAndGatherMask(LocalTensor<C_T> tensorND, LocalTensor<C_T> tensorNZ, uint64_t ubProcessM,
uint8_t pingPongId);
__aicore__ inline void UpdateOffsetC(bool isNd);
protected:
GlobalTensor<C_T> tempCGlobal_;
GatherMaskParams params_;
uint64_t baseSize_ = 0UL;
uint64_t alignedN_ = 0UL;
uint64_t c0Size_ = BLOCK_SIZE;
};
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init(
GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, GM_ADDR workspaceGM,
const void* tilingData, TPipe* pipe)
{
GetSizeC0<C_T>(c0Size_);
uint64_t cDtypeSize = sizeof(C_T);
this->block_.template Init<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(tilingData);
this->InitInputs(aGM, bGM, cGM, biasGM);
this->pipe_ = pipe;
this->pipe_->InitBuffer(this->ubBuf_, TOTAL_UB_SIZE);
int64_t originShapeM = 0;
if constexpr (FIXPIPE_OPT == FIXPIPE_OPT_SELECT::VEC_NZ2ND_UNALIGNOUT) {
alignedN_ = AlignUp(this->block_.matmulTilingData_->matmulTiling.N, BLOCK_SIZE);
originShapeM = this->block_.matmulTilingData_->matmulTiling.baseM;
} else {
alignedN_ = AlignUp(this->block_.matmulTilingData_->matmulTiling.N, MM_ALIGN_SIZE / cDtypeSize);
originShapeM = this->block_.matmulTilingData_->matmulTiling.M;
}
baseSize_ = alignedN_ * this->block_.matmulTilingData_->matmulTiling.baseM;
params_.src0BlockStride = 1;
params_.src0RepeatStride = alignedN_ / c0Size_;
params_.src1RepeatStride = 0;
tempCGlobal_.SetGlobalBuffer(reinterpret_cast<__gm__ C_T*>(workspaceGM),
baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum);
this->mm_.SetSubBlockIdx(0);
this->mm_.Init(&this->block_.matmulTilingData_->matmulTiling, pipe);
this->mm_.SetUserDefInfo(reinterpret_cast<uint64_t>(tilingData));
this->mm_.SetOrgShape(originShapeM, this->block_.params_.alignedOriN,
this->block_.matmulTilingData_->matmulTiling.singleCoreK, this->block_.params_.alignedKbSize,
this->alignedN_);
if (this->block_.params_.isHf32) {
this->mm_.SetHF32(true, 1);
} else {
this->mm_.SetHF32(false, 0);
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AivProcess(
GlobalTensor<C_T>& cTensor, uint8_t pingPongId)
{
if ASCEND_IS_AIV {
uint32_t vBlockIndex = GetBlockIdx();
if (vBlockIndex >= (this->block_.matmulTilingData_->matmulTiling.usedCoreNum * NUM_TWO)) {
return;
}
CrossCoreWaitFlag(0x4 + pingPongId);
uint64_t cDtypeSize = sizeof(C_T);
LocalTensor<C_T> ubTensor = this->ubBuf_.template Get<C_T>();
uint64_t vecM = min(MMV3CeilAlign(this->block_.params_.singleCoreM / NUM_TWO, c0Size_),
static_cast<uint64_t>(this->block_.params_.singleCoreM));
uint64_t subIdx = GetSubBlockIdx();
uint64_t srcOffset = 0UL;
uint64_t dstOffset = 0UL;
if (subIdx == 1) {
srcOffset = alignedN_ * vecM;
dstOffset = vecM * this->block_.matmulTilingData_->matmulTiling.N;
vecM = this->block_.params_.singleCoreM - vecM;
}
if (vecM == 0UL) {
return;
}
uint64_t ubOffset = (pingPongId * TOTAL_UB_SIZE >> 1) / cDtypeSize;
DataCopy<C_T>(ubTensor[ubOffset], cTensor[srcOffset], vecM * alignedN_);
CrossCoreSetFlag<0x2, PIPE_MTE2>(0x6 + pingPongId);
SetFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId));
WaitFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId));
params_.repeatTimes = vecM;
uint64_t rsvdCnt = 0UL;
GatherMask(ubTensor[ubOffset], ubTensor[ubOffset], 7, true, this->block_.matmulTilingData_->matmulTiling.N,
params_, rsvdCnt);
SetFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId));
WaitFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId));
DataCopy<C_T>(this->cGlobal_[this->block_.offset_.offsetC + dstOffset], ubTensor[ubOffset],
AlignUp(vecM * this->block_.matmulTilingData_->matmulTiling.N, c0Size_));
SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(pingPongId));
WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(pingPongId));
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AicProcess(
GlobalTensor<typename C_TYPE::T>& cTensor, uint8_t enAtomic, bool aicNeedWaitAiv, uint8_t pingPongId)
{
if ASCEND_IS_AIC {
this->mm_.SetSingleShape(this->block_.params_.singleCoreM, this->block_.params_.singleCoreN,
this->block_.matmulTilingData_->matmulTiling.singleCoreK);
this->mm_.SetTensorA(this->aGlobal_[this->block_.offset_.offsetA], A_TYPE::isTrans);
this->mm_.SetTensorB(this->bGlobal_[this->block_.offset_.offsetB], B_TYPE::isTrans);
if (this->block_.matmulTilingData_->matmulTiling.isBias) {
this->mm_.SetBias(this->biasGlobal_[this->block_.offset_.offsetBias]);
}
this->mm_.Iterate();
if (aicNeedWaitAiv) {
CrossCoreWaitFlag(0x6 + pingPongId);
}
this->mm_.GetTensorC(cTensor, enAtomic);
#if defined(__CCE_AICORE__) && __CCE_AICORE__ == 220
CrossCoreSetFlag<0x2, PIPE_FIX>(0x4 + pingPongId);
#endif
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::CopyInWithNz(
LocalTensor<C_T> tensorNZ, GlobalTensor<C_T> cNzGlobal, uint64_t ubProcessM, uint8_t pingPongId)
{
size_t NfractualNum = alignedN_ / BLOCK_SIZE;
DataCopyParams copyParams;
copyParams.blockCount = NfractualNum;
copyParams.blockLen = ubProcessM * NUM_TWO;
copyParams.srcStride = (this->block_.matmulTilingData_->matmulTiling.baseM - ubProcessM) * NUM_TWO;
copyParams.dstStride = 0;
DataCopy(tensorNZ, cNzGlobal, copyParams);
SetFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId));
WaitFlag<HardEvent::MTE2_V>(static_cast<event_t>(pingPongId));
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::UpdateOffsetC(
bool isNd)
{
uint64_t mCntIndex = this->block_.params_.index / this->block_.params_.nCntUse;
uint64_t nCntIndex = this->block_.params_.index % this->block_.params_.nCntUse;
if (isNd) {
this->block_.offset_.offsetC =
(nCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreN +
mCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreM *
this->block_.matmulTilingData_->matmulTiling.N +
(this->block_.params_.mTileAddrOffset * this->block_.matmulTilingData_->matmulTiling.N +
this->block_.params_.nTileAddrOffset));
} else {
this->block_.offset_.offsetC =
(nCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreN *
this->block_.matmulTilingData_->matmulTiling.M +
mCntIndex * this->block_.matmulTilingData_->matmulTiling.singleCoreM * BLOCK_SIZE +
(this->block_.params_.mTileAddrOffset * BLOCK_SIZE +
this->block_.params_.nTileAddrOffset * this->block_.matmulTilingData_->matmulTiling.M));
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB,
FIXPIPE_OPT>::Nz2NdAndGatherMask(LocalTensor<C_T> tensorND, LocalTensor<C_T> tensorNZ,
uint64_t ubProcessM, uint8_t pingPongId)
{
size_t NfractalNum = alignedN_ / BLOCK_SIZE;
uint8_t repeatTimes = MMV3DivCeil(ubProcessM, 8);
uint64_t mask[2] = {UINT64_MAX, UINT64_MAX};
UnaryRepeatParams mulsRepeatParams;
mulsRepeatParams.srcBlkStride = 2;
mulsRepeatParams.dstBlkStride = alignedN_ / c0Size_;
mulsRepeatParams.dstRepStride = alignedN_;
mulsRepeatParams.srcRepStride = 16;
if constexpr (std::is_same_v<typename A_TYPE::T, float>) {
for (size_t inLoop = 0; inLoop < NfractalNum; inLoop++) {
Muls(tensorND[inLoop * BLOCK_SIZE], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE], static_cast<C_T>(1.0), mask,
repeatTimes, mulsRepeatParams);
Muls(tensorND[inLoop * BLOCK_SIZE + c0Size_], tensorNZ[inLoop * ubProcessM * BLOCK_SIZE + c0Size_],
static_cast<C_T>(1.0), mask, repeatTimes, mulsRepeatParams);
}
}
PipeBarrier<PIPE_V>();
uint64_t rsvdCnt = 0;
params_.repeatTimes = ubProcessM;
GatherMask(tensorND, tensorND, 7, true, this->block_.matmulTilingData_->matmulTiling.N, params_, rsvdCnt);
SetFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId));
WaitFlag<HardEvent::V_MTE3>(static_cast<event_t>(pingPongId));
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::AivNz2NdProcess(
GlobalTensor<C_T> cNzGlobal, uint8_t pingPongId)
{
if ASCEND_IS_AIV {
uint32_t vBlockIndex = GetBlockIdx();
if (vBlockIndex >= (this->block_.matmulTilingData_->matmulTiling.usedCoreNum * NUM_TWO)) {
return;
}
CrossCoreWaitFlag(0x4 + pingPongId);
LocalTensor<C_T> ubTensor = this->ubBuf_.template Get<C_T>();
uint64_t cDtypeSize = sizeof(C_T);
uint64_t ubProcessMNum = min(MMV3CeilAlign(this->block_.params_.singleCoreM / NUM_TWO, c0Size_),
static_cast<uint64_t>(this->block_.params_.singleCoreM));
int64_t subIdx = GetSubBlockIdx();
uint64_t srcGmOffset = 0UL;
uint64_t dstGmOffset = 0UL;
if (subIdx == 1) {
srcGmOffset = ubProcessMNum * ALIGNED_H;
dstGmOffset = ubProcessMNum * this->block_.matmulTilingData_->matmulTiling.N;
ubProcessMNum = this->block_.params_.singleCoreM - ubProcessMNum;
}
if (ubProcessMNum == 0UL) {
return;
}
uint64_t ndOffset = (TOTAL_UB_SIZE >> 2) / cDtypeSize;
uint64_t pingpongOffset = (TOTAL_UB_SIZE >> 1) / cDtypeSize;
size_t NfractalNum = alignedN_ / ALIGNED_H;
LocalTensor<C_T> tensorNZ = ubTensor[pingPongId * pingpongOffset];
LocalTensor<C_T> tensorND = ubTensor[pingPongId * pingpongOffset + ndOffset];
WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId));
CopyInWithNz(tensorNZ, cNzGlobal[srcGmOffset], ubProcessMNum, pingPongId);
CrossCoreSetFlag<0x2, PIPE_MTE2>(0x6 + pingPongId);
Nz2NdAndGatherMask(tensorND, tensorNZ, ubProcessMNum, pingPongId);
this->UpdateOffsetC(true);
DataCopy(this->cGlobal_[this->block_.offset_.offsetC + dstGmOffset], tensorND,
AlignUp(ubProcessMNum * this->block_.matmulTilingData_->matmulTiling.N, c0Size_));
SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + pingPongId));
}
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process(
uint64_t index, uint8_t enAtomic)
{
bool reverse = true;
int8_t pingPongId = 0;
bool aicNeedWaitAiv = false;
ctx.isFirst = true;
ctx.inputDtypeSize = sizeof(typename A_TYPE::T);
GlobalTensor<C_T> tempCGlobal = tempCGlobal_;
for (uint64_t mTileIndex = 0; mTileIndex < this->block_.params_.mTileCntL2; mTileIndex++) {
reverse = !reverse;
for (uint64_t nTileIndexTemp = 0; nTileIndexTemp < this->block_.params_.nTileCntL2; nTileIndexTemp++) {
uint64_t nTileIndex = reverse ? (this->block_.params_.nTileCntL2 - nTileIndexTemp - 1) : nTileIndexTemp;
this->block_.UpdateBlockCnt(mTileIndex, nTileIndex);
this->block_.InitBlockIndex(index);
SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG));
SetFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + 1));
for (uint64_t j = 0; j < this->block_.params_.realRound; j++) {
tempCGlobal = tempCGlobal_[baseSize_ * (GetCurrentBlockIdx() * 2 + pingPongId)];
if (this->block_.params_.rowOrder == 0) {
this->block_.UpdateBasicIndex(j);
}
if (this->block_.params_.index < this->block_.params_.totalTileCnt) {
this->block_.UpdateBlockParams(mTileIndex, nTileIndex);
this->block_.template CalcGMOffset<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE>(mTileIndex, nTileIndex);
AicProcess(tempCGlobal, enAtomic, aicNeedWaitAiv, pingPongId);
if constexpr (FIXPIPE_OPT == FIXPIPE_OPT_SELECT::VEC_NZ2ND_UNALIGNOUT) {
AivNz2NdProcess(tempCGlobal, pingPongId);
} else {
AivProcess(tempCGlobal, pingPongId);
}
aicNeedWaitAiv = aicNeedWaitAiv || bool(pingPongId);
pingPongId = (pingPongId + 1) & 1;
}
this->block_.UpdateBlockIndex();
}
WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG));
WaitFlag<HardEvent::MTE3_MTE2>(static_cast<event_t>(AIV_DB_SYNC_FLAG + 1));
}
}
if (this->block_.params_.isHf32) {
this->mm_.SetHF32(false, 0);
}
PipeBarrier<PIPE_ALL>();
return;
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE = MatmulBaseBlock,
const MatmulConfig& MM_CFG = MM_CFG_NO_PRELOAD, class MM_CB = MatmulCallBackFunc<nullptr, nullptr, nullptr>,
FIXPIPE_OPT_SELECT FIXPIPE_OPT = FIXPIPE_OPT_SELECT::BASE_ENABLE_ALIGNOUT>
class MatmulBaseAToNZWithBL1FixpipeKernel
: public MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT> {
struct BaseUnAlignedNKernelParams {
GM_ADDR aGMNZ;
GM_ADDR workspaceGMNZ;
uint64_t baseAN;
uint64_t baseAD;
};
public:
__aicore__ inline MatmulBaseAToNZWithBL1FixpipeKernel() {}
__aicore__ inline void Init(GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM,
GM_ADDR workspaceGM, const MatmulTilingData* tilingData, TPipe* pipe);
__aicore__ inline void Process(uint64_t index = 0, uint8_t enAtomic = 0);
protected:
using C_T = typename C_TYPE::T;
BaseUnAlignedNKernelParams fixpipeInnerParams_;
};
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseAToNZWithBL1FixpipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Init(
GM_ADDR aGM, GM_ADDR bGM, GM_ADDR cGM, GM_ADDR biasGM, GM_ADDR offsetWGM, GM_ADDR workspaceGM,
const MatmulTilingData* matmulTilingData, TPipe* pipe)
{
GetSizeC0<C_T>(this->c0Size_);
uint64_t cDtypeSize = sizeof(C_T);
uint64_t alignedN = AlignUp(matmulTilingData->matmulTiling.N, MM_ALIGN_SIZE / cDtypeSize);
uint64_t baseSize = alignedN * matmulTilingData->matmulTiling.baseM;
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB>::Init(
workspaceGM + baseSize * NUM_TWO * matmulTilingData->matmulTiling.usedCoreNum * cDtypeSize, bGM, cGM, biasGM,
offsetWGM, workspaceGM, matmulTilingData, pipe);
this->fixpipeInnerParams_.baseAN = this->block_.matmulTilingData_->baseAN;
this->fixpipeInnerParams_.baseAD = this->block_.matmulTilingData_->baseAD;
this->fixpipeInnerParams_.aGMNZ = aGM;
this->fixpipeInnerParams_.workspaceGMNZ =
workspaceGM + this->baseSize_ * NUM_TWO * this->block_.matmulTilingData_->matmulTiling.usedCoreNum * cDtypeSize;
this->mm_.SetOrgShape(this->block_.params_.alignedOriM, this->block_.matmulTilingData_->matmulTiling.N,
this->block_.params_.alignedKaSize, this->block_.matmulTilingData_->matmulTiling.Kb,
this->alignedN_);
}
template <class A_TYPE, class B_TYPE, class C_TYPE, class BIAS_TYPE, class BLOCK_TYPE, const MatmulConfig& MM_CFG,
class MM_CB, FIXPIPE_OPT_SELECT FIXPIPE_OPT>
__aicore__ inline void
MatmulBaseAToNZWithBL1FixpipeKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process(
uint64_t index, uint8_t enAtomic)
{
if ASCEND_IS_AIV {
MatrixAtoNZV2<typename A_TYPE::T>(this->fixpipeInnerParams_.workspaceGMNZ, this->fixpipeInnerParams_.aGMNZ,
this->block_.matmulTilingData_->matmulTiling, A_TYPE::isTrans, this->ubBuf_,
this->fixpipeInnerParams_.baseAN, this->fixpipeInnerParams_.baseAD);
SyncAll();
CrossCoreSetFlag<0x2, PIPE_MTE3>(CV_FLAG);
}
if ASCEND_IS_AIC {
CrossCoreWaitFlag(CV_FLAG);
}
MatmulBaseUnalignedNKernel<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, BLOCK_TYPE, MM_CFG, MM_CB, FIXPIPE_OPT>::Process(
index, enAtomic);
}
#endif