LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_context - ccu_context.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.3 % 847 629
Test Date: 2026-08-04 10:52:23 Functions: 90.3 % 93 84

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 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              : #include "ccu_ctx.h"
      12              : #include "ccu_context_resource.h"
      13              : #include "ccu_assist.h"
      14              : #include "ccu_microcode.h"
      15              : 
      16              : #include "exception_util.h"
      17              : #include "ccu_api_exception.h"
      18              : #include "ccu_device_manager.h"
      19              : #include "ccu_rep_type.h"
      20              : 
      21              : namespace Hccl {
      22              : 
      23              : constexpr u32 DATAT_SIZE_U32 = 32;
      24              : constexpr u32 TOKEN_VALUE_INDEX = 2;
      25              : 
      26           41 : CcuContext::CcuContext(const CcuCtxArg &arg, const std::vector<CcuTransport*> &transports,
      27           41 :                        const CcuTransportGroup &transportGroup)
      28           41 :     : transports(transports), transportGroup(&transportGroup)
      29              : {
      30          123 :     HCCL_INFO("Construct CcuContext: %s", arg.GetCtxSignature().GetData().c_str());
      31           41 :     if (transports.size() == 0 || transports[0] == nullptr) {
      32            6 :         HCCL_WARNING("No valid transport in CcuContext, Use Die0");
      33            2 :         SetDieId(0);
      34              :     } else {
      35           39 :         SetDieId(transports[0]->GetDieId());
      36              :     }
      37              : 
      38              :     // 生成SQE粒度profiling信息
      39           41 :     AddSqeProfiling(arg);
      40           41 : }
      41              : 
      42           70 : CcuContext::~CcuContext()
      43              : {
      44          210 :     HCCL_DEBUG("~CcuContext");
      45           70 : }
      46              : 
      47           24 : HcclResult CcuContext::Init()
      48              : {
      49          339 :     TRY_CATCH_RETURN(Algorithm());
      50           19 :     return HCCL_SUCCESS;
      51              : }
      52              : 
      53           19 : HcclResult CcuContext::GeneTaskParam(const CcuTaskArg &arg, std::vector<CcuTaskParam> &taskParams)
      54              : {
      55           19 :     auto args    = GeneArgs(arg);
      56           13 :     auto agrsNum = args.size();
      57           13 :     if (agrsNum != loadArgIndex) {
      58            0 :         HCCL_ERROR("Args number does not match the Load instruction, agrsNum = %lu, loadArgInstr= %u", agrsNum, loadArgIndex);
      59            0 :         return HCCL_E_PARA;
      60              :     }
      61              : 
      62              :     // 如果agrs数量超过sqe arg的最大数量,则返回多个TaskParam,前面几个只从sqe中加载args;
      63              :     // args数量大于等于0、小于等于最大值时,返回1个TaskParam
      64           13 :     uint32_t seqNum
      65           13 :         = (agrsNum / CCU_SQE_ARGS_LEN) + ((agrsNum % CCU_SQE_ARGS_LEN) == 0 ? 0 : 1) + (agrsNum == 0 ? 1 : 0);
      66           13 :     taskParams.resize(seqNum);
      67           27 :     for (uint32_t index = 0; index < seqNum; index++) {
      68           14 :         taskParams[index].dieId       = GetDieId();
      69           14 :         taskParams[index].missionId   = GetMissionId();
      70           14 :         taskParams[index].instStartId = instrInfo.missionStartInstrId + index * CCU_SQE_ARGS_LEN;
      71           14 :         taskParams[index].key         = GetMissionKey();
      72           14 :         taskParams[index].argSize     = CCU_SQE_ARGS_LEN;
      73           14 :         if (index == seqNum - 1) {
      74           13 :             taskParams[index].instCnt = instrInfo.missionInstrCount - index * CCU_SQE_ARGS_LEN;
      75           65 :             std::copy(std::begin(args) + index * CCU_SQE_ARGS_LEN, std::end(args), std::begin(taskParams[index].args));
      76              :         } else {
      77            1 :             taskParams[index].instCnt = CCU_SQE_ARGS_LEN;
      78            3 :             std::copy(std::begin(args) + index * CCU_SQE_ARGS_LEN, std::begin(args) + (index + 1) * CCU_SQE_ARGS_LEN,
      79            1 :                       std::begin(taskParams[index].args));
      80              :         }
      81              : 
      82           42 :         HCCL_INFO("[GeneTaskParam]task Param, dieId[%u] missionId[%u] instStartId[%u] instCnt[%u], argSize[%u]",
      83              :                   taskParams[index].dieId, taskParams[index].missionId, taskParams[index].instStartId,
      84              :                   taskParams[index].instCnt, taskParams[index].argSize);
      85              :     }
      86           13 :     return HCCL_SUCCESS;
      87           13 : }
      88              : 
      89           19 : void CcuContext::AllocGoResource(uint32_t parallelDim, uint32_t msPerLoop)
      90              : {
      91           19 :     if (moConfig.loopCount != 0xFFFFFFFF && moConfig.msInterleave != 0xFFFFFFFF &&
      92            0 :         moConfig.memSlice != 0xFFFFFFFFFFFFFFFF) {
      93              :         // 已经配置过,略过
      94            0 :         return;
      95              :     } else {
      96              :         // 采用默认配置
      97           19 :         moConfig = {CcuRep::CCU_MS_INTERLEAVE, CcuRep::CCU_MS_DEFAULT_LOOP_COUNT, CcuRep::CCU_MS_SIZE};
      98              :     }
      99              :     // 算法配置的loop数覆盖默认配置,parallelDim默认为CCU_MS_DEFAULT_LOOP_COUNT
     100           19 :     moConfig.loopCount = parallelDim;
     101              :     // 算法配置的msPerLoop * CcuRep::CCU_MS_SIZE覆盖默认配置,msPerLoop默认为1
     102           19 :     moConfig.memSlice = msPerLoop * CcuRep::CCU_MS_SIZE;
     103              : 
     104           57 :     HCCL_INFO("[AllocGoResource]moConfig: loopCount = %u, msInterleave = %u", moConfig.loopCount, moConfig.msInterleave);
     105              : 
     106              :     // 简单实现,只需要申请一次资源
     107           19 :     if (moRes.executor.size() == 0) {
     108           19 :         moRes.executor = CreateBlockExecutor(moConfig.loopCount);
     109           19 :         moRes.maskSignal = CreateBlockMaskSignal(moConfig.loopCount);
     110           19 :         moRes.ccuBuffer = CreateBlockCcuBuffer(moConfig.loopCount * moConfig.msInterleave);
     111              :     }
     112              : 
     113           19 :     constexpr size_t minMaskSignalCount = 2;
     114           19 :     if (moRes.maskSignal.size() < minMaskSignalCount) {
     115            0 :         THROW<CcuApiException>("MaskSignal is not enough, maskSignal = %lu", moRes.maskSignal.size());
     116              :     }
     117              : }
     118              : 
     119           26 : std::vector<uint64_t> CcuContext::CalGoSize(uint64_t size)
     120              : {
     121           26 :     return CalGoSizeStatic(size, moConfig);
     122              : }
     123              : 
     124           26 : std::vector<uint64_t> CcuContext::CalGoSizeStatic(uint64_t size, GroupOpConfig &moCfg)
     125              : {
     126           26 :     uint64_t offset        = 0;
     127           26 :     uint64_t loopIterNum   = 0;
     128           26 :     uint64_t loopExtendNum = 0;
     129           26 :     uint64_t tailSize      = 0;
     130              : 
     131           26 :     uint64_t loopSize = moCfg.loopCount * moCfg.memSlice;
     132           26 :     uint64_t maxSize = loopSize * (CcuRep::GetMaxLoopIterNum() + 1);
     133              : 
     134           26 :     if (moCfg.loopCount == 0 || moCfg.memSlice == 0) {
     135            0 :         THROW<CcuApiException>("Please Check Configure, loopCount = %u, memSlice = %u", moCfg.loopCount,
     136              :                                moCfg.memSlice);
     137              :     }
     138              : 
     139           26 :     if (size > maxSize) {
     140            0 :         THROW<CcuApiException>("Too Large Size, size = %llu, maxSize = %llu", size, maxSize);
     141              :     }
     142              : 
     143           26 :     uint64_t m = size / loopSize;
     144           26 :     uint64_t n = (size - m * loopSize) / moCfg.memSlice;
     145           26 :     uint64_t p = size - m * loopSize - n * moCfg.memSlice;
     146              : 
     147           26 :     if (size == maxSize) {
     148            0 :         m = CcuRep::GetMaxLoopIterNum();
     149            0 :         n = moCfg.loopCount - 1;
     150            0 :         p = moCfg.memSlice;
     151              :     }
     152              : 
     153           78 :     HCCL_INFO("[CalGoSizeStatic] moCfg.memSlice[%llu], moCfg.loopCount[%u], moCfg.msInterleave[%u]", 
     154              :         moCfg.memSlice, moCfg.loopCount, moCfg.msInterleave);
     155           78 :     HCCL_INFO("Ccu Slice Split: m = %llu, n = %llu, p = %llu", m, n, p);
     156              : 
     157              :     // 数据量 < 256K, 跳过LoopGroup0
     158              :     // 此时loopIterNum == 0
     159              :     // 可以以此做为跳过LoopGroup0的条件
     160           26 :     offset = moCfg.memSlice * moCfg.loopCount * m;
     161              :     // 未实现, 这里可以只传入m, 在内部通过加法获得完整的参数
     162           26 :     loopIterNum = m;
     163              : 
     164           26 :     if (n == 0 && p == 0) {
     165              :         // 数据量为256K的整数倍,跳过LoopGroup1
     166              :         // 此时tailSize = 0,可以依次做为跳过LoopGroup1的条件
     167            3 :         loopExtendNum = 0; // loopExtendNum 赋值
     168            3 :         tailSize      = 0; // tailSize 赋值
     169           23 :     } else if (n != 0 && p == 0) {
     170              :         // 数据量为256K * m + 4K * n
     171              :         // 因为p == 0, 所以只需要使用第一个Loop, 数据量4K, 展开成n次
     172            4 :         loopExtendNum = CcuRep::GetParallelParam(n - 1, 0, 1); // loopExtendNum 赋值
     173            4 :         tailSize      = moCfg.memSlice;                     // tailSize 赋值
     174           19 :     } else if (n == 0 && p != 0) {
     175              :         // 数据量为256K * m + p
     176              :         // 因为n == 0, 所以只需要使用第一个Loop, 数据量p, 不展开
     177           11 :         loopExtendNum = CcuRep::GetParallelParam(0, 0, 1); // loopExtendNum 赋值
     178           11 :         tailSize      = p;                                 // tailSize 赋值
     179              :     } else {
     180            8 :         loopExtendNum = CcuRep::GetParallelParam(n - 1, 1, 2); // loopExtendNum 赋值, 为2
     181            8 :         tailSize      = p;                                     // tailSize 赋值
     182              :     }
     183              : 
     184           78 :     HCCL_INFO("offset = %lu, loopIterNum = %lu, loopExtendNum = %lu, tailSize = %lu", offset, loopIterNum,
     185              :                loopExtendNum, tailSize);
     186              : 
     187           78 :     return {offset, loopIterNum, loopExtendNum, tailSize};
     188              : }
     189              : 
     190            6 : CcuRep::Variable CcuContext::CreateVariable(const CcuTransport &transport, uint32_t varIndex) const
     191              : {
     192            6 :     CcuRep::Variable var;
     193            6 :     var.Reset(transport.GetLocXnByIndex(varIndex), transport.GetDieId());
     194            6 :     return var;
     195            0 : }
     196              : 
     197            6 : CcuRep::Variable CcuContext::ImportVariable(const std::string &tag)
     198              : {
     199            6 :     CcuRep::Variable var;
     200            6 :     importRes.sharedVar.insert({tag, var});
     201            6 :     return var;
     202            0 : }
     203              : 
     204            6 : void CcuContext::ExportVariable(const CcuRep::Variable &var, const std::string &tag)
     205              : {
     206            6 :     exportRes.sharedVar.insert({tag, var});
     207            6 : }
     208              : 
     209           14 : CcuRep::MaskSignal CcuContext::ImportMaskSignal(const std::string &tag)
     210              : {
     211           14 :     CcuRep::MaskSignal sig;
     212           14 :     importRes.sharedSig.insert({tag, sig});
     213           14 :     return sig;
     214            0 : }
     215              : 
     216           14 : void CcuContext::ExportMaskSignal(const CcuRep::MaskSignal &sig, const std::string &tag)
     217              : {
     218           14 :     exportRes.sharedSig.insert({tag, sig});
     219           14 : }
     220              : 
     221           10 : CcuSharedResource &CcuContext::GetExportRes()
     222              : {
     223           10 :     return exportRes;
     224              : }
     225              : 
     226            7 : CcuSharedResource &CcuContext::GetImportRes()
     227              : {
     228            7 :     return importRes;
     229              : }
     230              : 
     231            9 : CcuRepResource &CcuContext::GetResource()
     232              : {
     233            9 :     return res;
     234              : }
     235              : 
     236           15 : CcuResReq CcuContext::GetResourceRequest()
     237              : {
     238           15 :     CcuResReq req;
     239           15 :     uint32_t dieId = GetDieId();
     240           15 :     req.msReq[dieId]              = res.ccubuffers[dieId].size();
     241           15 :     req.blockMsReq[dieId]         = res.blockCcubuffers[dieId].size();
     242           15 :     req.ckeReq[dieId]             = res.maskSignal[dieId].size();
     243           15 :     req.blockCkeReq[dieId]        = res.blockMaskSignal[dieId].size();
     244           15 :     req.loopEngineReq[dieId]      = res.executor[dieId].size();
     245           15 :     req.blockLoopEngineReq[dieId] = res.blockExecutor[dieId].size();
     246           15 :     req.gsaReq[dieId]             = res.address[dieId].size();
     247           15 :     req.blockGsaReq[dieId]        = res.blockAddress[dieId].size();
     248           15 :     req.xnReq[dieId]              = res.variable[dieId].size();
     249           15 :     req.blockXnReq[dieId]         = res.continuousVariable[dieId].size();
     250              : 
     251           15 :     req.missionReq.reqType           = MissionReqType::FUSION_MULTIPLE_DIE;
     252           15 :     req.missionReq.req[dieId] = 1;
     253              : 
     254              :     auto info
     255              :         = StringFormat("resource request: dieId[%u], ms[%u], blockMs[%u], cke[%u], blockCke[%u], "
     256              :                        "loopEngine[%u], blockLoopEngine[%u], gsa[%u], blockGsa[%u], xn[%u], block xn[%u], missionId[%u]",
     257           60 :                        dieId, req.msReq[dieId], req.blockMsReq[dieId], req.ckeReq[dieId], req.blockCkeReq[dieId],
     258           30 :                        req.loopEngineReq[dieId], req.blockLoopEngineReq[dieId],
     259           45 :                        req.gsaReq[dieId], req.blockGsaReq[dieId], req.xnReq[dieId],
     260           15 :                        req.blockXnReq[dieId], req.missionReq.req[dieId]);
     261              : 
     262           45 :     HCCL_INFO("%s", info.c_str());
     263              : 
     264           30 :     return req;
     265           15 : }
     266              : 
     267          194 : void CcuContext::Load(const CcuRep::Variable &var)
     268              : {
     269              :     // 记录goSize相关变量对应的task argIndex
     270          194 :     auto loadArgRep = std::make_shared<CcuRep::CcuRepLoadArg>(var, loadArgIndex % CCU_SQE_ARGS_LEN);
     271          194 :     GetLGProfilingInfo().loadRep2ArgIdxMap[loadArgRep] = loadArgIndex;
     272          194 :     Append(loadArgRep);
     273          194 :     loadArgIndex++;
     274          194 : }
     275              : 
     276            0 : void CcuContext::LoadVariable(uint64_t addr, const CcuRep::Variable &var)
     277              : {
     278            0 :     Append(std::make_shared<CcuRep::CcuRepLoad>(addr, var));
     279            0 : }
     280              : 
     281            0 : void CcuContext::LoadVariable(uint64_t addr, const CcuRep::Variable &var, uint32_t num)
     282              : {
     283            0 :     Append(std::make_shared<CcuRep::CcuRepLoad>(addr, var, num));
     284            0 : }
     285              : 
     286            0 : void CcuContext::StoreVariable(const CcuRep::Variable &var, uint64_t addr)
     287              : {
     288            0 :     Append(std::make_shared<CcuRep::CcuRepStore>(var, addr));
     289            0 : }
     290              : 
     291            4 : void CcuContext::LoadVariable(const CcuRep::Variable &src, const CcuRep::Variable &var, uint32_t num)
     292              : {
     293            4 :     Append(std::make_shared<CcuRep::CcuRepLoadVar>(src, var, num));
     294            4 : }
     295              : 
     296            4 : void CcuContext::StoreVariable(const CcuRep::Variable &var, const CcuRep::Variable &src)
     297              : {
     298            4 :     Append(std::make_shared<CcuRep::CcuRepStoreVar>(src, var));
     299            4 : }
     300              : 
     301           18 : void CcuContext::Load(GroupOpSize moSize)
     302              : {
     303           18 :     Load(moSize.addrOffset);
     304           18 :     Load(moSize.loopParam);
     305           18 :     Load(moSize.parallelParam);
     306           18 :     Load(moSize.residual);
     307           18 : }
     308              : 
     309            9 : void CcuContext::LocalCtxPost(const CcuRep::MaskSignal &sig, uint32_t mask)
     310              : {
     311            9 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     312            0 :         THROW<CcuApiException>("LocalCtxPost is not allowed in LoopBlock");
     313              :     }
     314            9 :     Append(std::make_shared<CcuRep::CcuRepPostSharedSem>(sig, mask));
     315            9 : }
     316              : 
     317            4 : void CcuContext::LocalCtxPostVar(const CcuRep::Variable &srcVar, const CcuRep::Variable &dstVar,
     318              :                                  const CcuRep::MaskSignal &sig, uint32_t mask)
     319              : {
     320            4 :     Append(std::make_shared<CcuRep::CcuRepPostSharedVar>(srcVar, dstVar, sig, mask));
     321            4 : }
     322              : 
     323            9 : void CcuContext::LocalPost(const CcuRep::MaskSignal &sig, uint32_t mask)
     324              : {
     325            9 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     326            0 :         THROW<CcuApiException>("LocalPost is not allowed in LoopBlock");
     327              :     }
     328            9 :     auto rep = std::make_shared<CcuRep::CcuRepLocPostSem>(sig, mask);
     329            9 :     Append(rep);
     330            9 :     SetDependencyInfo(sig.Id(), mask, rep);
     331            9 : }
     332              : 
     333          116 : void CcuContext::LocalWait(const CcuRep::MaskSignal &sig, uint32_t mask)
     334              : {
     335          116 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     336           71 :         Append(std::make_shared<CcuRep::CcuRepLocWaitSem>(sig, mask, false));
     337              :     } else {
     338           45 :         auto rep = std::make_shared<CcuRep::CcuRepLocWaitSem>(sig, mask, true);
     339           90 :         AddProfiling("LocalWait", mask);
     340           45 :         rep->SetDependencyInfo(GetDependencyInfo(sig.Id()));
     341           45 :         ClearDependencyInfo();
     342           45 :         Append(rep);
     343           45 :     }
     344          116 : }
     345              : 
     346           25 : void CcuContext::RemotePost(const CcuTransport &transport, uint32_t signalIndex, uint32_t mask, bool single)
     347              : {
     348           25 :     Append(std::make_shared<CcuRep::CcuRepRemPostSem>(transport, signalIndex, mask, single));
     349           25 : }
     350              : 
     351          333 : void CcuContext::WriteVariableWithSignal(const CcuTransport &transport, const CcuRep::Variable &var, uint32_t varIndex,
     352              :                                          uint32_t signalIndex, uint32_t mask)
     353              : {
     354          333 :     Append(std::make_shared<CcuRep::CcuRepRemPostVar>(var, transport, varIndex, signalIndex, mask));
     355          333 : }
     356              : 
     357           34 : void CcuContext::RemoteWait(const CcuTransport &transport, uint32_t signalIndex, uint32_t mask)
     358              : {
     359           34 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     360            1 :         Append(std::make_shared<CcuRep::CcuRepRemWaitSem>(transport, signalIndex, mask, false));
     361              :     } else {
     362           33 :         auto rep = std::make_shared<CcuRep::CcuRepRemWaitSem>(transport, signalIndex, mask, true);
     363           66 :         AddProfiling(transport, "RemoteWait", signalIndex, mask);
     364           33 :         Append(rep);
     365           33 :     }
     366           34 : }
     367              : 
     368           49 : void CcuContext::GroupWait(const CcuTransportGroup &transportGroup, uint32_t signalIndex, uint32_t mask)
     369              : {
     370           49 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     371            1 :         Append(std::make_shared<CcuRep::CcuRepWaitGroup>(transportGroup, signalIndex, mask, false));
     372              :     } else {
     373           48 :         auto rep = std::make_shared<CcuRep::CcuRepWaitGroup>(transportGroup, signalIndex, mask, true);
     374           96 :         AddProfiling(transportGroup, "GroupWait", signalIndex, mask);
     375           48 :         Append(rep);
     376           48 :     }
     377           49 : }
     378              : 
     379           14 : void CcuContext::Read(const CcuTransport &transport, const CcuRep::CcuBuffer &loc, const CcuRep::Memory &rem,
     380              :                       const CcuRep::Variable &len, const CcuRep::MaskSignal &locSig, uint32_t mask)
     381              : {
     382           14 :     auto rep = std::make_shared<CcuRep::CcuRepBufRead>(transport, rem, loc, len, locSig, mask);
     383           14 :     Append(rep);
     384           14 :     SetDependencyInfo(locSig.Id(), mask, rep);
     385           14 : }
     386              : 
     387          196 : void CcuContext::Write(const CcuTransport &transport, const CcuRep::Memory &rem, const CcuRep::CcuBuffer &loc,
     388              :                        const CcuRep::Variable &len, const CcuRep::MaskSignal &locSig, uint32_t mask)
     389              : {
     390          196 :     auto rep = std::make_shared<CcuRep::CcuRepBufWrite>(transport, loc, rem, len, locSig, mask);
     391          196 :     Append(rep);
     392          196 :     SetDependencyInfo(locSig.Id(), mask, rep);
     393          196 : }
     394              : 
     395            9 : static bool isLowPrecisionIn(DataType dataType)
     396              : {
     397           15 :     return dataType == DataType::INT8 || dataType == DataType::HIF8 || dataType == DataType::FP8E4M3
     398           15 :            || dataType == DataType::FP8E5M2;
     399              : }
     400              : 
     401            2 : static bool isLowPrecisionOut(DataType dataType)
     402              : {
     403            2 :     return dataType == DataType::FP16 || dataType == DataType::BFP16 || dataType == DataType::FP32;
     404              : }
     405              : 
     406           10 : void CcuContext::LocalReduce(const std::vector<CcuRep::CcuBuffer> &bufs, uint32_t count, DataType dataType,
     407              :                      DataType outputDataType, ReduceOp opType, const CcuRep::MaskSignal &locSig,
     408              :                      const CcuRep::Variable &len, uint32_t mask)
     409              : {
     410           15 :     if ((opType == ReduceOp::SUM && isLowPrecisionIn(dataType) && !isLowPrecisionOut(outputDataType))
     411            9 :         || (opType == ReduceOp::SUM && !isLowPrecisionIn(dataType) && dataType != outputDataType)
     412           20 :         || (opType != ReduceOp::SUM && dataType != outputDataType)) {
     413            9 :         THROW<CcuApiException>("Unsupported inputDataType[%s], outputDataType[%s] for reduceOp[%s]",
     414           15 :                                dataType.Describe().c_str(), outputDataType.Describe().c_str(),
     415            9 :                                opType.Describe().c_str());
     416              :     }
     417              : 
     418            0 :     auto rep = std::make_shared<CcuRep::CcuRepBufReduce>(bufs, count, CcuRep::GetCcuDataType(dataType, opType),
     419            7 :                                                      CcuRep::GetCcuDataType(outputDataType, opType),
     420           14 :                                                      CcuRep::GetCcuReduceType(opType), locSig, len, mask);
     421            6 :     Append(rep);
     422            6 :     SetDependencyInfo(locSig.Id(), mask, rep);
     423            6 : }
     424              : 
     425            1 : void CcuContext::Read(const CcuTransport &transport, const CcuRep::Memory &loc, const CcuRep::Memory &rem,
     426              :                       const CcuRep::Variable &len, const CcuRep::MaskSignal &locSig, uint32_t mask)
     427              : {
     428            1 :     auto rep = std::make_shared<CcuRep::CcuRepRead>(transport, loc, rem, len, locSig, mask);
     429            1 :     Append(rep);
     430            1 :     SetDependencyInfo(locSig.Id(), mask, rep);
     431            1 : }
     432              : 
     433            1 : void CcuContext::ReadReduce(const CcuTransport &transport, const CcuRep::Memory &loc, const CcuRep::Memory &rem,
     434              :                             const CcuRep::Variable &len, DataType dataType, ReduceOp opType,
     435              :                             const CcuRep::MaskSignal &locSig, uint32_t mask)
     436              : {
     437            0 :     auto rep = std::make_shared<CcuRep::CcuRepRead>(transport, loc, rem, len, CcuRep::GetUBDataType(dataType),
     438            1 :                                                 CcuRep::GetUBReduceType(opType), locSig, mask);
     439            1 :     Append(rep);
     440            1 :     SetDependencyInfo(locSig.Id(), mask, rep);
     441            1 : }
     442              : 
     443            9 : void CcuContext::Write(const CcuTransport &transport, const CcuRep::Memory &rem, const CcuRep::Memory &loc,
     444              :                        const CcuRep::Variable &len, const CcuRep::MaskSignal &locSig, uint32_t mask)
     445              : {
     446            9 :     auto rep = std::make_shared<CcuRep::CcuRepWrite>(transport, rem, loc, len, locSig, mask);
     447            9 :     Append(rep);
     448            9 :     SetDependencyInfo(locSig.Id(), mask, rep);
     449            9 : }
     450              : 
     451            1 : void CcuContext::WriteReduce(const CcuTransport &transport, const CcuRep::Memory &rem, const CcuRep::Memory &loc,
     452              :                              const CcuRep::Variable &len, DataType dataType, ReduceOp opType,
     453              :                              const CcuRep::MaskSignal &locSig, uint32_t mask)
     454              : {
     455            0 :     auto rep = std::make_shared<CcuRep::CcuRepWrite>(transport, rem, loc, len, CcuRep::GetUBDataType(dataType),
     456            1 :                                                  CcuRep::GetUBReduceType(opType), locSig, mask);
     457            1 :     Append(rep);
     458            1 :     SetDependencyInfo(locSig.Id(), mask, rep);                                                 
     459            1 : }
     460              : 
     461            1 : void CcuContext::LocalCopy(const CcuRep::Memory &dst, const CcuRep::Memory &src, const CcuRep::Variable &len,
     462              :                            const CcuRep::MaskSignal &locSig, uint32_t mask)
     463              : {
     464            1 :     auto rep = std::make_shared<CcuRep::CcuRepLocCpy>(dst, src, len, locSig, mask);
     465            1 :     Append(rep);
     466            1 :     SetDependencyInfo(locSig.Id(), mask, rep);
     467            1 : }
     468              : 
     469           34 : void CcuContext::LocalCopy(const CcuRep::CcuBuffer &dst, const CcuRep::Memory &src, const CcuRep::Variable &len,
     470              :                            const CcuRep::MaskSignal &locSig, uint32_t mask)
     471              : {
     472           34 :     auto rep = std::make_shared<CcuRep::CcuRepBufLocRead>(src, dst, len, locSig, mask);
     473           34 :     Append(rep);
     474           34 :     SetDependencyInfo(locSig.Id(), mask, rep);
     475           34 : }
     476              : 
     477           34 : void CcuContext::LocalCopy(const CcuRep::Memory &dst, const CcuRep::CcuBuffer &src, const CcuRep::Variable &len,
     478              :                            const CcuRep::MaskSignal &locSig, uint32_t mask)
     479              : {
     480           34 :     auto rep = std::make_shared<CcuRep::CcuRepBufLocWrite>(src, dst, len, locSig, mask);
     481           34 :     Append(rep);
     482           34 :     SetDependencyInfo(locSig.Id(), mask, rep);
     483           34 : }
     484              : 
     485            1 : void CcuContext::LocalReduce(const CcuRep::Memory &dst, const CcuRep::Memory &src, const CcuRep::Variable &len,
     486              :                              DataType dataType, ReduceOp opType, const CcuRep::MaskSignal &locSig, uint32_t mask)
     487              : {
     488            1 :     auto rep = std::make_shared<CcuRep::CcuRepLocCpy>(dst, src, len, CcuRep::GetUBDataType(dataType), CcuRep::GetUBReduceType(opType),
     489            1 :                                                   locSig, mask);
     490            1 :     Append(rep);
     491            1 :     SetDependencyInfo(locSig.Id(), mask, rep);                                                  
     492            1 : }
     493              : 
     494            1 : void CcuContext::CreateMultiOpCopy()
     495              : {
     496            1 :     AllocGoResource(CCU_MS_LOCAL_COPY_LOOP_COUNT, LOCAL_COPY_MS_PER_LOOP);
     497            1 :     std::string loopType = "localcopy";
     498            1 :     if (registeredLoop.find(loopType) != registeredLoop.end()) {
     499            0 :         return;
     500              :     }
     501              : 
     502            1 :     uint32_t usedBufNum = moConfig.memSlice / CcuRep::CCU_MS_SIZE;
     503              : 
     504            3 :     for (uint32_t index = 0; index < 2; index++) { // 需要实现化2个Loop
     505            2 :         CcuRep::Memory    src = CreateMemory();
     506            2 :         CcuRep::Memory    dst = CreateMemory();
     507            2 :         CcuRep::Variable  len = CreateVariable();
     508            2 :         CcuRep::LoopBlock lb(this, loopType + "_loop_" + std::to_string(index));
     509            2 :         lb(src, dst, len);
     510              : 
     511            2 :         CcuRep::MaskSignal sem = moRes.maskSignal[index];
     512              : 
     513            2 :         std::vector<CcuRep::CcuBuffer> bufs = {moRes.ccuBuffer.begin() + index * moConfig.msInterleave,
     514            4 :                                                moRes.ccuBuffer.begin() + index * moConfig.msInterleave + usedBufNum};
     515              : 
     516            2 :         LocalCopy(bufs[0], src, len, sem);
     517            2 :         LocalWait(sem);
     518            2 :         LocalCopy(dst, bufs[0], len, sem);
     519            2 :         LocalWait(sem);
     520            2 :     }
     521              : 
     522            1 :     registeredLoop.insert(loopType);
     523            1 :     return;
     524            1 : }
     525              : 
     526            1 : void CcuContext::GroupCopy(CcuRep::Memory dst, CcuRep::Memory src, GroupOpSize goSize)
     527              : {
     528            1 :     CcuRep::Memory tmpDst = CreateMemory();
     529            1 :     tmpDst = dst;
     530            1 :     CcuRep::Memory tmpSrc = CreateMemory();
     531            1 :     tmpSrc = src;
     532              : 
     533            1 :     CreateMultiOpCopy();
     534            2 :     CCU_IF(goSize.addrOffset != 0)
     535              :     {
     536            1 :         CcuRep::Variable loopParam = CreateVariable();
     537            1 :         loopParam                  = CcuRep::GetLoopParam(0, moConfig.memSlice * moConfig.loopCount, 0);
     538            1 :         loopParam += goSize.loopParam;
     539              : 
     540            1 :         CcuRep::Variable sliceSize = CreateVariable();
     541            1 :         sliceSize                  = moConfig.memSlice;
     542            1 :         auto lc                    = Loop("localcopy_loop_0")(tmpSrc, tmpDst, sliceSize);
     543              : 
     544            1 :         CcuRep::Variable paraCfg   = CreateVariable();
     545            1 :         paraCfg                    = CcuRep::GetParallelParam(moConfig.loopCount - 1, 0, 1);
     546            1 :         CcuRep::Variable offsetCfg = CreateVariable();
     547            1 :         offsetCfg                  = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     548            6 :         LoopGroup({lc}, {loopParam}, paraCfg, offsetCfg);
     549            2 :     }
     550              : 
     551            2 :     CCU_IF(goSize.parallelParam != 0)
     552              :     {
     553            1 :         CcuRep::Condition cond(this, goSize.parallelParam != 0);
     554              : 
     555            1 :         tmpSrc.addr += goSize.addrOffset;
     556            1 :         tmpDst.addr += goSize.addrOffset;
     557            1 :         auto lc0 = Loop("localcopy_loop_0")(tmpSrc, tmpDst, goSize.residual);
     558              : 
     559            1 :         tmpSrc.addr += goSize.residual;
     560            1 :         tmpDst.addr += goSize.residual;
     561            1 :         CcuRep::Variable sliceSize = CreateVariable();
     562            1 :         sliceSize                  = moConfig.memSlice;
     563            1 :         auto lc1                   = Loop("localcopy_loop_1")(tmpSrc, tmpDst, sliceSize);
     564              : 
     565            1 :         CcuRep::Variable loopCfg0  = CreateVariable();
     566            1 :         loopCfg0                   = CcuRep::GetLoopParam(0, 0, 1);
     567            1 :         CcuRep::Variable loopCfg1  = CreateVariable();
     568            1 :         loopCfg1                   = CcuRep::GetLoopParam(0, 0, 1);
     569            1 :         CcuRep::Variable offsetCfg = CreateVariable();
     570            1 :         offsetCfg                  = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     571            8 :         LoopGroup({lc0, lc1}, {loopCfg0, loopCfg1}, goSize.parallelParam, offsetCfg);
     572            2 :     }
     573            5 : }
     574              : 
     575           14 : void CcuContext::CreateMultiOpBroadcast(const std::vector<CcuTransport *> &transports)
     576              : {
     577           14 :     AllocGoResource();
     578              : 
     579           14 :     std::string loopType = "broadcast";
     580           14 :     if (registeredLoop.find(loopType) != registeredLoop.end()) {
     581            0 :         return;
     582              :     }
     583              : 
     584           14 :     uint32_t size = transports.size() + 1;
     585              : 
     586           42 :     for (uint32_t index = 0; index < 2; index++) { // 需要实现化2个Loop
     587           28 :         CcuRep::Memory              src = CreateMemory();
     588           28 :         std::vector<CcuRep::Memory> dst;
     589          252 :         for (uint32_t i = 0; i < size; i++) {
     590          224 :             dst.emplace_back(CreateMemory());
     591              :         }
     592           28 :         CcuRep::Variable            len = CreateVariable();
     593           28 :         CcuRep::LoopBlock           lb(this, loopType + "_loop_" + std::to_string(index));
     594           28 :         lb(src, dst, len);
     595              : 
     596           28 :         CcuRep::CcuBuffer  buf = moRes.ccuBuffer[index * moConfig.msInterleave];
     597           28 :         CcuRep::MaskSignal sem = moRes.maskSignal[index];
     598              : 
     599           28 :         LocalCopy(buf, src, len, sem);
     600           28 :         LocalWait(sem);
     601              : 
     602          224 :         for (uint32_t i = 0; i < transports.size(); i++) {
     603          196 :             if (transports[i] == nullptr) {
     604            0 :                 THROW<CcuApiException>("transport is nullptr");
     605              :             }
     606          196 :             Write(*transports[i], dst[i], buf, len, sem, 1 << i);
     607              :         }
     608           28 :         LocalCopy(dst[size - 1], buf, len, sem, 1 << (size - 1));
     609           28 :         LocalWait(sem, (1 << size) - 1);
     610           28 :     }
     611              : 
     612           14 :     registeredLoop.insert(loopType);
     613           14 : }
     614              : 
     615            0 : void CcuContext::CreateMultiOpBroadcastWithoutMyRank(const std::vector<CcuTransport *> &ccuTransports)
     616              : {
     617            0 :     AllocGoResource();
     618              : 
     619            0 :     std::string loopType = "broadcast";
     620            0 :     if (registeredLoop.find(loopType) != registeredLoop.end()) {
     621            0 :         return;
     622              :     }
     623              : 
     624            0 :     uint32_t size = ccuTransports.size() + 1;
     625              : 
     626            0 :     for (uint32_t index = 0; index < 2; index++) { // 需要实现化2个Loop
     627            0 :         CcuRep::Memory              src = CreateMemory();
     628            0 :         std::vector<CcuRep::Memory> dst;
     629            0 :         for (uint32_t i = 0; i < size; i++) {
     630            0 :             dst.emplace_back(CreateMemory());
     631              :         }
     632            0 :         CcuRep::Variable            len = CreateVariable();
     633            0 :         CcuRep::LoopBlock           lb(this, loopType + "_loop_" + std::to_string(index));
     634            0 :         lb(src, dst, len);
     635              : 
     636            0 :         CcuRep::CcuBuffer  buf = moRes.ccuBuffer[index * moConfig.msInterleave];
     637            0 :         CcuRep::MaskSignal sem = moRes.maskSignal[index];
     638              : 
     639            0 :         LocalCopy(buf, src, len, sem);
     640            0 :         LocalWait(sem);
     641              : 
     642            0 :         for (uint32_t i = 0; i < ccuTransports.size(); i++) {
     643            0 :             if (ccuTransports[i] == nullptr) {
     644            0 :                 THROW<CcuApiException>("transport is nullptr");
     645              :             }
     646            0 :             Write(*ccuTransports[i], dst[i], buf, len, sem, 1 << i);
     647              :         }
     648            0 :         LocalWait(sem, (1 << ccuTransports.size()) - 1);
     649            0 :     }
     650              : 
     651            0 :     registeredLoop.insert(loopType);
     652            0 : }
     653              : 
     654            0 : void CcuContext::GroupBroadcastWithoutMyRank(const std::vector<CcuTransport*> &ccuTransports, std::vector<CcuRep::Memory> dst,
     655              :                                 CcuRep::Memory src, GroupOpSize goSize)
     656              : {
     657            0 :     CreateMultiOpBroadcastWithoutMyRank(ccuTransports);
     658              : 
     659            0 :     uint32_t size = ccuTransports.size() + 1;
     660              : 
     661            0 :     CCU_IF(goSize.addrOffset != 0)
     662              :     {
     663            0 :         CcuRep::Variable loopParam = CreateVariable();
     664            0 :         loopParam = CcuRep::GetLoopParam(0, moConfig.memSlice * moConfig.loopCount, 0);
     665            0 :         loopParam += goSize.loopParam;
     666              : 
     667            0 :         CcuRep::Variable sliceSize = CreateVariable();
     668            0 :         sliceSize = moConfig.memSlice;
     669            0 :         auto lc   = Loop("broadcast_loop_0")(src, dst, sliceSize);
     670              : 
     671            0 :         CcuRep::Variable paraCfg = CreateVariable();
     672            0 :         paraCfg = CcuRep::GetParallelParam(moConfig.loopCount - 1, 0, 1);
     673            0 :         CcuRep::Variable offsetCfg = CreateVariable();
     674            0 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     675              : 
     676            0 :         LoopGroup({lc}, {loopParam}, paraCfg, offsetCfg);
     677            0 :         AddCcuProfiling(goSize, ccuTransports);
     678            0 :     }
     679              : 
     680            0 :     CCU_IF(goSize.parallelParam != 0)
     681              :     {
     682            0 :         src.addr += goSize.addrOffset;
     683            0 :         for (uint32_t i = 0; i < size; i++) {
     684            0 :             dst[i].addr += goSize.addrOffset;
     685              :         }
     686              : 
     687            0 :         auto lc0 = Loop("broadcast_loop_0")(src, dst, goSize.residual);
     688              : 
     689            0 :         src.addr += goSize.residual;
     690            0 :         for (uint32_t i = 0; i < size; i++) {
     691            0 :             dst[i].addr += goSize.residual;
     692              :         }
     693              : 
     694            0 :         CcuRep::Variable sliceSize = CreateVariable();
     695            0 :         sliceSize = moConfig.memSlice;
     696            0 :         auto lc1  = Loop("broadcast_loop_1")(src, dst, sliceSize);
     697              : 
     698            0 :         CcuRep::Variable loopCfg0 = CreateVariable();
     699            0 :         loopCfg0 = CcuRep::GetLoopParam(0, 0, 1);
     700            0 :         CcuRep::Variable loopCfg1 = CreateVariable();
     701            0 :         loopCfg1 = CcuRep::GetLoopParam(0, 0, 1);
     702            0 :         CcuRep::Variable offsetCfg = CreateVariable();
     703            0 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     704              : 
     705            0 :         LoopGroup({lc0, lc1}, {loopCfg0, loopCfg1}, goSize.parallelParam, offsetCfg);
     706            0 :         AddCcuProfiling(goSize, ccuTransports);
     707            0 :     }
     708            0 : }
     709              : 
     710            0 : void CcuContext::CreateMultiOpReduceWithoutMyRank(const std::vector<CcuTransport*> &ccuTransports, DataType dataType,
     711              :                                      DataType outputDataType, ReduceOp opType)
     712              : {
     713            0 :     AllocGoResource();
     714              : 
     715            0 :     std::string loopType = CcuRep::GetReduceTypeStr(dataType, opType);
     716            0 :     if (registeredLoop.find(loopType) != registeredLoop.end()) {
     717            0 :         return;
     718              :     }
     719              : 
     720            0 :     uint32_t size         = ccuTransports.size();
     721            0 :     uint32_t expansionNum = CcuRep::GetReduceExpansionNum(opType, dataType, outputDataType);
     722            0 :     uint32_t usedBufNum   = size > expansionNum ? size : expansionNum;
     723              : 
     724            0 :     for (int32_t index = 0; index < 2; index++) { // 需要实现化2个Loop
     725            0 :         std::vector<CcuRep::Memory> src;
     726            0 :         for (uint32_t i = 0; i < size; i++) {
     727            0 :             src.emplace_back(CreateMemory());
     728              :         }
     729            0 :         CcuRep::Memory              dst = CreateMemory();
     730            0 :         CcuRep::Variable            len = CreateVariable();
     731            0 :         CcuRep::Variable            lenForExpansion = CreateVariable();
     732            0 :         CcuRep::LoopBlock           lb(this, loopType + "_loop_" + std::to_string(index));
     733            0 :         lb(src, dst, len, lenForExpansion);
     734              : 
     735            0 :         std::vector<CcuRep::CcuBuffer> bufs = {moRes.ccuBuffer.begin() + index * moConfig.msInterleave,
     736            0 :                                                moRes.ccuBuffer.begin() + index * moConfig.msInterleave + usedBufNum};
     737            0 :         CcuRep::MaskSignal             sem  = moRes.maskSignal[index];
     738            0 :         for (uint32_t i = 0; i < ccuTransports.size(); i++) {
     739            0 :             if (ccuTransports[i] == nullptr) {
     740            0 :                 THROW<CcuApiException>("transport is nullptr");
     741              :             }
     742            0 :             Read(*ccuTransports[i], bufs[i], src[i], len, sem, 1 << i);
     743              :         }
     744            0 :         LocalWait(sem, (1 << size) - 1);
     745              : 
     746            0 :         if (size > 1) {
     747            0 :             LocalReduce(bufs, size, dataType, outputDataType, opType, sem, len);
     748            0 :             LocalWait(sem);
     749              :         }
     750              : 
     751            0 :         LocalCopy(dst, bufs[0], lenForExpansion, sem);
     752              : 
     753            0 :         LocalWait(sem);
     754            0 :     }
     755              : 
     756            0 :     registeredLoop.insert(loopType);
     757            0 : }
     758              : 
     759            0 : void CcuContext::GroupReduceWithoutMyRank(const std::vector<CcuTransport*> &ccuTransports, CcuRep::Memory &dst,
     760              :                                 std::vector<CcuRep::Memory> &src, GroupOpSize &goSize, DataType dataType,
     761              :                                 DataType outputDataType, ReduceOp opType)
     762              : {
     763            0 :     CreateMultiOpReduceWithoutMyRank(ccuTransports, dataType, outputDataType, opType);
     764              : 
     765            0 :     uint32_t         size         = src.size();
     766            0 :     uint32_t         expansionNum = CcuRep::GetReduceExpansionNum(opType, dataType, outputDataType);
     767            0 :     CcuRep::Variable sliceSizeExpansion = CreateVariable();
     768              : 
     769            0 :     if (expansionNum != 1) {
     770            0 :         CcuRep::Variable tmp = CreateVariable();
     771            0 :         tmp = CcuRep::GetExpansionParam(expansionNum);
     772            0 :         dst.token += tmp;
     773            0 :     }
     774              : 
     775            0 :     CCU_IF(goSize.loopParam != 0)
     776              :     {
     777            0 :         CcuRep::Variable loopParam = CreateVariable();
     778            0 :         loopParam = CcuRep::GetLoopParam(0, moConfig.memSlice * moConfig.loopCount, 0);
     779            0 :         loopParam += goSize.loopParam;
     780              : 
     781            0 :         CcuRep::Variable sliceSize = CreateVariable();
     782            0 :         sliceSize          = moConfig.memSlice;
     783            0 :         sliceSizeExpansion = moConfig.memSlice * expansionNum;
     784              : 
     785            0 :         auto lc = Loop(CcuRep::GetReduceTypeStr(dataType, opType) + "_loop_0")(src, dst, sliceSize, sliceSizeExpansion);
     786              : 
     787            0 :         CcuRep::Variable paraCfg = CreateVariable();
     788            0 :         paraCfg = CcuRep::GetParallelParam(moConfig.loopCount - 1, 0, 1);
     789            0 :         CcuRep::Variable offsetCfg = CreateVariable();
     790            0 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     791              : 
     792            0 :         LoopGroup({lc}, {loopParam}, paraCfg, offsetCfg);
     793            0 :         AddCcuProfiling(goSize, ccuTransports, dataType, outputDataType, opType);
     794            0 :     }
     795              : 
     796            0 :     CCU_IF(goSize.parallelParam != 0)
     797              :     {
     798            0 :         for (uint32_t i = 0; i < size; i++) {
     799            0 :             src[i].addr += goSize.addrOffset;
     800              :         }
     801            0 :         for (uint32_t i = 0; i < expansionNum; i++) {
     802            0 :             dst.addr += goSize.addrOffset;
     803              :         }
     804              : 
     805            0 :         sliceSizeExpansion = 0;
     806            0 :         for (uint32_t i = 0; i < expansionNum; i++) {
     807            0 :             sliceSizeExpansion += goSize.residual;
     808              :         }
     809              : 
     810            0 :         auto lc0 = Loop(CcuRep::GetReduceTypeStr(dataType, opType) + "_loop_0")(src, dst, goSize.residual, sliceSizeExpansion);
     811              : 
     812            0 :         for (uint32_t i = 0; i < size; i++) {
     813            0 :             src[i].addr += goSize.residual;
     814              :         }
     815            0 :         for (uint32_t i = 0; i < expansionNum; i++) {
     816            0 :             dst.addr += goSize.residual;
     817              :         }
     818              : 
     819            0 :         CcuRep::Variable sliceSize = CreateVariable();
     820            0 :         sliceSize          = moConfig.memSlice;
     821            0 :         sliceSizeExpansion = moConfig.memSlice * expansionNum;
     822              : 
     823            0 :         auto lc1 = Loop(CcuRep::GetReduceTypeStr(dataType, opType) + "_loop_1")(src, dst, sliceSize, sliceSizeExpansion);
     824              : 
     825            0 :         CcuRep::Variable loopCfg0 = CreateVariable();
     826            0 :         loopCfg0 = CcuRep::GetLoopParam(0, 0, 1);
     827            0 :         CcuRep::Variable loopCfg1 = CreateVariable();
     828            0 :         loopCfg1 = CcuRep::GetLoopParam(0, 0, 1);
     829            0 :         CcuRep::Variable offsetCfg = CreateVariable();
     830            0 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     831              : 
     832            0 :         LoopGroup({lc0, lc1}, {loopCfg0, loopCfg1}, goSize.parallelParam, offsetCfg);
     833            0 :         AddCcuProfiling(goSize, ccuTransports, dataType, outputDataType, opType);
     834            0 :     }
     835            0 : }
     836              : 
     837           14 : void CcuContext::GroupBroadcast(const std::vector<CcuTransport*> &transports, std::vector<CcuRep::Memory> dst,
     838              :                                 CcuRep::Memory src, GroupOpSize goSize)
     839              : {
     840           14 :     CreateMultiOpBroadcast(transports);
     841              : 
     842           14 :     uint32_t size = transports.size() + 1;
     843              : 
     844           28 :     CCU_IF(goSize.addrOffset != 0)
     845              :     {
     846           14 :         CcuRep::Variable loopParam = CreateVariable();
     847           14 :         loopParam = CcuRep::GetLoopParam(0, moConfig.memSlice * moConfig.loopCount, 0);
     848           14 :         loopParam += goSize.loopParam;
     849              : 
     850           14 :         CcuRep::Variable sliceSize = CreateVariable();
     851           14 :         sliceSize = moConfig.memSlice;
     852           14 :         auto lc   = Loop("broadcast_loop_0")(src, dst, sliceSize);
     853              : 
     854           14 :         CcuRep::Variable paraCfg = CreateVariable();
     855           14 :         paraCfg = CcuRep::GetParallelParam(moConfig.loopCount - 1, 0, 1);
     856           14 :         CcuRep::Variable offsetCfg = CreateVariable();
     857           14 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     858              : 
     859           84 :         LoopGroup({lc}, {loopParam}, paraCfg, offsetCfg);
     860           14 :         AddCcuProfiling(goSize, transports);
     861           28 :     }
     862              : 
     863           28 :     CCU_IF(goSize.parallelParam != 0)
     864              :     {
     865           14 :         src.addr += goSize.addrOffset;
     866          126 :         for (uint32_t i = 0; i < size; i++) {
     867          112 :             dst[i].addr += goSize.addrOffset;
     868              :         }
     869              : 
     870           14 :         auto lc0 = Loop("broadcast_loop_0")(src, dst, goSize.residual);
     871              : 
     872           14 :         src.addr += goSize.residual;
     873          126 :         for (uint32_t i = 0; i < size; i++) {
     874          112 :             dst[i].addr += goSize.residual;
     875              :         }
     876              : 
     877           14 :         CcuRep::Variable sliceSize = CreateVariable();
     878           14 :         sliceSize = moConfig.memSlice;
     879           14 :         auto lc1  = Loop("broadcast_loop_1")(src, dst, sliceSize);
     880              : 
     881           14 :         CcuRep::Variable loopCfg0 = CreateVariable();
     882           14 :         loopCfg0 = CcuRep::GetLoopParam(0, 0, 1);
     883           14 :         CcuRep::Variable loopCfg1 = CreateVariable();
     884           14 :         loopCfg1 = CcuRep::GetLoopParam(0, 0, 1);
     885           14 :         CcuRep::Variable offsetCfg = CreateVariable();
     886           14 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     887              : 
     888          112 :         LoopGroup({lc0, lc1}, {loopCfg0, loopCfg1}, goSize.parallelParam, offsetCfg);
     889           14 :         AddCcuProfiling(goSize, transports);
     890           28 :     }
     891           70 : }
     892              : 
     893            1 : void CcuContext::CreateMultiOpReduce(const std::vector<CcuTransport*> &transports, DataType dataType,
     894              :                                      DataType outputDataType, ReduceOp opType)
     895              : {
     896            1 :     AllocGoResource();
     897              : 
     898            1 :     std::string loopType = CcuRep::GetReduceTypeStr(dataType, opType);
     899            1 :     if (registeredLoop.find(loopType) != registeredLoop.end()) {
     900            0 :         return;
     901              :     }
     902              : 
     903            1 :     uint32_t size         = transports.size() + 1;
     904            1 :     uint32_t expansionNum = CcuRep::GetReduceExpansionNum(opType, dataType, outputDataType);
     905            1 :     uint32_t usedBufNum   = size > expansionNum ? size : expansionNum;
     906              : 
     907            3 :     for (int32_t index = 0; index < 2; index++) { // 需要实现化2个Loop
     908            2 :         std::vector<CcuRep::Memory> src;
     909           18 :         for (uint32_t i = 0; i < size; i++) {
     910           16 :             src.emplace_back(CreateMemory());
     911              :         }
     912            2 :         CcuRep::Memory              dst = CreateMemory();
     913            2 :         CcuRep::Variable            len = CreateVariable();
     914            2 :         CcuRep::Variable            lenForExpansion = CreateVariable();
     915            2 :         CcuRep::LoopBlock           lb(this, loopType + "_loop_" + std::to_string(index));
     916            2 :         lb(src, dst, len, lenForExpansion);
     917              : 
     918            2 :         std::vector<CcuRep::CcuBuffer> bufs = {moRes.ccuBuffer.begin() + index * moConfig.msInterleave,
     919            4 :                                                moRes.ccuBuffer.begin() + index * moConfig.msInterleave + usedBufNum};
     920            2 :         CcuRep::MaskSignal             sem  = moRes.maskSignal[index];
     921           16 :         for (uint32_t i = 0; i < transports.size(); i++) {
     922           14 :             if (transports[i] == nullptr) {
     923            0 :                 THROW<CcuApiException>("transport is nullptr");
     924              :             }
     925           14 :             Read(*transports[i], bufs[i], src[i], len, sem, 1 << i);
     926              :         }
     927            2 :         if (size > DATAT_SIZE_U32) {
     928            0 :             THROW<CcuApiException>("CcuContext::CreateMultiOpReduce size is invalide ,size[%u]", size);
     929              :         }
     930            2 :         LocalCopy(bufs[size - 1], src[size - 1], len, sem, 1 << (size - 1));
     931            2 :         LocalWait(sem, (1 << size) - 1);
     932              : 
     933            2 :         if (size > 1) {
     934            2 :             LocalReduce(bufs, size, dataType, outputDataType, opType, sem, len);
     935            2 :             LocalWait(sem);
     936              :         }
     937              : 
     938            2 :         LocalCopy(dst, bufs[0], lenForExpansion, sem);
     939              : 
     940            2 :         LocalWait(sem);
     941            2 :     }
     942              : 
     943            1 :     registeredLoop.insert(loopType);
     944            1 : }
     945              : 
     946            1 : void CcuContext::GroupReduce(const std::vector<CcuTransport*> &transports, CcuRep::Memory dst,
     947              :                              std::vector<CcuRep::Memory> src, GroupOpSize goSize, DataType dataType,
     948              :                              DataType outputDataType, ReduceOp opType)
     949              : {
     950            1 :     CreateMultiOpReduce(transports, dataType, outputDataType, opType);
     951              : 
     952            1 :     uint32_t         size         = transports.size() + 1;
     953            1 :     uint32_t         expansionNum = CcuRep::GetReduceExpansionNum(opType, dataType, outputDataType);
     954            1 :     CcuRep::Variable sliceSizeExpansion = CreateVariable();
     955              : 
     956            1 :     if (expansionNum != 1) {
     957            0 :         CcuRep::Variable tmp = CreateVariable();
     958            0 :         tmp = CcuRep::GetExpansionParam(expansionNum);
     959            0 :         dst.token += tmp;
     960            0 :     }
     961              : 
     962            2 :     CCU_IF(goSize.loopParam != 0)
     963              :     {
     964            1 :         CcuRep::Variable loopParam = CreateVariable();
     965            1 :         loopParam = CcuRep::GetLoopParam(0, moConfig.memSlice * moConfig.loopCount, 0);
     966            1 :         loopParam += goSize.loopParam;
     967              : 
     968            1 :         CcuRep::Variable sliceSize = CreateVariable();
     969            1 :         sliceSize          = moConfig.memSlice;
     970            1 :         sliceSizeExpansion = moConfig.memSlice * expansionNum;
     971              : 
     972            1 :         auto lc = Loop(CcuRep::GetReduceTypeStr(dataType, opType) + "_loop_0")(src, dst, sliceSize, sliceSizeExpansion);
     973              : 
     974            1 :         CcuRep::Variable paraCfg = CreateVariable();
     975            1 :         paraCfg = CcuRep::GetParallelParam(moConfig.loopCount - 1, 0, 1);
     976            1 :         CcuRep::Variable offsetCfg = CreateVariable();
     977            1 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
     978              : 
     979            6 :         LoopGroup({lc}, {loopParam}, paraCfg, offsetCfg);
     980            1 :         AddCcuProfiling(goSize, transports, dataType, outputDataType, opType);
     981            2 :     }
     982              : 
     983            2 :     CCU_IF(goSize.parallelParam != 0)
     984              :     {
     985            9 :         for (uint32_t i = 0; i < size; i++) {
     986            8 :             src[i].addr += goSize.addrOffset;
     987              :         }
     988            2 :         for (uint32_t i = 0; i < expansionNum; i++) {
     989            1 :             dst.addr += goSize.addrOffset;
     990              :         }
     991              : 
     992            1 :         sliceSizeExpansion = 0;
     993            2 :         for (uint32_t i = 0; i < expansionNum; i++) {
     994            1 :             sliceSizeExpansion += goSize.residual;
     995              :         }
     996              : 
     997            1 :         auto lc0 = Loop(CcuRep::GetReduceTypeStr(dataType, opType) + "_loop_0")(src, dst, goSize.residual, sliceSizeExpansion);
     998              : 
     999            9 :         for (uint32_t i = 0; i < size; i++) {
    1000            8 :             src[i].addr += goSize.residual;
    1001              :         }
    1002            2 :         for (uint32_t i = 0; i < expansionNum; i++) {
    1003            1 :             dst.addr += goSize.residual;
    1004              :         }
    1005              : 
    1006            1 :         CcuRep::Variable sliceSize = CreateVariable();
    1007            1 :         sliceSize          = moConfig.memSlice;
    1008            1 :         sliceSizeExpansion = moConfig.memSlice * expansionNum;
    1009              : 
    1010            1 :         auto lc1 = Loop(CcuRep::GetReduceTypeStr(dataType, opType) + "_loop_1")(src, dst, sliceSize, sliceSizeExpansion);
    1011              : 
    1012            1 :         CcuRep::Variable loopCfg0 = CreateVariable();
    1013            1 :         loopCfg0 = CcuRep::GetLoopParam(0, 0, 1);
    1014            1 :         CcuRep::Variable loopCfg1 = CreateVariable();
    1015            1 :         loopCfg1 = CcuRep::GetLoopParam(0, 0, 1);
    1016            1 :         CcuRep::Variable offsetCfg = CreateVariable();
    1017            1 :         offsetCfg = CcuRep::GetOffsetParam(moConfig.memSlice, moConfig.msInterleave, 1);
    1018              : 
    1019            8 :         LoopGroup({lc0, lc1}, {loopCfg0, loopCfg1}, goSize.parallelParam, offsetCfg);
    1020            1 :         AddCcuProfiling(goSize, transports, dataType, outputDataType, opType);
    1021            2 :     }
    1022            5 : }
    1023              : 
    1024            2 : CcuRep::FuncCall CcuContext::Func(const std::string &label)
    1025              : {
    1026            2 :     return CcuRep::FuncCall(this, label);
    1027              : }
    1028              : 
    1029            2 : CcuRep::FuncCall CcuContext::Func(const CcuRep::Variable &funcAddr)
    1030              : {
    1031            2 :     return CcuRep::FuncCall(this, funcAddr);
    1032              : }
    1033              : 
    1034           51 : CcuRep::LoopCall CcuContext::Loop(const std::string &label)
    1035              : {
    1036           51 :     return CcuRep::LoopCall(this, label);
    1037              : }
    1038              : 
    1039           34 : void CcuContext::LoopGroup(const std::vector<CcuRep::LoopCall> &loops, const std::vector<CcuRep::Variable> &loopCfg,
    1040              :                            const CcuRep::Variable &paraCfg, const CcuRep::Variable &offsetCfg)
    1041              : {
    1042           34 :     auto                          lgc = CcuRep::LoopGroupCall(this);
    1043           34 :     std::vector<CcuRep::Executor> executors;
    1044           85 :     for (size_t i = 0; i < loops.size(); i++) {
    1045           51 :         executors.push_back(moRes.executor[i]);
    1046              :     }
    1047           34 :     lgc.Run(loops, loopCfg, executors, paraCfg, offsetCfg);
    1048           34 : }
    1049              : 
    1050            6 : void CcuContext::SetResPack(CcuResPack &resPack)
    1051              : {
    1052            6 :     resPack_ = &resPack;
    1053            6 : }
    1054              : 
    1055            5 : CcuResPack* CcuContext::GetResPack() const
    1056              : {
    1057            5 :     return resPack_;
    1058              : }
    1059              : 
    1060            7 : void CcuContext::SetInstrId(uint32_t instrId)
    1061              : {
    1062           21 :     HCCL_INFO("[SetInstrId] Input params: instrId[%u]", instrId);
    1063            7 :     instrInfo.startInstrId = instrId;
    1064            7 : }
    1065              : 
    1066           43 : uint32_t CcuContext::GetInstrId() const
    1067              : {
    1068           43 :     return instrInfo.startInstrId;
    1069              : }
    1070              : 
    1071           16 : uint32_t CcuContext::GetInstrCount()
    1072              : {
    1073           16 :     uint32_t instrCount = 0;
    1074          636 :     for (const auto &rep : GetRepSequence()) {
    1075          620 :         instrCount += rep->InstrCount();
    1076              :     }
    1077           16 :     instrInfo.instrCount = instrCount;
    1078           48 :     HCCL_INFO("Ctx inst %u", instrCount);
    1079           16 :     return instrCount;
    1080              : }
    1081              : 
    1082           15 : void CcuContext::SetCcuInstrInfo(const CcuRep::CcuInstrInfo &instrInfo)
    1083              : {
    1084           45 :     HCCL_INFO("[SetCcuInstrInfo] Input params: instrVec size[%u], startInstrId[%u], instrCount[%u], missionStartInstrId[%u], missionInstrCount[%u]", 
    1085              :         instrInfo.instrVec.size(), instrInfo.startInstrId, instrInfo.instrCount, instrInfo.missionStartInstrId, instrInfo.missionInstrCount);
    1086           15 :     this->instrInfo = instrInfo;
    1087           15 : }
    1088              : 
    1089              : template <typename T>
    1090         1971 : T CcuContext::CreateResAssist(std::array<std::vector<T>, MAX_CCU_IODIE_NUM> &resRecord)
    1091              : {
    1092              :     // 获取DieId
    1093         1971 :     uint32_t dieId = GetDieId();
    1094              :     // 检查DieId是否越界
    1095         1971 :     if (dieId >= MAX_CCU_IODIE_NUM) {
    1096            0 :         THROW<CcuApiException>("dieId[%u] out of range[0, %u]", dieId, MAX_CCU_IODIE_NUM - 1);
    1097              :     }
    1098         1971 :     resRecord[dieId].emplace_back(this);
    1099              : 
    1100         1971 :     auto& item = resRecord[dieId].back();
    1101         1971 :     item.Reset(resRecord[dieId].size(), dieId);
    1102         1971 :     return item;
    1103              : }
    1104              : 
    1105         1438 : CcuRep::Variable CcuContext::CreateVariable()
    1106              : {
    1107         1438 :     return CreateResAssist(res.continuousVariable);
    1108              : }
    1109              : 
    1110           64 : CcuRep::Variable CcuContext::CreateContinuousVariable()
    1111              : {
    1112           64 :     return CreateResAssist(res.continuousVariable);
    1113              : }
    1114              : 
    1115          444 : CcuRep::Address CcuContext::CreateAddress()
    1116              : {
    1117          444 :     return CreateResAssist(res.blockAddress);
    1118              : }
    1119              : 
    1120           21 : CcuRep::MaskSignal CcuContext::CreateMaskSignal()
    1121              : {
    1122           21 :     return CreateResAssist(res.blockMaskSignal);
    1123              : }
    1124              : 
    1125            2 : CcuRep::CcuBuffer CcuContext::CreateCcuBuffer()
    1126              : {
    1127            2 :     return CreateResAssist(res.blockCcubuffers);
    1128              : }
    1129              : 
    1130            2 : CcuRep::Executor CcuContext::CreateExecutor()
    1131              : {
    1132            2 :     return CreateResAssist(res.blockExecutor);
    1133              : }
    1134              : 
    1135          437 : CcuRep::Memory CcuContext::CreateMemory()
    1136              : {
    1137          437 :     return CcuRep::Memory(CreateAddress(), CreateVariable());
    1138              : }
    1139              : 
    1140            0 : CcuRep::Memory CcuContext::GetRmtBuffer(const CcuTransport &transport, uint32_t index)
    1141              : {
    1142              :     (void)index;
    1143            0 :     auto mem = CcuRep::Memory(CreateAddress(), CreateVariable());
    1144            0 :     Append(std::make_shared<CcuRep::CcuRepRemMem>(transport, mem));
    1145            0 :     return mem;
    1146            0 : }
    1147              : 
    1148            1 : CcuRep::Memory CcuContext::CreateMemory(const CcuRep::Variable &token)
    1149              : {
    1150            2 :     return CcuRep::Memory(CreateAddress(), token);
    1151              : }
    1152              : 
    1153           21 : CcuContext::GroupOpSize CcuContext::CreateGroupOpSize()
    1154              : {
    1155           21 :     return GroupOpSize{CreateVariable(), CreateVariable(), CreateVariable(), CreateVariable()};
    1156              : }
    1157              : 
    1158              : template <typename T>
    1159           60 : std::vector<T> CcuContext::CreateBlockResAssist(uint32_t                                                  count,
    1160              :                                                 std::array<std::vector<T>, MAX_CCU_IODIE_NUM> &resRecord)
    1161              : {
    1162           60 :     std::vector<T> block;
    1163              :     // 获取DieId
    1164           60 :     uint32_t dieId = GetDieId();
    1165              :     // 检查DieId是否越界
    1166           60 :     if (dieId >= MAX_CCU_IODIE_NUM) {
    1167            0 :         THROW<CcuApiException>("dieId[%u] out of range[0, %u]", dieId, MAX_CCU_IODIE_NUM - 1);
    1168              :     }
    1169           60 :     block.reserve(count);
    1170        19652 :     for (size_t i = 0; i < count; i++) {
    1171        19592 :         block.emplace_back(this);
    1172        19592 :         block.back().Reset(0x1000 + resRecord[dieId].size() + i, dieId);  // 0x1000分割Block资源和离散资源
    1173              :     }
    1174           60 :     resRecord[dieId].insert(resRecord[dieId].end(), block.begin(), block.end());
    1175           60 :     return block;
    1176            0 : }
    1177              : 
    1178           20 : std::vector<CcuRep::CcuBuffer> CcuContext::CreateBlockCcuBuffer(uint32_t count)
    1179              : {
    1180           20 :     return CreateBlockResAssist(count, res.blockCcubuffers);
    1181              : }
    1182              : 
    1183           20 : std::vector<CcuRep::Executor> CcuContext::CreateBlockExecutor(uint32_t count)
    1184              : {
    1185           20 :     return CreateBlockResAssist(count, res.blockExecutor);
    1186              : }
    1187              : 
    1188           20 : std::vector<CcuRep::MaskSignal> CcuContext::CreateBlockMaskSignal(uint32_t count)
    1189              : {
    1190           20 :     return CreateBlockResAssist(count, res.blockMaskSignal);
    1191              : }
    1192              : 
    1193              : /*
    1194              :  * 功能描述:通过goSize varId获取其对应的task arg index。当前仅支持两种场景:
    1195              :  * 场景1:goSize var直接通过LoadArg赋值得到;
    1196              :  * 场景2:goSize var经过LoadArg和若干Assign(varB, varA)操作得到。
    1197              :  */
    1198           41 : uint64_t CcuContext::GetArgIndex(const std::unordered_map<uint16_t, uint16_t> &varId2VarIdMap,
    1199              :                                  const std::unordered_map<uint16_t, uint32_t> &varId2ArgIndexMap,
    1200              :                                  const std::vector<uint64_t> &taskArgs, uint16_t varId) const
    1201              : {
    1202          123 :     HCCL_INFO("[GetArgIndex] Enter varId(%u)", varId);
    1203           41 :     auto item = varId2ArgIndexMap.find(varId);
    1204           41 :     if (item == varId2ArgIndexMap.end()) {
    1205            0 :         string msg = StringFormat("Invalid goSize variable id(%u).", varId);
    1206            0 :         uint16_t oriVarId = varId;
    1207            0 :         auto iter = varId2VarIdMap.find(varId);
    1208            0 :         while (iter != varId2VarIdMap.end()) { // 循环查找中间assign Rep,找到起始varId
    1209            0 :             oriVarId = iter->second;
    1210            0 :             iter = varId2VarIdMap.find(oriVarId);
    1211              :         }
    1212            0 :         if (oriVarId != varId) { // 起始varId预期通过LoadArg赋值
    1213            0 :             item = varId2ArgIndexMap.find(oriVarId);
    1214            0 :             if (item == varId2ArgIndexMap.end()) {
    1215            0 :                 THROW<CcuApiException>(msg);
    1216              :             }
    1217              :         } else {
    1218            0 :             THROW<CcuApiException>(msg);
    1219              :         }
    1220            0 :     }
    1221          123 :     HCCL_INFO("[GetArgIndex] find end");
    1222           41 :     if (item->second >= taskArgs.size()) {
    1223            0 :         string msg = StringFormat("Invalid goSize variable index(%u).", item->second);
    1224            0 :         THROW<CcuApiException>(msg);
    1225            0 :     }
    1226          123 :     HCCL_INFO(
    1227              :         "GetArgIndex success: varId(%u) varId2VarIdMapSize(%u) varId2ArgIndexMapSize(%u) taskArgsSize(%u)",
    1228              :         varId, varId2VarIdMap.size(), varId2ArgIndexMap.size(), taskArgs.size());
    1229           82 :     return taskArgs[item->second];
    1230              : }
    1231              : 
    1232           28 : void CcuContext::AddCcuProfiling(GroupOpSize goSize, const std::vector<CcuTransport*> &transportsIn)
    1233              : {
    1234           28 :     AddProfiling(transportsIn);
    1235           28 :     groupOpSizeInfo.push_back(goSize);
    1236           28 : }
    1237              : 
    1238            2 : void CcuContext::AddCcuProfiling(GroupOpSize goSize, const std::vector<CcuTransport *> &transportsIn, DataType dataType,
    1239              :                                  DataType outputDataType, ReduceOp opType)
    1240              : {
    1241            2 :     AddProfiling(transportsIn, dataType, outputDataType, opType);
    1242            2 :     groupOpSizeInfo.push_back(goSize);
    1243            2 : }
    1244              : 
    1245              : /*
    1246              :  * variable/maskSignal等资源变量Id,一定要在获取ccu profiling时才获取;
    1247              :  * 原因:在创建context Rep时,其资源Id属于虚拟资源;翻译时,才会绑定固定的物理资源。
    1248              :  */
    1249           22 : HcclResult CcuContext::GetCcuProfilingInfo(const CcuTaskArg &arg, std::vector<CcuProfilingInfo> &allCcuProfilingInfo)
    1250              : {
    1251           66 :     HCCL_INFO("[GetCcuProfilingInfo] Enter.");
    1252           22 :     std::vector<CcuProfilingInfo> allCcuProfilingInfos;
    1253           22 :     auto &ccuProfilingCache = GetProfilingInfo();
    1254              : 
    1255           22 :     auto taskArgs = GeneArgs(arg);
    1256           22 :     uint32_t count = 0;
    1257           66 :     HCCL_INFO("[GetCcuProfilingInfo] Process sqe&waitcke profiling info start.");
    1258          140 :     for (auto &profInfo : ccuProfilingCache) {
    1259          118 :         profInfo.missionId = GetMissionId();
    1260          118 :         if (profInfo.type == CcuProfilinType::CCU_TASK_PROFILING) {
    1261           22 :             profInfo.instrId   = GetInstrId();
    1262           22 :             allCcuProfilingInfos.push_back(profInfo);
    1263           22 :             continue;
    1264              :         }
    1265           96 :         if (count >= GetWaiteCkeProfilingReps().size()) {
    1266            0 :             HCCL_ERROR("count[%u] out of range[0, %u], cache size(%u).", count, GetWaiteCkeProfilingReps().size(), ccuProfilingCache.size());
    1267            0 :             return HCCL_E_INTERNAL;
    1268              :         }
    1269           96 :         auto waitCkeRep = GetWaiteCkeProfilingReps()[count];
    1270           96 :         profInfo.instrId = waitCkeRep->StartInstrId();
    1271           96 :         if (profInfo.ckeId == INVALID_CKE_ID) { // localWait Rep
    1272           32 :             if (waitCkeRep.get() == nullptr) {
    1273            0 :                 HCCL_ERROR("[GetCcuProfilingInfo] localWaitRep is nullptr.");
    1274            0 :                 return HCCL_E_PTR;
    1275              :             }
    1276           32 :             auto localWaitRep = dynamic_cast<CcuRep::CcuRepLocWaitSem*>(waitCkeRep.get());
    1277           32 :             profInfo.ckeId = localWaitRep->GetSemId();
    1278              :         }
    1279           96 :         allCcuProfilingInfos.push_back(profInfo);
    1280           96 :         count++;
    1281           96 :     }
    1282              : 
    1283              :     // loopGroup
    1284           22 :     auto &lgProfInfo = GetLGProfilingInfo();
    1285           66 :     HCCL_INFO("[GetCcuProfilingInfo] create varId2ArgIndexMap start. size=%lu", lgProfInfo.loadRep2ArgIdxMap.size());
    1286           22 :     std::unordered_map<uint16_t, uint32_t> varId2ArgIndexMap;
    1287          134 :     for (auto &iter : lgProfInfo.loadRep2ArgIdxMap) {
    1288          112 :         if (iter.first.get() == nullptr) {
    1289            0 :             HCCL_ERROR("[GetCcuProfilingInfo] loadRep is nullptr.");
    1290            0 :             return HCCL_E_PTR;
    1291              :         }
    1292          112 :         auto loadRep = dynamic_cast<CcuRep::CcuRepLoadArg*>(iter.first.get());
    1293          112 :         varId2ArgIndexMap[loadRep->GetVarId()] = iter.second;
    1294              :     }
    1295              : 
    1296           66 :     HCCL_INFO("[GetCcuProfilingInfo] create varId2VarIdMap start. size=%lu", lgProfInfo.assignProfilingReps.size());
    1297           22 :     std::unordered_map<uint16_t, uint16_t> varId2VarIdMap;
    1298          204 :     for (auto &iter : lgProfInfo.assignProfilingReps) {
    1299          182 :         if (iter.get() == nullptr) {
    1300            0 :             HCCL_ERROR("[GetCcuProfilingInfo] assignRep is nullptr.");
    1301            0 :             return HCCL_E_PTR;
    1302              :         }
    1303          182 :         auto assignRep = dynamic_cast<CcuRep::CcuRepAssign*>(iter.get());
    1304          182 :         varId2VarIdMap[assignRep->varB.Id()] = assignRep->varA.Id();
    1305              :     }
    1306              : 
    1307           66 :     HCCL_INFO("[GetCcuProfilingInfo] process loop group profiling start: lgsize(%lu), goSize(%lu)", lgProfInfo.lgProfilingReps.size(), groupOpSizeInfo.size());
    1308           36 :     for (uint32_t i = 0; i < lgProfInfo.lgProfilingReps.size(); i += 2) { // 2: 一个goSize对应一个CcuProfilingInfo,对应1个loopGroup Rep
    1309           14 :         if (taskArgs.empty() || varId2ArgIndexMap.empty()) {
    1310            0 :             continue;
    1311              :         }
    1312           14 :         uint64_t loopParam = GetArgIndex(varId2VarIdMap, varId2ArgIndexMap, taskArgs, groupOpSizeInfo[i].loopParam.Id());
    1313           14 :         uint64_t parallelParam = GetArgIndex(varId2VarIdMap, varId2ArgIndexMap, taskArgs, groupOpSizeInfo[i].parallelParam.Id());
    1314           42 :         HCCL_INFO("Collect loopgroup profiling info: repSize[%u], index[%u], loopParam[%llu], parallelParam[%llu].",
    1315              :                    lgProfInfo.lgProfilingReps.size(), i, loopParam, parallelParam);
    1316              : 
    1317           14 :         if (loopParam != 0) {
    1318            1 :             lgProfInfo.ccuProfilingInfos[i].dataSize = loopParam * moConfig.loopCount * moConfig.memSlice;
    1319            1 :             lgProfInfo.ccuProfilingInfos[i].instrId = dynamic_cast<CcuRep::CcuRepLoopGroup*>(lgProfInfo.lgProfilingReps[i].get())->StartInstrId();
    1320            1 :             allCcuProfilingInfos.push_back(lgProfInfo.ccuProfilingInfos[i]);
    1321              :         }
    1322              : 
    1323           14 :         if (parallelParam != 0) {
    1324           39 :             HCCL_INFO("[GetCcuProfilingInfo] collect lg, residual start i=%lu", i);
    1325           13 :             uint64_t residual = GetArgIndex(varId2VarIdMap, varId2ArgIndexMap, taskArgs, groupOpSizeInfo[i].residual.Id());
    1326           13 :             uint64_t repeatNum = CcuRep::ParseRepeatNumFromParallelParam(parallelParam);
    1327           13 :             lgProfInfo.ccuProfilingInfos[i].dataSize = repeatNum * moConfig.memSlice + residual;
    1328           13 :             lgProfInfo.ccuProfilingInfos[i].instrId = dynamic_cast<CcuRep::CcuRepLoopGroup*>(lgProfInfo.lgProfilingReps[i + 1].get())->StartInstrId();
    1329           13 :             allCcuProfilingInfos.push_back(lgProfInfo.ccuProfilingInfos[i]);
    1330              :         }
    1331              :     }
    1332           22 :     DumpCcuProfilingInfo(allCcuProfilingInfos);
    1333           22 :     allCcuProfilingInfo = allCcuProfilingInfos;
    1334           22 :     return HCCL_SUCCESS;
    1335           22 : }
    1336              : 
    1337           22 : void CcuContext::DumpCcuProfilingInfo(const std::vector<CcuProfilingInfo> &ccuProfilingInfo) const
    1338              : {
    1339          110 :     auto dumpLinkInfo = [] (const CcuProfilingInfo &info) -> void {
    1340         1870 :         for (int i = 0; i < CCU_MAX_CHANNEL_NUM; i++) {
    1341         1760 :             if (info.channelId[i] == INVALID_VALUE_CHANNELID) {
    1342         1406 :                 continue;
    1343              :             }
    1344         1062 :             HCCL_INFO("channelId(%u), remoteRankId(%u).", info.channelId[i], info.remoteRankId[i]);
    1345              :         }
    1346          110 :     };
    1347              : 
    1348          154 :     for (const auto &profInfo : ccuProfilingInfo) {
    1349          132 :         if (profInfo.type == CcuProfilinType::CCU_TASK_PROFILING) {
    1350           66 :             HCCL_INFO("Dump CCU Profiling Info:SQE Profiling Info: ctxSignautre(%s), "
    1351              :                        "dieId(%d), missionId(%d), instrId(%d).",
    1352              :                        profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
    1353              :                        static_cast<int>(profInfo.instrId));
    1354          110 :         } else if (profInfo.type == CcuProfilinType::CCU_WAITCKE_PROFILING) {
    1355          288 :             HCCL_INFO("Microcode WaitCKE Profiling Info: name(%s), "
    1356              :                        "dieId(%d), missionId(%d), instrId(%d), ckeId(%u), mask(%u).",
    1357              :                        profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
    1358              :                        static_cast<int>(profInfo.instrId), profInfo.ckeId, profInfo.mask);
    1359           96 :             dumpLinkInfo(profInfo);
    1360           14 :         } else if (profInfo.type == CcuProfilinType::CCU_LOOPGROUP_PROFILING) {
    1361           42 :             HCCL_INFO("Microcode LoopGroup Profiling Info: name(%s), "
    1362              :                        "dieId(%d), missionId(%d), instrId(%d), reduceOpType(%d), inputDataType(%d), "
    1363              :                        "outputDataType(%d), dataSize(%llu).",
    1364              :                        profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
    1365              :                        static_cast<int>(profInfo.instrId), static_cast<int>(profInfo.reduceOpType),
    1366              :                        static_cast<int>(profInfo.inputDataType), static_cast<int>(profInfo.outputDataType),
    1367              :                        profInfo.dataSize);
    1368           14 :             dumpLinkInfo(profInfo);
    1369              :         }
    1370              :     }
    1371           22 : }
    1372              : 
    1373              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1