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

Generated by: LCOV version 2.0-1