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: 64.6 % 1758 1136
Test Date: 2026-07-28 12:11:00 Functions: 71.8 % 195 140

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

Generated by: LCOV version 2.0-1