LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_context - ccu_context_mgr_imp.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.3 % 419 370
Test Date: 2026-07-28 12:11:00 Functions: 94.9 % 39 37

            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_context_mgr_imp.h"
      12              : 
      13              : #include <unordered_set>
      14              : 
      15              : #include "ccu_ctx_mgr.h"
      16              : #include "ccu_res_pack.h"
      17              : 
      18              : #include "hccl_common_v2.h"
      19              : #include "orion_adapter_rts.h"
      20              : #include "exception_util.h"
      21              : #include "ccu_api_exception.h"
      22              : #include "orion_adapter_hccp.h"
      23              : #include "ccu_assist.h"
      24              : #include "dev_buffer.h"
      25              : #include "hccp_tlv_hdc_manager.h"
      26              : 
      27              : #ifdef HCCL_ALG_ANALYZER_DAVID
      28              : #include "instruction.h"
      29              : #endif
      30              : 
      31              : 
      32              : namespace Hccl {
      33           66 : CtxMgrImp::CtxMgrImp()
      34              : {
      35           66 : }
      36              : 
      37           66 : CtxMgrImp::~CtxMgrImp()
      38              : {
      39           66 :     if (initializedFlag_) {
      40            0 :         HCCL_INFO("[CtxMgrImp]~CtxMgrImp: deviceLogicId[%d], free addr[%p]", deviceLogicId_, instructionLoadDevMem_);
      41            0 :         if (instructionLoadDevMem_ != nullptr) {
      42            0 :             DECTOR_TRY_CATCH("CtxMgrImp", HrtFree(instructionLoadDevMem_));
      43            0 :             instructionLoadDevMem_ = nullptr;
      44              :         }
      45            0 :         ctxGroupMap_.clear();
      46            0 :         initializedFlag_ = false;
      47              :     }
      48           66 : }
      49              : 
      50           51 : CtxMgrImp &CtxMgrImp::GetInstance(s32 deviceLogicId)
      51              : {
      52          117 :     static CtxMgrImp contextManager[MAX_MODULE_DEVICE_NUM + 1];
      53              : 
      54           51 :     if (deviceLogicId < 0 || static_cast<u32>(deviceLogicId) > MAX_MODULE_DEVICE_NUM) {
      55            0 :         THROW<CcuApiException>("ProcessSharedResources failed deviceLogicId[%d]", deviceLogicId);
      56              :     }
      57              : 
      58           51 :     contextManager[deviceLogicId].deviceLogicId_ = deviceLogicId;
      59           51 :     return contextManager[deviceLogicId];
      60              : }
      61              : 
      62            0 : void CtxMgrImp::Init()
      63              : {
      64            0 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
      65            0 :     if (initializedFlag_) {
      66            0 :         return;
      67              :     }
      68              : 
      69            0 :     initializedFlag_ = true;
      70            0 :     ctxGroupMap_.clear();
      71            0 : }
      72              : 
      73            2 : void CtxMgrImp::Deinit()
      74              : {
      75            2 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
      76            2 :     translatorResPack.handles.clear();
      77            2 :     translatorResPack.count = 0;
      78            2 :     initializedFlag_ = false;
      79            2 :     ctxGroupMap_.clear();
      80            2 :     translators.clear();
      81            2 :     referenceMgrs.clear();
      82            2 : }
      83              : 
      84            3 : HcclResult CtxMgrImp::AllocRes(CcuCtxGroup &ctxGroup, CcuResPack &resPack)
      85              : {
      86            3 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
      87              :     // 初始化ctx
      88            3 :     CtxInit(ctxGroup);
      89              : 
      90              :     // 获取ctxGroup使用到的所有dieId
      91            3 :     std::unordered_set<uint16_t> usedDieId;
      92            9 :     for (const auto &ctx : ctxGroup.ctxs) {
      93            6 :         usedDieId.insert(ctx->GetDieId());
      94              :     }
      95            7 :     for (auto dieId : usedDieId) {
      96              :         // 实例化translator,并且为RefManager和translator申请&绑定资源
      97            4 :         CHK_RET_UNAVAIL(InstantiationTranslator(dieId));
      98              :     }
      99              : 
     100              :     // 获取通信域当前所持有的资源
     101            3 :     CcuResReq totalRes;
     102            3 :     CHK_RET(GetResPackTotalResNum(resPack, totalRes));
     103              : 
     104              :     // 计算本次编排逻辑所需的资源
     105            3 :     CcuResReq resReq = GetCtxGroupResReq(ctxGroup);
     106              : 
     107              :     // 比较额外需要的资源
     108            3 :     CHK_RET_UNAVAIL(CompareResAndApplyAsNeeded(totalRes, resReq, resPack));
     109              : 
     110              :     // 申请指令空间资源
     111            3 :     CHK_RET_UNAVAIL(AllocInstrRes(ctxGroup));
     112              : 
     113              :     // 保存本次编排的资源信息到Ctx中
     114            3 :     resPack.count++;
     115            3 :     SaveResPackToCtx(ctxGroup, resPack);
     116            9 :     HCCL_INFO("[CtxMgrImp:%s]cur resPack count[%u], resHandle[%u], handle size[%u]",  __func__, resPack.count, resPack.GetId(), resPack.handles.size());
     117            3 :     return HcclResult::HCCL_SUCCESS;
     118            3 : }
     119              : 
     120              : // 在外侧调用的UnRegister函数中已加锁,所以当前函数不需要加锁
     121            2 : HcclResult CtxMgrImp::ReleaseRes(CcuCtxGroup &ctxGroup) const
     122              : {
     123              :     // 获取本次编排Ctx多对应的资源信息
     124            2 :     CcuResPack *resPack = ctxGroup.ctxs[0]->GetResPack();
     125            2 :     CHK_PTR_NULL(resPack);
     126            6 :     HCCL_INFO("[CtxMgrImp:%s]cur resPack count[%u], resHandle[%u], handle size[%u]",  __func__, resPack->count, resPack->GetId(), resPack->handles.size());
     127            2 :     if(resPack->count > 0) {
     128            2 :         resPack->count--;
     129              :     }
     130              : 
     131              :     // 释放资源
     132            2 :     if (resPack->count == 0) {
     133            4 :         for (CcuResHandle resHandle : resPack->handles) {
     134            6 :             HCCL_INFO("[CtxMgrImp]ReleaseRes: deviceLogicId[%d], resHandle[%p]", deviceLogicId_, resHandle);
     135            2 :             CHK_RET(CcuDeviceManager::ReleaseResHandle(deviceLogicId_, resHandle));
     136              :         }
     137              :     }
     138              : 
     139            2 :     return HcclResult::HCCL_SUCCESS;
     140              : }
     141              : 
     142            3 : uint64_t CtxMgrImp::Register(CcuCtxGroup &ctxGroup, bool isFuncBlock)
     143              : {
     144              :     // 多通信域场景需要加锁
     145            3 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
     146              : 
     147              :     // REP编排虚拟资源和实际物理资源映射关联
     148            3 :     TransRepResToPhyRes(ctxGroup);
     149              : 
     150              :     // 构造翻译器,翻译本次编排的ctxGroup
     151            3 :     TransRepSequenceToMicrocode(ctxGroup, isFuncBlock);
     152              : 
     153              :     // 保存本次编排的ctxGroup和exeutorId关联关系
     154            3 :     executorId_++; // executorId_ = executorId_ > UINT64_MAX ? 0 : executorId_++;
     155            3 :     ctxGroupMap_[executorId_] = std::move(ctxGroup);
     156              :     // 清除referenceMgr中保存的引用关系
     157            7 :     for (auto &referenceMgrMap : referenceMgrs) {
     158           68 :         for (auto &referenceMgr : referenceMgrMap.second) {
     159           64 :             referenceMgr.second->ClearRepReference();
     160              :         }
     161              :     }
     162            3 :     return executorId_;
     163            3 : }
     164              : 
     165            9 : HcclResult CtxMgrImp::UnRegister(const uint64_t executorId)
     166              : {
     167            9 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
     168              : 
     169              :     // 校验ctxGroupMap_中是否存在executorId对应的ctxGroup
     170           30 :     CHK_PRT_RET(ctxGroupMap_.find(executorId) == ctxGroupMap_.end(),
     171              :                 HCCL_ERROR("[CtxMgrImp][UnRegister]executorId [%llu] is not exist", executorId),
     172              :                 HcclResult::HCCL_E_NOT_FOUND);
     173              : 
     174              :     // 释放指令空间
     175            2 :     ReleaseInstrRes(ctxGroupMap_[executorId]);
     176              : 
     177              :     // 尝试释放掉ctx对应的handle
     178            2 :     CHK_RET(ReleaseRes(ctxGroupMap_[executorId]));
     179              : 
     180            2 :     ctxGroupMap_.erase(executorId);
     181              : 
     182            2 :     return HcclResult::HCCL_SUCCESS;
     183            9 : }
     184              : 
     185            8 : std::vector<std::vector<CcuTaskParam>> CtxMgrImp::GetTaskParam(CcuTaskArg &ccuTaskArg, const uint64_t executorId)
     186              : {
     187              :     // 根据executorId获取ctxGroup
     188            8 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
     189              : 
     190              :     // 校验ctxGroupMap_中是否存在executorId对应的ctxGroup
     191            8 :     CHK_PRT_RET(ctxGroupMap_.find(executorId) == ctxGroupMap_.end(),
     192              :                 HCCL_ERROR("[CtxMgrImp][GetTaskParam]executorId [%llu] is not exist", executorId),
     193              :                 std::vector<std::vector<CcuTaskParam>>());
     194              : 
     195              :     // 获取每个ctx的taskParam信息
     196            8 :     std::vector<std::vector<CcuTaskParam>> taskParam;
     197           12 :     for (auto &ctx : ctxGroupMap_[executorId].ctxs) {
     198           10 :         std::vector<CcuTaskParam> tmp;
     199           10 :         auto ret = ctx->GeneTaskParam(ccuTaskArg, tmp);
     200            4 :         if (ret != HcclResult::HCCL_SUCCESS) {
     201            0 :             THROW<CcuApiException>("GeneTaskParam is failed. ret[%d]", ret);
     202              :         }
     203            4 :         taskParam.push_back(tmp);
     204           10 :     }
     205              : 
     206            2 :     return taskParam;
     207           14 : }
     208              : 
     209              : // ctx初始化
     210            3 : void CtxMgrImp::CtxInit(CcuCtxGroup &ctxGroup) const
     211              : {
     212            9 :     for (auto &ctx : ctxGroup.ctxs) {
     213              :         // 初始化ctx
     214            6 :         CHK_PRT_RET_NULL(ctx->Init(), HCCL_ERROR("Init failed"));
     215              :     }
     216            3 :     return;
     217              : }
     218              : 
     219              : // 申请指令空间资源
     220            3 : HcclResult CtxMgrImp::AllocInstrRes(CcuCtxGroup &ctxGroup) const
     221              : {
     222            9 :     for (auto &ctx : ctxGroup.ctxs) {
     223            6 :         ResInfo  insInfo(0, 0);
     224            6 :         uint32_t instrCount = ctx->GetInstrCount() + CcuRepTranslator::GetInstrNum();
     225            6 :         CHK_RET_UNAVAIL(CcuDeviceManager::AllocIns(deviceLogicId_, ctx->GetDieId(), instrCount, insInfo));
     226           18 :         HCCL_INFO("[CtxMgrImp]AllocInstrRes: deviceLogicId[%d], dieId[%u], startId[%u], count[%u]", deviceLogicId_,
     227              :                    ctx->GetDieId(), insInfo.startId, insInfo.num);
     228            6 :         ctx->SetInstrId(insInfo.startId);
     229              :     }
     230              : 
     231            3 :     return HcclResult::HCCL_SUCCESS;
     232              : }
     233              : 
     234              : // 释放指令空间资源
     235            2 : HcclResult CtxMgrImp::ReleaseInstrRes(CcuCtxGroup &ctxGroup) const
     236              : {
     237            6 :     for (auto &ctx : ctxGroup.ctxs) {
     238            4 :         ResInfo insInfo(ctx->GetInstrId(), (ctx->GetInstrCount() + CcuRepTranslator::GetInstrNum()));
     239           12 :         HCCL_INFO("[CtxMgrImp]ReleaseInstrRes: deviceLogicId[%d], dieId[%u], startId[%u], count[%u]", deviceLogicId_,
     240              :                    ctx->GetDieId(), insInfo.startId, insInfo.num);
     241            4 :         CHK_RET(CcuDeviceManager::ReleaseIns(deviceLogicId_, ctx->GetDieId(), insInfo));
     242              :     }
     243              : 
     244            2 :     return HcclResult::HCCL_SUCCESS;
     245              : }
     246              : 
     247            3 : HcclResult CtxMgrImp::GetResPackTotalResNum(const CcuResPack &resPack, CcuResReq &totalRes) const
     248              : {
     249            3 :     CcuResRepository tmpResRepository;
     250              : 
     251              :     // 获取通信域当前所持有的资源
     252            3 :     for (CcuResHandle resHandle : resPack.handles) {
     253            0 :         CHK_RET(CcuDeviceManager::GetResource(deviceLogicId_, resHandle, tmpResRepository));
     254              : 
     255              :         // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes的第0个vector中
     256            0 :         for (u32 i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     257            0 :             totalRes.msReq[i] += GetResTotalNum(tmpResRepository.ms[i]);
     258            0 :             totalRes.blockMsReq[i] += GetResTotalNum(tmpResRepository.blockMs[i]);
     259            0 :             totalRes.ckeReq[i] += GetResTotalNum(tmpResRepository.cke[i]);
     260            0 :             totalRes.blockCkeReq[i] += GetResTotalNum(tmpResRepository.blockCke[i]);
     261            0 :             totalRes.loopEngineReq[i] += GetResTotalNum(tmpResRepository.loopEngine[i]);
     262            0 :             totalRes.blockLoopEngineReq[i] += GetResTotalNum(tmpResRepository.blockLoopEngine[i]);
     263            0 :             totalRes.gsaReq[i] += GetResTotalNum(tmpResRepository.gsa[i]);
     264            0 :             totalRes.xnReq[i] += GetResTotalNum(tmpResRepository.xn[i]);
     265            0 :             totalRes.continuousXnReq[i] += GetResTotalNum(tmpResRepository.continuousXn[i]);
     266            0 :             totalRes.missionReq.req[i] += GetResTotalNum(tmpResRepository.mission.mission[i]);
     267              :         }
     268              :     }
     269              : 
     270            3 :     DumpResReqInfo(totalRes);
     271            9 :     HCCL_INFO("GetResPackTotalResNum:dumpInfos success.");
     272            3 :     return HcclResult::HCCL_SUCCESS;
     273            3 : }
     274              : 
     275            3 : CcuResReq CtxMgrImp::GetCtxGroupResReq(CcuCtxGroup &ctxGroup) const
     276              : {
     277            3 :     CcuResReq totalResReq;
     278              : 
     279            3 :     std::unordered_set<uint16_t> usedDieId; // CCUCtxGroup使用到的所有dieId
     280              : 
     281              :     // 获取CCUCtxGroup所有ctx资源诉求
     282            9 :     for (auto &ctx : ctxGroup.ctxs) {
     283            6 :         auto dieId = ctx->GetDieId();
     284            6 :         usedDieId.insert(dieId);
     285              : 
     286            6 :         CcuResReq tmpResReq = ctx->GetResourceRequest();
     287            6 :         MergeCcuResReq(totalResReq, tmpResReq);
     288              :     }
     289              : 
     290            3 :     DumpResReqInfo(totalResReq);
     291            9 :     HCCL_INFO("CtxGroupResReq:dumpInfos success.");
     292              : 
     293            6 :     return totalResReq;
     294            3 : }
     295              : 
     296          102 : void CtxMgrImp::MergeCcuResReq(CcuResReq &resReqA, const CcuResReq &resReqB) const
     297              : {
     298              :     // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes的第0个vector中
     299          306 :     for (u32 i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     300          204 :         resReqA.msReq[i] += resReqB.msReq[i];
     301          204 :         resReqA.blockMsReq[i] += resReqB.blockMsReq[i];
     302          204 :         resReqA.ckeReq[i] += resReqB.ckeReq[i];
     303          204 :         resReqA.blockCkeReq[i] += resReqB.blockCkeReq[i];
     304          204 :         resReqA.loopEngineReq[i] += resReqB.loopEngineReq[i];
     305          204 :         resReqA.blockLoopEngineReq[i] += resReqB.blockLoopEngineReq[i];
     306          204 :         resReqA.gsaReq[i] += resReqB.gsaReq[i];
     307          204 :         resReqA.xnReq[i] += resReqB.xnReq[i];
     308          204 :         resReqA.continuousXnReq[i] += resReqB.continuousXnReq[i];
     309          204 :         resReqA.missionReq.req[i] += resReqB.missionReq.req[i];
     310              : 
     311          204 :         if (resReqB.missionReq.req[i] > 0) {
     312            6 :             resReqA.missionReq.reqType = resReqB.missionReq.reqType;
     313              :         }
     314              :     }
     315          102 :     return;
     316              : }
     317              : 
     318            3 : HcclResult CtxMgrImp::CompareResAndApplyAsNeeded(const CcuResReq &totalRes, const CcuResReq &resReq,
     319              :                                                  CcuResPack &resPack) const
     320              : {
     321              :     // 比较额外需要的资源
     322            3 :     bool      isNeedAlloc = false;
     323            3 :     CcuResReq needResReq;
     324              : 
     325            9 :     for (u32 i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     326            6 :         needResReq.msReq[i]              = GetReqResNum(resReq.msReq[i], totalRes.msReq[i]);
     327            6 :         needResReq.blockMsReq[i]         = GetReqResNum(resReq.blockMsReq[i], totalRes.blockMsReq[i]);
     328            6 :         needResReq.ckeReq[i]             = GetReqResNum(resReq.ckeReq[i], totalRes.ckeReq[i]);
     329            6 :         needResReq.blockCkeReq[i]        = GetReqResNum(resReq.blockCkeReq[i], totalRes.blockCkeReq[i]);
     330            6 :         needResReq.loopEngineReq[i]      = GetReqResNum(resReq.loopEngineReq[i], totalRes.loopEngineReq[i]);
     331            6 :         needResReq.blockLoopEngineReq[i] = GetReqResNum(resReq.blockLoopEngineReq[i], totalRes.blockLoopEngineReq[i]);
     332            6 :         needResReq.gsaReq[i]             = GetReqResNum(resReq.gsaReq[i], totalRes.gsaReq[i]);
     333            6 :         needResReq.xnReq[i]              = GetReqResNum(resReq.xnReq[i], totalRes.xnReq[i]);
     334            6 :         needResReq.continuousXnReq[i]    = GetReqResNum(resReq.continuousXnReq[i], totalRes.continuousXnReq[i]);
     335            6 :         needResReq.missionReq.req[i]
     336            6 :             = GetReqResNum(resReq.missionReq.req[i], totalRes.missionReq.req[i]);
     337              : 
     338            6 :         if (needResReq.missionReq.req[i] > 0) {
     339            4 :             needResReq.missionReq.reqType = resReq.missionReq.reqType;
     340              :         }
     341              : 
     342           12 :         if (needResReq.msReq[i] != 0 || needResReq.blockMsReq[i] != 0 || needResReq.ckeReq[i] != 0 || needResReq.blockCkeReq[i] != 0
     343            3 :                 || needResReq.loopEngineReq[i] != 0 || needResReq.blockLoopEngineReq[i] != 0 || needResReq.gsaReq[i] != 0
     344            3 :                 || needResReq.xnReq[i] != 0 || needResReq.continuousXnReq[i] != 0
     345           12 :                 || needResReq.missionReq.req[i] != 0) {
     346            4 :             isNeedAlloc = true;
     347              :         }
     348              :     }
     349              : 
     350            3 :     if (isNeedAlloc) {
     351              :         // 申请额外资源
     352              :         CcuResHandle handle;
     353            3 :         DumpResReqInfo(needResReq);
     354              : 
     355            3 :         CHK_RET_UNAVAIL(CcuDeviceManager::AllocResHandle(deviceLogicId_, needResReq, handle));
     356              :         // 将申请的资源保存到resPack中
     357            3 :         resPack.handles.push_back(handle);
     358              : 
     359            9 :         HCCL_INFO("ApplyAsNeeded:dumpInfos success deviceLogicId[%d] handle[%p].", deviceLogicId_, handle);
     360              :     }
     361              : 
     362            3 :     return HcclResult::HCCL_SUCCESS;
     363              : }
     364              : 
     365            3 : void CtxMgrImp::SaveResPackToCtx(CcuCtxGroup &ctxGroup, CcuResPack &resPack) const
     366              : {
     367            9 :     for (auto &ctx : ctxGroup.ctxs) {
     368            6 :         ctx->SetResPack(resPack);
     369              :     }
     370            3 :     return;
     371              : }
     372              : 
     373            4 : HcclResult CtxMgrImp::InstantiationTranslator(uint16_t dieId)
     374              : {
     375            4 :     if (translators.find(dieId) != translators.end()) {
     376            1 :         return HcclResult::HCCL_SUCCESS;
     377              :     }
     378              : 
     379            3 :     std::array<uint16_t, MAX_CCU_IODIE_NUM> tmpChannelId{};
     380            3 :     uint32_t chaneelId = 0;
     381              :     // 获取innerDieChannelId
     382            3 :     auto     ret       = CcuDeviceManager::GetLoopChannelId(deviceLogicId_, dieId, dieId, chaneelId);
     383            3 :     if (ret != HcclResult::HCCL_SUCCESS) {
     384            0 :         THROW<CcuApiException>("Failed to get inner die channel id. deviceLogicId = %d, dieId = %u, ret = %d",
     385              :                                deviceLogicId_, dieId, ret);
     386              :     }
     387            3 :     tmpChannelId[0] = chaneelId;
     388              :     // 获取interDieChannelId
     389            3 :     uint8_t dstDieId = ((dieId == 0) ? 1 : 0);
     390            3 :     ret              = CcuDeviceManager::GetLoopChannelId(deviceLogicId_, dieId, dstDieId, chaneelId);
     391            3 :     if (ret != HcclResult::HCCL_SUCCESS) {
     392              :         // 当前验证环境为单die环境,获取die间ChannelId会失败,打印WARNING日志。
     393            0 :         HCCL_WARNING("Failed to get inter die channel id. deviceLogicId = %d, srcDieId = %u, dstDieId = %u, ret = %d",
     394              :                      deviceLogicId_, dieId, dstDieId, ret);
     395              :     }
     396            3 :     tmpChannelId[1] = chaneelId;
     397              :     // 获取ccu token信息
     398            3 :     uint64_t tokenId = 0;
     399            3 :     uint64_t tokenValue = 0;
     400            3 :     ret = CcuDeviceManager::GetCcuResourceSpaceTokenInfoForLocal(deviceLogicId_, dieId, tokenId, tokenValue);
     401            3 :     if (ret != HcclResult::HCCL_SUCCESS) {
     402            0 :         THROW<CcuApiException>("Failed to get ccu resource space token info. deviceLogicId = %d, dieId = %u, ret = %d",
     403              :                                deviceLogicId_, dieId, ret);
     404              :     }
     405            3 :     std::pair<uint64_t, uint64_t> ccuTokenInfo(tokenId, tokenValue);
     406            3 :     CcuResReq totalResReq;
     407              : 
     408              :     // 先获取hbm token,避免创建mission时循环获取
     409            3 :     DevBuffer tmpDevMem{1}; 
     410            3 :     auto hbmTokenInfo = GetTokenInfo(tmpDevMem.GetAddr(), 1);
     411              : 
     412              :     // 实例化CcuRepReferenceManager和CcuRepTranslator,并为CcuRepReferenceManager绑定物理资源
     413           51 :     for (uint32_t i = 0; i < 16; i++) {  // mgr有16个
     414           48 :         referenceMgrs[dieId][i] = std::make_shared<CcuRepReferenceManager>(dieId);
     415           96 :         translators[dieId][i]   = std::make_shared<CcuRepTranslator>(deviceLogicId_, dieId, referenceMgrs[dieId][i],
     416           48 :                                                                    tmpChannelId, ccuTokenInfo, hbmTokenInfo);
     417              : 
     418              :         // 统计&合并refManager和translaotr所有资源REQ
     419           48 :         auto refMangerResReq = CcuRep::CcuRepReferenceManager::GetResReq(dieId);
     420           48 :         auto transLatorResReq = CcuRep::CcuRepTranslator::GetResReq(dieId);
     421           48 :         MergeCcuResReq(totalResReq, refMangerResReq);
     422           48 :         MergeCcuResReq(totalResReq, transLatorResReq);
     423              :     }
     424              : 
     425            3 :     DumpResReqInfo(totalResReq);
     426              : 
     427              :     // 为refManager和translaotr申请物理资源
     428              :     CcuResHandle handle;
     429            3 :     CHK_RET_UNAVAIL(CcuDeviceManager::AllocResHandle(deviceLogicId_, totalResReq, handle));
     430            3 :     translatorResPack.handles.push_back(handle);
     431              : 
     432            3 :     CcuRepResource translatorRepRes;
     433           51 :     for (uint32_t i = 0; i < 16; i++) {  // mgr有16个
     434           48 :         referenceMgrs[dieId][i]->GetRes(translatorRepRes);
     435           48 :         translators[dieId][i]->GetRes(translatorRepRes);
     436              :     }
     437              : 
     438            3 :     CcuResRepository totalResRepository;
     439            3 :     CHK_RET(GetResPackTotalResRepository(translatorResPack, totalResRepository));
     440              :     // 将ctx中的rep虚拟资源按类型进行和CCU物理资源映射
     441            3 :     ResetRepResourceToResRepository(translatorRepRes, totalResRepository);
     442            3 :     return HcclResult::HCCL_SUCCESS;
     443            3 : }
     444              : 
     445            3 : HcclResult CtxMgrImp::TransRepResToPhyRes(CcuCtxGroup &ctxGroup) const
     446              : {
     447              :     // 获取ctxGroup中CCU物理资源句柄
     448            3 :     CcuResPack *resPack = ctxGroup.ctxs[0]->GetResPack();
     449            3 :     CHK_PTR_NULL(resPack);
     450              : 
     451              :     // 获取通信域当前所持有的资源
     452            3 :     CcuResRepository totalResRepository;
     453            3 :     CHK_RET(GetResPackTotalResRepository(*resPack, totalResRepository));
     454              : 
     455              :     // 遍历ctxGroup, 将每个ctx的虚拟资源进行合并
     456            3 :     CcuRepResource totalRepRes = GetTotalCcuRepResource(ctxGroup);
     457              : 
     458              :     // 将ctx中的rep虚拟资源按类型进行和CCU物理资源映射
     459            3 :     ResetRepResourceToResRepository(totalRepRes, totalResRepository);
     460              : 
     461              :     // 针对跨ctx的资源进行特殊映射处理
     462            3 :     ProcessInterCtxRes(ctxGroup);
     463              : 
     464              :     // missionId、mission key赋值给ctx
     465            3 :     CHK_RET(SaveCtxMissionInfo(ctxGroup, totalResRepository.mission.mission));
     466            3 :     return HcclResult::HCCL_SUCCESS;
     467            3 : }
     468              : 
     469            6 : HcclResult CtxMgrImp::GetResPackTotalResRepository(const CcuResPack &resPack, CcuResRepository &totalRes) const
     470              : {
     471            6 :     CcuResRepository tmpResRepository;
     472              : 
     473              :     // 获取通信域当前所持有的资源
     474           13 :     for (CcuResHandle resHandle : resPack.handles) {
     475            7 :         CHK_RET(CcuDeviceManager::GetResource(deviceLogicId_, resHandle, tmpResRepository));
     476              : 
     477              :         // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes中
     478           21 :         for (u32 i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     479           14 :             ExpandResInfo(totalRes.ms[i], tmpResRepository.ms[i]);
     480           14 :             ExpandResInfo(totalRes.blockMs[i], tmpResRepository.blockMs[i]);
     481           14 :             ExpandResInfo(totalRes.loopEngine[i], tmpResRepository.loopEngine[i]);
     482           14 :             ExpandResInfo(totalRes.blockLoopEngine[i], tmpResRepository.blockLoopEngine[i]);
     483           14 :             ExpandResInfo(totalRes.cke[i], tmpResRepository.cke[i]);
     484           14 :             ExpandResInfo(totalRes.blockCke[i], tmpResRepository.blockCke[i]);
     485           14 :             ExpandResInfo(totalRes.gsa[i], tmpResRepository.gsa[i]);
     486           14 :             ExpandResInfo(totalRes.xn[i], tmpResRepository.xn[i]);
     487           14 :             ExpandResInfo(totalRes.continuousXn[i], tmpResRepository.continuousXn[i]);
     488           14 :             ExpandResInfo(totalRes.mission.mission[i], tmpResRepository.mission.mission[i]);
     489              :         }
     490            7 :         DumpResRepositoryInfo(totalRes);
     491           21 :         HCCL_INFO("GetResPackTotalResRepository:dumpInfos success deviceLogicId[%d] resHandle[%p].", deviceLogicId_,
     492              :                    resHandle);
     493              :     }
     494            6 :     return HcclResult::HCCL_SUCCESS;
     495            6 : }
     496              : 
     497            3 : CcuRepResource CtxMgrImp::GetTotalCcuRepResource(CcuCtxGroup &ctxGroup) const
     498              : {
     499            3 :     CcuRepResource totalRepRes;
     500              : 
     501              :     // 遍历ctxGroup, 将每个ctx的虚拟资源进行合并
     502            9 :     for (auto &ctx : ctxGroup.ctxs) {
     503              :         // 获取ctx的虚拟资源
     504            6 :         CcuRepResource tmpRepRes = ctx->GetResource();
     505            6 :         MergeCtxRepResource(totalRepRes, tmpRepRes);
     506            6 :     }
     507              : 
     508            3 :     return totalRepRes;
     509            0 : }
     510              : 
     511            6 : void CtxMgrImp::MergeCtxRepResource(CcuRepResource &repResourceA, CcuRepResource &repResourceB) const
     512              : {
     513           18 :     for (u32 i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     514              :         // 合并repRes
     515           24 :         repResourceA.ccubuffers[i].insert(repResourceA.ccubuffers[i].end(), repResourceB.ccubuffers[i].begin(),
     516           12 :                                           repResourceB.ccubuffers[i].end());
     517              : 
     518           36 :         repResourceA.blockCcubuffers[i].insert(repResourceA.blockCcubuffers[i].end(),
     519           12 :                                                repResourceB.blockCcubuffers[i].begin(),
     520           12 :                                                repResourceB.blockCcubuffers[i].end());
     521              : 
     522           24 :         repResourceA.executor[i].insert(repResourceA.executor[i].end(), repResourceB.executor[i].begin(),
     523           12 :                                         repResourceB.executor[i].end());
     524              : 
     525           24 :         repResourceA.blockExecutor[i].insert(repResourceA.blockExecutor[i].end(), repResourceB.blockExecutor[i].begin(),
     526           12 :                                              repResourceB.blockExecutor[i].end());
     527              : 
     528           24 :         repResourceA.maskSignal[i].insert(repResourceA.maskSignal[i].end(), repResourceB.maskSignal[i].begin(),
     529           12 :                                           repResourceB.maskSignal[i].end());
     530              : 
     531           36 :         repResourceA.blockMaskSignal[i].insert(repResourceA.blockMaskSignal[i].end(),
     532           12 :                                                repResourceB.blockMaskSignal[i].begin(),
     533           12 :                                                repResourceB.blockMaskSignal[i].end());
     534              : 
     535           24 :         repResourceA.address[i].insert(repResourceA.address[i].end(), repResourceB.address[i].begin(),
     536           12 :                                        repResourceB.address[i].end());
     537              : 
     538           24 :         repResourceA.variable[i].insert(repResourceA.variable[i].end(), repResourceB.variable[i].begin(),
     539           12 :                                         repResourceB.variable[i].end());
     540              : 
     541           36 :         repResourceA.continuousVariable[i].insert(repResourceA.continuousVariable[i].end(),
     542           12 :                                                   repResourceB.continuousVariable[i].begin(),
     543           12 :                                                   repResourceB.continuousVariable[i].end());
     544              :     }
     545            6 :     return;
     546              : }
     547              : 
     548              : template <typename T1, typename T2>
     549          108 : void CtxMgrImp::ResetRepResourceTemplate(std::vector<T1> &resource, const std::vector<T2> &repository) const
     550              : {
     551          108 :     if (resource.size() > repository.size()) {
     552            0 :         THROW<CcuApiException>("[CtxMgrImp][ResetRepResourceTemplate]resource size[%u] bigger repository size[%u] typeid[%s]",
     553              :                                resource.size(), repository.size(), typeid(T1).name());
     554              :         return;
     555              :     }
     556              : 
     557         5768 :     for (uint32_t j = 0; j < resource.size(); j++) {
     558         5660 :         resource[j].Reset(repository[j].startId);
     559              :     }
     560              : }
     561              : 
     562            6 : void CtxMgrImp::ResetRepResourceToResRepository(CcuRepResource &totalRepRes, const CcuResRepository &totalResRepository) const
     563              : {
     564              :     // 遍历translatorRepRes, 将每个rep的虚拟资源翻译到实际物理资源上
     565           18 :     for (u32 i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     566           12 :         ResetRepResourceTemplate(totalRepRes.ccubuffers[i], totalResRepository.ms[i]);
     567           12 :         ResetRepResourceTemplate(totalRepRes.blockCcubuffers[i], totalResRepository.blockMs[i]);
     568           12 :         ResetRepResourceTemplate(totalRepRes.executor[i], totalResRepository.loopEngine[i]);
     569           12 :         ResetRepResourceTemplate(totalRepRes.blockExecutor[i], totalResRepository.blockLoopEngine[i]);
     570           12 :         ResetRepResourceTemplate(totalRepRes.maskSignal[i], totalResRepository.cke[i]);
     571           12 :         ResetRepResourceTemplate(totalRepRes.blockMaskSignal[i], totalResRepository.blockCke[i]);
     572           12 :         ResetRepResourceTemplate(totalRepRes.address[i], totalResRepository.gsa[i]);
     573           12 :         ResetRepResourceTemplate(totalRepRes.variable[i], totalResRepository.xn[i]);
     574           12 :         ResetRepResourceTemplate(totalRepRes.continuousVariable[i], totalResRepository.continuousXn[i]);
     575              :     }
     576            6 : }
     577              : 
     578              : template <typename T>
     579           12 : void CtxMgrImp::ProcessSharedResources(std::unordered_map<std::string, T>              &resources,
     580              :                                        std::vector<std::unordered_map<std::string, T>> &exportedResources, uint32_t i) const
     581              : {
     582           18 :     for (auto &res : resources) {
     583              :         uint32_t j;
     584           13 :         for (j = 0; j < exportedResources.size(); j++) {
     585           13 :             if (i != j) {
     586            8 :                 auto exportedRes = exportedResources[j].find(res.first);
     587            8 :                 if (exportedRes != exportedResources[j].end()) {
     588            6 :                     res.second.Reset(exportedRes->second.Id(), exportedRes->second.DieId());
     589            6 :                     break;
     590              :                 }
     591              :             }
     592              :         }
     593              : 
     594            6 :         if (j >= exportedResources.size()) {
     595            0 :             THROW<CcuApiException>("ProcessSharedResources failed tag[%s]", res.first.c_str());
     596              :         }
     597              :     }
     598           12 : }
     599              : 
     600            3 : void CtxMgrImp::ProcessInterCtxRes(CcuCtxGroup &ctxGroup) const
     601              : {
     602              :     // 针对跨ctx的资源进行特殊映射处理
     603            9 :     for (uint32_t i = 0; i < ctxGroup.ctxs.size(); i++) {
     604              :         // 获取当前ctx中导入的ccuShrRes
     605            6 :         CcuSharedResource importRes = ctxGroup.ctxs[i]->GetImportRes();
     606              : 
     607              :         // 提前计算所有ctx的exportRes,以减少不必要的重复计算
     608           12 :         std::vector<std::unordered_map<std::string, CcuRep::Variable>>   exportVarResList(ctxGroup.ctxs.size());
     609            6 :         std::vector<std::unordered_map<std::string, CcuRep::MaskSignal>> exportSigResList(ctxGroup.ctxs.size());
     610              : 
     611           20 :         for (uint32_t j = 0; j < ctxGroup.ctxs.size(); j++) {
     612           14 :             if (i != j) {
     613            8 :                 auto exportRes      = ctxGroup.ctxs[j]->GetExportRes();
     614            8 :                 exportVarResList[j] = exportRes.sharedVar;
     615            8 :                 exportSigResList[j] = exportRes.sharedSig;
     616            8 :             }
     617              :         }
     618              : 
     619              :         // 处理sharedVar和sharedSig
     620            6 :         ProcessSharedResources(importRes.sharedVar, exportVarResList, i);
     621            6 :         ProcessSharedResources(importRes.sharedSig, exportSigResList, i);
     622            6 :     }
     623            3 : }
     624              : 
     625            3 : HcclResult CtxMgrImp::SaveCtxMissionInfo(CcuCtxGroup &ctxGroup, array<vector<ResInfo>, MAX_CCU_IODIE_NUM> &missionId) const
     626              : {
     627            9 :     for (auto &ctx : ctxGroup.ctxs) {
     628            6 :         auto     dieId = ctx->GetDieId();
     629              :         uint32_t missionKey;
     630            6 :         CHK_RET(CcuDeviceManager::GetMissionKey(deviceLogicId_, dieId, missionKey));
     631              : 
     632           18 :         HCCL_INFO("[SaveCtxMissionInfo]GetMissionKey:deviceLogicId[%d] dieId[%u]", deviceLogicId_, dieId);
     633              : 
     634            6 :         ctx->SetMissionKey(missionKey);
     635              :         // 从missionId中获取一个元素并从missionId中删除
     636            6 :         ctx->SetMissionId(missionId[dieId].back().startId);
     637            6 :         missionId[dieId].pop_back();
     638              :     }
     639              : 
     640            3 :     return HcclResult::HCCL_SUCCESS;
     641              : }
     642              : 
     643            3 : void CtxMgrImp::TransRepSequenceToMicrocode(CcuCtxGroup &ctxGroup, bool isFuncBlock)
     644              : {
     645            9 :     for (auto &ctx : ctxGroup.ctxs) {
     646            6 :         auto dieId = ctx->GetDieId();
     647            6 :         auto missionId = ctx->GetMissionId();
     648              :         // 翻译本ctx的REP序列
     649            6 :         auto instrInfo = translators[dieId][missionId]->Translate(ctx->GetRepSequence(), ctx->GetInstrId(), isFuncBlock);
     650              : 
     651              : #ifdef HCCL_ALG_ANALYZER_DAVID
     652              :         // 建立CCU指令和微码的映射关系
     653              :         extern std::map<const Hccl::Instruction*, std::vector<Hccl::CcuRep::CcuInstrInfo>> g_ccuIns2MicroCode;
     654              :         extern Hccl::Instruction* g_ccuIns;
     655              :         g_ccuIns2MicroCode[g_ccuIns].push_back(instrInfo);
     656              : #endif
     657              : 
     658              :         // 保存翻译后的指令信息
     659            6 :         ctx->SetCcuInstrInfo(instrInfo);
     660              : 
     661              :         // 加载指令到CCU指令空间
     662            6 :         LoadInstruction(instrInfo, dieId);
     663            6 :     }
     664            3 :     return;
     665              : }
     666              : 
     667            6 : void CtxMgrImp::LoadInstruction(CcuRep::CcuInstrInfo &instrInfo, uint32_t dieId)
     668              : {
     669            6 :     uint64_t instrInfoSize = instrInfo.instrVec.size() * sizeof(CcuInstr);
     670              : 
     671            6 :     if (!instructionLoadDevMem_) {
     672            6 :         uint32_t instrNum = 0;
     673            6 :         if (CcuDeviceManager::GetInstructionNum(deviceLogicId_, 0, instrNum) != HcclResult::HCCL_SUCCESS) {
     674            0 :             THROW<CcuApiException>("CtxMgrImp::Init failed");
     675              :         }
     676           18 :         HCCL_INFO("[CtxMgrImp]LoadInstruction: deviceLogicId[%d], instrNum[%u]", deviceLogicId_, instrNum);
     677              :         // rt接口申请device内存
     678            6 :         instructionLoadDevMem_ = HrtMalloc(instrNum * sizeof(CcuInstr),
     679              :                                                                                    static_cast<int>(ACL_MEM_TYPE_HIGH_BAND_WIDTH));
     680              :     }
     681              : 
     682              :     // rt接口memcpySync
     683            6 :     HrtMemcpy(instructionLoadDevMem_, instrInfoSize, instrInfo.instrVec.data(), instrInfoSize,
     684              :               RT_MEMCPY_HOST_TO_DEVICE);
     685              : 
     686            6 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(deviceLogicId_);
     687            6 :     CHECK_NULLPTR(tlvHandle, StringFormat("[CtxMgrImp][%s] tlvHandle is nullptr, deviceLogicId[%d]", __func__, deviceLogicId_));
     688              : 
     689            6 :     struct CustomChannelInfoIn  inBuff;
     690            6 :     struct CustomChannelInfoOut outBuff;
     691              : 
     692              :     CcuDataTypeUnion tmp;
     693            6 :     tmp.insinfo.resourceAddr = reinterpret_cast<uint64_t>(instructionLoadDevMem_);
     694              : 
     695              :     // 设置操作码和通道数据
     696            6 :     inBuff.op                          = CcuOpcodeType::CCU_U_OP_SET_INSTRUCTION;
     697            6 :     inBuff.offsetStartIdx              = instrInfo.startInstrId;
     698            6 :     inBuff.data.dataInfo.udieIdx       = dieId;
     699            6 :     inBuff.data.dataInfo.dataArraySize = 1;
     700            6 :     inBuff.data.dataInfo.dataLen       = instrInfoSize;
     701              : 
     702              :     // 复制通道数据
     703            6 :     (void)memcpy_s(inBuff.data.dataInfo.dataArray, sizeof(CcuDataTypeUnion), &tmp, sizeof(CcuDataTypeUnion));
     704              : 
     705            6 :     HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     706              : 
     707           18 :     HCCL_RUN_INFO("Entry-LoadInstruction: load instruction success startInstrId[%u] instrCount[%u]",
     708              :                   instrInfo.startInstrId, instrInfo.instrCount);
     709              : 
     710           12 :     return;
     711              : }
     712              : 
     713           12 : void CtxMgrImp::DumpResReqInfo(const CcuResReq &totalRes) const
     714              : {
     715           36 :     for (uint32_t i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     716           48 :         if (totalRes.msReq[i] != 0 || totalRes.blockMsReq[i] != 0 || totalRes.ckeReq[i] != 0 || totalRes.blockCkeReq[i] != 0
     717           15 :                 || totalRes.loopEngineReq[i] != 0 || totalRes.blockLoopEngineReq[i] != 0 || totalRes.gsaReq[i] != 0
     718           15 :                 || totalRes.xnReq[i] != 0 || totalRes.continuousXnReq[i] != 0
     719           48 :                 ||totalRes.missionReq.req[i] != 0) {
     720           33 :             HCCL_INFO("DumpResReqInfo: dieId[%u], msReq[%u], blockMsReq[%u], ckeReq[%u], blockCkeReq[%u], "
     721              :                        "loopEngineReq[%u], blockLoopEngineReq[%u], gsaReq[%u], xnReq[%u], continuousXnReq[%u], "
     722              :                        "missionReq[%u]",
     723              :                        i, totalRes.msReq[i], totalRes.blockMsReq[i], totalRes.ckeReq[i], totalRes.blockCkeReq[i],
     724              :                        totalRes.loopEngineReq[i], totalRes.blockLoopEngineReq[i], totalRes.gsaReq[i],
     725              :                        totalRes.xnReq[i], totalRes.continuousXnReq[i], totalRes.missionReq.req[i]);
     726              :         }
     727              :     }
     728           12 : }
     729              : 
     730            7 : void CtxMgrImp::DumpResRepositoryInfo(const CcuResRepository &resRepo) const
     731              : {
     732           21 :     for (uint32_t i = 0; i < MAX_CCU_IODIE_NUM; i++) {
     733           28 :         if (resRepo.ms[i].size() != 0 || resRepo.blockMs[i].size() != 0 || resRepo.cke[i].size() != 0 || resRepo.blockCke[i].size() != 0
     734            3 :                 || resRepo.loopEngine[i].size() != 0 || resRepo.blockLoopEngine[i].size() != 0 || resRepo.gsa[i].size() != 0
     735            3 :                 || resRepo.xn[i].size() != 0 || resRepo.continuousXn[i].size() != 0
     736           28 :                 || resRepo.mission.mission[i].size() != 0) {
     737           33 :             HCCL_INFO("DumpResRepository: dieId[%u], ms size[%u], blockMs size[%u], cke size[%u], blockCke size[%u], "
     738              :                        "loopEngine size[%u], blockLoopEngine size[%u], gsa size[%u], xn size[%u], "
     739              :                        "continuous xn size[%u], mission size[%u]",
     740              :                        i, resRepo.ms[i].size(), resRepo.blockMs[i].size(), resRepo.cke[i].size(),
     741              :                        resRepo.blockCke[i].size(), resRepo.loopEngine[i].size(), resRepo.blockLoopEngine[i].size(),
     742              :                        resRepo.gsa[i].size(), resRepo.xn[i].size(), resRepo.continuousXn[i].size(),
     743              :                        resRepo.mission.mission[i].size());
     744              :         }
     745              :     }
     746            7 : }
     747              : 
     748            0 : std::vector<std::vector<CcuProfilingInfo>> CtxMgrImp::GetProfilingInfo(CcuTaskArg &ccuTaskArg, const uint64_t entityId)
     749              : {
     750              :     // 根据entityId获取ctxGroup
     751            0 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
     752              : 
     753              :     // 校验ctxGroupMap_中是否存在entityId对应的ctxGroup
     754            0 :     CHK_PRT_RET(ctxGroupMap_.find(entityId) == ctxGroupMap_.end(),
     755              :                 HCCL_ERROR("[CtxMgrImp][GetProfilingInfo]entityId [%llu] is not exist", entityId),
     756              :                 std::vector<std::vector<CcuProfilingInfo>>());
     757              : 
     758              :     // 获取每个ctx的profiling信息
     759            0 :     std::vector<std::vector<CcuProfilingInfo>> ccuProfilingInfo;
     760            0 :     for (auto &ctx : ctxGroupMap_[entityId].ctxs) {
     761            0 :         std::vector<CcuProfilingInfo> tmp;
     762            0 :         auto ret = ctx->GetCcuProfilingInfo(ccuTaskArg, tmp);
     763            0 :         if (ret != HcclResult::HCCL_SUCCESS) {
     764            0 :             THROW<CcuApiException>("GetCcuProfilingInfo is failed. ret[%d]", ret);
     765              :         }
     766            0 :         ccuProfilingInfo.push_back(tmp);
     767            0 :     }
     768              : 
     769            0 :     return ccuProfilingInfo;
     770            0 : }
     771              : 
     772            2 : CcuContext* CtxMgrImp::GetCtx(uint64_t executorId, uint32_t dieId, uint32_t missionId)
     773              : {
     774            2 :     std::unique_lock<std::mutex> lock(contextMapMutex_);
     775              : 
     776            2 :     if (ctxGroupMap_.find(executorId) == ctxGroupMap_.end()) {
     777            3 :         HCCL_ERROR("[CtxMgrImp][GetCtx] executorId [%llu] is not exist", executorId);
     778            1 :         return nullptr;
     779              :     }
     780              : 
     781            1 :     for (auto& ctx : ctxGroupMap_[executorId].ctxs) {
     782            0 :         if (ctx->GetDieId() == dieId && ctx->GetMissionId() == missionId) {
     783            0 :             return ctx.get();
     784              :         }
     785              :     }
     786              : 
     787            3 :     HCCL_ERROR("[CtxMgrImp][GetCtx] CcuContext is not exist, dieId[%u], missionId[%u]", dieId, missionId);
     788            1 :     return nullptr;
     789            2 : }
     790              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1