LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_kernel - ccu_kernel_mgr.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.3 % 503 454
Test Date: 2026-08-29 17:38:31 Functions: 97.9 % 47 46

            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_mgr.h"
      12              : 
      13              : #include <acl/acl.h>
      14              : 
      15              : #include "hccl_common.h"
      16              : #include "exception_handler.h"
      17              : #include "adapter_rts.h"
      18              : #include "ccu_assist_v1.h"
      19              : #include "dev_buffer.h"
      20              : #include "ccu_ins_generator_v1.h"
      21              : #include "ccu_ins_generator_v2.h"
      22              : #include "ccu_dev_mgr_imp.h"
      23              : 
      24              : #include "ccu_rep_base_v1.h"
      25              : #include "ccu_rep_block_v1.h"
      26              : #include "ccu_rep_type_v1.h"
      27              : 
      28              : #include "hcomm_adapter_hccp.h"
      29              : 
      30              : #include "ccu_log.h"
      31              : #include "ccu_kernel_func.h"
      32              : 
      33              : namespace hcomm {
      34              : 
      35            0 : HcclResult GetHcclVersionForCcuKernelMgr(int& hcclVersion)
      36              : {
      37            0 :     char hcclPkgName[] = "hccl";
      38            0 :     aclError aclRet = aclsysGetVersionNum(hcclPkgName, &hcclVersion);
      39            0 :     CHK_PRT_RET(
      40              :         aclRet != ACL_SUCCESS,
      41              :         HCCL_ERROR("[GetHcclVersionForCcuKernelMgr] aclsysGetVersionNum failed, aclRet[%d].", aclRet), HCCL_E_INTERNAL);
      42            0 :     HCCL_RUN_INFO("[GetHcclVersionForCcuKernelMgr] hccl version is %d.", hcclVersion);
      43            0 :     return HCCL_SUCCESS;
      44              : }
      45              : 
      46              : constexpr int MAX_HCCL_VERSION_USING_CCU_RES_STATIC_ALLOC = 90100000;
      47              : 
      48              : static uint32_t ComputeKernelInstrRegionSize(CcuKernel* kernel, const int32_t devLogicId);
      49              : 
      50          198 : CcuKernelMgr::~CcuKernelMgr()
      51              : {
      52          198 :     if (!initializedFlag_) {
      53          198 :         return;
      54              :     }
      55              : 
      56            0 :     if (instructionLoadDevMem_) {
      57            0 :         HCCL_RUN_INFO(
      58              :             "[CcuKernelMgr][~CcuKernelMgr]: deviceLogicId[%d], free addr[%p]", devLogicId_, instructionLoadDevMem_);
      59            0 :         (void)hrtFree(instructionLoadDevMem_);
      60            0 :         instructionLoadDevMem_ = nullptr;
      61              :     }
      62              : 
      63            0 :     (void)Deinit();
      64         1188 : }
      65              : 
      66         2927 : CcuKernelMgr& CcuKernelMgr::GetInstance(const int32_t deviceLogicId)
      67              : {
      68         3125 :     static CcuKernelMgr kernelManager[MAX_MODULE_DEVICE_NUM + 1];
      69              : 
      70         2927 :     int32_t devLogicId = deviceLogicId;
      71         2927 :     if (devLogicId < 0 || static_cast<uint32_t>(devLogicId) >= MAX_MODULE_DEVICE_NUM) {
      72            0 :         HCCL_WARNING(
      73              :             "[CcuKernelMgr][%s] use the backup device, devLogicId[%d] should be "
      74              :             "less than %u.",
      75              :             __func__, devLogicId, MAX_MODULE_DEVICE_NUM);
      76            0 :         devLogicId = MAX_MODULE_DEVICE_NUM; // 使用备份设备
      77              :     }
      78              : 
      79         2927 :     kernelManager[devLogicId].devLogicId_ = devLogicId;
      80         2927 :     return kernelManager[devLogicId];
      81              : }
      82              : 
      83           99 : HcclResult CcuKernelMgr::Init()
      84              : {
      85           99 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
      86           99 :     if (initializedFlag_) {
      87            0 :         return HcclResult::HCCL_SUCCESS;
      88              :     }
      89              : 
      90          297 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
      91          198 :         bool enableFlag = false;
      92          198 :         CHK_RET(static_cast<HcclResult>(CcuGetDieEnableInfo(devLogicId_, dieId, enableFlag)));
      93          198 :         if (!enableFlag) {
      94            0 :             continue;
      95              :         }
      96              : 
      97          198 :         CHK_RET(InstantiationTranslator(dieId));
      98              :     }
      99              : 
     100           99 :     initializedFlag_ = true;
     101           99 :     kernelMap_.clear();
     102              : 
     103           99 :     CHK_RET(CcuDevMgrImp::GetCcuVersion(devLogicId_, ccuVersion_));
     104           99 :     HCCL_INFO("[CcuKernelMgr] Get CcuVersion[%d](0: CcuV1, 1: CcuV2, 2: Invalid)", ccuVersion_);
     105           99 :     if (ccuVersion_ == CcuVersion::INVALID) {
     106            0 :         HCCL_ERROR("[CcuKernelMgr][%s] Invalid chip type, abort Init.", __func__);
     107            0 :         return HcclResult::HCCL_E_INTERNAL;
     108              :     }
     109              : 
     110           99 :     if (ccuVersion_ == CcuVersion::CCU_V2) {
     111           19 :         HCCL_INFO("[CcuKernelMgr] Init CcuInsGeneratorV2");
     112           19 :         insGenePtr = std::make_shared<CcuRep::CcuInsGeneratorV2>();
     113           19 :         return HcclResult::HCCL_SUCCESS;
     114              :     }
     115              : 
     116           80 :     HCCL_INFO("[CcuKernelMgr] Init CcuInsGeneratorV1");
     117           80 :     insGenePtr = std::make_shared<CcuRep::CcuInsGeneratorV1>();
     118           80 :     return HcclResult::HCCL_SUCCESS;
     119           99 : }
     120              : 
     121          180 : HcclResult CcuKernelMgr::Deinit()
     122              : {
     123              :     // 不需要主动释放CCU指令空间等资源,因为设备管理与kernelMgr都为静态,生命周期一致
     124          180 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
     125          180 :     translatorResPack.handles.clear();
     126          180 :     initializedFlag_ = false;
     127          180 :     kernelMap_.clear();
     128          180 :     translators.clear();
     129          180 :     referenceMgrs.clear();
     130          180 :     return HcclResult::HCCL_SUCCESS;
     131          180 : }
     132              : 
     133           62 : CcuResult CcuKernelMgr::Register(
     134              :     CcuResPack& resPack, const uint32_t dieId, const char* kernelFuncName, const void* kernelFunc,
     135              :     const void** kernelArgs, const uint32_t argNum, CcuInstance* ccuIns, CcuKernelHandle& kernelHandle)
     136              : {
     137              :     // 允许kernelFuncName为空,此时传递默认名称
     138           62 :     CCU_CHK_PTR_NULL(kernelFunc);
     139              : 
     140              :     // 当前argNum仅允许 0 或 1
     141           62 :     if (argNum > 1) {
     142            0 :         HCCL_ERROR("[%s] failed, argNum[%u] now only support 0 or 1.", __func__, argNum);
     143            0 :         return CcuResult::CCU_E_PARA;
     144              :     }
     145              : 
     146              :     // 注意处理时序,需要先重置后处理rep
     147           62 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
     148           62 :     CCU_CHK_RET(BuildKernel(dieId, kernelFuncName, kernelFunc, kernelArgs, argNum, ccuIns));
     149              : 
     150           47 :     CcuResult ret = AllocRes(resPack);
     151           47 :     if (ret != CcuResult::CCU_SUCCESS) {
     152            0 :         HCCL_WARNING("[%s] AllocRes failed, maybe resource not enough, please check ret[%d]", __func__, ret);
     153            0 :         return ret;
     154              :     }
     155              : 
     156           47 :     kernelId_++;
     157           47 :     kernelMap_[kernelId_] = std::move(currKernel_);
     158              : 
     159           47 :     kernelHandle = kernelId_;
     160           47 :     return CcuResult::CCU_SUCCESS;
     161           62 : }
     162              : 
     163           77 : CcuResult CcuKernelMgr::BuildKernel(
     164              :     uint32_t dieId, const char* kernelFuncName, const void* kernelFunc, const void** kernelArgs, uint32_t argNum,
     165              :     CcuInstance* ccuIns)
     166              : {
     167           77 :     currKernel_ = std::make_unique<CcuKernel>(); // 重置待构建kernel
     168              :     // 执行算法流程时将资源占用临时记录在 die 0,后续确定实际 die 并迁移资源
     169           77 :     currKernel_->SetDieId(0);
     170           77 :     CCU_CHK_RET(currKernel_->SetupProfilingInfo(kernelFuncName));
     171              : 
     172              :     // 初始化翻译器(需在执行kernel func前设置,因为func执行时会创建rep对象)
     173           77 :     currKernel_->SetInsGenerater(insGenePtr.get());
     174           77 :     currKernel_->SetCcuVersion(ccuVersion_);
     175              : 
     176           77 :     if (argNum == 0) {
     177            8 :         auto ccuKernelFunc = reinterpret_cast<CcuKernelFuncNoArg>(kernelFunc);
     178            8 :         CCU_CHK_RET(ccuKernelFunc()); // 执行算法流程,生成rep和计算资源占用
     179              :     } else {
     180           69 :         CCU_CHK_PTR_NULL(kernelArgs);
     181           69 :         const void* kernelArg = kernelArgs[0];
     182           69 :         CCU_CHK_PTR_NULL(kernelArg);
     183           69 :         const auto ccuKernelArg = const_cast<CcuKernelArg>(kernelArg);
     184           69 :         auto ccuKernelFunc = reinterpret_cast<CcuKernelFuncOneArg>(kernelFunc);
     185           69 :         CCU_CHK_RET(ccuKernelFunc(ccuKernelArg)); // 执行算法流程,生成rep和计算资源占用
     186              :     }
     187              : 
     188           60 :     currKernel_->FlushClosablePendingIfs(); // 处理未闭合的if
     189           60 :     if (ccuIns != nullptr && ccuIns->IsFixedResNum()) {
     190              :         // 按固定资源数量创建的 ccu instance,外部 dieId 始终为 0,从 channel 获取实际 dieId
     191            1 :         CCU_CHK_RET(currKernel_->ApplyDieFromChannels());
     192              :     } else {
     193              :         // 按需创建的 ccu instance,校验所有 channel 使用相同的 die,然后将资源占用从 die 0 迁移到指定 die
     194           59 :         CCU_CHK_RET(currKernel_->ValidateAndApplyDie(dieId));
     195              :     }
     196           57 :     CCU_CHK_RET(PrepareConstValueResources()); // 记录翻译过程所需常量并申请对应资源
     197           57 :     return CcuResult::CCU_SUCCESS;
     198              : }
     199              : 
     200           15 : CcuResult CcuKernelMgr::GetKernelResourceRequest(
     201              :     const uint32_t dieId, const char* kernelFuncName, const void* kernelFunc, const void** kernelArgs,
     202              :     const uint32_t argNum, CcuResReq& resReq, uint32_t& instrCount)
     203              : {
     204           15 :     CCU_CHK_PTR_NULL(kernelFunc);
     205           15 :     if (argNum > 1) {
     206            0 :         HCCL_ERROR("[%s] failed, argNum[%u] now only support 0 or 1.", __func__, argNum);
     207            0 :         return CcuResult::CCU_E_PARA;
     208              :     }
     209           15 :     if (argNum == 1) {
     210            7 :         CCU_CHK_PTR_NULL(kernelArgs);
     211            7 :         CCU_CHK_PTR_NULL(kernelArgs[0]);
     212              :     }
     213              : 
     214           15 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
     215           15 :     currKernel_.reset();
     216              :     struct CurrentKernelGuard {
     217           15 :         explicit CurrentKernelGuard(std::unique_ptr<CcuKernel>& kernel) : kernel_(kernel) {}
     218           15 :         ~CurrentKernelGuard() { kernel_.reset(); }
     219              :         std::unique_ptr<CcuKernel>& kernel_;
     220           15 :     } guard(currKernel_);
     221              : 
     222           15 :     CCU_CHK_RET(BuildKernel(dieId, kernelFuncName, kernelFunc, kernelArgs, argNum, nullptr));
     223           10 :     resReq = currKernel_->GetResourceRequest();
     224           10 :     const uint32_t kernelInstrCount = currKernel_->GetInstrCount();
     225           10 :     const uint32_t translatorInstrCount = CcuRepTranslator::GetInstrNum(devLogicId_);
     226           10 :     const uint32_t constInstrCount = currKernel_->GetConstValue2VarMap().size();
     227           10 :     const uint32_t ckeReserveInstrCount = currKernel_->GetRepNeedToAddLatency() * CcuRep::CCU_CKE_RAW_LATENCY;
     228              :     // 总数统一走 ComputeKernelInstrRegionSize, 与申请/释放口径保持结构一致; 分项仅用于日志观测
     229           10 :     instrCount = ComputeKernelInstrRegionSize(currKernel_.get(), devLogicId_);
     230           10 :     HCCL_INFO(
     231              :         "[HcommCcuKernelQueryResReq][%s] resource request instruction count, kernelInstrCount[%u], "
     232              :         "translatorInstrCount[%u], constInstrCount[%u], ckeReserveInstrCount[%u], totalInstrCount[%u].",
     233              :         __func__, kernelInstrCount, translatorInstrCount, constInstrCount, ckeReserveInstrCount, instrCount);
     234           10 :     return CcuResult::CCU_SUCCESS;
     235           16 : }
     236              : 
     237          292 : static void DumpResReqInfo(const CcuResReq& totalRes)
     238              : {
     239          876 :     for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     240         1168 :         if (totalRes.msReq[i] != 0 || totalRes.blockMsReq[i] != 0 || totalRes.ckeReq[i] != 0
     241          286 :             || totalRes.blockCkeReq[i] != 0 || totalRes.loopEngineReq[i] != 0 || totalRes.blockLoopEngineReq[i] != 0
     242          272 :             || totalRes.gsaReq[i] != 0 || totalRes.blockGsaReq[i] != 0 || totalRes.xnReq[i] != 0
     243         1168 :             || totalRes.blockXnReq[i] != 0 || totalRes.missionReq.req[i] != 0) {
     244          339 :             HCCL_INFO(
     245              :                 "DumpResReqInfo: dieId[%u], msReq[%u], blockMsReq[%u], ckeReq[%u], blockCkeReq[%u], "
     246              :                 "loopEngineReq[%u], blockLoopEngineReq[%u], gsaReq[%u], blockGsaReq[%u], xnReq[%u], blockXnReq[%u], "
     247              :                 "missionReq[%u]",
     248              :                 i, totalRes.msReq[i], totalRes.blockMsReq[i], totalRes.ckeReq[i], totalRes.blockCkeReq[i],
     249              :                 totalRes.loopEngineReq[i], totalRes.blockLoopEngineReq[i], totalRes.gsaReq[i], totalRes.blockGsaReq[i],
     250              :                 totalRes.xnReq[i], totalRes.blockXnReq[i], totalRes.missionReq.req[i]);
     251              :         }
     252              :     }
     253          292 : }
     254              : 
     255         1034 : inline int32_t GetResTotalNum(const std::vector<ResInfo>& resInfos)
     256              : {
     257         1034 :     int32_t resNum = 0;
     258         1564 :     for (ResInfo resInfo : resInfos) {
     259          530 :         resNum += static_cast<int32_t>(resInfo.num);
     260              :     }
     261         1034 :     return resNum;
     262              : }
     263              : 
     264           47 : static void GetResNumFromResPack(CcuResPack& resPack, CcuResReq& totalRes)
     265              : {
     266              :     // 获取通信域当前所持有的资源
     267           47 :     const auto& tmpResRepository = resPack.GetCcuResRepo();
     268              : 
     269              :     // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes的第0个vector中
     270          141 :     for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     271           94 :         totalRes.msReq[i] += GetResTotalNum(tmpResRepository.ms[i]);
     272           94 :         totalRes.blockMsReq[i] += GetResTotalNum(tmpResRepository.blockMs[i]);
     273           94 :         totalRes.ckeReq[i] += GetResTotalNum(tmpResRepository.cke[i]);
     274           94 :         totalRes.blockCkeReq[i] += GetResTotalNum(tmpResRepository.blockCke[i]);
     275           94 :         totalRes.loopEngineReq[i] += GetResTotalNum(tmpResRepository.loopEngine[i]);
     276           94 :         totalRes.blockLoopEngineReq[i] += GetResTotalNum(tmpResRepository.blockLoopEngine[i]);
     277           94 :         totalRes.gsaReq[i] += GetResTotalNum(tmpResRepository.gsa[i]);
     278           94 :         totalRes.blockGsaReq[i] += GetResTotalNum(tmpResRepository.blockGsa[i]);
     279           94 :         totalRes.xnReq[i] += GetResTotalNum(tmpResRepository.xn[i]);
     280           94 :         totalRes.blockXnReq[i] += GetResTotalNum(tmpResRepository.blockXn[i]);
     281           94 :         totalRes.missionReq.req[i] += GetResTotalNum(tmpResRepository.mission.mission[i]);
     282              :     }
     283              : 
     284           47 :     DumpResReqInfo(totalRes);
     285           47 :     HCCL_INFO("GetResPackTotalResNum:dumpInfos success.");
     286           47 : }
     287              : 
     288         1034 : inline uint32_t GetReqResNum(const uint32_t reqRes, const uint32_t totalRes)
     289              : {
     290         1034 :     return ((reqRes > totalRes) ? (reqRes - totalRes) : 0);
     291              : }
     292              : 
     293           47 : static bool CheckResIfAvailable(const CcuResReq& totalRes, const CcuResReq& resReq)
     294              : {
     295           47 :     DumpResReqInfo(resReq);
     296              : 
     297           47 :     CcuResReq needResReq{};
     298              :     // todo: 优化为遍历数组
     299          141 :     for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     300           94 :         needResReq.msReq[i] = GetReqResNum(resReq.msReq[i], totalRes.msReq[i]);
     301           94 :         needResReq.blockMsReq[i] = GetReqResNum(resReq.blockMsReq[i], totalRes.blockMsReq[i]);
     302           94 :         needResReq.ckeReq[i] = GetReqResNum(resReq.ckeReq[i], totalRes.ckeReq[i]);
     303           94 :         needResReq.blockCkeReq[i] = GetReqResNum(resReq.blockCkeReq[i], totalRes.blockCkeReq[i]);
     304           94 :         needResReq.loopEngineReq[i] = GetReqResNum(resReq.loopEngineReq[i], totalRes.loopEngineReq[i]);
     305           94 :         needResReq.blockLoopEngineReq[i] = GetReqResNum(resReq.blockLoopEngineReq[i], totalRes.blockLoopEngineReq[i]);
     306           94 :         needResReq.gsaReq[i] = GetReqResNum(resReq.gsaReq[i], totalRes.gsaReq[i]);
     307           94 :         needResReq.blockGsaReq[i] = GetReqResNum(resReq.blockGsaReq[i], totalRes.blockGsaReq[i]);
     308           94 :         needResReq.xnReq[i] = GetReqResNum(resReq.xnReq[i], totalRes.xnReq[i]);
     309           94 :         needResReq.blockXnReq[i] = GetReqResNum(resReq.blockXnReq[i], totalRes.blockXnReq[i]);
     310           94 :         needResReq.missionReq.req[i] = GetReqResNum(resReq.missionReq.req[i], totalRes.missionReq.req[i]);
     311              : 
     312           94 :         if (needResReq.missionReq.req[i] > 0) {
     313            0 :             needResReq.missionReq.reqType = resReq.missionReq.reqType;
     314              :         }
     315              : 
     316          188 :         if (needResReq.msReq[i] != 0 || needResReq.blockMsReq[i] != 0 || needResReq.ckeReq[i] != 0
     317           94 :             || needResReq.blockCkeReq[i] != 0 || needResReq.loopEngineReq[i] != 0
     318           94 :             || needResReq.blockLoopEngineReq[i] != 0 || needResReq.gsaReq[i] != 0 || needResReq.blockGsaReq[i] != 0
     319          188 :             || needResReq.xnReq[i] != 0 || needResReq.blockXnReq[i] != 0 || needResReq.missionReq.req[i] != 0) {
     320            0 :             HCCL_WARNING(
     321              :                 "[CcuKernelMgr][%s] dieId[%u] not enough, msReq[%u] blockMsReq[%u] ckeReq[%u]"
     322              :                 "blockCkeReq[%u] loopEngineReq[%u] blockLoopEngineReq[%u] gsaReq[%u] blockGsaReq[%u] xnReq[%u]"
     323              :                 "blockXnReq[%u] missionReq[%u].",
     324              :                 __func__, i, needResReq.msReq[i], needResReq.blockMsReq[i], needResReq.ckeReq[i],
     325              :                 needResReq.blockCkeReq[i], needResReq.loopEngineReq[i], needResReq.blockLoopEngineReq[i],
     326              :                 needResReq.gsaReq[i], needResReq.blockGsaReq[i], needResReq.xnReq[i], needResReq.blockXnReq[i],
     327              :                 needResReq.missionReq.req[i]);
     328            0 :             return false;
     329              :         }
     330              :     }
     331              : 
     332           47 :     return true;
     333              : }
     334              : 
     335         1034 : static void MoveResInfo(std::vector<ResInfo>& dest, std::vector<ResInfo>& source, const uint32_t resNum)
     336              : {
     337              :     // Register 前序流程已检查资源不足场景
     338         1034 :     if (resNum == 0) {
     339          907 :         return;
     340              :     }
     341              : 
     342          127 :     dest.clear();
     343          127 :     auto iter = source.begin();
     344          127 :     uint32_t remain = resNum;
     345          254 :     while (remain > 0 && iter != source.end()) {
     346          127 :         auto& srcBlock = *iter;
     347          127 :         const uint32_t take = std::min(remain, srcBlock.num);
     348          127 :         dest.emplace_back(srcBlock.startId, take);
     349              : 
     350          127 :         if (take == srcBlock.num) {
     351              :             // 完全用掉这个资源,source中移除
     352            1 :             iter = source.erase(iter);
     353              :         } else {
     354              :             // 只用了部分,更新source中的资源
     355          126 :             srcBlock.startId += take;
     356          126 :             srcBlock.num -= take;
     357              :         }
     358              : 
     359          127 :         remain -= take; // 更新剩余需要的资源数量
     360              :     }
     361              : }
     362              : 
     363           47 : static void LoadRes(std::unique_ptr<CcuKernel>& kernel, CcuResPack& resPack)
     364              : {
     365           47 :     const CcuResReq& resReq = kernel->GetResourceRequest();
     366           47 :     CcuResRepository& totalResRepo = resPack.GetCcuResRepo();
     367         1081 :     CcuResRepository kernelResRepo{};
     368              : 
     369          141 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) { // todo: 建议改成dieId
     370           94 :         MoveResInfo(kernelResRepo.loopEngine[i], totalResRepo.loopEngine[i], resReq.loopEngineReq[i]);
     371           94 :         MoveResInfo(kernelResRepo.blockLoopEngine[i], totalResRepo.blockLoopEngine[i], resReq.blockLoopEngineReq[i]);
     372           94 :         MoveResInfo(kernelResRepo.ms[i], totalResRepo.ms[i], resReq.msReq[i]);
     373           94 :         MoveResInfo(kernelResRepo.blockMs[i], totalResRepo.blockMs[i], resReq.blockMsReq[i]);
     374           94 :         MoveResInfo(kernelResRepo.cke[i], totalResRepo.cke[i], resReq.ckeReq[i]);
     375           94 :         MoveResInfo(kernelResRepo.blockCke[i], totalResRepo.blockCke[i], resReq.blockCkeReq[i]);
     376           94 :         MoveResInfo(kernelResRepo.blockXn[i], totalResRepo.blockXn[i], resReq.blockXnReq[i]);
     377           94 :         MoveResInfo(kernelResRepo.xn[i], totalResRepo.xn[i], resReq.xnReq[i]);
     378           94 :         MoveResInfo(kernelResRepo.gsa[i], totalResRepo.gsa[i], resReq.gsaReq[i]);
     379           94 :         MoveResInfo(kernelResRepo.blockGsa[i], totalResRepo.blockGsa[i], resReq.blockGsaReq[i]);
     380           94 :         MoveResInfo(kernelResRepo.mission.mission[i], totalResRepo.mission.mission[i], resReq.missionReq.req[i]);
     381              :     }
     382              : 
     383           47 :     kernel->SetResRepository(kernelResRepo);
     384           47 : }
     385              : 
     386              : // 指令空间区域大小的唯一计算入口:
     387              : //   裸指令数 (rep InstrCount 累加) + 翻译器结构指令 (GetInstrNum) + 常量赋值指令
     388              : //   + 每个会翻译出 waitCKEId!=0 && clearType=1 的 set/clearCKE 的 rep 预留 CCU_CKE_RAW_LATENCY 条
     389              : //     NOP 空间 (计入集合见 CcuKernel::GetRepNeedToAddLatency / IsCkeWaitRep: 三种 wait 类 +
     390              : //     LOAD/LOAD_VAR/STORE/STORE_VAR/RECORD_SHARED_NOTIFY).
     391              : // 后端优化 cke-only 档只会为 CKE 写后读补 NOP, 每个此类 rep 最多补 (latency-1) 条,
     392              : // 故此预留可从构造上保证优化后指令数不超过申请区. 申请 / 查询 / 释放三处必须走本函数,
     393              : // 保证口径一致 (尤其申请与释放必须完全相等).
     394          150 : static uint32_t ComputeKernelInstrRegionSize(CcuKernel* kernel, const int32_t devLogicId)
     395              : {
     396          150 :     return kernel->GetInstrCount() + CcuRep::CcuRepTranslator::GetInstrNum(devLogicId)
     397          150 :            + static_cast<uint32_t>(kernel->GetConstValue2VarMap().size())
     398          150 :            + kernel->GetRepNeedToAddLatency() * CcuRep::CCU_CKE_RAW_LATENCY;
     399              : }
     400              : 
     401           47 : static CcuResult AllocInstrRes(std::unique_ptr<CcuKernel>& kernel, const int32_t devLogicId)
     402              : {
     403           47 :     const uint32_t instrCount = ComputeKernelInstrRegionSize(kernel.get(), devLogicId);
     404           47 :     const uint32_t dieId = kernel->GetDieId();
     405           47 :     ResInfo insInfo(0, 0);
     406           47 :     CCU_CHK_RET(CcuDevMgrImp::AllocIns(devLogicId, dieId, instrCount, insInfo));
     407           47 :     HCCL_INFO(
     408              :         "[CcuKernelMgr][%s]: devLogicId[%d], dieId[%u], startId[%u], count[%u]", __func__, devLogicId, dieId,
     409              :         insInfo.startId, insInfo.num);
     410           47 :     kernel->SetInstrId(insInfo.startId);
     411              : 
     412           47 :     return CcuResult::CCU_SUCCESS;
     413              : }
     414              : 
     415           57 : CcuResult CcuKernelMgr::PrepareConstValueResources()
     416              : {
     417              :     // insGenerator统计rep中常量,并填写当前kernel的常量表,当前只有A6有对应处理,A5没有常量处理需求
     418           57 :     CCU_CHK_PTR_NULL(currKernel_);
     419           57 :     const auto& repVec = currKernel_->GetRepSequence();
     420              : 
     421           57 :     const auto& translator = translators[currKernel_->GetDieId()][0];
     422           57 :     CCU_CHK_PTR_NULL(translator);
     423           57 :     const auto& transDep = translator->GetTransDep(); // 此时未分配missionid,取0对应的transDep读取常量
     424           57 :     CCU_CHK_PTR_NULL(insGenePtr);
     425         1169 :     for (uint32_t index = 0; index < repVec.size(); index++) {
     426         1112 :         const auto& curRepType = repVec[index]->Type();
     427         1112 :         CcuRep::CcuRepBase* curRepPtr = repVec[index].get();
     428         1112 :         CCU_CHK_PTR_NULL(curRepPtr);
     429         1112 :         HCCL_DEBUG("Current rep[%d] ptr[%p] repType[%d]", index, curRepPtr, curRepType);
     430              : 
     431              :         // 遍历每个rep,包括repBlock中的每个rep,将常量资源需求记录在currkernel中
     432         1112 :         CCU_CHK_RET(insGenePtr->PrepareConstValue(curRepPtr, transDep, currKernel_.get()));
     433         1112 :         if (curRepType == CcuRep::CcuRepType::BLOCK || curRepType == CcuRep::CcuRepType::FUNC_BLOCK
     434         1108 :             || curRepType == CcuRep::CcuRepType::LOOP_BLOCK) {
     435           48 :             CcuRep::CcuRepBlock* curRepBlockPtr = static_cast<CcuRep::CcuRepBlock*>(curRepPtr);
     436           48 :             CCU_CHK_PTR_NULL(curRepBlockPtr);
     437          126 :             for (const auto& repInBlock : curRepBlockPtr->GetReps()) {
     438           78 :                 CCU_CHK_RET(insGenePtr->PrepareConstValue(repInBlock.get(), transDep, currKernel_.get()));
     439              :             }
     440              :         }
     441              :     }
     442           57 :     return CcuResult::CCU_SUCCESS;
     443              : }
     444              : 
     445           47 : CcuResult CcuKernelMgr::AllocRes(CcuResPack& resPack)
     446              : {
     447           47 :     CcuResReq leftRes{};
     448           47 :     GetResNumFromResPack(resPack, leftRes);
     449              : 
     450           47 :     const CcuResReq& resReq = currKernel_->GetResourceRequest();
     451              :     // todo: 需要整改,传递资源不足的信息
     452           47 :     if (!CheckResIfAvailable(leftRes, resReq)) {
     453            0 :         HCCL_WARNING("[CcuKernelMgr][%s] resource is not enough.", __func__);
     454            0 :         return CcuResult::CCU_E_UNAVAIL;
     455              :     }
     456              : 
     457              :     // 申请指令空间资源
     458           47 :     CCU_CHK_RET(AllocInstrRes(currKernel_, devLogicId_));
     459              : 
     460              :     // 资源从respack转移至kernel
     461           47 :     LoadRes(currKernel_, resPack);
     462              : 
     463           47 :     return CcuResult::CCU_SUCCESS;
     464              : }
     465              : 
     466              : template <typename T1, typename T2>
     467              : HcclResult
     468         5390 : ResetRepResourceTemplate(std::vector<T1>& resource, const std::vector<T2>& repository, const uint32_t startIndex = 0)
     469              : {
     470         5390 :     if (resource.size() > repository.size() - startIndex) {
     471            0 :         HCCL_ERROR(
     472              :             "[CcuKernelMgr][ResetRepResourceTemplate]resource size[%u] bigger "
     473              :             "repository size[%u] typeid[%s]",
     474              :             resource.size(), repository.size(), typeid(T1).name());
     475            0 :         return HcclResult::HCCL_E_INTERNAL;
     476              :     }
     477              : 
     478        49480 :     for (uint32_t j = 0; j < resource.size(); j++) {
     479        44090 :         resource[j].Reset(repository[j + startIndex].startId);
     480              :     }
     481              : 
     482         5390 :     return HcclResult::HCCL_SUCCESS;
     483              : }
     484              : 
     485              : static HcclResult
     486          245 : ResetRepResourceToResRepository(CcuRepResource& totalRepRes, const CcuResRepository& totalResRepository)
     487              : {
     488              :     // 遍历translatorRepRes, 将每个rep的虚拟资源翻译到实际物理资源上
     489          735 :     for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     490          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.ccubufs[i], totalResRepository.ms[i]));
     491          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.blockCcubufs[i], totalResRepository.blockMs[i]));
     492          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.executor[i], totalResRepository.loopEngine[i]));
     493          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.blockExecutor[i], totalResRepository.blockLoopEngine[i]));
     494          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.completedEvent[i], totalResRepository.cke[i]));
     495          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.blockCompletedEvent[i], totalResRepository.blockCke[i]));
     496          490 :         CHK_RET(ResetRepResourceTemplate(
     497              :             totalRepRes.localNotify[i], totalResRepository.blockCke[i],
     498              :             totalRepRes.blockCompletedEvent[i].size())); // 两类资源都使用cke,需要调整起始分配位置
     499          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.address[i], totalResRepository.gsa[i]));
     500          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.blockAddress[i], totalResRepository.blockGsa[i]));
     501          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.variable[i], totalResRepository.xn[i]));
     502          490 :         CHK_RET(ResetRepResourceTemplate(totalRepRes.continuousVariable[i], totalResRepository.blockXn[i]));
     503              :     }
     504          245 :     return HcclResult::HCCL_SUCCESS;
     505              : }
     506              : 
     507              : using DieResInfos = std::array<std::vector<ResInfo>, CCU_MAX_IODIE_NUM>;
     508           47 : static HcclResult SaveKernelMissionInfo(CcuKernel* kernel, const DieResInfos& missionId, const int32_t devLogicId)
     509              : {
     510           47 :     const uint32_t dieId = kernel->GetDieId();
     511           47 :     uint32_t missionKey{0};
     512           47 :     CHK_RET(CcuDevMgrImp::GetMissionKey(devLogicId, dieId, missionKey));
     513              : 
     514           47 :     HCCL_INFO("[CcuKernelMgr][%s] deviceLogicId[%d] dieId[%u]", __func__, devLogicId, dieId);
     515              : 
     516           47 :     kernel->SetMissionKey(missionKey);
     517              :     // 从missionId中获取一个元素并从missionId中删除,当前应只有一个元素,且无需删除
     518           47 :     if (missionId[dieId].empty()) {
     519            0 :         HCCL_ERROR("[%s] failed, devLogicId[%d] dieId[%u] do not have missions.", __func__, devLogicId, dieId);
     520            0 :         return HcclResult::HCCL_E_INTERNAL;
     521              :     }
     522              : 
     523           47 :     kernel->SetMissionId(missionId[dieId].back().startId);
     524           47 :     return HcclResult::HCCL_SUCCESS;
     525              : }
     526              : 
     527          344 : static void DumpResRepositoryInfo(const CcuResRepository& resRepo)
     528              : {
     529         1032 :     for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     530         1376 :         if (resRepo.ms[i].size() != 0 || resRepo.blockMs[i].size() != 0 || resRepo.cke[i].size() != 0
     531          286 :             || resRepo.blockCke[i].size() != 0 || resRepo.loopEngine[i].size() != 0
     532          283 :             || resRepo.blockLoopEngine[i].size() != 0 || resRepo.gsa[i].size() != 0 || resRepo.blockGsa[i].size() != 0
     533         1376 :             || resRepo.xn[i].size() != 0 || resRepo.blockXn[i].size() != 0 || resRepo.mission.mission[i].size() != 0) {
     534          443 :             HCCL_INFO(
     535              :                 "DumpResRepository: dieId[%u], ms size[%u], blockMs size[%u], cke size[%u], blockCke size[%u], "
     536              :                 "loopEngine size[%u], blockLoopEngine size[%u], gsa size[%u], blockGsa size[%u], xn size[%u], "
     537              :                 "block xn size[%u], mission size[%u]",
     538              :                 i, resRepo.ms[i].size(), resRepo.blockMs[i].size(), resRepo.cke[i].size(), resRepo.blockCke[i].size(),
     539              :                 resRepo.loopEngine[i].size(), resRepo.blockLoopEngine[i].size(), resRepo.gsa[i].size(),
     540              :                 resRepo.blockGsa[i].size(), resRepo.xn[i].size(), resRepo.blockXn[i].size(),
     541              :                 resRepo.mission.mission[i].size());
     542              :         }
     543              :     }
     544          344 : }
     545              : 
     546         7568 : inline void ExpandResInfo(std::vector<ResInfo>& expendResInfos, const std::vector<ResInfo>& resInfos)
     547              : {
     548              :     // 将resInfo中的资源信息还原为单个资源粒度
     549         8529 :     for (auto& resInfo : resInfos) {
     550        66362 :         for (uint32_t id = 0; id < resInfo.num; id++) {
     551        65401 :             expendResInfos.push_back({(resInfo.startId + id), {1}});
     552              :         }
     553              :     }
     554         7568 : }
     555              : 
     556          344 : static CcuResult ExpandResRepo(CcuResRepository& totalRes, const CcuResRepository& tmpResRepository)
     557              : {
     558              :     // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes中
     559         1032 :     for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     560          688 :         ExpandResInfo(totalRes.ms[i], tmpResRepository.ms[i]);
     561          688 :         ExpandResInfo(totalRes.blockMs[i], tmpResRepository.blockMs[i]);
     562          688 :         ExpandResInfo(totalRes.loopEngine[i], tmpResRepository.loopEngine[i]);
     563          688 :         ExpandResInfo(totalRes.blockLoopEngine[i], tmpResRepository.blockLoopEngine[i]);
     564          688 :         ExpandResInfo(totalRes.cke[i], tmpResRepository.cke[i]);
     565          688 :         ExpandResInfo(totalRes.blockCke[i], tmpResRepository.blockCke[i]);
     566          688 :         ExpandResInfo(totalRes.gsa[i], tmpResRepository.gsa[i]);
     567          688 :         ExpandResInfo(totalRes.blockGsa[i], tmpResRepository.blockGsa[i]);
     568          688 :         ExpandResInfo(totalRes.xn[i], tmpResRepository.xn[i]);
     569          688 :         ExpandResInfo(totalRes.blockXn[i], tmpResRepository.blockXn[i]);
     570          688 :         ExpandResInfo(totalRes.mission.mission[i], tmpResRepository.mission.mission[i]);
     571              :     }
     572          344 :     DumpResRepositoryInfo(totalRes);
     573          344 :     return CcuResult::CCU_SUCCESS;
     574              : }
     575              : 
     576              : template <typename T>
     577           47 : static HcclResult MergeExportedResources(
     578              :     const std::unordered_map<std::string, T>& inputRes, std::unordered_map<std::string, T>& outputRes)
     579              : {
     580           47 :     for (const auto& item : inputRes) {
     581            0 :         const auto& resTag = item.first;
     582            0 :         if (outputRes.find(resTag) != outputRes.end()) {
     583            0 :             HCCL_ERROR(
     584              :                 "[CcuKernelMgr][%s] failed, exported resource tag[%s] is already existed, "
     585              :                 "please check.",
     586              :                 __func__, resTag);
     587            0 :             return HcclResult::HCCL_E_PARA;
     588              :         }
     589              : 
     590            0 :         outputRes.insert(item);
     591              :     }
     592              : 
     593           47 :     return HcclResult::HCCL_SUCCESS;
     594              : }
     595              : 
     596              : template <typename T>
     597           47 : static HcclResult ResetImportedResources(
     598              :     std::unordered_map<std::string, T>& importedRes, const std::unordered_map<std::string, T>& exportedRes)
     599              : {
     600           47 :     for (auto& item : importedRes) {
     601            0 :         const auto& resTag = item.first;
     602            0 :         const auto& iter = exportedRes.find(resTag);
     603            0 :         if (iter == exportedRes.end()) {
     604            0 :             HCCL_ERROR("[CcuKernelMgr][%s] failed to find exported resources by tag[%s].", __func__, resTag.c_str());
     605            0 :             return HcclResult::HCCL_E_NOT_FOUND;
     606              :         }
     607              : 
     608            0 :         item.second.Reset(iter->second.Id(), iter->second.DieId());
     609              :     }
     610              : 
     611           47 :     return HcclResult::HCCL_SUCCESS;
     612              : }
     613              : 
     614           47 : static HcclResult ProcessInterCtxRes(const std::vector<CcuKernel*>& kernels)
     615              : {
     616           47 :     std::unordered_map<std::string, CcuRep::LocalNotify> totalExportedNotifies;
     617              : 
     618           94 :     for (const auto kernel : kernels) {
     619           47 :         const auto& exportedRes = kernel->GetExportedRes();
     620           47 :         CHK_RET(MergeExportedResources(exportedRes.sharedNotifies, totalExportedNotifies));
     621              :     }
     622              : 
     623           94 :     for (auto kernel : kernels) {
     624           47 :         auto& importedRes = kernel->GetImportedRes();
     625           47 :         CHK_RET(ResetImportedResources(importedRes.sharedNotifies, totalExportedNotifies));
     626              :     }
     627              : 
     628           47 :     return HcclResult::HCCL_SUCCESS;
     629           47 : }
     630              : 
     631           47 : static HcclResult TransRepResToPhyRes(const std::vector<CcuKernel*>& kernels, const int32_t devLogicId)
     632              : {
     633           94 :     for (auto kernel : kernels) {
     634           47 :         const auto& totalResRepository = kernel->GetResRepository();
     635           47 :         auto& totalRepRes = kernel->GetResource();
     636              : 
     637              :         // 将ccu kernel持有的物理资源赋给资源对象
     638         1081 :         CcuResRepository expandedResRepo{};
     639           47 :         ExpandResRepo(expandedResRepo, totalResRepository);
     640           47 :         CHK_RET(ResetRepResourceToResRepository(totalRepRes, expandedResRepo));
     641              : 
     642           47 :         CHK_RET(SaveKernelMissionInfo(kernel, totalResRepository.mission.mission, devLogicId));
     643           47 :     }
     644              : 
     645           47 :     CHK_RET(ProcessInterCtxRes(kernels));
     646              : 
     647           47 :     return HcclResult::HCCL_SUCCESS;
     648              : }
     649              : 
     650           48 : CcuResult CcuKernelMgr::Translate(const std::vector<CcuKernelHandle>& kernelHandles)
     651              : {
     652           48 :     if (kernelHandles.empty()) {
     653            1 :         HCCL_INFO("[CcuKernelMgr][%s] passed, kernelHandles are empty.", __func__);
     654            1 :         return CcuResult::CCU_SUCCESS;
     655              :     }
     656              : 
     657           47 :     std::vector<CcuKernel*> kernels{};
     658           47 :     std::unique_lock<std::mutex> mapLock(kernelMapMutex_);
     659           94 :     for (const auto kernelHandle : kernelHandles) {
     660           47 :         const auto& iter = kernelMap_.find(kernelHandle);
     661           47 :         if (iter == kernelMap_.end()) {
     662            0 :             HCCL_ERROR(
     663              :                 "[CcuKernelMgr][%s] failed to find kernel by ccu kernel handle[0x%llx].", __func__, kernelHandle);
     664            0 :             return CcuResult::CCU_E_NOT_FOUND;
     665              :         }
     666              : 
     667           47 :         kernels.push_back(iter->second.get());
     668              :     }
     669           47 :     mapLock.unlock();
     670              : 
     671           47 :     constexpr bool isFuncBlock = false; // 当前不支持MC2
     672              : 
     673           47 :     std::unique_lock<std::mutex> translateLock(translateMutex_);
     674           47 :     CCU_CHK_RET(TransRepResToPhyRes(kernels, devLogicId_));
     675           47 :     CCU_CHK_RET(TransRepSequenceToMicrocode(kernels, isFuncBlock));
     676              : 
     677          138 :     for (auto& referenceMgrMap : referenceMgrs) {
     678         1564 :         for (auto& referenceMgr : referenceMgrMap.second) {
     679         1472 :             referenceMgr.second->ClearRepReference();
     680              :         }
     681              :     }
     682           46 :     return CcuResult::CCU_SUCCESS;
     683           47 : }
     684              : 
     685           47 : static HcclResult ReleaseInstrRes(CcuKernel* kernel, const int32_t devLogicId)
     686              : {
     687           47 :     const uint32_t instrCount = ComputeKernelInstrRegionSize(kernel, devLogicId);
     688           47 :     const ResInfo insInfo{kernel->GetInstrId(), instrCount};
     689           47 :     const uint8_t dieId = static_cast<uint8_t>(kernel->GetDieId());
     690           47 :     HCCL_INFO(
     691              :         "[CcuKernelMgr][%s] devLogicId[%d], dieId[%u], startId[%u], count[%u]", __func__, devLogicId, dieId,
     692              :         insInfo.startId, insInfo.num);
     693           47 :     CHK_RET(CcuDevMgrImp::ReleaseIns(devLogicId, dieId, insInfo));
     694              : 
     695           47 :     return HcclResult::HCCL_SUCCESS;
     696              : }
     697              : 
     698           47 : CcuResult CcuKernelMgr::UnRegister(CcuKernelHandle kernelHandle)
     699              : {
     700           47 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
     701              : 
     702              :     // 校验kernelMap_中是否存在executorId对应的kernel
     703           47 :     auto it = kernelMap_.find(kernelHandle);
     704           47 :     CHK_PRT_RET(
     705              :         it == kernelMap_.end(),
     706              :         HCCL_ERROR("[CcuKernelMgr][%s] kernelHandle [%llu] does not exist", __func__, kernelHandle),
     707              :         CcuResult::CCU_E_NOT_FOUND);
     708              : 
     709           47 :     auto kernel = it->second.get();
     710           47 :     CCU_CHK_RET(ReleaseInstrRes(kernel, devLogicId_));
     711           47 :     kernelMap_.erase(kernelHandle);
     712           47 :     return CcuResult::CCU_SUCCESS;
     713           47 : }
     714              : 
     715          198 : HcclResult CcuKernelMgr::GetResPackTotalResRepository(
     716              :     const CcuKernelMgr::CcuTranslatResPack& resPack, CcuResRepository& totalRes) const
     717              : {
     718         4554 :     CcuResRepository tmpResRepository{};
     719              :     // 获取通信域当前所持有的资源
     720          495 :     for (CcuResHandle resHandle : resPack.handles) {
     721          297 :         CHK_RET(CcuDevMgrImp::GetResource(devLogicId_, resHandle, tmpResRepository));
     722          297 :         ExpandResRepo(totalRes, tmpResRepository);
     723          297 :         HCCL_INFO("[%s] succeed, deviceLogicId[%d] resHandle[%p].", __func__, devLogicId_, resHandle);
     724              :     }
     725          198 :     return HcclResult::HCCL_SUCCESS;
     726          198 : }
     727              : 
     728         6336 : static void MergeCcuResReq(CcuResReq& resReqA, const CcuResReq& resReqB)
     729              : {
     730              :     // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes的第0个vector中
     731        19008 :     for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     732        12672 :         resReqA.msReq[i] += resReqB.msReq[i];
     733        12672 :         resReqA.blockMsReq[i] += resReqB.blockMsReq[i];
     734        12672 :         resReqA.ckeReq[i] += resReqB.ckeReq[i];
     735        12672 :         resReqA.blockCkeReq[i] += resReqB.blockCkeReq[i];
     736        12672 :         resReqA.loopEngineReq[i] += resReqB.loopEngineReq[i];
     737        12672 :         resReqA.blockLoopEngineReq[i] += resReqB.blockLoopEngineReq[i];
     738        12672 :         resReqA.gsaReq[i] += resReqB.gsaReq[i];
     739        12672 :         resReqA.blockGsaReq[i] += resReqB.blockGsaReq[i];
     740        12672 :         resReqA.xnReq[i] += resReqB.xnReq[i];
     741        12672 :         resReqA.blockXnReq[i] += resReqB.blockXnReq[i];
     742        12672 :         resReqA.missionReq.req[i] += resReqB.missionReq.req[i];
     743              : 
     744        12672 :         if (resReqB.missionReq.req[i] > 0) {
     745            0 :             resReqA.missionReq.reqType = resReqB.missionReq.reqType;
     746              :         }
     747              :     }
     748         6336 : }
     749              : 
     750          198 : HcclResult CcuKernelMgr::InstantiationTranslator(const uint16_t dieId)
     751              : {
     752          198 :     if (translators.find(dieId) != translators.end()) {
     753            0 :         return HcclResult::HCCL_SUCCESS;
     754              :     }
     755              : 
     756          198 :     std::array<uint16_t, CCU_MAX_IODIE_NUM> tmpChannelId{};
     757          198 :     uint32_t channelId = 0;
     758              :     // 获取innerDieChannelId
     759          198 :     auto ret = CcuDevMgrImp::GetLoopChannelId(devLogicId_, dieId, dieId, channelId);
     760          198 :     CHK_RET(ret);
     761              : 
     762          198 :     tmpChannelId[0] = channelId;
     763              :     // 获取interDieChannelId
     764          198 :     uint8_t dstDieId = ((dieId == 0) ? 1 : 0);
     765          198 :     ret = CcuDevMgrImp::GetLoopChannelId(devLogicId_, dieId, dstDieId, channelId);
     766          198 :     CHK_RET(ret);
     767          198 :     tmpChannelId[1] = channelId;
     768              : 
     769          198 :     uint64_t tokenId = 0;
     770          198 :     uint64_t tokenValue = 0;
     771          198 :     ret = CcuDevMgrImp::GetCcuResourceSpaceTokenInfo(devLogicId_, dieId, tokenId, tokenValue);
     772          198 :     CHK_RET(ret);
     773              : 
     774          198 :     std::pair<uint64_t, uint64_t> ccuTokenInfo(tokenId, tokenValue);
     775          198 :     Hccl::DevBuffer tmpDevMem{1}; // 临时申请device hbm内存用于查询token信息
     776          198 :     auto hbmTokenInfo = hcomm::CcuRep::GetTokenInfo(tmpDevMem.GetAddr(), 1);
     777              : 
     778          198 :     CcuResReq totalResReq{};
     779              :     // 实例化CcuRepReferenceManager和CcuRepTranslator,并为CcuRepReferenceManager绑定物理资源
     780         3366 :     for (uint32_t i = 0; i < 16; i++) { // mgr有16个
     781         3168 :         referenceMgrs[dieId][i] = std::make_shared<hcomm::CcuRep::CcuRepReferenceManager>(dieId);
     782         6336 :         translators[dieId][i] = std::make_shared<hcomm::CcuRep::CcuRepTranslator>(
     783         6336 :             devLogicId_, dieId, referenceMgrs[dieId][i], tmpChannelId, ccuTokenInfo, hbmTokenInfo);
     784              : 
     785              :         // 统计&合并refManager和translator所有资源REQ
     786         3168 :         auto refMangerResReq = CcuRep::CcuRepReferenceManager::GetResReq(dieId);
     787         3168 :         auto transLatorResReq = CcuRep::CcuRepTranslator::GetResReq(devLogicId_, dieId);
     788         3168 :         MergeCcuResReq(totalResReq, refMangerResReq);
     789         3168 :         MergeCcuResReq(totalResReq, transLatorResReq);
     790              :     }
     791          198 :     DumpResReqInfo(totalResReq);
     792              : 
     793              :     // 为refManager和translator申请物理资源
     794              :     CcuResHandle handle;
     795          198 :     CHK_RET(CcuDevMgrImp::AllocResHandle(devLogicId_, totalResReq, handle));
     796          198 :     translatorResPack.handles.push_back(handle);
     797              : 
     798          198 :     CcuRepResource translatorRepRes;
     799         3366 :     for (uint32_t i = 0; i < 16; i++) { // mgr有16个
     800         3168 :         referenceMgrs[dieId][i]->GetRes(translatorRepRes);
     801         3168 :         translators[dieId][i]->GetRes(translatorRepRes);
     802              :     }
     803              : 
     804          198 :     CcuResRepository totalResRepository;
     805          198 :     CHK_RET(GetResPackTotalResRepository(translatorResPack, totalResRepository));
     806              :     // 将kernel中的rep虚拟资源按类型进行和CCU物理资源映射
     807          198 :     CHK_RET(ResetRepResourceToResRepository(translatorRepRes, totalResRepository));
     808          198 :     return HcclResult::HCCL_SUCCESS;
     809          198 : }
     810              : 
     811           46 : HcclResult CcuKernelMgr::LoadInstruction(const CcuRep::CcuInstrInfo& instrInfo, const uint32_t dieId)
     812              : {
     813           46 :     const uint64_t instrInfoSize = instrInfo.instrVec.size() * sizeof(hcomm::CcuRep::CcuInstr);
     814              : 
     815           46 :     if (!instructionLoadDevMem_) {
     816           20 :         uint32_t instrNum = 0;
     817           20 :         CHK_RET(CcuDevMgrImp::GetResSpecsInstructionNum(devLogicId_, 0, instrNum));
     818           20 :         HCCL_INFO("[CcuKernelMgr]LoadInstruction: deviceLogicId[%d], instrNum[%u]", devLogicId_, instrNum);
     819           20 :         CHK_RET(hrtMalloc(&instructionLoadDevMem_, instrNum * sizeof(hcomm::CcuRep::CcuInstr)));
     820              :     }
     821              : 
     822           46 :     CHK_RET(hrtMemcpy(
     823              :         instructionLoadDevMem_, instrInfoSize, instrInfo.instrVec.data(), instrInfoSize,
     824              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     825              : 
     826           46 :     uint32_t devPhyId = 0;
     827           46 :     CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(devLogicId_), devPhyId));
     828              : 
     829           46 :     CustomChannelInfoIn inBuff{};
     830           46 :     CustomChannelInfoOut outBuff{};
     831              : 
     832              :     // 设置操作码和通道数据
     833           46 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_INSTRUCTION;
     834           46 :     inBuff.offsetStartIdx = instrInfo.startInstrId;
     835           46 :     inBuff.data.dataInfo.udieIdx = dieId;
     836           46 :     inBuff.data.dataInfo.dataArraySize = 1;
     837           46 :     inBuff.data.dataInfo.dataLen = instrInfoSize;
     838              : 
     839           46 :     CcuDataTypeUnion tmp{};
     840           46 :     tmp.insinfo.resourceAddr = reinterpret_cast<uint64_t>(instructionLoadDevMem_);
     841           46 :     (void)memcpy_s(inBuff.data.dataInfo.dataArray, sizeof(CcuDataTypeUnion), &tmp, sizeof(CcuDataTypeUnion));
     842              : 
     843           46 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
     844           46 :     if (ret != HCCL_SUCCESS) {
     845            0 :         HCCL_ERROR(
     846              :             "[CcuResSpecifications][%s] failed to call ccu driver, "
     847              :             "devLogicId[%d] devPhyId[%u] dieId[%d] op[%s] ret[%d].",
     848              :             __func__, devLogicId_, devPhyId, dieId, "SET_INSTRUCTION", ret);
     849            0 :         return ret;
     850              :     }
     851              : 
     852           46 :     return HcclResult::HCCL_SUCCESS;
     853              : }
     854              : 
     855           47 : HcclResult CcuKernelMgr::TransRepSequenceToMicrocode(const std::vector<CcuKernel*>& kernels, bool isFuncBlock)
     856              : {
     857           93 :     for (auto kernel : kernels) {
     858           47 :         const uint32_t dieId = kernel->GetDieId();
     859           47 :         const uint32_t missionId = kernel->GetMissionId();
     860              : 
     861              :         EXCEPTION_HANDLE_BEGIN
     862           48 :         const auto& instrInfo = translators[dieId][missionId]->Translate(
     863           47 :             kernel, kernel->GetRepSequence(), kernel->GetInstrId(), isFuncBlock);
     864              : 
     865              :         // 后端优化会插 NOP 改变指令数; 按与申请同一口径校验不越界, 把静默越界变成快速失败.
     866           46 :         const uint32_t regionSize = ComputeKernelInstrRegionSize(kernel, devLogicId_);
     867           46 :         CHK_PRT_RET(
     868              :             instrInfo.instrVec.size() > regionSize,
     869              :             HCCL_ERROR(
     870              :                 "[CcuKernelMgr][%s] optimized instr count[%zu] exceeds reserved region size[%u], "
     871              :                 "dieId[%u] startId[%u]. Check cke reservation / backend optimizer NOP insertion.",
     872              :                 __func__, instrInfo.instrVec.size(), regionSize, dieId, kernel->GetInstrId()),
     873              :             HcclResult::HCCL_E_INTERNAL);
     874              : 
     875           46 :         CHK_RET(LoadInstruction(instrInfo, dieId));
     876              : 
     877           46 :         kernel->SetCcuInstrInfo(instrInfo); // 指令下发成功后可以对kernel进行launch
     878           47 :         EXCEPTION_HANDLE_END
     879              :     }
     880              : 
     881           46 :     return HcclResult::HCCL_SUCCESS;
     882              : }
     883              : 
     884           20 : CcuKernel* CcuKernelMgr::GetKernel(CcuKernelHandle kernelHandle)
     885              : {
     886           20 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
     887           20 :     auto it = kernelMap_.find(kernelHandle);
     888           20 :     if (it == kernelMap_.end()) {
     889            4 :         HCCL_ERROR("[CcuKernelMgr][%s] handle[%llx] is not existed.", __func__, kernelHandle);
     890            4 :         return nullptr;
     891              :     }
     892              : 
     893           16 :     return it->second.get();
     894           20 : }
     895              : 
     896            4 : CcuResult CcuKernelMgr::GetCcuKernelInfo(CcuKernelHandle kernelHandle, CcuKernelInfo& info)
     897              : {
     898            4 :     std::unique_lock<std::mutex> lock(kernelMapMutex_);
     899            4 :     auto it = kernelMap_.find(kernelHandle);
     900            4 :     if (it == kernelMap_.end()) {
     901            1 :         HCCL_ERROR("[CcuKernelMgr][%s] handle[%llx] is not existed.", __func__, kernelHandle);
     902            1 :         return CcuResult::CCU_E_NOT_FOUND;
     903              :     }
     904              :     // 在锁内填充 info,避免裸指针逃逸锁后 kernel 被 UnRegister 导致 use-after-free
     905            3 :     CCU_CHK_RET(it->second->GetCcuKernelInfo(info));
     906            3 :     return CcuResult::CCU_SUCCESS;
     907            4 : }
     908              : 
     909         2443 : CcuKernel* CcuKernelMgr::GetCurrentKernel() { return currKernel_.get(); }
     910              : 
     911              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1