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: 89.8 % 500 449
Test Date: 2026-08-18 17:47:01 Functions: 97.8 % 46 45

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

Generated by: LCOV version 2.0-1