LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_kernel - ccu_kernel.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.7 % 1849 1382
Test Date: 2026-08-18 17:47:01 Functions: 82.3 % 203 167

            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_kernel.h"
      12              : #include "ccu_rep_v1.h"
      13              : #include "ccu_kernel_resource.h"
      14              : #include "ccu_microcode_v1.h"
      15              : 
      16              : #include "ccu_types.h"
      17              : #include "exception_util.h"
      18              : #include "ccu_api_exception.h"
      19              : #include "ccu_dev_mgr_imp.h"
      20              : #include "env_config.h"
      21              : #include "ccu_rep_type_v1.h"
      22              : 
      23              : #include "hcomm_c_adpt.h"
      24              : 
      25              : #include "ccu_rep_context_v1.h"
      26              : #include "ccu_rep_funccall_v1.h"
      27              : #include "../../endpoint_pairs/channels/ccu/ccu_urma_channel.h"
      28              : #include "../ccu_instance/ccu_var_event_res_mgr.h"
      29              : 
      30              : #include "ccu_log.h"
      31              : 
      32              : #include "hcom_common.h"
      33              : 
      34              : // todo: 引入头文件需要检查
      35              : #include "ccu_assist_v1.h"
      36              : #include "hccl_comm_pub.h"
      37              : #include "hcclCommDfx.h"
      38              : #include "task_info.h"
      39              : #include "task_param.h"
      40              : 
      41              : #include "ccu_ins_generator_base.h"
      42              : #include "ccu_ins_generator_v1.h"
      43              : #include "unified_platform/pub_inc/config_plf_log.h"
      44              : 
      45              : namespace hcomm {
      46              : 
      47              : using Hccl::PLF_DATA_OP;
      48              : 
      49              : constexpr uint32_t TOKEN_VALUE_INDEX = 2;
      50              : constexpr uint16_t INVALID_U16 = 65535;
      51              : 
      52              : using CcuRep::CcuInsGeneratorBase;
      53              : using CcuRep::CcuInsGeneratorV1;
      54              : 
      55              : template <typename T>
      56          213 : T CcuKernel::CreateResAssist(std::array<std::vector<T>, CCU_MAX_IODIE_NUM>& resRecord)
      57              : {
      58              :     // kernel确认die之前默认为0,需要刷新资源
      59              :     // 确认die之后按实际使用die分配资源
      60          213 :     const uint32_t dieId = GetDieId();
      61          213 :     resRecord[dieId].emplace_back(this);
      62          213 :     auto& item = resRecord[dieId].back();
      63          213 :     item.Reset(resRecord[dieId].size(), dieId);
      64          213 :     return item;
      65              : }
      66              : 
      67              : template <typename T>
      68              : std::vector<T>
      69          893 : CcuKernel::CreateBlockResAssist(const uint32_t count, std::array<std::vector<T>, CCU_MAX_IODIE_NUM>& resRecord)
      70              : {
      71          893 :     constexpr uint16_t CCU_BLOCK_RES_ID_BASE = 0x1000; // block 批量分配资源 id 基址,与单资源 id 区间隔离便于 DFX 定位
      72          893 :     std::vector<T> block;
      73          893 :     block.reserve(count);
      74          893 :     const uint32_t dieId = GetDieId();
      75         2162 :     for (size_t i = 0; i < count; i++) {
      76         1269 :         block.emplace_back(this);
      77         1269 :         block.back().Reset(static_cast<uint16_t>(CCU_BLOCK_RES_ID_BASE + resRecord[dieId].size() + i), dieId);
      78              :     }
      79          893 :     resRecord[dieId].insert(resRecord[dieId].end(), block.begin(), block.end());
      80          893 :     return block;
      81            0 : }
      82              : 
      83          155 : CcuKernel::~CcuKernel() {}
      84              : 
      85           11 : static HcclResult GetDieIdByChannel(const ChannelHandle channel, uint32_t& dieId)
      86              : {
      87           11 :     void* channelPtr{nullptr};
      88           11 :     CHK_RET(static_cast<HcclResult>(HcommChannelGet(channel, &channelPtr)));
      89           11 :     auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
      90           11 :     if (channelImpl == nullptr) {
      91            0 :         HCCL_ERROR("[%s] failed to cast channel[0x%llx] to CcuUrmaChannel", __func__, channel);
      92            0 :         return HcclResult::HCCL_E_PTR;
      93              :     }
      94           11 :     dieId = channelImpl->GetDieId();
      95           11 :     HCCL_INFO("[%s], channelHandle[0x%llx], dieId[%u]", __func__, channel, dieId);
      96           11 :     return HcclResult::HCCL_SUCCESS;
      97              : }
      98              : 
      99            0 : static HcclResult GetDieIdByChannels(const std::unordered_set<ChannelHandle>& channels, uint32_t& dieId)
     100              : {
     101            0 :     if (channels.empty()) {
     102            0 :         int32_t devLogicId = HcclGetThreadDeviceId();
     103            0 :         for (uint32_t die = 0; die < CCU_MAX_IODIE_NUM; die++) {
     104            0 :             bool enableFlag = false;
     105            0 :             CHK_RET(static_cast<HcclResult>(CcuGetDieEnableInfo(devLogicId, die, enableFlag)));
     106            0 :             if (enableFlag) {
     107            0 :                 dieId = die;
     108            0 :                 return HcclResult::HCCL_SUCCESS;
     109              :             }
     110              :         }
     111              : 
     112            0 :         HCCL_ERROR("[CcuKernel][%s] failed, all dies are disable, devLogicId[%d].", __func__, devLogicId);
     113            0 :         return HcclResult::HCCL_E_INTERNAL;
     114              :     }
     115              : 
     116            0 :     uint32_t firstDieId = 0;
     117            0 :     CHK_RET(GetDieIdByChannel(*channels.begin(), firstDieId));
     118            0 :     for (const auto channel : channels) {
     119            0 :         uint32_t nextDieId = 0;
     120            0 :         CHK_RET(GetDieIdByChannel(channel, nextDieId));
     121            0 :         if (firstDieId != nextDieId) {
     122            0 :             HCCL_ERROR("[%s] failed, the dies of channels are not same.", __func__);
     123            0 :             return HcclResult::HCCL_E_PARA;
     124              :         }
     125              :     }
     126              : 
     127            0 :     dieId = firstDieId;
     128            0 :     return HcclResult::HCCL_SUCCESS;
     129              : }
     130              : 
     131           57 : static HcclResult CheckChannelsDie(const std::unordered_set<ChannelHandle>& channels, const uint32_t targetDieId)
     132              : {
     133           65 :     for (const auto channel : channels) {
     134           11 :         uint32_t channelDieId = 0;
     135           14 :         CHK_RET(GetDieIdByChannel(channel, channelDieId));
     136           11 :         if (channelDieId != targetDieId) {
     137            3 :             HCCL_ERROR(
     138              :                 "[%s] failed, channel[0x%llx] dieId[%u] differs from target dieId[%u].", __func__, channel,
     139              :                 channelDieId, targetDieId);
     140            3 :             return HcclResult::HCCL_E_PARA;
     141              :         }
     142              :     }
     143           54 :     return HcclResult::HCCL_SUCCESS;
     144              : }
     145              : 
     146           54 : static void MoveResourcesToDie(CcuRepResource& res, uint32_t targetDieId)
     147              : {
     148           54 :     if (targetDieId == 0)
     149           53 :         return; // 初始资源位于die0,不用设置
     150              : 
     151           11 :     auto moveAndSet = [&](auto& arr) {
     152           11 :         arr[targetDieId] = std::move(arr[0]);
     153           11 :         for (auto& item : arr[targetDieId])
     154            0 :             item.SetDieId(targetDieId);
     155           12 :     };
     156              : 
     157            1 :     moveAndSet(res.ccubufs);
     158            1 :     moveAndSet(res.blockCcubufs);
     159            1 :     moveAndSet(res.executor);
     160            1 :     moveAndSet(res.blockExecutor);
     161            1 :     moveAndSet(res.completedEvent);
     162            1 :     moveAndSet(res.blockCompletedEvent);
     163            1 :     moveAndSet(res.address);
     164            1 :     moveAndSet(res.blockAddress);
     165            1 :     moveAndSet(res.continuousVariable);
     166            1 :     moveAndSet(res.variable);
     167            1 :     moveAndSet(res.localNotify);
     168              : }
     169              : 
     170           70 : HcclResult CcuKernel::SetupProfilingInfo(const char* kernelFuncName)
     171              : {
     172           70 :     if (kernelFuncName == nullptr || strlen(kernelFuncName) == 0) {
     173            0 :         name_ = std::string("CCU_KERNEL"); // 默认名称
     174            0 :         AddSqeProfiling(name_);
     175            0 :         return HcclResult::HCCL_SUCCESS;
     176              :     }
     177              : 
     178           70 :     constexpr size_t MAX_KERNEL_FUNC_NAME_LEN = 128;
     179           70 :     const auto nameLen = strlen(kernelFuncName);
     180           70 :     if (nameLen > MAX_KERNEL_FUNC_NAME_LEN) {
     181            0 :         name_ = std::string(kernelFuncName, MAX_KERNEL_FUNC_NAME_LEN);
     182            0 :         HCCL_WARNING("[CcuKernel][%s] kernelFuncName is too long, reset to %s.", __func__, name_.c_str());
     183              :     }
     184              : 
     185              :     // 生成SQE粒度profiling信息,此时未选择die,默认die 0
     186           70 :     AddSqeProfiling(name_);
     187           70 :     return HcclResult::HCCL_SUCCESS;
     188              : }
     189              : 
     190              : static HcclResult
     191           54 : UpdateProfilingInfo(std::vector<CcuProfilingInfo>& profilingInfos, uint32_t dieId, const std::string& kernelName)
     192              : {
     193           54 :     if (dieId == 0) {
     194              :         // 与默认dieId相同,不需要修改
     195           53 :         return HcclResult::HCCL_SUCCESS;
     196              :     }
     197              : 
     198              :     // 正常情况仅首个info包含die信息,仅应为CCU_TASK_PROFILING类型
     199            1 :     if (UNLIKELY(profilingInfos.empty())) {
     200              :         // profiling不属于主流程,不打断算子业务
     201            0 :         HCCL_INFO("[%s] passed, profiling infos are empty, ccu kernel func[%s].", __func__, kernelName.c_str());
     202            0 :         return HcclResult::HCCL_SUCCESS;
     203              :     }
     204              : 
     205              :     // 根据选择的die跟新profiling信息
     206            2 :     for (auto& info : profilingInfos) {
     207            1 :         info.dieId = dieId;
     208              :     }
     209              : 
     210            1 :     HCCL_INFO("[%s] reset profiling info dieId to [%u], ccu kernel func[%s].", __func__, dieId, kernelName.c_str());
     211            1 :     return HcclResult::HCCL_SUCCESS;
     212              : }
     213              : 
     214            0 : HcclResult CcuKernel::ApplyDieFromChannels()
     215              : {
     216            0 :     uint32_t dieId{0};
     217            0 :     CHK_RET(GetDieIdByChannels(channels_, dieId));
     218            0 :     CHK_PRT_RET(
     219              :         dieId >= CCU_MAX_IODIE_NUM,
     220              :         HCCL_ERROR("[CcuKernel][%s] failed, dieId[%u] should be less than [%u].", __func__, dieId, CCU_MAX_IODIE_NUM),
     221              :         HcclResult::HCCL_E_PARA);
     222            0 :     SetDieId(dieId);
     223            0 :     MoveResourcesToDie(res_, dieId);
     224            0 :     (void)UpdateProfilingInfo(profilingInfo, dieId, name_);
     225              : 
     226            0 :     return HcclResult::HCCL_SUCCESS;
     227              : }
     228              : 
     229           57 : HcclResult CcuKernel::ValidateAndApplyDie(const uint32_t targetDieId)
     230              : {
     231           57 :     CHK_PRT_RET(
     232              :         targetDieId >= CCU_MAX_IODIE_NUM,
     233              :         HCCL_ERROR(
     234              :             "[CcuKernel][%s] failed, dieId[%u] should be less than [%u].", __func__, targetDieId, CCU_MAX_IODIE_NUM),
     235              :         HcclResult::HCCL_E_PARA);
     236              : 
     237           57 :     const int32_t devLogicId = HcclGetThreadDeviceId();
     238           57 :     bool enableFlag = false;
     239           57 :     CHK_RET(static_cast<HcclResult>(CcuGetDieEnableInfo(devLogicId, static_cast<uint8_t>(targetDieId), enableFlag)));
     240           57 :     CHK_PRT_RET(
     241              :         !enableFlag,
     242              :         HCCL_ERROR(
     243              :             "[CcuKernel][%s] failed, target dieId[%u] is disabled, devLogicId[%d].", __func__, targetDieId, devLogicId),
     244              :         HcclResult::HCCL_E_PARA);
     245           57 :     CHK_RET(CheckChannelsDie(channels_, targetDieId));
     246              : 
     247           54 :     SetDieId(targetDieId);
     248           54 :     MoveResourcesToDie(res_, targetDieId);
     249           54 :     (void)UpdateProfilingInfo(profilingInfo, targetDieId, name_);
     250              : 
     251           54 :     return HcclResult::HCCL_SUCCESS;
     252              : }
     253              : 
     254           73 : void CcuKernel::SetInsGenerater(CcuInsGeneratorBase* insGeneratorBase) { insGenerator = insGeneratorBase; }
     255              : 
     256            5 : CcuResult CcuKernel::ValidateTaskArgs(const uint64_t* taskArgs, uint32_t argsNum) const
     257              : {
     258            5 :     if (loadArgUsedSet_.size() != argsNum) {
     259            0 :         HCCL_ERROR(
     260              :             "[CcuKernel][%s] failed, args number does not match the Load instruction, "
     261              :             "argsNum = %u, loaded = %zu",
     262              :             __func__, argsNum, loadArgUsedSet_.size());
     263            0 :         return CcuResult::CCU_E_INTERNAL;
     264              :     }
     265           50 :     for (uint32_t i = 0; i < argsNum; ++i) {
     266           45 :         if (loadArgUsedSet_.count(i) == 0) {
     267            0 :             HCCL_ERROR("[CcuKernel][%s] failed, argId %u not loaded (argsNum=%u)", __func__, i, argsNum);
     268            0 :             return CcuResult::CCU_E_INTERNAL;
     269              :         }
     270              :     }
     271            5 :     if (argsNum != 0) {
     272            3 :         CCU_CHK_PTR_NULL(taskArgs);
     273              :     }
     274            5 :     if (instrInfo_.missionInstrCount == 0 || instrInfo_.instrVec.empty()) {
     275            0 :         HCCL_ERROR(
     276              :             "[CcuKernel][%s] failed, mission instructions are empty, "
     277              :             "the kernel is not been translated yet.",
     278              :             __func__);
     279            0 :         return CcuResult::CCU_E_INTERNAL;
     280              :     }
     281            5 :     return CcuResult::CCU_SUCCESS;
     282              : }
     283              : 
     284            8 : void CcuKernel::FillTaskParam(
     285              :     CcuTaskParam& param, uint32_t index, uint32_t seqNum, const uint64_t* taskArgs, uint32_t argsNum) const
     286              : {
     287            8 :     param.dieId = GetDieId();
     288            8 :     param.missionId = GetMissionId();
     289            8 :     param.instStartId = instrInfo_.missionStartInstrId + index * CCU_SQE_ARGS_LEN;
     290            8 :     param.key = GetMissionKey();
     291            8 :     param.argSize = CCU_SQE_ARGS_LEN;
     292              : 
     293            8 :     const uint32_t preMissionInsCnt = index * CCU_SQE_ARGS_LEN;
     294            8 :     const bool isLast = (index == seqNum - 1);
     295            8 :     param.instCnt = isLast ? (instrInfo_.missionInstrCount - preMissionInsCnt) : CCU_SQE_ARGS_LEN;
     296              : 
     297            8 :     if (argsNum > preMissionInsCnt) {
     298            6 :         const uint32_t argsToCopy = isLast ? std::min(argsNum - preMissionInsCnt, CCU_SQE_ARGS_LEN) : CCU_SQE_ARGS_LEN;
     299           12 :         std::copy(taskArgs + preMissionInsCnt, taskArgs + preMissionInsCnt + argsToCopy, std::begin(param.args));
     300              :     }
     301              : 
     302            8 :     HCCL_INFO(
     303              :         "[GeneTaskParam]task Param, dieId[%u] missionId[%u] instStartId[%u] instCnt[%u], argSize[%u]", param.dieId,
     304              :         param.missionId, param.instStartId, param.instCnt, param.argSize);
     305            8 : }
     306              : 
     307            5 : CcuResult CcuKernel::GeneTaskParams(const uint64_t* taskArgs, uint32_t argsNum, std::vector<CcuTaskParam>& taskParams)
     308              : {
     309            5 :     CCU_CHK_RET(ValidateTaskArgs(taskArgs, argsNum));
     310              : 
     311              :     // 如果agrs数量超过sqe arg的最大数量,则返回多个TaskParam,前面几个只从sqe中加载args;
     312              :     // args数量大于等于0、小于等于最大值时,返回1个TaskParam
     313            5 :     const uint32_t seqNum
     314            5 :         = (argsNum / CCU_SQE_ARGS_LEN) + ((argsNum % CCU_SQE_ARGS_LEN) == 0 ? 0 : 1) + (argsNum == 0 ? 1 : 0);
     315              : 
     316            5 :     const uint32_t preMissonSqeInsCnt = (seqNum - 1) * CCU_SQE_ARGS_LEN;
     317            5 :     if (instrInfo_.missionInstrCount < preMissonSqeInsCnt) {
     318            0 :         HCCL_ERROR(
     319              :             "[CcuKernel][%s] failed, missionInstrCount[%u] should be greater "
     320              :             "than preMissonSqeInsCnt[%u].",
     321              :             __func__, instrInfo_.missionInstrCount, preMissonSqeInsCnt);
     322            0 :         return CcuResult::CCU_E_INTERNAL;
     323              :     }
     324              : 
     325            5 :     taskParams.resize(seqNum);
     326           13 :     for (uint32_t index = 0; index < seqNum; index++) {
     327            8 :         FillTaskParam(taskParams[index], index, seqNum, taskArgs, argsNum);
     328              :     }
     329              : 
     330            5 :     return CcuResult::CCU_SUCCESS;
     331              : }
     332              : 
     333           14 : HcclResult CcuKernel::CreateVariable(const ChannelHandle channel, uint32_t varIndex, CcuRep::Variable* var)
     334              : {
     335           14 :     channels_.insert(channel);
     336              : 
     337           14 :     void* channelPtr{nullptr};
     338           14 :     CHK_RET(static_cast<HcclResult>(HcommChannelGet(channel, &channelPtr)));
     339           14 :     auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
     340           14 :     if (channelImpl == nullptr) {
     341            0 :         HCCL_ERROR("[%s] failed to cast channel[0x%llx] to CcuUrmaChannel", __func__, channel);
     342            0 :         return HcclResult::HCCL_E_PTR;
     343              :     }
     344           14 :     uint32_t locXnId{0};
     345           14 :     CHK_RET(channelImpl->GetLocXnByIndex(varIndex, locXnId));
     346           14 :     var->Reset(locXnId, channelImpl->GetDieId());
     347           14 :     return HcclResult::HCCL_SUCCESS;
     348              : }
     349              : 
     350           44 : CcuRepResource& CcuKernel::GetResource() { return res_; }
     351              : 
     352           91 : CcuResReq CcuKernel::GetResourceRequest()
     353              : {
     354           91 :     CcuResReq req;
     355           91 :     uint32_t dieId = GetDieId();
     356           91 :     req.msReq[dieId] = res_.ccubufs[dieId].size();
     357           91 :     req.blockMsReq[dieId] = res_.blockCcubufs[dieId].size();
     358           91 :     req.ckeReq[dieId] = res_.completedEvent[dieId].size();
     359           91 :     req.blockCkeReq[dieId] = res_.blockCompletedEvent[dieId].size() + res_.localNotify[dieId].size();
     360           91 :     req.loopEngineReq[dieId] = res_.executor[dieId].size();
     361           91 :     req.blockLoopEngineReq[dieId] = res_.blockExecutor[dieId].size();
     362           91 :     req.gsaReq[dieId] = res_.address[dieId].size();
     363           91 :     req.blockGsaReq[dieId] = res_.blockAddress[dieId].size();
     364           91 :     req.xnReq[dieId] = res_.variable[dieId].size();
     365           91 :     req.blockXnReq[dieId] = res_.continuousVariable[dieId].size();
     366              : 
     367           91 :     req.missionReq.reqType = MissionReqType::FUSION_MULTIPLE_DIE;
     368           91 :     req.missionReq.req[dieId] = 1;
     369              : 
     370              :     auto info = Hccl::StringFormat(
     371              :         "resource request: dieId[%u], ms[%u], blockMs[%u], cke[%u], blockCke[%u], "
     372              :         "loopEngine[%u], blockLoopEngine[%u], gsa[%u], blockGsa[%u], xn[%u], blockXn[%u], "
     373              :         "missionId[%u]",
     374          364 :         dieId, req.msReq[dieId], req.blockMsReq[dieId], req.ckeReq[dieId], req.blockCkeReq[dieId],
     375          364 :         req.loopEngineReq[dieId], req.blockLoopEngineReq[dieId], req.gsaReq[dieId], req.blockGsaReq[dieId],
     376           91 :         req.xnReq[dieId], req.blockXnReq[dieId], req.missionReq.req[dieId]);
     377              : 
     378           91 :     HCCL_INFO("%s", info.c_str());
     379              : 
     380          182 :     return req;
     381           91 : }
     382              : 
     383              : template <typename HandleType, typename ResourceType>
     384         1701 : static CcuResult GetResourceByHandle(
     385              :     std::unordered_map<HandleType, ResourceType>& resourceMap, HandleType handle, ResourceType** resource,
     386              :     const char* resourceType)
     387              : {
     388         1701 :     auto iter = resourceMap.find(handle);
     389         1701 :     if (iter == resourceMap.end()) {
     390            0 :         HCCL_ERROR("[%s] failed to find %s by handle: 0x%llx", __func__, resourceType, handle);
     391            0 :         return CcuResult::CCU_E_NOT_FOUND;
     392              :     }
     393              : 
     394              :     // ccu资源本身可能重载=,对象赋值会被转换成指令,导致流程失败
     395         1701 :     *resource = &(iter->second);
     396         1701 :     return CcuResult::CCU_SUCCESS;
     397              : }
     398              : 
     399         1373 : CcuResult CcuKernel::GetVariableByHandle(CcuVariableHandle varHandle, CcuRep::Variable** variable)
     400              : {
     401         1373 :     return GetResourceByHandle(ccuVarMap_, varHandle, variable, "variable");
     402              : }
     403              : // Alloc 相关接口
     404          496 : CcuResult CcuKernel::VariableAlloc(CcuVariableHandle* varHandle)
     405              : {
     406          496 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAlloc]");
     407          496 :     const auto& var = CreateBlockResAssist(1, res_.continuousVariable);
     408          496 :     CcuVariableHandle handle = ccuVarMap_.size();
     409          496 :     ccuVarMap_.emplace(handle, var[0]);
     410              : 
     411          496 :     *varHandle = handle;
     412          496 :     return CcuResult::CCU_SUCCESS;
     413          496 : }
     414           10 : CcuResult CcuKernel::AddressAlloc(CcuAddressHandle* addrHandle)
     415              : {
     416           10 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAlloc]");
     417           10 :     const auto addr = CreateAddress();
     418           10 :     CcuAddressHandle handle = ccuAddrMap_.size();
     419           10 :     ccuAddrMap_.emplace(handle, addr);
     420           10 :     *addrHandle = handle;
     421           10 :     return CcuResult::CCU_SUCCESS;
     422           10 : }
     423           10 : CcuResult CcuKernel::EventAlloc(CcuEventHandle* eventHandle)
     424              : {
     425           10 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[EventAlloc]");
     426           10 :     const auto& event = CreateResAssist(res_.blockCompletedEvent);
     427           10 :     CcuEventHandle handle = ccuEventMap_.size();
     428           10 :     ccuEventMap_.emplace(handle, event);
     429           10 :     *eventHandle = handle;
     430           10 :     return CcuResult::CCU_SUCCESS;
     431           10 : }
     432            2 : CcuResult CcuKernel::BufferAlloc(CcuBufferHandle* bufHandle)
     433              : {
     434            2 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[BufferAlloc]");
     435            2 :     const auto& buffer = CreateBlockResAssist(1, res_.blockCcubufs);
     436            2 :     CcuBufferHandle handle = ccuBufferMap_.size();
     437            2 :     ccuBufferMap_.emplace(handle, buffer[0]);
     438            2 :     *bufHandle = handle;
     439            2 :     return CcuResult::CCU_SUCCESS;
     440            2 : }
     441          156 : CcuResult CcuKernel::LocalAddrAlloc(
     442              :     CcuLocalAddrHandle* localAddrHandle, CcuAddressHandle* addrHandle, CcuVariableHandle* tokenHandle)
     443              : {
     444          156 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalAddrAlloc]");
     445          156 :     auto localAddr = CreateLocalAddr();
     446              : 
     447          156 :     CcuAddressHandle aHandle = ccuAddrMap_.size();
     448          156 :     ccuAddrMap_.emplace(aHandle, localAddr.addr);
     449              : 
     450          156 :     CcuVariableHandle tHandle = ccuVarMap_.size();
     451          156 :     ccuVarMap_.emplace(tHandle, localAddr.token);
     452              : 
     453          156 :     CcuLocalAddrHandle laHandle = ccuLocalAddrMap_.size();
     454          156 :     ccuLocalAddrMap_.emplace(laHandle, localAddr);
     455              : 
     456          156 :     *localAddrHandle = laHandle;
     457          156 :     *addrHandle = aHandle;
     458          156 :     *tokenHandle = tHandle;
     459          156 :     return CcuResult::CCU_SUCCESS;
     460          156 : }
     461           37 : CcuResult CcuKernel::RemoteAddrAlloc(
     462              :     CcuRemoteAddrHandle* remoteAddrHandle, CcuAddressHandle* addrHandle, CcuVariableHandle* tokenHandle)
     463              : {
     464           37 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[RemoteAddrAlloc]");
     465           37 :     auto remoteAddr = CreateRemoteAddr();
     466              : 
     467           37 :     CcuAddressHandle aHandle = ccuAddrMap_.size();
     468           37 :     ccuAddrMap_.emplace(aHandle, remoteAddr.addr);
     469              : 
     470           37 :     CcuVariableHandle tHandle = ccuVarMap_.size();
     471           37 :     ccuVarMap_.emplace(tHandle, remoteAddr.token);
     472              : 
     473           37 :     CcuRemoteAddrHandle raHandle = ccuRemoteAddrMap_.size();
     474           37 :     ccuRemoteAddrMap_.emplace(raHandle, remoteAddr);
     475              : 
     476           37 :     *remoteAddrHandle = raHandle;
     477           37 :     *addrHandle = aHandle;
     478           37 :     *tokenHandle = tHandle;
     479           37 :     return CcuResult::CCU_SUCCESS;
     480           37 : }
     481              : 
     482            6 : CcuResult CcuKernel::BlockVariableAlloc(CcuVariableHandle* varHandles, uint32_t count)
     483              : {
     484            6 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[BlockVariableAlloc] count=%u", count);
     485            6 :     const auto& var = CreateBlockResAssist(count, res_.continuousVariable);
     486           18 :     for (uint32_t i = 0; i < count; i++) {
     487           12 :         CcuVariableHandle handle = ccuVarMap_.size();
     488           12 :         ccuVarMap_.emplace(handle, var[i]);
     489           12 :         varHandles[i] = handle;
     490              :     }
     491            6 :     return CcuResult::CCU_SUCCESS;
     492            6 : }
     493              : 
     494            6 : CcuResult CcuKernel::BlockEventAlloc(CcuEventHandle* eventHandles, uint32_t count)
     495              : {
     496            6 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[BlockEventAlloc] count=%u", count);
     497            6 :     const auto& event = CreateBlockResAssist(count, res_.blockCompletedEvent);
     498           52 :     for (uint32_t i = 0; i < count; i++) {
     499           46 :         CcuEventHandle handle = ccuEventMap_.size();
     500           46 :         ccuEventMap_.emplace(handle, event[i]);
     501           46 :         eventHandles[i] = handle;
     502              :     }
     503            6 :     return CcuResult::CCU_SUCCESS;
     504            6 : }
     505              : 
     506            7 : CcuResult CcuKernel::BlockBufferAlloc(CcuBufferHandle* bufHandles, uint32_t count)
     507              : {
     508            7 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[BlockBufferAlloc] count=%u", count);
     509            7 :     const auto& buffer = CreateBlockResAssist(count, res_.blockCcubufs);
     510          332 :     for (uint32_t i = 0; i < count; i++) {
     511          325 :         CcuBufferHandle handle = ccuBufferMap_.size();
     512          325 :         ccuBufferMap_.emplace(handle, buffer[i]);
     513          325 :         bufHandles[i] = handle;
     514              :     }
     515            7 :     return CcuResult::CCU_SUCCESS;
     516            7 : }
     517              : 
     518           14 : CcuResult CcuKernel::VariableCreateByChannel(ChannelHandle channel, uint32_t varIndex, CcuVariableHandle* varHandle)
     519              : {
     520           14 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableCreateByChannel] channel=%llu, varIndex=%u", channel, varIndex);
     521           14 :     channels_.insert(channel);
     522           14 :     CcuRep::Variable var(this);
     523           14 :     CCU_CHK_RET(CreateVariable(channel, varIndex, &var));
     524           14 :     CcuVariableHandle handle = ccuVarMap_.size();
     525           14 :     ccuVarMap_.emplace(handle, var);
     526           14 :     *varHandle = handle;
     527           14 :     return CcuResult::CCU_SUCCESS;
     528           14 : }
     529              : 
     530           10 : CcuResult CcuKernel::VariableCreateByAcquire(CcuVariableHandle acqHandle, uint32_t index, CcuVariableHandle* varHandle)
     531              : {
     532           10 :     uint8_t dieId = 0;
     533           10 :     uint32_t xnId = 0;
     534           10 :     CCU_CHK_RET(CcuVarEventResMgr::GetInstance(HcclGetThreadDeviceId()).GetVariableXnId(acqHandle, index, dieId, xnId));
     535              : 
     536           10 :     CcuRep::Variable var(this);
     537           10 :     var.Reset(static_cast<uint16_t>(xnId), static_cast<uint16_t>(dieId));
     538           10 :     CcuVariableHandle handle = ccuVarMap_.size();
     539           10 :     ccuVarMap_.emplace(handle, var);
     540           10 :     *varHandle = handle;
     541           10 :     return CcuResult::CCU_SUCCESS;
     542           10 : }
     543              : 
     544            4 : CcuResult CcuKernel::EventCreateByAcquire(CcuEventHandle acqHandle, uint32_t index, CcuEventHandle* eventHandle)
     545              : {
     546            4 :     uint8_t dieId = 0;
     547            4 :     uint32_t ckeId = 0;
     548            4 :     CCU_CHK_RET(CcuVarEventResMgr::GetInstance(HcclGetThreadDeviceId()).GetEventCkeId(acqHandle, index, dieId, ckeId));
     549              : 
     550            4 :     CcuRep::CompletedEvent event(this);
     551            4 :     event.Reset(static_cast<uint16_t>(ckeId), static_cast<uint16_t>(dieId));
     552            4 :     CcuEventHandle handle = ccuEventMap_.size();
     553            4 :     ccuEventMap_.emplace(handle, event);
     554            4 :     *eventHandle = handle;
     555            4 :     return CcuResult::CCU_SUCCESS;
     556            4 : }
     557              : 
     558          283 : CcuResult CcuKernel::VariableAssignImm(CcuVariableHandle varHandle, uint64_t immediate)
     559              : {
     560          283 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAssignImm] varHandle=%llu, immediate=%llu", varHandle, immediate);
     561          283 :     CcuRep::Variable* variable{nullptr};
     562          283 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
     563              :     // 通过符号重载实现,内部记录rep;异常由入口 HcommCcuKernelRegister 的
     564              :     // CCU_EXCEPTION_HANDLE_BEGIN/END 统一接住,无需在此局部 try/catch。
     565          283 :     (*variable) = immediate;
     566          283 :     return CcuResult::CCU_SUCCESS;
     567              : }
     568              : 
     569          158 : CcuResult CcuKernel::VariableAssignVar(CcuVariableHandle varHandle, CcuVariableHandle varA)
     570              : {
     571          158 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAssignVar] varHandle=%llu, varA=%llu", varHandle, varA);
     572          158 :     CcuRep::Variable* variable{nullptr};
     573          158 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
     574          158 :     CcuRep::Variable* variableA{nullptr};
     575          158 :     CCU_CHK_RET(GetVariableByHandle(varA, &variableA));
     576              :     // 通过符号重载实现,内部记录rep;异常由入口统一 catch。
     577          158 :     (*variable) = (*variableA);
     578          158 :     return CcuResult::CCU_SUCCESS;
     579              : }
     580              : 
     581              : CcuResult
     582          109 : CcuKernel::VariableAddVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     583              : {
     584          109 :     PLF_CONFIG_INFO(
     585              :         PLF_DATA_OP, "[VariableAddVarToVar] varHandle=%llu, varAHandle=%llu, varBHandle=%llu", varHandle, varAHandle,
     586              :         varBHandle);
     587          109 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     588          109 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     589          109 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     590          109 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     591              : 
     592              :     // 通过符号重载实现,内部记录rep;异常由入口统一 catch。
     593          109 :     *resVar = *leftVar + *rightVar;
     594          109 :     return CcuResult::CCU_SUCCESS;
     595              : }
     596              : 
     597              : CcuResult
     598            2 : CcuKernel::VariableSubVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     599              : {
     600            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     601            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     602            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     603            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     604              : 
     605            2 :     *resVar = *leftVar - *rightVar;
     606            2 :     return CcuResult::CCU_SUCCESS;
     607              : }
     608              : 
     609              : CcuResult
     610            2 : CcuKernel::VariableMulVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     611              : {
     612            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     613            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     614            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     615            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     616              : 
     617            2 :     *resVar = *leftVar * *rightVar;
     618            2 :     return CcuResult::CCU_SUCCESS;
     619              : }
     620              : 
     621            1 : CcuResult CcuKernel::VariableAddImmToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, uint16_t immediate)
     622              : {
     623            1 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
     624            1 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     625            1 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     626              : 
     627            1 :     *resVar = *leftVar + immediate;
     628            1 :     return CcuResult::CCU_SUCCESS;
     629              : }
     630              : 
     631            2 : CcuResult CcuKernel::VariableSubImmToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, uint16_t immediate)
     632              : {
     633            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
     634            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     635            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     636              : 
     637            2 :     *resVar = *leftVar - immediate;
     638            2 :     return CcuResult::CCU_SUCCESS;
     639              : }
     640              : 
     641            2 : CcuResult CcuKernel::VariableMulImmToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, uint16_t immediate)
     642              : {
     643            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
     644            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     645            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     646              : 
     647            2 :     *resVar = *leftVar * immediate;
     648            2 :     return CcuResult::CCU_SUCCESS;
     649              : }
     650              : 
     651              : CcuResult
     652            2 : CcuKernel::VariableAndVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     653              : {
     654            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     655            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     656            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     657            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     658              : 
     659            2 :     *resVar = *leftVar & *rightVar;
     660            2 :     return CcuResult::CCU_SUCCESS;
     661              : }
     662              : 
     663              : CcuResult
     664            2 : CcuKernel::VariableOrVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     665              : {
     666            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     667            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     668            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     669            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     670              : 
     671            2 :     *resVar = *leftVar | *rightVar;
     672            2 :     return CcuResult::CCU_SUCCESS;
     673              : }
     674              : 
     675              : CcuResult
     676            2 : CcuKernel::VariableXorVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     677              : {
     678            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     679            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     680            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     681            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     682              : 
     683            2 :     *resVar = *leftVar ^ *rightVar;
     684            2 :     return CcuResult::CCU_SUCCESS;
     685              : }
     686              : 
     687            1 : CcuResult CcuKernel::VariableNotVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle)
     688              : {
     689            1 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
     690            1 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     691            1 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     692              : 
     693            1 :     *resVar = ~(*leftVar);
     694            1 :     return CcuResult::CCU_SUCCESS;
     695              : }
     696              : 
     697              : CcuResult
     698            2 : CcuKernel::VariableShlVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     699              : {
     700            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     701            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     702            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     703            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     704              : 
     705            2 :     *resVar = *leftVar << *rightVar;
     706            2 :     return CcuResult::CCU_SUCCESS;
     707              : }
     708              : 
     709              : CcuResult
     710            2 : CcuKernel::VariableShrVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
     711              : {
     712            2 :     CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
     713            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
     714            2 :     CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
     715            2 :     CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
     716              : 
     717            2 :     *resVar = *leftVar >> *rightVar;
     718            2 :     return CcuResult::CCU_SUCCESS;
     719              : }
     720              : 
     721              : /*========== Event信号同步类 相关接口 ==========*/
     722           15 : CcuResult CcuKernel::EventRecord(CcuEventHandle eventHandle, uint32_t mask)
     723              : {
     724           15 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[EventRecord] eventHandle=%llu, mask=%u", eventHandle, mask);
     725           15 :     CcuRep::CompletedEvent* event{nullptr};
     726           15 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
     727              :     // 复用已有的 RecordEvent 实现(内部 Append CcuRepLocRecordEvent)
     728           15 :     CCU_CHK_RET(RecordEvent(*event, mask));
     729           14 :     return CcuResult::CCU_SUCCESS;
     730              : }
     731              : 
     732           41 : CcuResult CcuKernel::EventWait(CcuEventHandle eventHandle, uint32_t mask)
     733              : {
     734           41 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[EventWait] eventHandle=%llu, mask=%u", eventHandle, mask);
     735           41 :     CcuRep::CompletedEvent* event{nullptr};
     736           41 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
     737              :     // 复用已有的 WaitEvent 实现(内部 Append CcuRepLocWaitEvent)
     738           41 :     CCU_CHK_RET(WaitEvent(*event, mask));
     739           41 :     return CcuResult::CCU_SUCCESS;
     740              : }
     741              : 
     742            1 : CcuResult CcuKernel::LocalNotifyRecord(const char* notifyTag, const uint32_t mask)
     743              : {
     744            1 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalNotifyRecord] tag=%s, mask=%u", (notifyTag ? notifyTag : "null"), mask);
     745            1 :     if (notifyTag == nullptr) {
     746            0 :         HCCL_ERROR("[CcuKernel][%s] notifyTag is nullptr, please check.", __func__);
     747            0 :         return CcuResult::CCU_E_PTR;
     748              :     }
     749            1 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     750            1 :         HCCL_ERROR("[CcuKernel][%s] is not supported in loop block, please check.", __func__);
     751            1 :         return LatchBodyError(CcuResult::CCU_E_NOT_SUPPORT);
     752              :     }
     753              : 
     754            0 :     const std::string tagKey(notifyTag);
     755              : 
     756            0 :     auto& sharedNotifies = importedRes_.sharedNotifies;
     757            0 :     if (sharedNotifies.find(tagKey) == sharedNotifies.end()) {
     758            0 :         CcuRep::LocalNotify localNotify;
     759            0 :         sharedNotifies.insert({tagKey, localNotify});
     760            0 :     }
     761              : 
     762            0 :     Append(std::make_shared<CcuRep::CcuRepRecordSharedNotify>(insGenerator, sharedNotifies.at(tagKey), mask));
     763              : 
     764            0 :     return CcuResult::CCU_SUCCESS;
     765            0 : }
     766              : 
     767            0 : CcuResult CcuKernel::LocalNotifyWait(const char* notifyTag, const uint32_t mask)
     768              : {
     769            0 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalNotifyWait] tag=%s, mask=%u", (notifyTag ? notifyTag : "null"), mask);
     770            0 :     if (notifyTag == nullptr) {
     771            0 :         HCCL_ERROR("[CcuKernel][%s] notifyTag is nullptr, please check.", __func__);
     772            0 :         return CcuResult::CCU_E_PTR;
     773              :     }
     774              : 
     775            0 :     const std::string tagKey(notifyTag);
     776              : 
     777            0 :     auto& sharedNotifies = exportedRes_.sharedNotifies;
     778            0 :     if (sharedNotifies.find(tagKey) == sharedNotifies.end()) {
     779            0 :         CcuRep::LocalNotify notify = CreateLocalNotify();
     780            0 :         exportedRes_.sharedNotifies.insert({tagKey, notify});
     781            0 :     }
     782              : 
     783            0 :     bool isProfiling = CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK;
     784            0 :     Append(std::make_shared<CcuRep::CcuRepLocWaitNotify>(
     785            0 :         insGenerator, exportedRes_.sharedNotifies.at(tagKey), mask, isProfiling));
     786            0 :     return CcuResult::CCU_SUCCESS;
     787            0 : }
     788              : 
     789            6 : CcuResult CcuKernel::NotifyRecord(const ChannelHandle channel, uint32_t remoteNotifyIdx, uint32_t mask)
     790              : {
     791            6 :     PLF_CONFIG_INFO(
     792              :         PLF_DATA_OP, "[NotifyRecord] channel=%llu, remoteNotifyIdx=%u, mask=%u", channel, remoteNotifyIdx, mask);
     793            6 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     794            1 :         HCCL_ERROR("[%s] NotifyRecord is not allowed inside a ccu::Loop body", __func__);
     795            1 :         return LatchBodyError(CcuResult::CCU_E_NOT_SUPPORT);
     796              :     }
     797            5 :     channels_.insert(channel);
     798            5 :     Append(std::make_shared<CcuRep::CcuRepRemPostSem>(insGenerator, channel, remoteNotifyIdx, mask));
     799            5 :     return CCU_SUCCESS;
     800              : }
     801              : 
     802           11 : CcuResult CcuKernel::NotifyWait(const ChannelHandle channel, uint32_t localNotifyIdx, uint32_t mask)
     803              : {
     804           11 :     PLF_CONFIG_INFO(
     805              :         PLF_DATA_OP, "[NotifyWait] channel=%llu, localNotifyIdx=%u, mask=%u", channel, localNotifyIdx, mask);
     806           11 :     channels_.insert(channel);
     807           11 :     bool isProfiling = CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK;
     808           11 :     if (isProfiling) {
     809           33 :         CCU_CHK_RET(static_cast<HcclResult>(AddProfiling(channel, "NotifyWait", localNotifyIdx, mask)));
     810              :     }
     811           10 :     Append(std::make_shared<CcuRep::CcuRepRemWaitSem>(insGenerator, channel, localNotifyIdx, mask, isProfiling));
     812           10 :     return CcuResult::CCU_SUCCESS;
     813              : }
     814              : 
     815           10 : CcuResult CcuKernel::WriteVariableWithNotify(
     816              :     const ChannelHandle channel, CcuVariableHandle varHandle, uint32_t remoteVarIdx, uint32_t remoteNotifyIdx,
     817              :     uint32_t mask)
     818              : {
     819           10 :     PLF_CONFIG_INFO(
     820              :         PLF_DATA_OP,
     821              :         "[WriteVariableWithNotify] channel=%llu, varHandle=%llu, remoteVarIdx=%u,"
     822              :         " remoteNotifyIdx=%u, mask=%u",
     823              :         channel, varHandle, remoteVarIdx, remoteNotifyIdx, mask);
     824           10 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
     825            1 :         HCCL_ERROR("[%s] WriteVariableWithNotify is not allowed inside a ccu::Loop body", __func__);
     826            1 :         return LatchBodyError(CcuResult::CCU_E_NOT_SUPPORT);
     827              :     }
     828            9 :     channels_.insert(channel);
     829            9 :     CcuRep::Variable* var{nullptr};
     830            9 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
     831            9 :     Append(
     832           18 :         std::make_shared<CcuRep::CcuRepRemPostVar>(insGenerator, *var, channel, remoteVarIdx, remoteNotifyIdx, mask));
     833            9 :     return CcuResult::CCU_SUCCESS;
     834              : }
     835              : 
     836              : // 加载类 相关接口
     837           49 : CcuResult CcuKernel::LoadArg(CcuVariableHandle varHandle, uint32_t argId)
     838              : {
     839           49 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoadArg] varHandle=%llu, argId=%u", varHandle, argId);
     840           49 :     loadArgUsedSet_.insert(argId);
     841           49 :     CcuRep::Variable* var{nullptr};
     842           49 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
     843              :     auto loadArgRep = std::make_shared<CcuRep::CcuRepLoadArg>(
     844           49 :         insGenerator, *var, argId % CCU_SQE_ARGS_LEN, static_cast<uint16_t>(argId));
     845           49 :     Append(loadArgRep);
     846           49 :     return CcuResult::CCU_SUCCESS;
     847           49 : }
     848              : 
     849            3 : CcuResult CcuKernel::GetCcuKernelInfo(CcuKernelInfo& info) const
     850              : {
     851            3 :     uint32_t maxTaskArgsNum = 0;
     852              :     // 如果没有LoadArg指令,则说明不需要传入参数,直接返回0
     853            3 :     if (loadArgUsedSet_.empty()) {
     854            1 :         info.maxTaskArgsNum = 0;
     855            1 :         return CcuResult::CCU_SUCCESS;
     856              :     }
     857              :     // 遍历loadArgUsedSet_,获取最大的argId,加1得到最大任务参数数量(argId从0连续)
     858            7 :     for (const auto& argId : loadArgUsedSet_) {
     859            5 :         maxTaskArgsNum = std::max(maxTaskArgsNum, argId);
     860              :     }
     861            2 :     maxTaskArgsNum += 1;
     862            2 :     info.maxTaskArgsNum = maxTaskArgsNum;
     863            2 :     return CcuResult::CCU_SUCCESS;
     864              : }
     865              : 
     866           13 : CcuResult CcuKernel::CheckContinuousVariables(
     867              :     CcuVariableHandle varHandle, uint32_t num, const CcuRep::Variable& baseVar, const char* tag)
     868              : {
     869           13 :     if (num <= 1) {
     870            4 :         return CcuResult::CCU_SUCCESS;
     871              :     }
     872           18 :     for (uint32_t i = 1; i < num; i++) {
     873            9 :         CcuRep::Variable* nextVar{nullptr};
     874            9 :         CCU_CHK_RET(GetVariableByHandle(varHandle + i, &nextVar));
     875            9 :         if (nextVar->Id() != baseVar.Id() + i) {
     876            0 :             HCCL_ERROR(
     877              :                 "[CcuKernel][%s] variables not continuous at index %u, "
     878              :                 "expected Id %u but got %u",
     879              :                 tag, i, baseVar.Id() + i, nextVar->Id());
     880            0 :             return HCCL_TO_CCU_RET(HCCL_E_PARA);
     881              :         }
     882              :     }
     883            9 :     return CcuResult::CCU_SUCCESS;
     884              : }
     885              : 
     886            6 : CcuResult CcuKernel::LoadVar(uint64_t addr, CcuVariableHandle varHandle, uint32_t num)
     887              : {
     888            6 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoadVar] addr=0x%llx, varHandle=%llu, num=%u", addr, varHandle, num);
     889            6 :     CcuRep::Variable* var{nullptr};
     890            6 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
     891            6 :     CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "LoadVariable"));
     892            6 :     Append(std::make_shared<CcuRep::CcuRepLoad>(insGenerator, addr, *var, num));
     893            6 :     return CcuResult::CCU_SUCCESS;
     894              : }
     895              : 
     896            2 : CcuResult CcuKernel::CcuLoadVarFromVarAddr(CcuVariableHandle addrHandle, CcuVariableHandle varHandle, uint32_t num)
     897              : {
     898            2 :     PLF_CONFIG_INFO(
     899              :         PLF_DATA_OP,
     900              :         "[CcuLoadVarFromVarAddr] addrHandle=%llu, varHandle=%llu,"
     901              :         " num=%u",
     902              :         addrHandle, varHandle, num);
     903            2 :     CcuRep::Variable* addrVar{nullptr};
     904            2 :     CCU_CHK_RET(GetVariableByHandle(addrHandle, &addrVar));
     905            2 :     CcuRep::Variable* var{nullptr};
     906            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
     907            2 :     CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "LoadVar dst"));
     908            2 :     Append(std::make_shared<CcuRep::CcuRepLoadVar>(insGenerator, *addrVar, *var, num));
     909            2 :     return CcuResult::CCU_SUCCESS;
     910              : }
     911              : 
     912            3 : CcuResult CcuKernel::StoreVar(uint64_t addr, CcuVariableHandle varHandle, uint32_t num)
     913              : {
     914            3 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[StoreVar] addr=0x%llx, varHandle=%llu, num=%u", addr, varHandle, num);
     915            3 :     CcuRep::Variable* var{nullptr};
     916            3 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
     917            3 :     CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "StoreVariable"));
     918            3 :     Append(std::make_shared<CcuRep::CcuRepStore>(insGenerator, *var, addr, num));
     919            3 :     return CcuResult::CCU_SUCCESS;
     920              : }
     921              : 
     922            2 : CcuResult CcuKernel::CcuStoreVarToVarAddr(CcuVariableHandle addrHandle, CcuVariableHandle varHandle, uint32_t num)
     923              : {
     924            2 :     PLF_CONFIG_INFO(
     925              :         PLF_DATA_OP,
     926              :         "[CcuStoreVarToVarAddr] addrHandle=%llu, varHandle=%llu,"
     927              :         " num=%u",
     928              :         addrHandle, varHandle, num);
     929            2 :     CcuRep::Variable* addrVar{nullptr};
     930            2 :     CCU_CHK_RET(GetVariableByHandle(addrHandle, &addrVar));
     931            2 :     CcuRep::Variable* var{nullptr};
     932            2 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
     933            2 :     CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "StoreVar src"));
     934            2 :     Append(std::make_shared<CcuRep::CcuRepStoreVar>(insGenerator, *var, *addrVar, num));
     935            2 :     return CcuResult::CCU_SUCCESS;
     936              : }
     937              : 
     938              : // 本地数据拷贝 相关实现
     939           12 : CcuResult CcuKernel::LocalCopyMemToBuffer(
     940              :     CcuBufferHandle dstHandle, CcuLocalAddrHandle srcHandle, CcuVariableHandle lenHandle, CcuEventHandle eventHandle,
     941              :     uint32_t mask)
     942              : {
     943           12 :     PLF_CONFIG_INFO(
     944              :         PLF_DATA_OP,
     945              :         "[LocalCopyMemToBuffer] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu,"
     946              :         " eventHandle=%llu, mask=%u",
     947              :         dstHandle, srcHandle, lenHandle, eventHandle, mask);
     948           12 :     CcuRep::CcuBuf* dst{nullptr};
     949           12 :     CCU_CHK_RET(GetBufferByHandle(dstHandle, &dst));
     950           12 :     CcuRep::LocalAddr* src{nullptr};
     951           12 :     CCU_CHK_RET(GetLocalAddrByHandle(srcHandle, &src));
     952           12 :     CcuRep::Variable* len{nullptr};
     953           12 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
     954           12 :     CcuRep::CompletedEvent* event{nullptr};
     955           12 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
     956           12 :     auto ret = LocalCopyNb(*dst, *src, *len, *event, mask); // 复用 protected
     957           12 :     return HCCL_TO_CCU_RET(ret);
     958              : }
     959              : 
     960            8 : CcuResult CcuKernel::LocalCopyBufferToMem(
     961              :     CcuLocalAddrHandle dstHandle, CcuBufferHandle srcHandle, CcuVariableHandle lenHandle, CcuEventHandle eventHandle,
     962              :     uint32_t mask)
     963              : {
     964            8 :     PLF_CONFIG_INFO(
     965              :         PLF_DATA_OP,
     966              :         "[LocalCopyBufferToMem] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu,"
     967              :         " eventHandle=%llu, mask=%u",
     968              :         dstHandle, srcHandle, lenHandle, eventHandle, mask);
     969            8 :     CcuRep::LocalAddr* dst{nullptr};
     970            8 :     CCU_CHK_RET(GetLocalAddrByHandle(dstHandle, &dst));
     971            8 :     CcuRep::CcuBuf* src{nullptr};
     972            8 :     CCU_CHK_RET(GetBufferByHandle(srcHandle, &src));
     973            8 :     CcuRep::Variable* len{nullptr};
     974            8 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
     975            8 :     CcuRep::CompletedEvent* event{nullptr};
     976            8 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
     977            8 :     auto ret = LocalCopyNb(*dst, *src, *len, *event, mask);
     978            8 :     return HCCL_TO_CCU_RET(ret);
     979              : }
     980              : 
     981            1 : CcuResult CcuKernel::LocalCopyMemToMem(
     982              :     CcuLocalAddrHandle dstHandle, CcuLocalAddrHandle srcHandle, CcuVariableHandle lenHandle, CcuEventHandle eventHandle,
     983              :     uint32_t mask)
     984              : {
     985            1 :     PLF_CONFIG_INFO(
     986              :         PLF_DATA_OP,
     987              :         "[LocalCopyMemToMem] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu,"
     988              :         " eventHandle=%llu, mask=%u",
     989              :         dstHandle, srcHandle, lenHandle, eventHandle, mask);
     990            1 :     CcuRep::LocalAddr* dst{nullptr};
     991            1 :     CCU_CHK_RET(GetLocalAddrByHandle(dstHandle, &dst));
     992            1 :     CcuRep::LocalAddr* src{nullptr};
     993            1 :     CCU_CHK_RET(GetLocalAddrByHandle(srcHandle, &src));
     994            1 :     CcuRep::Variable* len{nullptr};
     995            1 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
     996            1 :     CcuRep::CompletedEvent* event{nullptr};
     997            1 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
     998            1 :     auto ret = LocalCopyNb(*dst, *src, *len, *event, mask);
     999            1 :     return HCCL_TO_CCU_RET(ret);
    1000              : }
    1001              : 
    1002              : // 本地reduce 相关实现
    1003            0 : CcuResult CcuKernel::LocalMemReduce(
    1004              :     CcuLocalAddrHandle dstHandle, CcuLocalAddrHandle srcHandle, CcuVariableHandle lenHandle, HcclDataType dataType,
    1005              :     HcclReduceOp opType, CcuEventHandle eventHandle, uint32_t mask)
    1006              : {
    1007            0 :     PLF_CONFIG_INFO(
    1008              :         PLF_DATA_OP,
    1009              :         "[LocalMemReduce] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu, dataType=%d,"
    1010              :         " op=%d, eventHandle=%llu, mask=%u",
    1011              :         dstHandle, srcHandle, lenHandle, dataType, opType, eventHandle, mask);
    1012            0 :     CcuRep::LocalAddr* dst{nullptr};
    1013            0 :     CCU_CHK_RET(GetLocalAddrByHandle(dstHandle, &dst));
    1014            0 :     CcuRep::LocalAddr* src{nullptr};
    1015            0 :     CCU_CHK_RET(GetLocalAddrByHandle(srcHandle, &src));
    1016            0 :     CcuRep::Variable* len{nullptr};
    1017            0 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
    1018            0 :     CcuRep::CompletedEvent* event{nullptr};
    1019            0 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
    1020            0 :     auto ret = LocalReduceNb(*dst, *src, *len, dataType, opType, *event, mask);
    1021            0 :     return HCCL_TO_CCU_RET(ret);
    1022              : }
    1023              : 
    1024            4 : CcuResult CcuKernel::LocalBufferReduce(
    1025              :     CcuBufferHandle* bufHandles, uint32_t count, HcclDataType dataType, HcclDataType outputDataType,
    1026              :     HcclReduceOp opType, CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
    1027              : {
    1028            4 :     PLF_CONFIG_INFO(
    1029              :         PLF_DATA_OP,
    1030              :         "[LocalBufferReduce] count=%u, dataType=%d, outDataType=%d,"
    1031              :         " op=%d, lenHandle=%llu, eventHandle=%llu, mask=%u",
    1032              :         count, dataType, outputDataType, opType, lenHandle, eventHandle, mask);
    1033            4 :     CcuRep::Variable* len{nullptr};
    1034            4 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
    1035            4 :     CcuRep::CompletedEvent* event{nullptr};
    1036            4 :     CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
    1037            4 :     std::vector<CcuRep::CcuBuf> bufs(count);
    1038           12 :     for (uint32_t i = 0; i < count; i++) {
    1039            8 :         CcuRep::CcuBuf* buf{nullptr};
    1040            8 :         CCU_CHK_RET(GetBufferByHandle(bufHandles[i], &buf));
    1041            8 :         bufs[i] = *buf;
    1042              :     }
    1043            4 :     auto ret = LocalReduceNb(bufs.data(), count, dataType, outputDataType, opType, *len, *event, mask);
    1044            4 :     return HCCL_TO_CCU_RET(ret);
    1045            4 : }
    1046              : 
    1047              : /*========== 远端数据传输操作 ==========*/
    1048              : 
    1049            4 : CcuResult CcuKernel::ResolveBufRemoteLenEvent(
    1050              :     CcuBufferHandle bufHandle, CcuRemoteAddrHandle remoteHandle, CcuVariableHandle lenHandle,
    1051              :     CcuEventHandle eventHandle, CcuRep::CcuBuf** buf, CcuRep::RemoteAddr** remote, CcuRep::Variable** len,
    1052              :     CcuRep::CompletedEvent** event)
    1053              : {
    1054            4 :     CCU_CHK_RET(GetBufferByHandle(bufHandle, buf));
    1055            4 :     CCU_CHK_RET(GetRemoteAddrByHandle(remoteHandle, remote));
    1056            4 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, len));
    1057            4 :     CCU_CHK_RET(GetEventByHandle(eventHandle, event));
    1058            4 :     return CcuResult::CCU_SUCCESS;
    1059              : }
    1060              : 
    1061            6 : CcuResult CcuKernel::ResolveLocalRemoteLenEvent(
    1062              :     CcuLocalAddrHandle localHandle, CcuRemoteAddrHandle remoteHandle, CcuVariableHandle lenHandle,
    1063              :     CcuEventHandle eventHandle, CcuRep::LocalAddr** local, CcuRep::RemoteAddr** remote, CcuRep::Variable** len,
    1064              :     CcuRep::CompletedEvent** event)
    1065              : {
    1066            6 :     CCU_CHK_RET(GetLocalAddrByHandle(localHandle, local));
    1067            6 :     CCU_CHK_RET(GetRemoteAddrByHandle(remoteHandle, remote));
    1068            6 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, len));
    1069            6 :     CCU_CHK_RET(GetEventByHandle(eventHandle, event));
    1070            6 :     return CcuResult::CCU_SUCCESS;
    1071              : }
    1072              : 
    1073            5 : CcuResult CcuKernel::ResolveRemoteLocalLenEvent(
    1074              :     CcuRemoteAddrHandle remoteHandle, CcuLocalAddrHandle localHandle, CcuVariableHandle lenHandle,
    1075              :     CcuEventHandle eventHandle, CcuRep::RemoteAddr** remote, CcuRep::LocalAddr** local, CcuRep::Variable** len,
    1076              :     CcuRep::CompletedEvent** event)
    1077              : {
    1078            5 :     CCU_CHK_RET(GetRemoteAddrByHandle(remoteHandle, remote));
    1079            5 :     CCU_CHK_RET(GetLocalAddrByHandle(localHandle, local));
    1080            5 :     CCU_CHK_RET(GetVariableByHandle(lenHandle, len));
    1081            5 :     CCU_CHK_RET(GetEventByHandle(eventHandle, event));
    1082            5 :     return CcuResult::CCU_SUCCESS;
    1083              : }
    1084              : 
    1085            4 : CcuResult CcuKernel::ReadMemToMem(
    1086              :     ChannelHandle channel, CcuLocalAddrHandle localHandle, CcuRemoteAddrHandle remoteHandle,
    1087              :     CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
    1088              : {
    1089            4 :     PLF_CONFIG_INFO(
    1090              :         PLF_DATA_OP,
    1091              :         "[ReadMemToMem] channel=%llu, localHandle=%llu, remoteHandle=%llu,"
    1092              :         " lenHandle=%llu, eventHandle=%llu, mask=%u",
    1093              :         channel, localHandle, remoteHandle, lenHandle, eventHandle, mask);
    1094            4 :     channels_.insert(channel);
    1095            4 :     CcuRep::LocalAddr* local{nullptr};
    1096            4 :     CcuRep::RemoteAddr* remote{nullptr};
    1097            4 :     CcuRep::Variable* len{nullptr};
    1098            4 :     CcuRep::CompletedEvent* event{nullptr};
    1099            4 :     CCU_CHK_RET(
    1100              :         ResolveLocalRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle, &local, &remote, &len, &event));
    1101            4 :     auto ret = ReadNb(channel, *local, *remote, *len, *event, mask);
    1102            4 :     return HCCL_TO_CCU_RET(ret);
    1103              : }
    1104              : 
    1105            2 : CcuResult CcuKernel::ReadMemToBuffer(
    1106              :     ChannelHandle channel, CcuBufferHandle localHandle, CcuRemoteAddrHandle remoteHandle, CcuVariableHandle lenHandle,
    1107              :     CcuEventHandle eventHandle, uint32_t mask)
    1108              : {
    1109            2 :     PLF_CONFIG_INFO(
    1110              :         PLF_DATA_OP,
    1111              :         "[ReadMemToBuffer] channel=%llu, bufHandle=%llu, remoteHandle=%llu,"
    1112              :         " lenHandle=%llu, eventHandle=%llu, mask=%u",
    1113              :         channel, localHandle, remoteHandle, lenHandle, eventHandle, mask);
    1114            2 :     channels_.insert(channel);
    1115            2 :     CcuRep::CcuBuf* local{nullptr};
    1116            2 :     CcuRep::RemoteAddr* remote{nullptr};
    1117            2 :     CcuRep::Variable* len{nullptr};
    1118            2 :     CcuRep::CompletedEvent* event{nullptr};
    1119            2 :     CCU_CHK_RET(
    1120              :         ResolveBufRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle, &local, &remote, &len, &event));
    1121            2 :     auto ret = ReadNb(channel, *local, *remote, *len, *event, mask);
    1122            2 :     return HCCL_TO_CCU_RET(ret);
    1123              : }
    1124              : 
    1125            2 : CcuResult CcuKernel::ReadMemToMemReduce(
    1126              :     ChannelHandle channel, CcuLocalAddrHandle localHandle, CcuRemoteAddrHandle remoteHandle,
    1127              :     CcuVariableHandle lenHandle, HcclDataType dataType, HcclReduceOp opType, CcuEventHandle eventHandle, uint32_t mask)
    1128              : {
    1129            2 :     PLF_CONFIG_INFO(
    1130              :         PLF_DATA_OP,
    1131              :         "[ReadMemToMemReduce] channel=%llu, lenHandle=%llu, dataType=%d, op=%d,"
    1132              :         " eventHandle=%llu, mask=%u",
    1133              :         channel, lenHandle, dataType, opType, eventHandle, mask);
    1134            2 :     channels_.insert(channel);
    1135            2 :     CcuRep::LocalAddr* local{nullptr};
    1136            2 :     CcuRep::RemoteAddr* remote{nullptr};
    1137            2 :     CcuRep::Variable* len{nullptr};
    1138            2 :     CcuRep::CompletedEvent* event{nullptr};
    1139            2 :     CCU_CHK_RET(
    1140              :         ResolveLocalRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle, &local, &remote, &len, &event));
    1141            2 :     auto ret = ReadReduceNb(channel, *local, *remote, *len, dataType, opType, *event, mask);
    1142            2 :     return HCCL_TO_CCU_RET(ret);
    1143              : }
    1144              : 
    1145            3 : CcuResult CcuKernel::WriteMemToMem(
    1146              :     ChannelHandle channel, CcuRemoteAddrHandle remoteHandle, CcuLocalAddrHandle localHandle,
    1147              :     CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
    1148              : {
    1149            3 :     PLF_CONFIG_INFO(
    1150              :         PLF_DATA_OP,
    1151              :         "[WriteMemToMem] channel=%llu, remoteHandle=%llu, localHandle=%llu,"
    1152              :         " lenHandle=%llu, eventHandle=%llu, mask=%u",
    1153              :         channel, remoteHandle, localHandle, lenHandle, eventHandle, mask);
    1154            3 :     channels_.insert(channel);
    1155            3 :     CcuRep::RemoteAddr* remote{nullptr};
    1156            3 :     CcuRep::LocalAddr* local{nullptr};
    1157            3 :     CcuRep::Variable* len{nullptr};
    1158            3 :     CcuRep::CompletedEvent* event{nullptr};
    1159            3 :     CCU_CHK_RET(
    1160              :         ResolveRemoteLocalLenEvent(remoteHandle, localHandle, lenHandle, eventHandle, &remote, &local, &len, &event));
    1161            3 :     auto ret = WriteNb(channel, *remote, *local, *len, *event, mask);
    1162            3 :     return HCCL_TO_CCU_RET(ret);
    1163              : }
    1164              : 
    1165            2 : CcuResult CcuKernel::WriteBufferToMem(
    1166              :     ChannelHandle channel, CcuRemoteAddrHandle remoteHandle, CcuBufferHandle localHandle, CcuVariableHandle lenHandle,
    1167              :     CcuEventHandle eventHandle, uint32_t mask)
    1168              : {
    1169            2 :     PLF_CONFIG_INFO(
    1170              :         PLF_DATA_OP,
    1171              :         "[WriteBufferToMem] channel=%llu, remoteHandle=%llu, bufHandle=%llu,"
    1172              :         " lenHandle=%llu, eventHandle=%llu, mask=%u",
    1173              :         channel, remoteHandle, localHandle, lenHandle, eventHandle, mask);
    1174            2 :     channels_.insert(channel);
    1175            2 :     CcuRep::CcuBuf* local{nullptr};
    1176            2 :     CcuRep::RemoteAddr* remote{nullptr};
    1177            2 :     CcuRep::Variable* len{nullptr};
    1178            2 :     CcuRep::CompletedEvent* event{nullptr};
    1179            2 :     CCU_CHK_RET(
    1180              :         ResolveBufRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle, &local, &remote, &len, &event));
    1181            2 :     auto ret = WriteNb(channel, *remote, *local, *len, *event, mask);
    1182            2 :     return HCCL_TO_CCU_RET(ret);
    1183              : }
    1184              : 
    1185            2 : CcuResult CcuKernel::WriteMemToMemReduce(
    1186              :     ChannelHandle channel, CcuRemoteAddrHandle remoteHandle, CcuLocalAddrHandle localHandle,
    1187              :     CcuVariableHandle lenHandle, HcclDataType dataType, HcclReduceOp opType, CcuEventHandle eventHandle, uint32_t mask)
    1188              : {
    1189            2 :     PLF_CONFIG_INFO(
    1190              :         PLF_DATA_OP,
    1191              :         "[WriteMemToMemReduce] channel=%llu, lenHandle=%llu, dataType=%d, op=%d,"
    1192              :         " eventHandle=%llu, mask=%u",
    1193              :         channel, lenHandle, dataType, opType, eventHandle, mask);
    1194            2 :     channels_.insert(channel);
    1195            2 :     CcuRep::RemoteAddr* remote{nullptr};
    1196            2 :     CcuRep::LocalAddr* local{nullptr};
    1197            2 :     CcuRep::Variable* len{nullptr};
    1198            2 :     CcuRep::CompletedEvent* event{nullptr};
    1199            2 :     CCU_CHK_RET(
    1200              :         ResolveRemoteLocalLenEvent(remoteHandle, localHandle, lenHandle, eventHandle, &remote, &local, &len, &event));
    1201            2 :     auto ret = WriteReduceNb(channel, *remote, *local, *len, dataType, opType, *event, mask);
    1202            2 :     return HCCL_TO_CCU_RET(ret);
    1203              : }
    1204              : 
    1205         1497 : void CcuKernel::FlushClosablePendingIfs()
    1206              : {
    1207         1497 :     if (isFlushing_) {
    1208           82 :         return;
    1209              :     }
    1210         1415 :     isFlushing_ = true;
    1211         2912 :     while (IfLabelStackTopIsClosable()) {
    1212           82 :         const char* lbl = IfLabelStackPop();
    1213           82 :         if (lbl != nullptr) {
    1214           82 :             IfEnd(lbl);
    1215              :         }
    1216              :     }
    1217         1415 :     isFlushing_ = false;
    1218              : }
    1219              : 
    1220         1232 : void CcuKernel::Append(std::shared_ptr<CcuRep::CcuRepBase> rep)
    1221              : {
    1222         1232 :     FlushClosablePendingIfs();
    1223         1232 :     CcuRep::CcuRepContext::Append(rep);
    1224         1232 : }
    1225              : 
    1226              : namespace {
    1227          104 :     std::shared_ptr<CcuRep::CcuRepJumpBase> MakeInvertedCondJumpImm(
    1228              :         CcuInsGeneratorBase* insGenerator, const std::string& destLabelStr, const CcuRep::Variable& targetVar,
    1229              :         const CcuRep::Variable& expectVar, const CcuRep::Variable& variable, uint64_t immediate,
    1230              :         CcuConditionType condType, const char* funcName)
    1231              :     {
    1232          104 :         switch (condType) {
    1233           82 :             case CCU_CONDITION_EQ:
    1234          164 :                 return std::make_shared<CcuRep::CcuRepJumpNE>(
    1235           82 :                     insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
    1236           12 :             case CCU_CONDITION_NE:
    1237           24 :                 return std::make_shared<CcuRep::CcuRepJumpEQ>(
    1238           12 :                     insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
    1239            3 :             case CCU_CONDITION_LT:
    1240            6 :                 return std::make_shared<CcuRep::CcuRepJumpGE>(
    1241            3 :                     insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
    1242            2 :             case CCU_CONDITION_LE:
    1243            4 :                 return std::make_shared<CcuRep::CcuRepJumpGT>(
    1244            2 :                     insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
    1245            2 :             case CCU_CONDITION_GT:
    1246            4 :                 return std::make_shared<CcuRep::CcuRepJumpLE>(
    1247            2 :                     insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
    1248            3 :             case CCU_CONDITION_GE:
    1249            6 :                 return std::make_shared<CcuRep::CcuRepJumpLT>(
    1250            3 :                     insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
    1251            0 :             default:
    1252            0 :                 HCCL_ERROR("[%s] unsupported condition type: %d", funcName, condType);
    1253            0 :                 return nullptr;
    1254              :         }
    1255              :     }
    1256              : 
    1257              :     // 双变量版本:当 (lhsVar OP rhsVar) 为假时跳转到 destLabelStr。
    1258            4 :     std::shared_ptr<CcuRep::CcuRepJumpBase> MakeInvertedCondJumpVar(
    1259              :         CcuInsGeneratorBase* insGenerator, const std::string& destLabelStr, const CcuRep::Variable& targetVar,
    1260              :         const CcuRep::Variable& lhsVar, const CcuRep::Variable& rhsVar, CcuConditionType condType, const char* funcName)
    1261              :     {
    1262            4 :         switch (condType) {
    1263            1 :             case CCU_CONDITION_EQ:
    1264            1 :                 return std::make_shared<CcuRep::CcuRepJumpNE>(insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
    1265            0 :             case CCU_CONDITION_NE:
    1266            0 :                 return std::make_shared<CcuRep::CcuRepJumpEQ>(insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
    1267            2 :             case CCU_CONDITION_LT:
    1268            2 :                 return std::make_shared<CcuRep::CcuRepJumpGE>(insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
    1269            0 :             case CCU_CONDITION_LE:
    1270            0 :                 return std::make_shared<CcuRep::CcuRepJumpGT>(insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
    1271            0 :             case CCU_CONDITION_GT:
    1272            0 :                 return std::make_shared<CcuRep::CcuRepJumpLE>(insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
    1273            1 :             case CCU_CONDITION_GE:
    1274            1 :                 return std::make_shared<CcuRep::CcuRepJumpLT>(insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
    1275            0 :             default:
    1276            0 :                 HCCL_ERROR("[%s] unsupported condition type: %d", funcName, condType);
    1277            0 :                 return nullptr;
    1278              :         }
    1279              :     }
    1280              : } // namespace
    1281              : 
    1282              : CcuResult
    1283          102 : CcuKernel::IfBegin(CcuVariableHandle varHandle, uint64_t immediate, CcuConditionType condType, const char* label)
    1284              : {
    1285          102 :     PLF_CONFIG_INFO(
    1286              :         PLF_DATA_OP, "[IfBegin] varHandle=%llu, immediate=%llu, condType=%d, label=%s", varHandle, immediate, condType,
    1287              :         (label ? label : "null"));
    1288          102 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1289            1 :         HCCL_ERROR(
    1290              :             "[%s] CCU_IF is not allowed inside a ccu::Loop body (label='%s')", __func__,
    1291              :             label != nullptr ? label : "(null)");
    1292            1 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    1293              :     }
    1294          101 :     CcuRep::Variable* variable{nullptr};
    1295          101 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
    1296              : 
    1297          101 :     FlushClosablePendingIfs();
    1298              : 
    1299          101 :     std::string labelStr(label);
    1300          101 :     if (pendingIfCtx_.find(labelStr) != pendingIfCtx_.end()) {
    1301            0 :         HCCL_ERROR("[%s] label '%s' already has a pending IfBegin without IfEnd", __func__, label);
    1302            0 :         return CcuResult::CCU_E_PARA;
    1303              :     }
    1304              : 
    1305          101 :     std::string elseLabelStr = labelStr + "_else";
    1306          101 :     std::string endLabelStr = labelStr + "_end";
    1307          101 :     auto elseLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, elseLabelStr);
    1308          101 :     auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
    1309          101 :     auto targetVar = CreateJumpTargetVar();
    1310          101 :     auto expectVar = CreateExpectVar();
    1311              : 
    1312              :     // 反转条件:"if <cond>, 执行块" 等价于 "!<cond> 时跳过块"。
    1313              :     auto jump = MakeInvertedCondJumpImm(
    1314          101 :         insGenerator, elseLabelStr, targetVar, expectVar, *variable, immediate, condType, __func__);
    1315          101 :     if (jump == nullptr) {
    1316            0 :         return CcuResult::CCU_E_PARA;
    1317              :     }
    1318          101 :     jump->Reference(elseLabel);
    1319          101 :     Append(jump);
    1320              : 
    1321          101 :     PendingIfContext ctx;
    1322          101 :     ctx.elseLabel = elseLabel;
    1323          101 :     ctx.endLabel = endLabel;
    1324          101 :     ctx.hasElse = false;
    1325          101 :     pendingIfCtx_.emplace(labelStr, std::move(ctx));
    1326              : 
    1327          101 :     return CcuResult::CCU_SUCCESS;
    1328          101 : }
    1329              : 
    1330            3 : CcuResult CcuKernel::IfBeginVar(
    1331              :     CcuVariableHandle lhsHandle, CcuVariableHandle rhsHandle, CcuConditionType condType, const char* label)
    1332              : {
    1333            3 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1334            0 :         HCCL_ERROR(
    1335              :             "[%s] CCU_IF is not allowed inside a ccu::Loop body (label='%s')", __func__,
    1336              :             label != nullptr ? label : "(null)");
    1337            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    1338              :     }
    1339            3 :     CcuRep::Variable* lhsVar{nullptr};
    1340            3 :     CcuRep::Variable* rhsVar{nullptr};
    1341            3 :     CCU_CHK_RET(GetVariableByHandle(lhsHandle, &lhsVar));
    1342            3 :     CCU_CHK_RET(GetVariableByHandle(rhsHandle, &rhsVar));
    1343              : 
    1344            3 :     FlushClosablePendingIfs();
    1345              : 
    1346            3 :     std::string labelStr(label);
    1347            3 :     if (pendingIfCtx_.find(labelStr) != pendingIfCtx_.end()) {
    1348            0 :         HCCL_ERROR("[%s] label '%s' already has a pending IfBegin without IfEnd", __func__, label);
    1349            0 :         return CcuResult::CCU_E_PARA;
    1350              :     }
    1351              : 
    1352            3 :     std::string endLabelStr = labelStr + "_end";
    1353            3 :     std::string elseLabelStr = labelStr + "_else";
    1354            3 :     auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
    1355            3 :     auto elseLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, elseLabelStr);
    1356            3 :     auto targetVar = CreateJumpTargetVar();
    1357              : 
    1358            3 :     auto jump = MakeInvertedCondJumpVar(insGenerator, elseLabelStr, targetVar, *lhsVar, *rhsVar, condType, __func__);
    1359            3 :     if (jump == nullptr) {
    1360            0 :         return CcuResult::CCU_E_PARA;
    1361              :     }
    1362            3 :     jump->Reference(elseLabel);
    1363            3 :     Append(jump);
    1364              : 
    1365            3 :     PendingIfContext ctx;
    1366            3 :     ctx.hasElse = false;
    1367            3 :     ctx.endLabel = endLabel;
    1368            3 :     ctx.elseLabel = elseLabel;
    1369            3 :     pendingIfCtx_.emplace(labelStr, std::move(ctx));
    1370              : 
    1371            3 :     return CcuResult::CCU_SUCCESS;
    1372            3 : }
    1373              : 
    1374           22 : CcuResult CcuKernel::IfElse(const char* label)
    1375              : {
    1376           22 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[IfElse] label=%s", (label ? label : "null"));
    1377           22 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1378            0 :         HCCL_ERROR(
    1379              :             "[%s] CCU_ELSE is not allowed inside a ccu::Loop body (label='%s')", __func__,
    1380              :             label != nullptr ? label : "(null)");
    1381            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    1382              :     }
    1383              : 
    1384           22 :     std::string labelStr(label);
    1385           22 :     auto iter = pendingIfCtx_.find(labelStr);
    1386           22 :     if (iter == pendingIfCtx_.end()) {
    1387            0 :         HCCL_ERROR("[%s] no matching IfBegin for label '%s'", __func__, label);
    1388            0 :         return CcuResult::CCU_E_NOT_FOUND;
    1389              :     }
    1390              : 
    1391           22 :     if (iter->second.hasElse) {
    1392            0 :         HCCL_ERROR("[%s] label '%s' already has an IfElse", __func__, label);
    1393            0 :         return CcuResult::CCU_E_PARA;
    1394              :     }
    1395              : 
    1396              :     // At end of then-block: unconditional jump past else-block to endLabel
    1397           22 :     std::string endLabelStr = labelStr + "_end";
    1398           22 :     auto skipElseVar = CreateJumpTargetVar();
    1399           22 :     auto skipElseJump = std::make_shared<CcuRep::CcuRepJump>(insGenerator, endLabelStr, skipElseVar);
    1400           22 :     skipElseJump->Reference(iter->second.endLabel);
    1401           22 :     Append(skipElseJump);
    1402              : 
    1403              :     // Place the else label (entry point of else-block)
    1404           22 :     Append(iter->second.elseLabel);
    1405              : 
    1406           22 :     iter->second.hasElse = true;
    1407              : 
    1408           22 :     return CcuResult::CCU_SUCCESS;
    1409           22 : }
    1410              : 
    1411          104 : CcuResult CcuKernel::IfEnd(const char* label)
    1412              : {
    1413          104 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[IfEnd] label=%s", (label ? label : "null"));
    1414          104 :     std::string labelStr(label);
    1415          104 :     auto iter = pendingIfCtx_.find(labelStr);
    1416          104 :     if (iter == pendingIfCtx_.end()) {
    1417            0 :         HCCL_ERROR("[%s] no matching IfBegin for label '%s'", __func__, label);
    1418            0 :         return CcuResult::CCU_E_NOT_FOUND;
    1419              :     }
    1420              : 
    1421          104 :     if (iter->second.hasElse) {
    1422              :         // Had else-block: place endLabel after else-block
    1423           22 :         Append(iter->second.endLabel);
    1424              :     } else {
    1425              :         // No else-block: place elseLabel as the skip target
    1426           82 :         Append(iter->second.elseLabel);
    1427              :     }
    1428              : 
    1429          104 :     pendingIfCtx_.erase(iter);
    1430              : 
    1431          104 :     return CcuResult::CCU_SUCCESS;
    1432          104 : }
    1433              : 
    1434              : CcuResult
    1435            3 : CcuKernel::WhileBegin(CcuVariableHandle varHandle, uint64_t immediate, CcuConditionType condType, const char* label)
    1436              : {
    1437            3 :     PLF_CONFIG_INFO(
    1438              :         PLF_DATA_OP, "[WhileBegin] varHandle=%llu, immediate=%llu, condType=%d, label=%s", varHandle, immediate,
    1439              :         condType, (label ? label : "null"));
    1440            3 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1441            0 :         HCCL_ERROR(
    1442              :             "[%s] CCU_WHILE is not allowed inside a ccu::Loop body (label='%s')", __func__,
    1443              :             label != nullptr ? label : "(null)");
    1444            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    1445              :     }
    1446              : 
    1447            3 :     CcuRep::Variable* variable{nullptr};
    1448            3 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
    1449              : 
    1450            3 :     std::string labelStr(label);
    1451            3 :     if (pendingWhileCtx_.find(labelStr) != pendingWhileCtx_.end()) {
    1452            0 :         HCCL_ERROR("[%s] label '%s' already has a pending WhileBegin without WhileEnd", __func__, label);
    1453            0 :         return CcuResult::CCU_E_PARA;
    1454              :     }
    1455              : 
    1456            3 :     std::string beginLabelStr = labelStr + "_begin";
    1457            3 :     std::string endLabelStr = labelStr + "_end";
    1458            3 :     auto beginLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, beginLabelStr);
    1459            3 :     auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
    1460              : 
    1461            3 :     Append(beginLabel);
    1462              : 
    1463            3 :     auto targetVar = CcuRep::CreateVariable(this);
    1464            3 :     auto expectVar = CreateExpectVar();
    1465              :     auto jump = MakeInvertedCondJumpImm(
    1466            3 :         insGenerator, endLabelStr, targetVar, expectVar, *variable, immediate, condType, __func__);
    1467            3 :     if (jump == nullptr) {
    1468            0 :         return CcuResult::CCU_E_PARA;
    1469              :     }
    1470            3 :     jump->Reference(endLabel);
    1471            3 :     Append(jump);
    1472              : 
    1473            3 :     PendingWhileContext ctx;
    1474            3 :     ctx.beginLabel = beginLabel;
    1475            3 :     ctx.endLabel = endLabel;
    1476            3 :     ctx.varHandle = varHandle;
    1477            3 :     ctx.immediate = immediate;
    1478            3 :     ctx.condType = condType;
    1479            3 :     pendingWhileCtx_.emplace(labelStr, std::move(ctx));
    1480              : 
    1481            3 :     return CcuResult::CCU_SUCCESS;
    1482            3 : }
    1483              : 
    1484            1 : CcuResult CcuKernel::WhileBeginVar(
    1485              :     CcuVariableHandle lhsHandle, CcuVariableHandle rhsHandle, CcuConditionType condType, const char* label)
    1486              : {
    1487            1 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1488            0 :         HCCL_ERROR(
    1489              :             "[%s] CCU_WHILE is not allowed inside a ccu::Loop body (label='%s')", __func__,
    1490              :             label != nullptr ? label : "(null)");
    1491            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    1492              :     }
    1493              : 
    1494            1 :     CcuRep::Variable* lhsVar{nullptr};
    1495            1 :     CcuRep::Variable* rhsVar{nullptr};
    1496            1 :     CCU_CHK_RET(GetVariableByHandle(lhsHandle, &lhsVar));
    1497            1 :     CCU_CHK_RET(GetVariableByHandle(rhsHandle, &rhsVar));
    1498              : 
    1499            1 :     std::string labelStr(label);
    1500            1 :     if (pendingWhileCtx_.find(labelStr) != pendingWhileCtx_.end()) {
    1501            0 :         HCCL_ERROR("[%s] label '%s' already has a pending WhileBegin without WhileEnd", __func__, label);
    1502            0 :         return CcuResult::CCU_E_PARA;
    1503              :     }
    1504              : 
    1505            1 :     std::string endLabelStr = labelStr + "_end";
    1506            1 :     std::string beginLabelStr = labelStr + "_begin";
    1507            1 :     auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
    1508            1 :     auto beginLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, beginLabelStr);
    1509              : 
    1510            1 :     Append(beginLabel);
    1511              : 
    1512            1 :     auto targetVar = CcuRep::CreateVariable(this);
    1513            1 :     auto jump = MakeInvertedCondJumpVar(insGenerator, endLabelStr, targetVar, *lhsVar, *rhsVar, condType, __func__);
    1514            1 :     if (jump == nullptr) {
    1515            0 :         return CcuResult::CCU_E_PARA;
    1516              :     }
    1517            1 :     jump->Reference(endLabel);
    1518            1 :     Append(jump);
    1519              : 
    1520            1 :     PendingWhileContext ctx;
    1521            1 :     ctx.beginLabel = beginLabel;
    1522            1 :     ctx.endLabel = endLabel;
    1523            1 :     ctx.varHandle = lhsHandle;
    1524            1 :     ctx.immediate = 0;
    1525            1 :     ctx.condType = condType;
    1526            1 :     pendingWhileCtx_.emplace(labelStr, std::move(ctx));
    1527              : 
    1528            1 :     return CcuResult::CCU_SUCCESS;
    1529            1 : }
    1530              : 
    1531            4 : CcuResult CcuKernel::WhileEnd(const char* label)
    1532              : {
    1533            4 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[WhileEnd] label=%s", (label ? label : "null"));
    1534            4 :     std::string labelStr(label);
    1535            4 :     auto iter = pendingWhileCtx_.find(labelStr);
    1536            4 :     if (iter == pendingWhileCtx_.end()) {
    1537            0 :         HCCL_ERROR("[%s] no matching WhileBegin for label '%s'", __func__, label);
    1538            0 :         return CcuResult::CCU_E_NOT_FOUND;
    1539              :     }
    1540              : 
    1541            4 :     std::string beginLabelStr = labelStr + "_begin";
    1542            4 :     auto loopBackVar = CcuRep::CreateVariable(this);
    1543            4 :     auto loopBackJump = std::make_shared<CcuRep::CcuRepJump>(insGenerator, beginLabelStr, loopBackVar);
    1544            4 :     loopBackJump->Reference(iter->second.beginLabel);
    1545            4 :     Append(loopBackJump);
    1546              : 
    1547            4 :     Append(iter->second.endLabel);
    1548              : 
    1549            4 :     pendingWhileCtx_.erase(iter);
    1550              : 
    1551            4 :     return CcuResult::CCU_SUCCESS;
    1552            4 : }
    1553              : 
    1554            9 : CcuResult CcuKernel::DoWhileBegin(const char* label)
    1555              : {
    1556            9 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[DoWhileBegin] label=%s", (label ? label : "null"));
    1557            9 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1558            0 :         HCCL_ERROR(
    1559              :             "[%s] CCU_DO is not allowed inside a ccu::Loop body (label='%s')", __func__,
    1560              :             label != nullptr ? label : "(null)");
    1561            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    1562              :     }
    1563              : 
    1564            9 :     std::string labelStr(label);
    1565            9 :     if (pendingDoWhileCtx_.find(labelStr) != pendingDoWhileCtx_.end()) {
    1566            0 :         HCCL_ERROR("[%s] label '%s' already has a pending DoWhileBegin without DoWhileEnd", __func__, label);
    1567            0 :         return CcuResult::CCU_E_PARA;
    1568              :     }
    1569              : 
    1570            9 :     std::string beginLabelStr = labelStr + "_begin";
    1571            9 :     auto beginLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, beginLabelStr);
    1572            9 :     Append(beginLabel);
    1573              : 
    1574            9 :     PendingDoWhileContext ctx;
    1575            9 :     ctx.beginLabel = beginLabel;
    1576            9 :     pendingDoWhileCtx_.emplace(labelStr, std::move(ctx));
    1577              : 
    1578            9 :     return CcuResult::CCU_SUCCESS;
    1579            9 : }
    1580              : 
    1581              : CcuResult
    1582            5 : CcuKernel::DoWhileEnd(CcuVariableHandle varHandle, uint64_t immediate, CcuConditionType condType, const char* label)
    1583              : {
    1584            5 :     PLF_CONFIG_INFO(
    1585              :         PLF_DATA_OP, "[DoWhileEnd] varHandle=%llu, immediate=%llu, condType=%d, label=%s", varHandle, immediate,
    1586              :         condType, (label ? label : "null"));
    1587            5 :     CcuRep::Variable* variable{nullptr};
    1588            5 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
    1589              : 
    1590            5 :     std::string labelStr(label);
    1591            5 :     auto iter = pendingDoWhileCtx_.find(labelStr);
    1592            5 :     if (iter == pendingDoWhileCtx_.end()) {
    1593            0 :         HCCL_ERROR("[%s] no matching DoWhileBegin for label '%s'", __func__, label);
    1594            0 :         return CcuResult::CCU_E_NOT_FOUND;
    1595              :     }
    1596              : 
    1597            5 :     std::string beginLabelStr = labelStr + "_begin";
    1598            5 :     auto targetVar = CcuRep::CreateVariable(this);
    1599            5 :     auto expectVar = CreateExpectVar();
    1600            5 :     std::shared_ptr<CcuRep::CcuRepJumpBase> jump{nullptr};
    1601              : 
    1602              :     // "condition true => continue looping" means jump back to begin when condition holds
    1603            5 :     if (condType == CCU_CONDITION_EQ) {
    1604            0 :         jump = std::make_shared<CcuRep::CcuRepJumpEQ>(
    1605            0 :             insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
    1606            5 :     } else if (condType == CCU_CONDITION_NE) {
    1607            4 :         jump = std::make_shared<CcuRep::CcuRepJumpNE>(
    1608            4 :             insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
    1609            1 :     } else if (condType == CCU_CONDITION_LT) {
    1610            0 :         jump = std::make_shared<CcuRep::CcuRepJumpLT>(
    1611            0 :             insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
    1612            1 :     } else if (condType == CCU_CONDITION_LE) {
    1613            1 :         jump = std::make_shared<CcuRep::CcuRepJumpLE>(
    1614            1 :             insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
    1615            0 :     } else if (condType == CCU_CONDITION_GT) {
    1616            0 :         jump = std::make_shared<CcuRep::CcuRepJumpGT>(
    1617            0 :             insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
    1618            0 :     } else if (condType == CCU_CONDITION_GE) {
    1619            0 :         jump = std::make_shared<CcuRep::CcuRepJumpGE>(
    1620            0 :             insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
    1621              :     } else {
    1622            0 :         HCCL_ERROR("[%s] unsupported condition type: %d", __func__, condType);
    1623            0 :         return CcuResult::CCU_E_PARA;
    1624              :     }
    1625              : 
    1626            5 :     jump->Reference(iter->second.beginLabel);
    1627            5 :     Append(jump);
    1628              : 
    1629            5 :     pendingDoWhileCtx_.erase(iter);
    1630              : 
    1631            5 :     return CcuResult::CCU_SUCCESS;
    1632            5 : }
    1633              : 
    1634            1 : CcuResult CcuKernel::DoWhileEndVar(
    1635              :     CcuVariableHandle lhsHandle, CcuVariableHandle rhsHandle, CcuConditionType condType, const char* label)
    1636              : {
    1637            1 :     CcuRep::Variable* lhsVar{nullptr};
    1638            1 :     CcuRep::Variable* rhsVar{nullptr};
    1639            1 :     CCU_CHK_RET(GetVariableByHandle(lhsHandle, &lhsVar));
    1640            1 :     CCU_CHK_RET(GetVariableByHandle(rhsHandle, &rhsVar));
    1641              : 
    1642            1 :     std::string labelStr(label);
    1643            1 :     auto iter = pendingDoWhileCtx_.find(labelStr);
    1644            1 :     if (iter == pendingDoWhileCtx_.end()) {
    1645            0 :         HCCL_ERROR("[%s] no matching DoWhileBegin for label '%s'", __func__, label);
    1646            0 :         return CcuResult::CCU_E_NOT_FOUND;
    1647              :     }
    1648              : 
    1649            1 :     std::string beginLabelStr = labelStr + "_begin";
    1650            1 :     auto targetVar = CcuRep::CreateVariable(this);
    1651            1 :     std::shared_ptr<CcuRep::CcuRepJumpBase> jump{nullptr};
    1652              : 
    1653            1 :     if (condType == CCU_CONDITION_EQ) {
    1654            0 :         jump = std::make_shared<CcuRep::CcuRepJumpEQ>(insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
    1655            1 :     } else if (condType == CCU_CONDITION_NE) {
    1656            1 :         jump = std::make_shared<CcuRep::CcuRepJumpNE>(insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
    1657            0 :     } else if (condType == CCU_CONDITION_LT) {
    1658            0 :         jump = std::make_shared<CcuRep::CcuRepJumpLT>(insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
    1659            0 :     } else if (condType == CCU_CONDITION_LE) {
    1660            0 :         jump = std::make_shared<CcuRep::CcuRepJumpLE>(insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
    1661            0 :     } else if (condType == CCU_CONDITION_GT) {
    1662            0 :         jump = std::make_shared<CcuRep::CcuRepJumpGT>(insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
    1663            0 :     } else if (condType == CCU_CONDITION_GE) {
    1664            0 :         jump = std::make_shared<CcuRep::CcuRepJumpGE>(insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
    1665              :     } else {
    1666            0 :         HCCL_ERROR("[%s] unsupported condition type: %d", __func__, condType);
    1667            0 :         return CcuResult::CCU_E_PARA;
    1668              :     }
    1669              : 
    1670            1 :     jump->Reference(iter->second.beginLabel);
    1671            1 :     Append(jump);
    1672              : 
    1673            1 :     pendingDoWhileCtx_.erase(iter);
    1674              : 
    1675            1 :     return CcuResult::CCU_SUCCESS;
    1676            1 : }
    1677              : 
    1678              : // 控制流标签栈实体
    1679          104 : void CcuKernel::IfLabelStackPush(const char* label) { iflabelStack_.push_back({label, false}); }
    1680          104 : void CcuKernel::IfLabelStackMarkBodyDone()
    1681              : {
    1682          104 :     if (iflabelStack_.empty()) {
    1683            0 :         HCCL_ERROR("[CcuKernel::IfLabelStack][MarkBodyDone] stack is empty");
    1684            0 :         return;
    1685              :     }
    1686          104 :     iflabelStack_.back().bodyDone = true;
    1687              : }
    1688           22 : const char* CcuKernel::IfLabelStackPopForElse()
    1689              : {
    1690           22 :     if (iflabelStack_.empty()) {
    1691            0 :         HCCL_ERROR("[CcuKernel::IfLabelStack][PopForElse] orphan CCU_ELSE: "
    1692              :                    "no matching CCU_IF on the stack");
    1693            0 :         return nullptr;
    1694              :     }
    1695           22 :     if (!iflabelStack_.back().bodyDone) {
    1696            0 :         HCCL_ERROR(
    1697              :             "[CcuKernel::IfLabelStack][PopForElse] CCU_ELSE called while "
    1698              :             "top if-body is still InBody (label='%s')",
    1699              :             iflabelStack_.back().label != nullptr ? iflabelStack_.back().label : "(null)");
    1700            0 :         return nullptr;
    1701              :     }
    1702           22 :     const char* label = iflabelStack_.back().label;
    1703           22 :     iflabelStack_.pop_back();
    1704           22 :     return label;
    1705              : }
    1706         1497 : bool CcuKernel::IfLabelStackTopIsClosable() { return !iflabelStack_.empty() && iflabelStack_.back().bodyDone; }
    1707              : 
    1708           82 : const char* CcuKernel::IfLabelStackPop()
    1709              : {
    1710           82 :     if (iflabelStack_.empty()) {
    1711            0 :         return nullptr;
    1712              :     }
    1713           82 :     const char* label = iflabelStack_.back().label;
    1714           82 :     iflabelStack_.pop_back();
    1715           82 :     return label;
    1716              : }
    1717              : 
    1718            9 : void CcuKernel::DoWhileLabelStackPush(const char* label)
    1719              : {
    1720            9 :     DoWhileLabelEntry entry;
    1721            9 :     entry.label = label;
    1722            9 :     entry.snapshotBlock = CurrentBlock();
    1723            9 :     entry.snapshotRepCount = (entry.snapshotBlock != nullptr) ? entry.snapshotBlock->GetReps().size() : 0;
    1724            9 :     doWhileLabelStack_.push_back(std::move(entry));
    1725            9 : }
    1726              : 
    1727           13 : const char* CcuKernel::DoWhileLabelStackPopForWhile()
    1728              : {
    1729           13 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1730            1 :         return nullptr;
    1731              :     }
    1732           12 :     if (doWhileLabelStack_.empty()) {
    1733            4 :         return nullptr;
    1734              :     }
    1735            8 :     DoWhileLabelEntry entry = doWhileLabelStack_.back();
    1736            8 :     doWhileLabelStack_.pop_back();
    1737              : 
    1738            8 :     auto currentBlock = CurrentBlock();
    1739            8 :     size_t currentRepCount = (currentBlock != nullptr) ? currentBlock->GetReps().size() : 0;
    1740            8 :     if (currentBlock != entry.snapshotBlock || currentRepCount != entry.snapshotRepCount) {
    1741            1 :         HCCL_ERROR(
    1742              :             "[CcuKernel::DoWhileLabelStackPopForWhile] dangling CCU calls between CCU_DO end "
    1743              :             "and CCU_WHILE (label='%s', snapRep=%zu, curRep=%zu, blockChanged=%d); they must "
    1744              :             "be syntactically adjacent, otherwise the code in between is pulled into the body.",
    1745              :             entry.label != nullptr ? entry.label : "(null)", entry.snapshotRepCount, currentRepCount,
    1746              :             currentBlock != entry.snapshotBlock ? 1 : 0);
    1747            1 :         return nullptr;
    1748              :     }
    1749            7 :     return entry.label;
    1750            8 : }
    1751              : 
    1752          152 : CcuResult CcuKernel::GetAddressByHandle(CcuAddressHandle addrHandle, CcuRep::Address** address)
    1753              : {
    1754          152 :     return GetResourceByHandle(ccuAddrMap_, addrHandle, address, "address");
    1755              : }
    1756              : 
    1757              : // addr = 立即数 → CcuRepAssign(Address, uint64_t)
    1758           13 : CcuResult CcuKernel::AddressAssignImm(CcuAddressHandle addrHandle, uint64_t immediate)
    1759              : {
    1760           13 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAssignImm] addrHandle=%llu, immediate=%llu", addrHandle, immediate);
    1761           13 :     CcuRep::Address* address{nullptr};
    1762           13 :     CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
    1763           13 :     (*address) = immediate;
    1764           13 :     return CcuResult::CCU_SUCCESS;
    1765              : }
    1766              : 
    1767              : // addr = variable → CcuRepAssign(Address, Variable)
    1768           14 : CcuResult CcuKernel::AddressAssignVar(CcuAddressHandle addrHandle, CcuVariableHandle varHandle)
    1769              : {
    1770           14 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAssignVar] addrHandle=%llu, varHandle=%llu", addrHandle, varHandle);
    1771           14 :     CcuRep::Address* address{nullptr};
    1772           14 :     CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
    1773              : 
    1774           14 :     CcuRep::Variable* variable{nullptr};
    1775           14 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
    1776              : 
    1777           14 :     (*address) = (*variable);
    1778           14 :     return CcuResult::CCU_SUCCESS;
    1779              : }
    1780              : // addr = addr → CcuRepAssign(Address, Address)
    1781           38 : CcuResult CcuKernel::AddressAssignAddr(CcuAddressHandle dstAddrHandle, CcuAddressHandle srcAddrHandle)
    1782              : {
    1783           38 :     PLF_CONFIG_INFO(
    1784              :         PLF_DATA_OP, "[AddressAssignAddr] dstAddrHandle=%llu, srcAddrHandle=%llu", dstAddrHandle, srcAddrHandle);
    1785           38 :     CcuRep::Address* dstAddress{nullptr};
    1786           38 :     CCU_CHK_RET(GetAddressByHandle(dstAddrHandle, &dstAddress));
    1787              : 
    1788           38 :     CcuRep::Address* srcAddress{nullptr};
    1789           38 :     CCU_CHK_RET(GetAddressByHandle(srcAddrHandle, &srcAddress));
    1790              : 
    1791           38 :     (*dstAddress) = (*srcAddress);
    1792           38 :     return CcuResult::CCU_SUCCESS;
    1793              : }
    1794              : 
    1795              : // resAddr = lhsAddr + rhsVar → CcuRepAdd(Address, Address, Variable)
    1796            0 : CcuResult CcuKernel::AddressAddVarToAddr(
    1797              :     CcuAddressHandle resAddrHandle, CcuAddressHandle lhsAddrHandle, CcuVariableHandle rhsVarHandle)
    1798              : {
    1799            0 :     PLF_CONFIG_INFO(
    1800              :         PLF_DATA_OP, "[AddressAddVarToAddr] resAddrHandle=%llu, lhsAddrHandle=%llu, rhsVarHandle=%llu", resAddrHandle,
    1801              :         lhsAddrHandle, rhsVarHandle);
    1802            0 :     CcuRep::Address *resAddr{nullptr}, *lhsAddr{nullptr};
    1803            0 :     CCU_CHK_RET(GetAddressByHandle(resAddrHandle, &resAddr));
    1804            0 :     CCU_CHK_RET(GetAddressByHandle(lhsAddrHandle, &lhsAddr));
    1805              : 
    1806            0 :     CcuRep::Variable* rhsVar{nullptr};
    1807            0 :     CCU_CHK_RET(GetVariableByHandle(rhsVarHandle, &rhsVar));
    1808              : 
    1809            0 :     *resAddr = *lhsAddr + *rhsVar;
    1810            0 :     return CcuResult::CCU_SUCCESS;
    1811              : }
    1812              : 
    1813              : // resAddr = addrA + addrB → CcuRepAdd(Address, Address, Address)
    1814            2 : CcuResult CcuKernel::AddressAddAddrToAddr(
    1815              :     CcuAddressHandle resAddrHandle, CcuAddressHandle addrAHandle, CcuAddressHandle addrBHandle)
    1816              : {
    1817            2 :     PLF_CONFIG_INFO(
    1818              :         PLF_DATA_OP, "[AddressAddAddrToAddr] resAddrHandle=%llu, addrAHandle=%llu, addrBHandle=%llu", resAddrHandle,
    1819              :         addrAHandle, addrBHandle);
    1820            2 :     CcuRep::Address *resAddr{nullptr}, *addrA{nullptr}, *addrB{nullptr};
    1821            2 :     CCU_CHK_RET(GetAddressByHandle(resAddrHandle, &resAddr));
    1822            2 :     CCU_CHK_RET(GetAddressByHandle(addrAHandle, &addrA));
    1823            2 :     CCU_CHK_RET(GetAddressByHandle(addrBHandle, &addrB));
    1824              : 
    1825            2 :     *resAddr = *addrA + *addrB;
    1826            2 :     return CcuResult::CCU_SUCCESS;
    1827              : }
    1828              : 
    1829              : // addr += variable → CcuRepAdd(Address, Variable) 就地加
    1830           41 : CcuResult CcuKernel::AddressAddAssignVar(CcuAddressHandle addrHandle, CcuVariableHandle varHandle)
    1831              : {
    1832           41 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAddAssignVar] addrHandle=%llu, varHandle=%llu", addrHandle, varHandle);
    1833           41 :     CcuRep::Address* address{nullptr};
    1834           41 :     CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
    1835              : 
    1836           41 :     CcuRep::Variable* variable{nullptr};
    1837           41 :     CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
    1838              : 
    1839           41 :     (*address) += (*variable);
    1840           41 :     return CcuResult::CCU_SUCCESS;
    1841              : }
    1842              : 
    1843              : // addr += addr → 等价于 addr = addr + otherAddr
    1844            0 : CcuResult CcuKernel::AddressAddAssignAddr(CcuAddressHandle addrHandle, CcuAddressHandle otherHandle)
    1845              : {
    1846            0 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAddAssignAddr] addrHandle=%llu, otherHandle=%llu", addrHandle, otherHandle);
    1847            0 :     CcuRep::Address* address{nullptr};
    1848            0 :     CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
    1849              : 
    1850            0 :     CcuRep::Address* other{nullptr};
    1851            0 :     CCU_CHK_RET(GetAddressByHandle(otherHandle, &other));
    1852              : 
    1853            0 :     (*address) = (*address) + (*other);
    1854            0 :     return CcuResult::CCU_SUCCESS;
    1855              : }
    1856              : 
    1857            1 : CcuResult CcuKernel::AddressAddImmToAddr(CcuAddressHandle resAddrHandle, CcuAddressHandle addrAHandle, uint16_t imm)
    1858              : {
    1859            1 :     CcuRep::Address *resAddr{nullptr}, *addrA{nullptr};
    1860            1 :     CCU_CHK_RET(GetAddressByHandle(resAddrHandle, &resAddr));
    1861            1 :     CCU_CHK_RET(GetAddressByHandle(addrAHandle, &addrA));
    1862              : 
    1863            1 :     *resAddr = *addrA + imm;
    1864            1 :     return CcuResult::CCU_SUCCESS;
    1865              : }
    1866              : 
    1867            0 : void CcuKernel::Load(const CcuRep::Variable& var)
    1868              : {
    1869              :     auto loadArgRep = std::make_shared<CcuRep::CcuRepLoadArg>(
    1870            0 :         insGenerator, var, loadArgIndex_ % CCU_SQE_ARGS_LEN, static_cast<uint16_t>(loadArgIndex_));
    1871            0 :     GetLGProfilingInfo().loadRep2ArgIdxMap[loadArgRep] = loadArgIndex_;
    1872            0 :     Append(loadArgRep);
    1873            0 :     loadArgIndex_++;
    1874            0 : }
    1875              : 
    1876            0 : void CcuKernel::StoreVariable(const CcuRep::Variable& var, uint64_t addr)
    1877              : {
    1878            0 :     Append(std::make_shared<CcuRep::CcuRepStore>(insGenerator, var, addr));
    1879            0 : }
    1880              : 
    1881            0 : void CcuKernel::LoadVariable(const CcuRep::Variable& src, const CcuRep::Variable& var)
    1882              : {
    1883            0 :     Append(std::make_shared<CcuRep::CcuRepLoadVar>(insGenerator, src, var));
    1884            0 : }
    1885              : 
    1886           15 : HcclResult CcuKernel::RecordEvent(CcuRep::CompletedEvent event, uint32_t mask)
    1887              : {
    1888           15 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    1889            1 :         HCCL_ERROR("[CcuKernel][%s] is not supported in loop block, please check.", __func__);
    1890            1 :         LatchBodyError(HCCL_TO_CCU_RET(HcclResult::HCCL_E_NOT_SUPPORT));
    1891            1 :         return HcclResult::HCCL_E_NOT_SUPPORT;
    1892              :     }
    1893              : 
    1894           14 :     auto rep = std::make_shared<CcuRep::CcuRepLocRecordEvent>(insGenerator, event, mask);
    1895           14 :     Append(rep);
    1896           14 :     SetDependencyInfo(event.Id(), mask, rep);
    1897           14 :     return HCCL_SUCCESS;
    1898           14 : }
    1899              : 
    1900           41 : HcclResult CcuKernel::WaitEvent(CcuRep::CompletedEvent event, uint32_t mask)
    1901              : {
    1902           41 :     bool isProfiling = CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK;
    1903           41 :     auto rep = std::make_shared<CcuRep::CcuRepLocWaitEvent>(insGenerator, event, mask, isProfiling);
    1904           41 :     if (isProfiling) {
    1905           75 :         CHK_RET(static_cast<HcclResult>(AddProfiling("WaitEvent", rep->GetMask())));
    1906              :     }
    1907           41 :     rep->SetDependencyInfo(GetDependencyInfo(event.Id()));
    1908           41 :     EraseDependencyInfo(event.Id());
    1909           41 :     Append(rep);
    1910           41 :     return HCCL_SUCCESS;
    1911           41 : }
    1912              : 
    1913           96 : CcuResult CcuKernel::GetEventByHandle(CcuEventHandle eventHandle, CcuRep::CompletedEvent** event)
    1914              : {
    1915           96 :     return GetResourceByHandle(ccuEventMap_, eventHandle, event, "completedEvent");
    1916              : }
    1917              : 
    1918              : /*
    1919              : LocalAddr / RemoteAddr 相关接口
    1920              : */
    1921           33 : CcuResult CcuKernel::GetLocalAddrByHandle(CcuLocalAddrHandle handle, CcuRep::LocalAddr** localAddr)
    1922              : {
    1923           33 :     return GetResourceByHandle(ccuLocalAddrMap_, handle, localAddr, "localAddr");
    1924              : }
    1925              : 
    1926           15 : CcuResult CcuKernel::GetRemoteAddrByHandle(CcuRemoteAddrHandle handle, CcuRep::RemoteAddr** remoteAddr)
    1927              : {
    1928           15 :     return GetResourceByHandle(ccuRemoteAddrMap_, handle, remoteAddr, "remoteAddr");
    1929              : }
    1930              : 
    1931              : /*Read新接口*/
    1932            2 : HcclResult CcuKernel::ReadNb(
    1933              :     const ChannelHandle channel, const CcuRep::CcuBuf& loc, const CcuRep::RemoteAddr& rem, const CcuRep::Variable& len,
    1934              :     CcuRep::CompletedEvent event, uint32_t mask)
    1935              : {
    1936            2 :     channels_.insert(channel);
    1937            2 :     auto rep = std::make_shared<CcuRep::CcuRepBufRead>(insGenerator, channel, rem, loc, len, event, mask);
    1938            2 :     Append(rep);
    1939            2 :     SetDependencyInfo(event.Id(), mask, rep);
    1940            2 :     return HCCL_SUCCESS;
    1941            2 : }
    1942              : 
    1943              : /*Write新接口*/
    1944            2 : HcclResult CcuKernel::WriteNb(
    1945              :     const ChannelHandle channel, const CcuRep::RemoteAddr& rem, const CcuRep::CcuBuf& loc, const CcuRep::Variable& len,
    1946              :     CcuRep::CompletedEvent event, uint32_t mask)
    1947              : {
    1948            2 :     channels_.insert(channel);
    1949            2 :     auto rep = std::make_shared<CcuRep::CcuRepBufWrite>(insGenerator, channel, loc, rem, len, event, mask);
    1950            2 :     Append(rep);
    1951            2 :     SetDependencyInfo(event.Id(), mask, rep);
    1952            2 :     return HCCL_SUCCESS;
    1953            2 : }
    1954              : 
    1955            8 : static bool isLowPrecisionIn(Hccl::DataType dataType)
    1956              : {
    1957           16 :     return dataType == Hccl::DataType::INT8 || dataType == Hccl::DataType::HIF8 || dataType == Hccl::DataType::FP8E4M3
    1958           16 :            || dataType == Hccl::DataType::FP8E5M2;
    1959              : }
    1960              : 
    1961            0 : static bool isLowPrecisionOut(Hccl::DataType dataType)
    1962              : {
    1963            0 :     return dataType == Hccl::DataType::FP16 || dataType == Hccl::DataType::BFP16 || dataType == Hccl::DataType::FP32;
    1964              : }
    1965              : 
    1966              : constexpr uint32_t MAX_DATA_TYPE = 17;
    1967              : 
    1968              : const Hccl::DataType orionDataTypes[]
    1969              :     = {Hccl::DataType::INT8,   Hccl::DataType::INT16,   Hccl::DataType::INT32,
    1970              :        Hccl::DataType::FP16,   Hccl::DataType::FP32,    Hccl::DataType::INT64,
    1971              :        Hccl::DataType::UINT64, Hccl::DataType::UINT8,   Hccl::DataType::UINT16,
    1972              :        Hccl::DataType::UINT32, Hccl::DataType::FP64,    Hccl::DataType::BFP16,
    1973              :        Hccl::DataType::INT128,
    1974              : #if !defined(OPEN_BUILD_PROJECT) || defined(ORION_MODE)
    1975              :        Hccl::DataType::HIF8,   Hccl::DataType::FP8E4M3, Hccl::DataType::FP8E5M2,
    1976              :        Hccl::DataType::FP8E8M0
    1977              : #endif
    1978              : };
    1979              : 
    1980           12 : static Hccl::DataType HcommDataTypeToHcclDataType(const HcclDataType dataType)
    1981              : {
    1982           12 :     const auto dataTypeNum = static_cast<uint32_t>(dataType);
    1983           12 :     if (dataTypeNum > MAX_DATA_TYPE) {
    1984            0 :         return Hccl::DataType::INVALID;
    1985              :     }
    1986              : 
    1987           12 :     return orionDataTypes[dataTypeNum];
    1988              : }
    1989              : 
    1990              : constexpr uint32_t MAX_REDUCE_TYPE = 4;
    1991              : const Hccl::ReduceOp orionReduceOps[] = {
    1992              :     Hccl::ReduceOp::SUM,
    1993              :     Hccl::ReduceOp::PROD,
    1994              :     Hccl::ReduceOp::MAX,
    1995              :     Hccl::ReduceOp::MIN,
    1996              : };
    1997              : 
    1998            8 : static Hccl::ReduceOp HcommReduceOpToHcclReduceOp(const HcclReduceOp reduceOp)
    1999              : {
    2000            8 :     const auto reduceOpNum = static_cast<uint32_t>(reduceOp);
    2001            8 :     if (reduceOpNum > MAX_REDUCE_TYPE) {
    2002            0 :         return Hccl::ReduceOp::INVALID;
    2003              :     }
    2004              : 
    2005            8 :     return orionReduceOps[reduceOpNum];
    2006              : }
    2007              : 
    2008            4 : HcclResult CcuKernel::LocalReduceNb(
    2009              :     const CcuRep::CcuBuf* bufs, uint32_t count, HcclDataType dataType, HcclDataType outputDataType, HcclReduceOp opType,
    2010              :     const CcuRep::Variable& len, CcuRep::CompletedEvent event, uint32_t mask)
    2011              : {
    2012            4 :     auto opType_ = HcommReduceOpToHcclReduceOp(opType);
    2013            4 :     auto dataType_ = HcommDataTypeToHcclDataType(dataType);
    2014            4 :     auto outputDataType_ = HcommDataTypeToHcclDataType(outputDataType);
    2015              : 
    2016            8 :     if ((opType_ == Hccl::ReduceOp::SUM && isLowPrecisionIn(dataType_) && !isLowPrecisionOut(outputDataType_))
    2017            4 :         || (opType_ == Hccl::ReduceOp::SUM && !isLowPrecisionIn(dataType_) && dataType_ != outputDataType_)
    2018            8 :         || (opType_ != Hccl::ReduceOp::SUM && dataType_ != outputDataType_)) {
    2019            0 :         return HCCL_E_NOT_SUPPORT;
    2020              :     }
    2021              : 
    2022            4 :     std::vector<CcuRep::CcuBuf> ccuBufs(count);
    2023           12 :     for (uint32_t i = 0; i < count; i++) {
    2024            8 :         ccuBufs[i] = bufs[i];
    2025              :     }
    2026              : 
    2027              :     auto rep = std::make_shared<CcuRep::CcuRepBufReduce>(
    2028            0 :         insGenerator, ccuBufs, count, CcuRep::GetCcuDataType(dataType_, opType_),
    2029            4 :         CcuRep::GetCcuDataType(outputDataType_, opType_), CcuRep::GetCcuReduceType(opType_), event, len, mask);
    2030            4 :     Append(rep);
    2031            4 :     SetDependencyInfo(event.Id(), mask, rep);
    2032            4 :     return HCCL_SUCCESS;
    2033            4 : }
    2034              : 
    2035              : /*Read新接口*/
    2036            4 : HcclResult CcuKernel::ReadNb(
    2037              :     const ChannelHandle channel, const CcuRep::LocalAddr& loc, const CcuRep::RemoteAddr& rem,
    2038              :     const CcuRep::Variable& len, CcuRep::CompletedEvent event, uint32_t mask)
    2039              : {
    2040            4 :     channels_.insert(channel);
    2041            4 :     auto rep = std::make_shared<CcuRep::CcuRepRead>(insGenerator, channel, loc, rem, len, event, mask);
    2042            4 :     Append(rep);
    2043            4 :     SetDependencyInfo(event.Id(), mask, rep);
    2044            4 :     return HCCL_SUCCESS;
    2045            4 : }
    2046              : 
    2047              : /*ReadReduce新接口*/
    2048            2 : HcclResult CcuKernel::ReadReduceNb(
    2049              :     const ChannelHandle channel, const CcuRep::LocalAddr& loc, const CcuRep::RemoteAddr& rem,
    2050              :     const CcuRep::Variable& len, HcclDataType dataType, HcclReduceOp opType, CcuRep::CompletedEvent event,
    2051              :     uint32_t mask)
    2052              : {
    2053            2 :     channels_.insert(channel);
    2054            2 :     auto opType_ = HcommReduceOpToHcclReduceOp(opType);
    2055            2 :     auto dataType_ = HcommDataTypeToHcclDataType(dataType);
    2056              : 
    2057              :     auto rep = std::make_shared<CcuRep::CcuRepRead>(
    2058            2 :         insGenerator, channel, loc, rem, len, CcuRep::GetUBDataType(dataType_), CcuRep::GetUBReduceType(opType_), event,
    2059            2 :         mask);
    2060            2 :     Append(rep);
    2061            2 :     SetDependencyInfo(event.Id(), mask, rep);
    2062            2 :     return HCCL_SUCCESS;
    2063            2 : }
    2064              : 
    2065              : /*Write新接口*/
    2066            3 : HcclResult CcuKernel::WriteNb(
    2067              :     const ChannelHandle channel, const CcuRep::RemoteAddr& rem, const CcuRep::LocalAddr& loc,
    2068              :     const CcuRep::Variable& len, CcuRep::CompletedEvent event, uint32_t mask)
    2069              : {
    2070            3 :     channels_.insert(channel);
    2071            3 :     auto rep = std::make_shared<CcuRep::CcuRepWrite>(insGenerator, channel, rem, loc, len, event, mask);
    2072            3 :     Append(rep);
    2073            3 :     SetDependencyInfo(event.Id(), mask, rep);
    2074            3 :     return HCCL_SUCCESS;
    2075            3 : }
    2076              : 
    2077            2 : HcclResult CcuKernel::WriteReduceNb(
    2078              :     const ChannelHandle channel, const CcuRep::RemoteAddr& rem, const CcuRep::LocalAddr& loc,
    2079              :     const CcuRep::Variable& len, HcclDataType dataType, HcclReduceOp opType, CcuRep::CompletedEvent event,
    2080              :     uint32_t mask)
    2081              : {
    2082            2 :     channels_.insert(channel);
    2083            2 :     auto opType_ = HcommReduceOpToHcclReduceOp(opType);
    2084            2 :     auto dataType_ = HcommDataTypeToHcclDataType(dataType);
    2085              : 
    2086              :     auto rep = std::make_shared<CcuRep::CcuRepWrite>(
    2087            2 :         insGenerator, channel, rem, loc, len, CcuRep::GetUBDataType(dataType_), CcuRep::GetUBReduceType(opType_), event,
    2088            2 :         mask);
    2089            2 :     Append(rep);
    2090            2 :     SetDependencyInfo(event.Id(), mask, rep);
    2091            2 :     return HCCL_SUCCESS;
    2092            2 : }
    2093              : 
    2094           32 : CcuResult CcuKernel::GetBufferByHandle(CcuBufferHandle bufferHandle, CcuRep::CcuBuf** buffer)
    2095              : {
    2096           32 :     return GetResourceByHandle(ccuBufferMap_, bufferHandle, buffer, "buffer");
    2097              : }
    2098              : 
    2099            1 : HcclResult CcuKernel::LocalCopyNb(
    2100              :     const CcuRep::LocalAddr& dst, const CcuRep::LocalAddr& src, const CcuRep::Variable& len,
    2101              :     CcuRep::CompletedEvent event, uint32_t mask)
    2102              : {
    2103            1 :     auto rep = std::make_shared<CcuRep::CcuRepLocCpy>(insGenerator, dst, src, len, event, mask);
    2104            1 :     Append(rep);
    2105            1 :     SetDependencyInfo(event.Id(), mask, rep);
    2106            1 :     return HCCL_SUCCESS;
    2107            1 : }
    2108              : 
    2109           12 : HcclResult CcuKernel::LocalCopyNb(
    2110              :     const CcuRep::CcuBuf& dst, const CcuRep::LocalAddr& src, const CcuRep::Variable& len, CcuRep::CompletedEvent event,
    2111              :     uint32_t mask)
    2112              : {
    2113           12 :     auto rep = std::make_shared<CcuRep::CcuRepBufLocRead>(insGenerator, src, dst, len, event, mask);
    2114           12 :     Append(rep);
    2115           12 :     SetDependencyInfo(event.Id(), mask, rep);
    2116           12 :     return HCCL_SUCCESS;
    2117           12 : }
    2118              : 
    2119            8 : HcclResult CcuKernel::LocalCopyNb(
    2120              :     const CcuRep::LocalAddr& dst, const CcuRep::CcuBuf& src, const CcuRep::Variable& len, CcuRep::CompletedEvent event,
    2121              :     uint32_t mask)
    2122              : {
    2123            8 :     auto rep = std::make_shared<CcuRep::CcuRepBufLocWrite>(insGenerator, src, dst, len, event, mask);
    2124            8 :     Append(rep);
    2125            8 :     SetDependencyInfo(event.Id(), mask, rep);
    2126            8 :     return HCCL_SUCCESS;
    2127            8 : }
    2128              : 
    2129            0 : HcclResult CcuKernel::LocalReduceNb(
    2130              :     const CcuRep::LocalAddr& dst, const CcuRep::LocalAddr& src, const CcuRep::Variable& len, HcclDataType dataType,
    2131              :     HcclReduceOp opType, CcuRep::CompletedEvent event, uint32_t mask)
    2132              : {
    2133            0 :     auto opType_ = HcommReduceOpToHcclReduceOp(opType);
    2134            0 :     auto dataType_ = HcommDataTypeToHcclDataType(dataType);
    2135              : 
    2136              :     auto rep = std::make_shared<CcuRep::CcuRepLocCpy>(
    2137            0 :         insGenerator, dst, src, len, CcuRep::GetUBDataType(dataType_), CcuRep::GetUBReduceType(opType_), event, mask);
    2138            0 :     Append(rep);
    2139            0 :     SetDependencyInfo(event.Id(), mask, rep);
    2140            0 :     return HCCL_SUCCESS;
    2141            0 : }
    2142              : 
    2143            0 : CcuRep::FuncCall CcuKernel::Func(const std::string& label) { return CcuRep::FuncCall(this, label); }
    2144              : 
    2145            0 : CcuRep::FuncCall CcuKernel::Func(const CcuRep::Variable& funcAddr) { return CcuRep::FuncCall(this, funcAddr); }
    2146              : 
    2147            0 : CcuRep::LoopCall CcuKernel::Loop(const std::string& label) { return CcuRep::LoopCall(this, label); }
    2148              : 
    2149           52 : CcuResult CcuKernel::LoopCreate(CcuLoop* loop)
    2150              : {
    2151           52 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopCreate]");
    2152           52 :     if (loop == nullptr) {
    2153            0 :         HCCL_ERROR("[CcuKernel::LoopCreate] null pointer");
    2154            0 :         return CcuResult::CCU_E_PTR;
    2155              :     }
    2156           52 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    2157            0 :         HCCL_ERROR("[CcuKernel::LoopCreate] cannot create loop inside a loop body");
    2158            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2159              :     }
    2160           52 :     if (inFuncBody_) {
    2161            0 :         HCCL_ERROR("[CcuKernel::LoopCreate] cannot create loop inside a func body");
    2162            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2163              :     }
    2164              : 
    2165           52 :     CcuLoop handle = ++loopHandleCounter_;
    2166           52 :     std::string label = "loop_" + std::to_string(handle);
    2167              : 
    2168           52 :     LoopDescriptor desc;
    2169           52 :     desc.label = label;
    2170           52 :     desc.repLoopBlock = std::make_shared<CcuRep::CcuRepLoopBlock>(insGenerator, label);
    2171              : 
    2172           52 :     loopMap_[handle] = std::move(desc);
    2173           52 :     *loop = handle;
    2174           52 :     return CcuResult::CCU_SUCCESS;
    2175           52 : }
    2176              : 
    2177            7 : CcuResult CcuKernel::LatchBodyError(CcuResult err)
    2178              : {
    2179           15 :     if ((CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_)
    2180           15 :         && bodyError_ == CcuResult::CCU_SUCCESS) {
    2181            7 :         bodyError_ = err;
    2182              :     }
    2183            7 :     return err;
    2184              : }
    2185              : 
    2186           52 : CcuResult CcuKernel::LoopBodyEnter(CcuLoop loop)
    2187              : {
    2188           52 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopBodyEnter] loop=%llu", loop);
    2189           52 :     auto it = loopMap_.find(loop);
    2190           52 :     if (it == loopMap_.end()) {
    2191            0 :         HCCL_ERROR("[CcuKernel::LoopBodyEnter] invalid loop handle %lu", loop);
    2192            0 :         return CcuResult::CCU_E_PARA;
    2193              :     }
    2194           52 :     auto& desc = it->second;
    2195           52 :     if (desc.bodyDefined) {
    2196            0 :         HCCL_ERROR("[CcuKernel::LoopBodyEnter] loop %lu body already defined", loop);
    2197            0 :         return CcuResult::CCU_E_INTERNAL;
    2198              :     }
    2199              : 
    2200           52 :     Append(desc.repLoopBlock);
    2201           52 :     desc.prevActiveBlock = CurrentBlock();
    2202           52 :     SetCurrentBlock(desc.repLoopBlock);
    2203           52 :     ++loopBodyDepth_;
    2204           52 :     bodyError_ = CcuResult::CCU_SUCCESS;
    2205              : 
    2206           52 :     return CcuResult::CCU_SUCCESS;
    2207              : }
    2208              : 
    2209           52 : CcuResult CcuKernel::LoopBodyExit(CcuLoop loop)
    2210              : {
    2211           52 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopBodyExit] loop=%llu", loop);
    2212           52 :     auto it = loopMap_.find(loop);
    2213           52 :     if (it == loopMap_.end()) {
    2214            0 :         HCCL_ERROR("[CcuKernel::LoopBodyExit] invalid loop handle %lu", loop);
    2215            0 :         return CcuResult::CCU_E_PARA;
    2216              :     }
    2217           52 :     auto& desc = it->second;
    2218              : 
    2219           52 :     SetCurrentBlock(desc.prevActiveBlock);
    2220           52 :     desc.bodyDefined = true;
    2221           52 :     --loopBodyDepth_;
    2222              : 
    2223           52 :     if (bodyError_ != CcuResult::CCU_SUCCESS) {
    2224            6 :         const CcuResult err = bodyError_;
    2225            6 :         HCCL_ERROR("[CcuKernel::LoopBodyExit] illegal operation inside loop body, err=%d", err);
    2226            6 :         bodyError_ = CcuResult::CCU_SUCCESS;
    2227            6 :         return err;
    2228              :     }
    2229              : 
    2230           46 :     return CcuResult::CCU_SUCCESS;
    2231              : }
    2232              : 
    2233            8 : CcuResult CcuKernel::FuncBlockLookup(const void* funcPtr, uint64_t* outHandle)
    2234              : {
    2235            8 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncBlockLookup] funcPtr=%p", funcPtr);
    2236            8 :     if (funcPtr == nullptr || outHandle == nullptr) {
    2237            0 :         HCCL_ERROR("[CcuKernel::FuncBlockLookup] null pointer");
    2238            0 :         return CcuResult::CCU_E_PTR;
    2239              :     }
    2240            8 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_) {
    2241            2 :         HCCL_ERROR("[CcuKernel::FuncBlockLookup] ccu::CallFunc only allowed at top level");
    2242            2 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2243              :     }
    2244              : 
    2245            6 :     auto it = funcInstanceMap_.find(funcPtr);
    2246            6 :     *outHandle = (it == funcInstanceMap_.end()) ? 0 : it->second;
    2247            6 :     return CcuResult::CCU_SUCCESS;
    2248              : }
    2249              : 
    2250            5 : CcuResult CcuKernel::FuncBlockBegin(const void* funcPtr, uint64_t* outHandle)
    2251              : {
    2252            5 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncBlockBegin] funcPtr=%p", funcPtr);
    2253            5 :     if (funcPtr == nullptr || outHandle == nullptr) {
    2254            0 :         HCCL_ERROR("[CcuKernel::FuncBlockBegin] null pointer");
    2255            0 :         return CcuResult::CCU_E_PTR;
    2256              :     }
    2257            5 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_) {
    2258            0 :         HCCL_ERROR("[CcuKernel::FuncBlockBegin] ccu::CallFunc only allowed at top level");
    2259            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2260              :     }
    2261              : 
    2262            5 :     auto exist = funcInstanceMap_.find(funcPtr);
    2263            5 :     if (exist != funcInstanceMap_.end()) {
    2264            0 :         *outHandle = exist->second;
    2265            0 :         return CcuResult::CCU_SUCCESS;
    2266              :     }
    2267              : 
    2268            5 :     const uint64_t handle = ++funcHandleCounter_;
    2269            5 :     std::string label = "func_" + std::to_string(handle);
    2270              : 
    2271            5 :     FuncDescriptor desc;
    2272            5 :     desc.funcPtr = funcPtr;
    2273            5 :     desc.label = label;
    2274            5 :     desc.repFuncBlock = std::make_shared<CcuRep::CcuRepFuncBlock>(insGenerator, label);
    2275            5 :     desc.prevActiveBlock = CurrentBlock();
    2276              : 
    2277            5 :     funcMap_[handle] = desc;
    2278            5 :     SetCurrentBlock(desc.repFuncBlock);
    2279            5 :     inFuncBody_ = true;
    2280            5 :     bodyError_ = CcuResult::CCU_SUCCESS;
    2281            5 :     *outHandle = handle;
    2282            5 :     return CcuResult::CCU_SUCCESS;
    2283            5 : }
    2284              : 
    2285            4 : CcuResult CcuKernel::FuncBlockEnd(uint64_t handle)
    2286              : {
    2287            4 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncBlockEnd] handle=%llu", handle);
    2288            4 :     auto it = funcMap_.find(handle);
    2289            4 :     if (it == funcMap_.end()) {
    2290            0 :         HCCL_ERROR("[CcuKernel::FuncBlockEnd] invalid func handle %lu", handle);
    2291            0 :         return CcuResult::CCU_E_PARA;
    2292              :     }
    2293            4 :     auto& desc = it->second;
    2294              : 
    2295            4 :     SetCurrentBlock(desc.prevActiveBlock);
    2296            4 :     inFuncBody_ = false;
    2297              : 
    2298            4 :     if (bodyError_ != CcuResult::CCU_SUCCESS) {
    2299            0 :         const CcuResult err = bodyError_;
    2300            0 :         HCCL_ERROR("[CcuKernel::FuncBlockEnd] illegal operation inside func body, err=%d", err);
    2301            0 :         bodyError_ = CcuResult::CCU_SUCCESS;
    2302            0 :         funcMap_.erase(it);
    2303            0 :         return err;
    2304              :     }
    2305              : 
    2306            4 :     Append(desc.repFuncBlock);
    2307            4 :     desc.bodyDefined = true;
    2308            4 :     funcInstanceMap_[desc.funcPtr] = handle;
    2309            4 :     return CcuResult::CCU_SUCCESS;
    2310              : }
    2311              : 
    2312            7 : CcuResult CcuKernel::FuncDefineInArg(uint64_t handle, CcuVariableHandle formal)
    2313              : {
    2314            7 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncDefineInArg] handle=%llu, formal=%llu", handle, formal);
    2315            7 :     auto it = funcMap_.find(handle);
    2316            7 :     if (it == funcMap_.end()) {
    2317            0 :         HCCL_ERROR("[CcuKernel::FuncDefineInArg] invalid func handle %lu", handle);
    2318            0 :         return CcuResult::CCU_E_PARA;
    2319              :     }
    2320              : 
    2321            7 :     CcuRep::Variable* formalVar = nullptr;
    2322            7 :     CCU_CHK_RET(GetVariableByHandle(formal, &formalVar));
    2323            7 :     it->second.repFuncBlock->DefineInArg(*formalVar);
    2324            7 :     return CcuResult::CCU_SUCCESS;
    2325              : }
    2326              : 
    2327            5 : CcuResult CcuKernel::FuncCall(uint64_t handle, const CcuVariableHandle* inArgs, uint32_t numIn)
    2328              : {
    2329            5 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncCall] handle=%llu, numIn=%u", handle, numIn);
    2330            5 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_) {
    2331            0 :         HCCL_ERROR("[CcuKernel::FuncCall] ccu::CallFunc only allowed at top level");
    2332            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2333              :     }
    2334            5 :     if (numIn > 0 && inArgs == nullptr) {
    2335            0 :         HCCL_ERROR("[CcuKernel::FuncCall] null input args");
    2336            0 :         return CcuResult::CCU_E_PTR;
    2337              :     }
    2338              : 
    2339            5 :     auto it = funcMap_.find(handle);
    2340            5 :     if (it == funcMap_.end() || !it->second.bodyDefined) {
    2341            0 :         HCCL_ERROR("[CcuKernel::FuncCall] invalid func handle %lu", handle);
    2342            0 :         return CcuResult::CCU_E_PARA;
    2343              :     }
    2344              : 
    2345            5 :     auto repFuncCall = std::make_shared<CcuRep::CcuRepFuncCall>(insGenerator, it->second.label);
    2346           12 :     for (uint32_t i = 0; i < numIn; i++) {
    2347            7 :         CcuRep::Variable* actual = nullptr;
    2348            7 :         CCU_CHK_RET(GetVariableByHandle(inArgs[i], &actual));
    2349            7 :         repFuncCall->SetInArg(*actual);
    2350              :     }
    2351            5 :     Append(repFuncCall);
    2352            5 :     return CcuResult::CCU_SUCCESS;
    2353            5 : }
    2354              : 
    2355              : // 按 maxLoopNum 把 res_.blockExecutor[0] 扩容到至少 maxLoopNum 个 LoopEngine。
    2356              : // 与 CreateBlockResAssist 对齐:所有 LoopEngine 资源先落在 die0 池,待实际 die 确定后
    2357              : // 再由 MoveResourcesToDie 迁移到目标 die。
    2358              : // 不同 LoopGroup 通过 local loopIdx 复用同一池低位 executorId,所以这里只
    2359              : // "补足"而不是"累加"。
    2360           28 : CcuResult CcuKernel::EnsureLoopEnginePool(uint32_t maxLoopNum)
    2361              : {
    2362           28 :     if (maxLoopNum == 0) {
    2363            0 :         HCCL_ERROR("[CcuKernel::EnsureLoopEnginePool] maxLoopNum must be > 0");
    2364            0 :         return CcuResult::CCU_E_PARA;
    2365              :     }
    2366           28 :     constexpr uint32_t poolDieId = 0;
    2367           28 :     auto& loopEnginePool = res_.blockExecutor[poolDieId];
    2368           28 :     if (maxLoopNum <= loopEnginePool.size()) {
    2369           10 :         return CcuResult::CCU_SUCCESS;
    2370              :     }
    2371           18 :     const uint32_t deficit = maxLoopNum - static_cast<uint32_t>(loopEnginePool.size());
    2372           18 :     std::vector<CcuRep::Executor> tmp(deficit, CcuRep::Executor(this));
    2373           18 :     (void)CreateBlockExecutor(deficit, tmp.data());
    2374           18 :     return CcuResult::CCU_SUCCESS;
    2375           18 : }
    2376              : 
    2377           13 : CcuResult CcuKernel::LoopGroupCreate(CcuLoopGroup* group, uint32_t maxLoopNum, const CcuLoopGroupCfg* cfg)
    2378              : {
    2379           13 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopGroupCreate] maxLoopNum=%u", maxLoopNum);
    2380           13 :     if (group == nullptr || cfg == nullptr) {
    2381            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreate] null pointer");
    2382            0 :         return CcuResult::CCU_E_PTR;
    2383              :     }
    2384           13 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    2385            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreate] cannot create loop group inside a loop body");
    2386            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2387              :     }
    2388           13 :     if (inFuncBody_) {
    2389            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreate] cannot create loop group inside a func body");
    2390            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2391              :     }
    2392              : 
    2393              :     // 按需扩 LoopEngine 池;池足够则复用低位 executorId,跨组共享。
    2394           13 :     CCU_CHK_RET(EnsureLoopEnginePool(maxLoopNum));
    2395              : 
    2396           13 :     CcuLoopGroup handle = ++loopGroupHandleCounter_;
    2397              : 
    2398           13 :     LoopGroupDescriptor desc;
    2399           13 :     desc.config = *cfg;
    2400           13 :     desc.parallelVar = CreateVariable();
    2401           13 :     desc.offsetVar = CreateVariable();
    2402           13 :     desc.isVarBased = false;
    2403              : 
    2404           13 :     auto bundle = std::make_shared<CcuRep::CcuRepLoopGroupBundle>(insGenerator, *cfg, desc.parallelVar, desc.offsetVar);
    2405           13 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
    2406            4 :         bundle->SetXnOffsetVar(CreateVariable());
    2407              :     }
    2408           13 :     desc.bundleRep = bundle;
    2409           13 :     Append(bundle);
    2410              : 
    2411           13 :     loopGroupMap_[handle] = std::move(desc);
    2412           13 :     *group = handle;
    2413           13 :     return CcuResult::CCU_SUCCESS;
    2414           13 : }
    2415              : 
    2416           11 : CcuResult CcuKernel::LoopGroupCreateFromVar(
    2417              :     CcuLoopGroup* group, uint32_t maxLoopNum, CcuVariableHandle parallelVarHandle, CcuVariableHandle offsetVarHandle)
    2418              : {
    2419           11 :     PLF_CONFIG_INFO(
    2420              :         PLF_DATA_OP, "[LoopGroupCreateFromVar] maxLoopNum=%u, parallelVarHandle=%llu, offsetVarHandle=%llu", maxLoopNum,
    2421              :         parallelVarHandle, offsetVarHandle);
    2422           11 :     if (group == nullptr) {
    2423            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] null pointer for group");
    2424            0 :         return CcuResult::CCU_E_PTR;
    2425              :     }
    2426           11 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    2427            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] cannot create loop group inside a loop body");
    2428            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2429              :     }
    2430           11 :     if (inFuncBody_) {
    2431            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] cannot create loop group inside a func body");
    2432            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2433              :     }
    2434              : 
    2435           11 :     CCU_CHK_RET(EnsureLoopEnginePool(maxLoopNum));
    2436              : 
    2437           11 :     CcuRep::Variable* parallelVarPtr = nullptr;
    2438           11 :     CcuRep::Variable* offsetVarPtr = nullptr;
    2439           11 :     CCU_CHK_RET(GetVariableByHandle(parallelVarHandle, &parallelVarPtr));
    2440           11 :     CCU_CHK_RET(GetVariableByHandle(offsetVarHandle, &offsetVarPtr));
    2441              : 
    2442           11 :     CcuLoopGroup handle = ++loopGroupHandleCounter_;
    2443              : 
    2444           11 :     LoopGroupDescriptor desc;
    2445           11 :     desc.parallelVar = CcuRep::Variable(*parallelVarPtr);
    2446           11 :     desc.offsetVar = CcuRep::Variable(*offsetVarPtr);
    2447           11 :     desc.isVarBased = true;
    2448              : 
    2449           11 :     auto bundle = std::make_shared<CcuRep::CcuRepLoopGroupBundle>(insGenerator, desc.parallelVar, desc.offsetVar);
    2450           11 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
    2451            1 :         bundle->SetCompatRemapVars(CreateVariable(), CreateVariable());
    2452              :     }
    2453           11 :     desc.bundleRep = bundle;
    2454           11 :     Append(bundle);
    2455              : 
    2456           11 :     loopGroupMap_[handle] = std::move(desc);
    2457           11 :     *group = handle;
    2458           11 :     return CcuResult::CCU_SUCCESS;
    2459           11 : }
    2460              : 
    2461            5 : CcuResult CcuKernel::LoopGroupCreateFromVarV2(
    2462              :     CcuLoopGroup* group, uint32_t maxLoopNum, CcuVariableHandle parallelVarV2Handle,
    2463              :     CcuVariableHandle offsetVarV2Handle, CcuVariableHandle varOffsetVarHandle)
    2464              : {
    2465            5 :     if (ccuVersion_ != CcuVersion::CCU_V2) {
    2466            1 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] only supported on V2");
    2467            1 :         return CcuResult::CCU_E_NOT_SUPPORT;
    2468              :     }
    2469            4 :     if (group == nullptr) {
    2470            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] null pointer for group");
    2471            0 :         return CcuResult::CCU_E_PTR;
    2472              :     }
    2473            4 :     if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
    2474            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] cannot create loop group inside a loop body");
    2475            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2476              :     }
    2477            4 :     if (inFuncBody_) {
    2478            0 :         HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] cannot create loop group inside a func body");
    2479            0 :         return LatchBodyError(CcuResult::CCU_E_INTERNAL);
    2480              :     }
    2481              : 
    2482            4 :     CCU_CHK_RET(EnsureLoopEnginePool(maxLoopNum));
    2483              : 
    2484            4 :     CcuRep::Variable* parallelVarPtr = nullptr;
    2485            4 :     CcuRep::Variable* offsetVarPtr = nullptr;
    2486            4 :     CcuRep::Variable* xnOffsetVarPtr = nullptr;
    2487            4 :     CCU_CHK_RET(GetVariableByHandle(parallelVarV2Handle, &parallelVarPtr));
    2488            4 :     CCU_CHK_RET(GetVariableByHandle(offsetVarV2Handle, &offsetVarPtr));
    2489            4 :     CCU_CHK_RET(GetVariableByHandle(varOffsetVarHandle, &xnOffsetVarPtr));
    2490              : 
    2491            4 :     CcuLoopGroup handle = ++loopGroupHandleCounter_;
    2492              : 
    2493            4 :     LoopGroupDescriptor desc;
    2494            4 :     desc.parallelVar = CcuRep::Variable(*parallelVarPtr);
    2495            4 :     desc.offsetVar = CcuRep::Variable(*offsetVarPtr);
    2496            4 :     desc.xnOffsetVar = CcuRep::Variable(*xnOffsetVarPtr);
    2497            4 :     desc.isVarBased = true;
    2498            4 :     desc.isVersionV2 = true;
    2499              : 
    2500            4 :     auto bundle = std::make_shared<CcuRep::CcuRepLoopGroupBundle>(insGenerator, desc.parallelVar, desc.offsetVar);
    2501            4 :     bundle->SetLayout(CcuRep::CcuRepLoopGroupBundle::Layout::VersionV2);
    2502            4 :     bundle->SetXnOffsetVar(desc.xnOffsetVar);
    2503            4 :     desc.bundleRep = bundle;
    2504            4 :     Append(bundle);
    2505              : 
    2506            4 :     loopGroupMap_[handle] = std::move(desc);
    2507            4 :     *group = handle;
    2508            4 :     return CcuResult::CCU_SUCCESS;
    2509            4 : }
    2510              : 
    2511           56 : CcuResult CcuKernel::LookupLoopGroupAndLoop(
    2512              :     CcuLoopGroup group, CcuLoop loop, const char* fnName, const char* createFnName, LoopGroupDescriptor*& grpDesc,
    2513              :     LoopDescriptor*& loopDesc, uint32_t& loopIdx)
    2514              : {
    2515           56 :     auto grpIt = loopGroupMap_.find(group);
    2516           56 :     if (grpIt == loopGroupMap_.end()) {
    2517            0 :         HCCL_ERROR("[CcuKernel::%s] invalid group handle %lu", fnName, group);
    2518            0 :         return CcuResult::CCU_E_PARA;
    2519              :     }
    2520           56 :     grpDesc = &grpIt->second;
    2521              : 
    2522           56 :     auto loopIt = loopMap_.find(loop);
    2523           56 :     if (loopIt == loopMap_.end()) {
    2524            0 :         HCCL_ERROR("[CcuKernel::%s] invalid loop handle %lu", fnName, loop);
    2525            0 :         return CcuResult::CCU_E_PARA;
    2526              :     }
    2527           56 :     loopDesc = &loopIt->second;
    2528              : 
    2529           56 :     if (!loopDesc->bodyDefined) {
    2530            0 :         HCCL_ERROR("[CcuKernel::%s] loop %lu body not defined", fnName, loop);
    2531            0 :         return CcuResult::CCU_E_INTERNAL; // CCU_E_LOOP_BODY_UNDEFINED
    2532              :     }
    2533              : 
    2534           56 :     auto& loopEnginePool = res_.blockExecutor[0];
    2535           56 :     loopIdx = grpDesc->loopCount;
    2536           56 :     if (loopIdx >= loopEnginePool.size()) {
    2537            0 :         HCCL_ERROR(
    2538              :             "[CcuKernel::%s] loopEngine pool exhausted (pool size %zu, loopIdx %u). "
    2539              :             "Pass a larger maxLoopNum to %s so the pool can be extended at create time.",
    2540              :             fnName, loopEnginePool.size(), loopIdx, createFnName);
    2541            0 :         return CcuResult::CCU_E_PARA;
    2542              :     }
    2543           56 :     return CcuResult::CCU_SUCCESS;
    2544              : }
    2545              : 
    2546           25 : CcuResult CcuKernel::LoopGroupAddLoop(CcuLoopGroup group, CcuLoop loop, const CcuLoopCfg* cfg)
    2547              : {
    2548           25 :     PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopGroupAddLoop] group=%llu, loop=%llu", group, loop);
    2549           25 :     if (cfg == nullptr) {
    2550            0 :         HCCL_ERROR("[CcuKernel::LoopGroupAddLoop] null pointer for cfg");
    2551            0 :         return CcuResult::CCU_E_PTR;
    2552              :     }
    2553           25 :     LoopGroupDescriptor* grpDesc = nullptr;
    2554           25 :     LoopDescriptor* loopDesc = nullptr;
    2555           25 :     uint32_t loopIdx = 0;
    2556           25 :     CCU_CHK_RET(
    2557              :         LookupLoopGroupAndLoop(group, loop, "LoopGroupAddLoop", "CcuLoopGroupCreate", grpDesc, loopDesc, loopIdx));
    2558           25 :     auto& loopEnginePool = res_.blockExecutor[0];
    2559              : 
    2560           25 :     grpDesc->loopCount++;
    2561           25 :     grpDesc->totalLoopNum = grpDesc->loopCount;
    2562              : 
    2563           25 :     CcuRep::CcuRepLoopGroupBundle::LoopEntry entry;
    2564           25 :     entry.config = *cfg;
    2565           25 :     entry.executor = loopEnginePool[loopIdx];
    2566           25 :     entry.repLoopBlock = loopDesc->repLoopBlock;
    2567           25 :     entry.loopParamVar = CreateVariable();
    2568           25 :     entry.layout = CcuRep::CcuRepLoopGroupBundle::Layout::Config;
    2569           25 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
    2570            7 :         entry.iterNumVar = CreateVariable();
    2571            7 :         entry.addrOffsetVar = CreateVariable();
    2572            7 :         entry.ctxIdVar = CreateVariable();
    2573              :     }
    2574              : 
    2575           25 :     auto bundle = std::static_pointer_cast<CcuRep::CcuRepLoopGroupBundle>(grpDesc->bundleRep);
    2576           25 :     bundle->AddLoop(entry);
    2577              : 
    2578           25 :     if (!grpDesc->isVarBased) {
    2579           19 :         bundle->SetRepeatLoopIdx(grpDesc->config.cloneLoopOffset);
    2580           19 :         bundle->SetTotalLoopNum(grpDesc->totalLoopNum);
    2581              :     }
    2582              : 
    2583           25 :     return CcuResult::CCU_SUCCESS;
    2584           25 : }
    2585              : 
    2586           23 : CcuResult CcuKernel::LoopGroupAddLoopFromVar(CcuLoopGroup group, CcuLoop loop, CcuVariableHandle loopParamVarHandle)
    2587              : {
    2588           23 :     PLF_CONFIG_INFO(
    2589              :         PLF_DATA_OP, "[LoopGroupAddLoopFromVar] group=%llu, loop=%llu, loopParamVarHandle=%llu", group, loop,
    2590              :         loopParamVarHandle);
    2591           23 :     LoopGroupDescriptor* grpDesc = nullptr;
    2592           23 :     LoopDescriptor* loopDesc = nullptr;
    2593           23 :     uint32_t loopIdx = 0;
    2594           23 :     CCU_CHK_RET(LookupLoopGroupAndLoop(
    2595              :         group, loop, "LoopGroupAddLoopFromVar", "CcuLoopGroupCreateFromVar", grpDesc, loopDesc, loopIdx));
    2596           23 :     auto& loopEnginePool = res_.blockExecutor[0];
    2597              : 
    2598           23 :     CcuRep::Variable* loopParamVarPtr = nullptr;
    2599           23 :     CCU_CHK_RET(GetVariableByHandle(loopParamVarHandle, &loopParamVarPtr));
    2600              : 
    2601           23 :     CcuRep::CcuRepLoopGroupBundle::LoopEntry entry;
    2602           23 :     entry.executor = loopEnginePool[loopIdx];
    2603           23 :     entry.repLoopBlock = loopDesc->repLoopBlock;
    2604           23 :     entry.loopParamVar = CcuRep::Variable(*loopParamVarPtr);
    2605           23 :     entry.layout = CcuRep::CcuRepLoopGroupBundle::Layout::PackedVar;
    2606           23 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
    2607            4 :         entry.iterNumVar = CreateVariable();
    2608            4 :         entry.addrOffsetVar = CreateVariable();
    2609            4 :         entry.ctxIdVar = CreateVariable();
    2610              :     }
    2611              : 
    2612           23 :     auto bundle = std::static_pointer_cast<CcuRep::CcuRepLoopGroupBundle>(grpDesc->bundleRep);
    2613           23 :     bundle->AddLoop(entry);
    2614              : 
    2615              :     // 计数放在入 bundle 之后统一更新:totalLoopNum 仅供 config 组同步编码使用,与 AddLoop 无先后依赖。
    2616           23 :     grpDesc->loopCount++;
    2617           23 :     grpDesc->totalLoopNum = grpDesc->loopCount;
    2618           23 :     if (!grpDesc->isVarBased) {
    2619            7 :         bundle->SetRepeatLoopIdx(grpDesc->config.cloneLoopOffset);
    2620            7 :         bundle->SetTotalLoopNum(grpDesc->totalLoopNum);
    2621              :     }
    2622              : 
    2623           23 :     return CcuResult::CCU_SUCCESS;
    2624           23 : }
    2625              : 
    2626            8 : CcuResult CcuKernel::LoopGroupAddLoopFromVarV2(
    2627              :     CcuLoopGroup group, CcuLoop loop, CcuVariableHandle iterNumVarHandle, CcuVariableHandle addrOffsetVarHandle,
    2628              :     CcuVariableHandle ctxIdVarHandle)
    2629              : {
    2630            8 :     if (ccuVersion_ != CcuVersion::CCU_V2) {
    2631            0 :         HCCL_ERROR("[CcuKernel::LoopGroupAddLoopFromVarV2] only supported on V2");
    2632            0 :         return CcuResult::CCU_E_NOT_SUPPORT;
    2633              :     }
    2634              : 
    2635            8 :     LoopGroupDescriptor* grpDesc = nullptr;
    2636            8 :     LoopDescriptor* loopDesc = nullptr;
    2637            8 :     uint32_t loopIdx = 0;
    2638            8 :     CCU_CHK_RET(LookupLoopGroupAndLoop(
    2639              :         group, loop, "LoopGroupAddLoopFromVarV2", "CcuLoopGroupCreateFromVarV2", grpDesc, loopDesc, loopIdx));
    2640            8 :     auto& loopEnginePool = res_.blockExecutor[0];
    2641              : 
    2642            8 :     CcuRep::Variable* iterNumVarPtr = nullptr;
    2643            8 :     CcuRep::Variable* addrOffsetVarPtr = nullptr;
    2644            8 :     CcuRep::Variable* ctxIdVarPtr = nullptr;
    2645            8 :     CCU_CHK_RET(GetVariableByHandle(iterNumVarHandle, &iterNumVarPtr));
    2646            8 :     CCU_CHK_RET(GetVariableByHandle(addrOffsetVarHandle, &addrOffsetVarPtr));
    2647            8 :     CCU_CHK_RET(GetVariableByHandle(ctxIdVarHandle, &ctxIdVarPtr));
    2648              : 
    2649            8 :     grpDesc->loopCount++;
    2650            8 :     grpDesc->totalLoopNum = grpDesc->loopCount;
    2651              : 
    2652            8 :     VersionV2LoopRecord record;
    2653            8 :     record.iterNumVar = CcuRep::Variable(*iterNumVarPtr);
    2654            8 :     record.addrOffsetVar = CcuRep::Variable(*addrOffsetVarPtr);
    2655            8 :     record.ctxIdVar = CcuRep::Variable(*ctxIdVarPtr);
    2656            8 :     grpDesc->versionV2Loops.push_back(record);
    2657              : 
    2658            8 :     CcuRep::CcuRepLoopGroupBundle::LoopEntry entry;
    2659            8 :     entry.executor = loopEnginePool[loopIdx];
    2660            8 :     entry.repLoopBlock = loopDesc->repLoopBlock;
    2661            8 :     entry.iterNumVar = CcuRep::Variable(*iterNumVarPtr);
    2662            8 :     entry.addrOffsetVar = CcuRep::Variable(*addrOffsetVarPtr);
    2663            8 :     entry.ctxIdVar = CcuRep::Variable(*ctxIdVarPtr);
    2664            8 :     entry.layout = CcuRep::CcuRepLoopGroupBundle::Layout::VersionV2;
    2665              : 
    2666            8 :     auto bundle = std::static_pointer_cast<CcuRep::CcuRepLoopGroupBundle>(grpDesc->bundleRep);
    2667            8 :     bundle->AddLoop(entry);
    2668              : 
    2669            8 :     if (!grpDesc->isVarBased) {
    2670            2 :         bundle->SetRepeatLoopIdx(grpDesc->config.cloneLoopOffset);
    2671            2 :         bundle->SetTotalLoopNum(grpDesc->totalLoopNum);
    2672              :     }
    2673              : 
    2674            8 :     return CcuResult::CCU_SUCCESS;
    2675            8 : }
    2676              : 
    2677           44 : void CcuKernel::SetInstrId(uint32_t instrId) { instrInfo_.startInstrId = instrId; }
    2678              : 
    2679           88 : uint32_t CcuKernel::GetInstrId() const { return instrInfo_.startInstrId; }
    2680              : 
    2681           91 : uint32_t CcuKernel::GetInstrCount()
    2682              : {
    2683           91 :     uint32_t instrCount = 0;
    2684         2285 :     for (const auto& rep : GetRepSequence()) {
    2685         2194 :         instrCount += rep->InstrCount();
    2686              :     }
    2687           91 :     instrInfo_.instrCount = instrCount;
    2688           91 :     HCCL_INFO("Kernel inst %u", instrCount);
    2689           91 :     return instrCount;
    2690              : }
    2691              : 
    2692           43 : void CcuKernel::SetCcuInstrInfo(const CcuRep::CcuInstrInfo& instrInfo) { this->instrInfo_ = instrInfo; }
    2693              : 
    2694          358 : CcuRep::Variable CcuKernel::CreateVariable()
    2695              : {
    2696          358 :     const auto& var = CreateBlockResAssist(1, res_.continuousVariable);
    2697          716 :     return var[0];
    2698          358 : }
    2699              : 
    2700          109 : CcuRep::Variable CcuKernel::CreateExpectVar()
    2701              : {
    2702              :     // v2(A6) 的 jump 只支持 var-var 比较,需要真实 XN 承载立即数;
    2703              :     // v1(A5) 的 jump 直接支持 var-imm,expectVar 不参与翻译,
    2704              :     // 用不进 res_ 账本的壳 Variable 即可,避免 v1 资源虚高。
    2705          109 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
    2706           20 :         return CreateVariable();
    2707              :     }
    2708           89 :     return CcuRep::Variable(this);
    2709              : }
    2710              : 
    2711          126 : CcuRep::Variable CcuKernel::CreateJumpTargetVar()
    2712              : {
    2713          126 :     if (ccuVersion_ == CcuVersion::CCU_V1) {
    2714              :         // A5(CCU_V1): 没有指令重排,可复用同一个 Xn 存放跳转目标地址。targetVar 仅用于 LoadImdToXn + 紧接 Jump。
    2715          102 :         if (!sharedJumpTargetVar_) {
    2716           14 :             sharedJumpTargetVar_ = std::make_unique<CcuRep::Variable>(CreateVariable());
    2717              :         }
    2718          102 :         return *sharedJumpTargetVar_;
    2719              :     }
    2720           24 :     return CcuRep::CreateVariable(this);
    2721              : }
    2722              : 
    2723          203 : CcuRep::Address CcuKernel::CreateAddress()
    2724              : {
    2725          203 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
    2726              :         // A6创建Address时,需要添加到Variable的列表中,但是仍以Address返回
    2727           91 :         return CcuRep::Address(CreateResAssist(res_.continuousVariable));
    2728              :     }
    2729          112 :     return CreateResAssist(res_.blockAddress);
    2730              : }
    2731              : 
    2732            0 : CcuRep::LocalNotify CcuKernel::CreateLocalNotify() { return CreateResAssist(res_.localNotify); }
    2733              : 
    2734            0 : CcuRep::CompletedEvent CcuKernel::CreateCompletedEvent() { return CreateResAssist(res_.blockCompletedEvent); }
    2735              : 
    2736            0 : CcuRep::CcuBuf CcuKernel::CreateCcuBuf()
    2737              : {
    2738            0 :     const auto& buffer = CreateBlockResAssist(1, res_.blockCcubufs);
    2739            0 :     return buffer[0];
    2740            0 : }
    2741              : 
    2742            0 : CcuRep::Executor CcuKernel::CreateExecutor() { return CreateResAssist(res_.blockExecutor); }
    2743              : 
    2744          156 : CcuRep::LocalAddr CcuKernel::CreateLocalAddr() { return CcuRep::LocalAddr(CreateAddress(), CreateVariable()); }
    2745              : 
    2746           37 : CcuRep::RemoteAddr CcuKernel::CreateRemoteAddr() { return CcuRep::RemoteAddr(CreateAddress(), CreateVariable()); }
    2747              : 
    2748            0 : CcuRep::RemoteAddr CcuKernel::GetRemoteAddr(const ChannelHandle channel, uint32_t index)
    2749              : {
    2750              :     (void)index;
    2751            0 :     channels_.insert(channel);
    2752            0 :     auto mem = CcuRep::RemoteAddr(CreateAddress(), CreateVariable());
    2753            0 :     Append(std::make_shared<CcuRep::CcuRepRemMem>(insGenerator, channel, mem));
    2754            0 :     return mem;
    2755            0 : }
    2756              : 
    2757            0 : CcuRep::LocalAddr CcuKernel::CreateLocalAddr(const CcuRep::Variable& token)
    2758              : {
    2759            0 :     return CcuRep::LocalAddr(CreateAddress(), token);
    2760              : }
    2761              : 
    2762            0 : HcclResult CcuKernel::CreateBlockCcuBuf(const uint32_t count, CcuRep::CcuBuf* ccuBufs)
    2763              : {
    2764            0 :     CHK_PTR_NULL(ccuBufs);
    2765            0 :     auto resources = CreateBlockResAssist(count, res_.blockCcubufs);
    2766              : 
    2767            0 :     for (uint32_t i = 0; i < count; i++) {
    2768            0 :         ccuBufs[i] = resources[i]; // 拷贝虚拟资源,通过shared_ptr链接到物理资源
    2769              :     }
    2770              : 
    2771            0 :     return HcclResult::HCCL_SUCCESS;
    2772            0 : }
    2773              : 
    2774           18 : HcclResult CcuKernel::CreateBlockExecutor(const uint32_t count, CcuRep::Executor* ccuExes)
    2775              : {
    2776           18 :     CHK_PTR_NULL(ccuExes);
    2777           18 :     auto resources = CreateBlockResAssist(count, res_.blockExecutor);
    2778              : 
    2779           48 :     for (uint32_t i = 0; i < count; i++) {
    2780           30 :         ccuExes[i] = resources[i]; // 拷贝虚拟资源,通过shared_ptr链接到物理资源
    2781              :     }
    2782              : 
    2783           18 :     return HcclResult::HCCL_SUCCESS;
    2784           18 : }
    2785              : 
    2786            0 : HcclResult CcuKernel::CreateBlockCompletedEvent(const uint32_t count, CcuRep::CompletedEvent* ccuEvents)
    2787              : {
    2788            0 :     CHK_PTR_NULL(ccuEvents);
    2789            0 :     auto resources = CreateBlockResAssist(count, res_.blockCompletedEvent);
    2790              : 
    2791            0 :     for (uint32_t i = 0; i < count; i++) {
    2792            0 :         ccuEvents[i] = resources[i]; // 拷贝虚拟资源,通过shared_ptr链接到物理资源
    2793              :     }
    2794              : 
    2795            0 :     return HcclResult::HCCL_SUCCESS;
    2796            0 : }
    2797              : 
    2798           44 : void CcuKernel::SetResRepository(const CcuResRepository& resRepo) { resRepo_ = resRepo; }
    2799              : 
    2800           44 : CcuResRepository& CcuKernel::GetResRepository() { return resRepo_; }
    2801              : 
    2802           44 : CcuSharedResource& CcuKernel::GetExportedRes() { return exportedRes_; }
    2803              : 
    2804           44 : CcuSharedResource& CcuKernel::GetImportedRes() { return importedRes_; }
    2805              : 
    2806            0 : static HcclResult GetArgIndex(
    2807              :     const std::unordered_map<uint16_t, uint16_t>& varId2VarIdMap,
    2808              :     const std::unordered_map<uint16_t, uint32_t>& varId2ArgIndexMap, const uint64_t* taskArgs, uint32_t argSize,
    2809              :     uint16_t varId, uint64_t& argIndex)
    2810              : {
    2811            0 :     HCCL_INFO("[GetArgIndex] Enter varId(%u)", varId);
    2812            0 :     auto item = varId2ArgIndexMap.find(varId);
    2813            0 :     if (item == varId2ArgIndexMap.end()) {
    2814            0 :         uint16_t oriVarId = varId;
    2815            0 :         auto iter = varId2VarIdMap.find(varId);
    2816            0 :         while (iter != varId2VarIdMap.end()) { // 循环查找中间assign Rep,找到起始varId
    2817            0 :             oriVarId = iter->second;
    2818            0 :             iter = varId2VarIdMap.find(oriVarId);
    2819              :         }
    2820            0 :         if (oriVarId != varId) { // 起始varId预期通过LoadArg赋值
    2821            0 :             item = varId2ArgIndexMap.find(oriVarId);
    2822            0 :             if (item == varId2ArgIndexMap.end()) {
    2823            0 :                 HCCL_ERROR("[%s]fail, Invalid goSize variable id(%u), oriVarId = %u", __func__, varId, oriVarId);
    2824            0 :                 return HCCL_E_PARA;
    2825              :             }
    2826              :         } else {
    2827            0 :             HCCL_ERROR("[%s]fail, Invalid goSize variable id(%u)", __func__, varId);
    2828            0 :             return HCCL_E_PARA;
    2829              :         }
    2830              :     }
    2831            0 :     HCCL_INFO("[GetArgIndex] find end");
    2832            0 :     if (item->second >= argSize) {
    2833            0 :         HCCL_ERROR("Invalid goSize variable index(%u).", item->second);
    2834            0 :         return HCCL_E_PARA;
    2835              :     }
    2836            0 :     HCCL_INFO(
    2837              :         "GetArgIndex success: varId(%u) varId2VarIdMapSize(%u) varId2ArgIndexMapSize(%u) taskArgsSize(%u)", varId,
    2838              :         varId2VarIdMap.size(), varId2ArgIndexMap.size(), argSize);
    2839            0 :     argIndex = taskArgs[item->second];
    2840            0 :     return HCCL_SUCCESS;
    2841              : }
    2842              : 
    2843            0 : void DumpCcuProfilingInfo(const std::vector<CcuProfilingInfo>& ccuProfilingInfo)
    2844              : {
    2845            0 :     auto dumpLinkInfo = [](const CcuProfilingInfo& info) -> void {
    2846            0 :         for (int i = 0; i < CCU_MAX_CHANNEL_NUM; i++) {
    2847            0 :             if (info.channelId[i] == INVALID_VALUE_CHANNELID) {
    2848            0 :                 continue;
    2849              :             }
    2850            0 :             HCCL_INFO("channelId(%u), remoteRankId(%u).", info.channelId[i], info.remoteRankId[i]);
    2851              :         }
    2852            0 :     };
    2853              : 
    2854            0 :     for (const auto& profInfo : ccuProfilingInfo) {
    2855            0 :         if (profInfo.type == static_cast<uint8_t>(CcuProfilinType::CCU_TASK_PROFILING)) {
    2856            0 :             HCCL_INFO(
    2857              :                 "Dump CCU Profiling Info:SQE Profiling Info: ctxSignautre(%s), "
    2858              :                 "dieId(%d), missionId(%d), instrId(%d).",
    2859              :                 profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
    2860              :                 static_cast<int>(profInfo.instrId));
    2861            0 :         } else if (profInfo.type == static_cast<uint8_t>(CcuProfilinType::CCU_WAITCKE_PROFILING)) {
    2862            0 :             HCCL_INFO(
    2863              :                 "Microcode WaitCKE Profiling Info: name(%s), "
    2864              :                 "dieId(%d), missionId(%d), instrId(%d), ckeId(%u), mask(%u).",
    2865              :                 profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
    2866              :                 static_cast<int>(profInfo.instrId), profInfo.ckeId, profInfo.mask);
    2867            0 :             dumpLinkInfo(profInfo);
    2868            0 :         } else if (profInfo.type == static_cast<uint8_t>(CcuProfilinType::CCU_LOOPGROUP_PROFILING)) {
    2869            0 :             HCCL_INFO(
    2870              :                 "Microcode LoopGroup Profiling Info: name(%s), "
    2871              :                 "dieId(%d), missionId(%d), instrId(%d), reduceOpType(%d), inputDataType(%d), "
    2872              :                 "outputDataType(%d), dataSize(%llu).",
    2873              :                 profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
    2874              :                 static_cast<int>(profInfo.instrId), static_cast<int>(profInfo.reduceOpType),
    2875              :                 static_cast<int>(profInfo.inputDataType), static_cast<int>(profInfo.outputDataType), profInfo.dataSize);
    2876            0 :             dumpLinkInfo(profInfo);
    2877              :         }
    2878              :     }
    2879            0 : }
    2880              : 
    2881            0 : constexpr uint64_t SetBits(uint16_t end) { return ((uint64_t(1) << (end + 1)) - uint64_t(1)); }
    2882              : 
    2883            0 : static uint16_t ParseRepeatNumFromParallelParam(uint64_t parallelParam)
    2884              : {
    2885            0 :     constexpr uint16_t repeatBitNum = 7;       // 7: repeat num 占 7 bits
    2886            0 :     constexpr uint16_t repeatNumShiftBit = 55; // 55: repeat num占[61:55]位置
    2887            0 :     return (parallelParam >> repeatNumShiftBit) & SetBits(repeatBitNum);
    2888              : }
    2889              : 
    2890            0 : HcclResult CcuKernel::CollectSqeAndWaitCkeProfilingInfo()
    2891              : {
    2892            0 :     auto& ccuProfilingCache = GetProfilingInfo();
    2893            0 :     uint32_t count{0};
    2894            0 :     HCCL_INFO("[GetCcuProfilingInfo] Process sqe&waitcke profiling info start.");
    2895            0 :     for (auto& profInfo : ccuProfilingCache) {
    2896            0 :         profInfo.missionId = GetMissionId();
    2897            0 :         if (profInfo.type == static_cast<uint8_t>(hcomm::CcuProfilinType::CCU_TASK_PROFILING)) {
    2898            0 :             profInfo.instrId = GetInstrId();
    2899            0 :             allCcuProfilingInfos_.push_back(profInfo);
    2900            0 :             continue;
    2901              :         }
    2902            0 :         if (count >= GetWaiteCkeProfilingReps().size()) {
    2903            0 :             HCCL_ERROR(
    2904              :                 "count[%u] out of range[0, %u], cache size(%u).", count, GetWaiteCkeProfilingReps().size(),
    2905              :                 ccuProfilingCache.size());
    2906            0 :             return HCCL_E_INTERNAL;
    2907              :         }
    2908            0 :         auto waitCkeRep = GetWaiteCkeProfilingReps()[count];
    2909            0 :         profInfo.instrId = waitCkeRep->StartInstrId();
    2910            0 :         if (profInfo.ckeId == INVALID_CKE_ID) { // localWait Rep
    2911            0 :             if (waitCkeRep.get() == nullptr) {
    2912            0 :                 HCCL_ERROR("[GetCcuProfilingInfo] localWaitRep is nullptr.");
    2913            0 :                 return HCCL_E_PTR;
    2914              :             }
    2915            0 :             profInfo.ckeId = waitCkeRep->GetId();
    2916            0 :             HCCL_INFO("[CcuKernel][GetCcuProfilingInfo] waitcke[%u]", profInfo.ckeId);
    2917              :         }
    2918            0 :         allCcuProfilingInfos_.push_back(profInfo);
    2919            0 :         count++;
    2920            0 :     }
    2921            0 :     return HCCL_SUCCESS;
    2922              : }
    2923              : 
    2924            0 : HcclResult CcuKernel::BuildLoopGroupVarIdMaps(
    2925              :     std::unordered_map<uint16_t, uint32_t>& varId2ArgIndexMap, std::unordered_map<uint16_t, uint16_t>& varId2VarIdMap)
    2926              : {
    2927            0 :     auto& lgProfInfo = GetLGProfilingInfo();
    2928            0 :     HCCL_INFO("[GetCcuProfilingInfo] create varId2ArgIndexMap start. size=%lu", lgProfInfo.loadRep2ArgIdxMap.size());
    2929            0 :     for (auto& iter : lgProfInfo.loadRep2ArgIdxMap) {
    2930            0 :         if (iter.first.get() == nullptr) {
    2931            0 :             HCCL_ERROR("[GetCcuProfilingInfo] loadRep is nullptr.");
    2932            0 :             return HCCL_E_PTR;
    2933              :         }
    2934            0 :         auto loadRep = dynamic_cast<CcuRep::CcuRepLoadArg*>(iter.first.get());
    2935            0 :         varId2ArgIndexMap[loadRep->GetVarId()] = iter.second;
    2936              :     }
    2937              : 
    2938            0 :     HCCL_INFO("[GetCcuProfilingInfo] create varId2VarIdMap start. size=%lu", lgProfInfo.assignProfilingReps.size());
    2939            0 :     for (auto& iter : lgProfInfo.assignProfilingReps) {
    2940            0 :         if (iter.get() == nullptr) {
    2941            0 :             HCCL_ERROR("[GetCcuProfilingInfo] assignRep is nullptr.");
    2942            0 :             return HCCL_E_PTR;
    2943              :         }
    2944            0 :         auto assignRep = dynamic_cast<CcuRep::CcuRepAssign*>(iter.get());
    2945            0 :         varId2VarIdMap[assignRep->GetVarB().Id()] = assignRep->GetVarA().Id();
    2946              :     }
    2947            0 :     return HCCL_SUCCESS;
    2948              : }
    2949              : 
    2950            0 : HcclResult CcuKernel::CollectLoopGroupProfilingInfo(
    2951              :     const uint64_t* taskArgs, uint32_t argSize, const std::unordered_map<uint16_t, uint32_t>& varId2ArgIndexMap,
    2952              :     const std::unordered_map<uint16_t, uint16_t>& varId2VarIdMap)
    2953              : {
    2954            0 :     auto& lgProfInfo = GetLGProfilingInfo();
    2955            0 :     HCCL_INFO(
    2956              :         "[GetCcuProfilingInfo] process loop group profiling start: "
    2957              :         "lgsize(%lu), goSize(%lu)",
    2958              :         lgProfInfo.lgProfilingReps.size(), groupOpSizeInfo_.size());
    2959            0 :     for (uint32_t i = 0; i < lgProfInfo.lgProfilingReps.size();
    2960            0 :          i += 2) { // 2: 一个goSize对应一个CcuProfilingInfo,对应1个loopGroup Rep
    2961            0 :         if (argSize == 0 || varId2ArgIndexMap.empty()) {
    2962            0 :             continue;
    2963              :         }
    2964            0 :         uint64_t loopParam{0};
    2965            0 :         CHK_RET(GetArgIndex(
    2966              :             varId2VarIdMap, varId2ArgIndexMap, taskArgs, argSize, groupOpSizeInfo_[i].loopParamId, loopParam));
    2967            0 :         uint64_t parallelParam{0};
    2968            0 :         CHK_RET(GetArgIndex(
    2969              :             varId2VarIdMap, varId2ArgIndexMap, taskArgs, argSize, groupOpSizeInfo_[i].parallelParamId, parallelParam));
    2970            0 :         HCCL_INFO(
    2971              :             "Collect loopgroup profiling info: repSize[%u], index[%u],"
    2972              :             "loopParam[%llu], parallelParam[%llu].",
    2973              :             lgProfInfo.lgProfilingReps.size(), i, loopParam, parallelParam);
    2974              : 
    2975            0 :         if (loopParam != 0) {
    2976            0 :             lgProfInfo.ccuProfilingInfos[i].dataSize = loopParam * moConfig_.loopCount * moConfig_.memSlice;
    2977            0 :             lgProfInfo.ccuProfilingInfos[i].instrId
    2978            0 :                 = dynamic_cast<CcuRep::CcuRepLoopGroupBundle*>(lgProfInfo.lgProfilingReps[i].get())->StartInstrId();
    2979            0 :             allCcuProfilingInfos_.push_back(lgProfInfo.ccuProfilingInfos[i]);
    2980              :         }
    2981              : 
    2982            0 :         if (parallelParam != 0) {
    2983            0 :             HCCL_INFO("[GetCcuProfilingInfo] collect lg, residual start i=%lu", i);
    2984            0 :             uint64_t residual{0};
    2985            0 :             CHK_RET(GetArgIndex(
    2986              :                 varId2VarIdMap, varId2ArgIndexMap, taskArgs, argSize, groupOpSizeInfo_[i].residualId, residual));
    2987            0 :             uint64_t repeatNum = ParseRepeatNumFromParallelParam(parallelParam);
    2988            0 :             lgProfInfo.ccuProfilingInfos[i].dataSize = repeatNum * moConfig_.memSlice + residual;
    2989            0 :             lgProfInfo.ccuProfilingInfos[i].instrId
    2990            0 :                 = dynamic_cast<CcuRep::CcuRepLoopGroupBundle*>(lgProfInfo.lgProfilingReps[i + 1].get())->StartInstrId();
    2991            0 :             allCcuProfilingInfos_.push_back(lgProfInfo.ccuProfilingInfos[i]);
    2992              :         }
    2993              :     }
    2994            0 :     return HCCL_SUCCESS;
    2995              : }
    2996              : 
    2997              : /*
    2998              :  * variable/maskSignal等资源变量Id,一定要在获取ccu profiling时才获取;
    2999              :  * 原因:在创建context Rep时,其资源Id属于虚拟资源;翻译时,才会绑定固定的物理资源。
    3000              :  */
    3001            0 : HcclResult CcuKernel::GetCcuProfilingInfo(
    3002              :     const uint64_t* taskArgs, uint32_t argSize, std::vector<CcuProfilingInfo>& allCcuProfilingInfo)
    3003              : {
    3004            0 :     HCCL_INFO("[GetCcuProfilingInfo] Enter.");
    3005            0 :     allCcuProfilingInfos_.clear();
    3006              : 
    3007            0 :     CHK_RET(CollectSqeAndWaitCkeProfilingInfo());
    3008              : 
    3009            0 :     std::unordered_map<uint16_t, uint32_t> varId2ArgIndexMap;
    3010            0 :     std::unordered_map<uint16_t, uint16_t> varId2VarIdMap;
    3011            0 :     CHK_RET(BuildLoopGroupVarIdMaps(varId2ArgIndexMap, varId2VarIdMap));
    3012              : 
    3013            0 :     CHK_RET(CollectLoopGroupProfilingInfo(taskArgs, argSize, varId2ArgIndexMap, varId2VarIdMap));
    3014              : 
    3015            0 :     DumpCcuProfilingInfo(allCcuProfilingInfos_);
    3016            0 :     allCcuProfilingInfo = allCcuProfilingInfos_;
    3017            0 :     return HCCL_SUCCESS;
    3018            0 : }
    3019              : 
    3020            0 : HcclResult CcuKernel::AddProfilingInfo(
    3021              :     const ChannelHandle* channels, uint32_t channelNum, HcclDataType dataType, HcclDataType outputDataType,
    3022              :     HcclReduceOp opType, const std::string& opName)
    3023              : {
    3024            0 :     CHK_PTR_NULL(channels);
    3025            0 :     ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_LOOPGROUP_PROFILING;
    3026            0 :     ccuProfilingInfoCache.name = opName;
    3027            0 :     ccuProfilingInfoCache.reduceOpType = opType;
    3028            0 :     ccuProfilingInfoCache.inputDataType = dataType;
    3029            0 :     ccuProfilingInfoCache.outputDataType = outputDataType;
    3030            0 :     ccuProfilingInfoCache.missionId = GetMissionId();
    3031              : 
    3032            0 :     CHK_SAFETY_FUNC_RET(memset_s(
    3033              :         ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId), INVALID_VALUE_CHANNELID,
    3034              :         sizeof(ccuProfilingInfoCache.channelId)));
    3035            0 :     for (uint32_t i = 0; i < channelNum; i++) {
    3036            0 :         void* channelPtr{nullptr};
    3037            0 :         CHK_RET(static_cast<HcclResult>(HcommChannelGet(channels[i], &channelPtr)));
    3038            0 :         auto* channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
    3039            0 :         CHK_PTR_NULL(channelImpl);
    3040            0 :         ccuProfilingInfoCache.channelId[i] = channelImpl->GetChannelId();
    3041            0 :         ccuProfilingInfoCache.channelHandle[i] = channels[i];
    3042            0 :         HCCL_INFO(
    3043              :             "[%s]type[%d], name[%s], opType[%d], dataType[%d], outputDataType[%d], missionId[%u], "
    3044              :             "channelHandle[0x%llx], channelId[%u]",
    3045              :             __func__, ccuProfilingInfoCache.type, ccuProfilingInfoCache.name.c_str(), opType, dataType, outputDataType,
    3046              :             ccuProfilingInfoCache.missionId, ccuProfilingInfoCache.channelHandle[i],
    3047              :             ccuProfilingInfoCache.channelId[i]);
    3048              :     }
    3049            0 :     lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
    3050            0 :     lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
    3051            0 :     return HCCL_SUCCESS;
    3052              : }
    3053              : 
    3054            0 : HcclResult CcuKernel::AddCcuProfiling(
    3055              :     GroupInfo groupInfo, const std::vector<ChannelHandle> channelHandle, HcclDataType dataType,
    3056              :     HcclDataType outputDataType, HcclReduceOp opType, const std::string& opName)
    3057              : {
    3058            0 :     CHK_RET(AddCcuProfiling(channelHandle.data(), channelHandle.size(), dataType, outputDataType, opType, opName));
    3059            0 :     groupOpSizeInfo_.push_back(groupInfo);
    3060            0 :     return HCCL_SUCCESS;
    3061              : }
    3062              : 
    3063            0 : HcclResult CcuKernel::AddCcuProfiling(
    3064              :     const ChannelHandle* channels, uint32_t channelNum, HcclDataType dataType, HcclDataType outputDataType,
    3065              :     HcclReduceOp opType, const std::string& opName)
    3066              : {
    3067            0 :     CHK_PTR_NULL(channels);
    3068            0 :     CHK_RET(AddProfilingInfo(channels, channelNum, dataType, outputDataType, opType, opName));
    3069            0 :     return HCCL_SUCCESS;
    3070              : }
    3071              : 
    3072            5 : HcclResult CcuKernel::Add2ConstValue2VarMap(std::vector<uint64_t>& values)
    3073              : {
    3074              :     // 记录当前context所需的常量,仅A6场景适用
    3075           21 :     for (uint64_t value : values) {
    3076           16 :         if (constValue2VarMap.find(value) == constValue2VarMap.end()) {
    3077            3 :             constValue2VarMap[value] = CreateVariable();
    3078              :         }
    3079              :     }
    3080            5 :     return HCCL_SUCCESS;
    3081              : }
    3082              : 
    3083              : }; // namespace hcomm
        

Generated by: LCOV version 2.0-1