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

Generated by: LCOV version 2.0-1