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

Generated by: LCOV version 2.0-1