LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_device - ccu_res_batch_allocator.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 77.9 % 524 408
Test Date: 2026-08-04 10:52:23 Functions: 93.5 % 31 29

            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_res_batch_allocator.h"
      12              : 
      13              : #include <array>
      14              : #include <memory>
      15              : #include <utility>
      16              : #include <iterator>
      17              : #include <algorithm>
      18              : 
      19              : #include "hccl_common.h"
      20              : 
      21              : #include "ccu_comp.h"
      22              : #include "ccu_res_specs.h"
      23              : #include "ccu_res_type_converter.h"
      24              : #include "ccu_device_res.h"
      25              : #include "ccu_rep_reference_manager_v1.h"
      26              : #include "ccu_rep_reference_manager.h"
      27              : 
      28              : namespace hcomm {
      29              : 
      30              : constexpr uint32_t REQ_RES_TYPE_NUM = 11;
      31              : constexpr uint32_t BLOCK_RES_TYPE_NUM = 5;
      32              : constexpr uint32_t CONS_RES_TYPE_NUM = 1;
      33              : constexpr uint32_t DISCRETE_RES_TYPE_NUM = 4;
      34              : constexpr uint32_t NON_BLOCK_TYPE_NUM = CONS_RES_TYPE_NUM + DISCRETE_RES_TYPE_NUM;
      35              : constexpr uint32_t BLOCK_SIZE_MS_AX_DIE0 = 128;
      36              : constexpr uint32_t CCUA_NUM = 4;
      37              : 
      38              : constexpr uint32_t CCU_REPREFMGR_NEW_XN_NUM = hcomm::CcuRep::FUNC_ARG_MAX
      39              :                                             + hcomm::CcuRep::FUNC_ARG_MAX
      40              :                                             + 1 + hcomm::CcuRep::FUNC_NEST_MAX + 1;
      41              : constexpr uint32_t CCU_REPREFMGR_LEGACY_XN_NUM = Hccl::CcuRep::FUNC_IN_MAX
      42              :                                             + Hccl::CcuRep::FUNC_OUT_MAX
      43              :                                             + 1 + Hccl::CcuRep::FUNC_NEST_MAX + 1;
      44              : constexpr uint32_t CCU_REP_TRANSLATOR_GSA_NUM = 3;
      45              : constexpr uint32_t CCU_REP_TRANSLATOR_CKE_NUM = 2;
      46              : constexpr uint32_t CCU_REP_TRANSLATOR_XN_NUM = 4;
      47              : // 建链预留数量 + 开源+legacy的CcuRepTranslator预留数量
      48              : constexpr uint32_t RESERVED_DISCRETE_CKE_NUM = 4 * 128
      49              :                                             + (CCU_REP_TRANSLATOR_CKE_NUM * 16) * 2;
      50              : // 建链预留数量 + 开源+legacy的CcuRepReferenceManager预留数量 + 开源+legacy的CcuRepTranslator预留数量
      51              : constexpr uint32_t RESERVED_DISCRETE_XN_NUM = 4 * 128
      52              :                                             + CCU_REPREFMGR_LEGACY_XN_NUM * 16
      53              :                                             + CCU_REPREFMGR_NEW_XN_NUM * 16
      54              :                                             + (CCU_REP_TRANSLATOR_XN_NUM * 16) * 2;
      55              : // 开源+legacy的CcuRepTranslator预留数量
      56              : constexpr uint32_t RESERVED_DISCRETE_GSA_NUM = (CCU_REP_TRANSLATOR_GSA_NUM * 16) * 2;
      57              : 
      58          897 : CcuResBatchAllocator &CcuResBatchAllocator::GetInstance(const int32_t deviceLogicId)
      59              : {
      60         1029 :     static CcuResBatchAllocator ccuResBatchAllocator[MAX_MODULE_DEVICE_NUM + 1];
      61          897 :     int32_t devLogicId = deviceLogicId;
      62          897 :     if (devLogicId < 0 || static_cast<uint32_t>(devLogicId) >= MAX_MODULE_DEVICE_NUM) {
      63            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] use the backup device, devLogicId[%d] "
      64              :             "should be less than %u.", __func__, devLogicId, MAX_MODULE_DEVICE_NUM);
      65            0 :         devLogicId = MAX_MODULE_DEVICE_NUM; // 使用备份设备
      66              :     }
      67          897 :     ccuResBatchAllocator[devLogicId].devLogicId_ = devLogicId;
      68          897 :     return ccuResBatchAllocator[devLogicId];
      69              : }
      70              : 
      71          143 : HcclResult CcuResBatchAllocator::Init()
      72              : {
      73          143 :     if (initFlag_) {
      74           62 :         return HcclResult::HCCL_SUCCESS;
      75              :     }
      76              : 
      77           81 :     dieEnableFlags_ = CcuComponent::GetInstance(devLogicId_).GetDieEnableFlags();
      78           81 :     if (!dieEnableFlags_[0] && !dieEnableFlags_[1]) {
      79            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] failed but passed, "
      80              :             "devLogicId[%d] no usable die.", __func__, devLogicId_);
      81            0 :         return HcclResult::HCCL_E_UNAVAIL;
      82              :     }
      83              : 
      84           81 :     auto ret = PreAllocBlockRes();
      85           81 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
      86            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] pre alloc block res failed but passed, "
      87              :             "some sources are not enough, devLogicId[%d].", __func__, devLogicId_);
      88            0 :         return ret;
      89              :     }
      90           81 :     CHK_RET(ret);
      91              : 
      92           81 :     ret = missionMgr_.PreAlloc(devLogicId_, resStrategies_[0].missionNum, dieEnableFlags_);
      93           81 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
      94            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] pre alloc mission res failed but passed, "
      95              :             "some sources are not enough, devLogicId[%d].", __func__, devLogicId_);
      96            0 :         return ret;
      97              :     }
      98           81 :     CHK_RET(ret);
      99              :     
     100           81 :     initFlag_ = true;
     101           81 :     return HcclResult::HCCL_SUCCESS;
     102              : }
     103              : 
     104          158 : HcclResult CcuResBatchAllocator::Deinit()
     105              : {
     106          158 :     missionMgr_.Reset();
     107          474 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     108          316 :         resBlocks_[dieId].clear();
     109              :     }
     110              : 
     111          158 :     handleMap_.clear();
     112          158 :     initFlag_ = false;
     113          158 :     return HcclResult::HCCL_SUCCESS;
     114              : }
     115              : 
     116          162 : static CcuResBlockNums GetPreAllocatedMaxBlockNums(const uint32_t devLogicId, const uint8_t dieId,
     117              :     const std::array<CcuBlockResStrategy, CCU_MAX_IODIE_NUM> &resStrategies)
     118              : {
     119          162 :     CcuResBlockNums blockNums{};
     120              : 
     121          162 :     CcuResSpecifications &ccuResSepcs = CcuResSpecifications::GetInstance(devLogicId);
     122              : 
     123          162 :     uint32_t loopNum = 0;
     124          162 :     (void)ccuResSepcs.GetLoopEngineNum(dieId, loopNum);
     125          162 :     blockNums.loopNum = loopNum / resStrategies[dieId].loopNum;
     126              : 
     127          162 :     uint32_t msNum = 0;
     128          162 :     (void)ccuResSepcs.GetMsNum(dieId, msNum);
     129          162 :     blockNums.msNum = msNum / resStrategies[dieId].msNum;
     130              : 
     131          162 :     uint32_t ckeNum = 0;
     132          162 :     (void)ccuResSepcs.GetCkeNum(dieId, ckeNum);
     133          162 :     if (ckeNum > RESERVED_DISCRETE_CKE_NUM) {
     134          162 :         blockNums.ckeNum = (ckeNum - RESERVED_DISCRETE_CKE_NUM) / resStrategies[dieId].ckeNum;
     135              :     } else {
     136            0 :         blockNums.ckeNum = 0;
     137              :     }
     138              : 
     139          162 :     uint32_t xnNum = 0;
     140          162 :     (void)ccuResSepcs.GetXnNum(dieId, xnNum);
     141          162 :     if (xnNum > RESERVED_DISCRETE_XN_NUM) {
     142          162 :         blockNums.xnNum = (xnNum - RESERVED_DISCRETE_XN_NUM) / resStrategies[dieId].xnNum;
     143              :     } else {
     144            0 :         blockNums.xnNum = 0;
     145              :     }
     146              : 
     147          162 :     if (ccuResSepcs.GetCcuVersion() == CcuVersion::CCU_V1) {
     148          134 :         uint32_t gsaNum = 0;
     149          134 :         (void)ccuResSepcs.GetGsaNum(dieId, gsaNum);
     150          134 :         if (gsaNum > RESERVED_DISCRETE_GSA_NUM) {
     151          134 :             blockNums.gsaNum = (gsaNum - RESERVED_DISCRETE_GSA_NUM) / resStrategies[dieId].gsaNum;
     152              :         } else {
     153            0 :             blockNums.gsaNum = 0;
     154              :         }
     155              :     } else {
     156           28 :         blockNums.gsaNum = 0;
     157              :     }
     158              : 
     159          162 :     HCCL_INFO("[CcuResBatchAllocator][%s] batch allocator will alloc blocks resources: loop blocks[%u] "
     160              :         "ms blocks[%u] cke blocks[%u] xn blocks[%u] gsa blocks[%u], devLogicId[%d] dieId[%u].",
     161              :         __func__, blockNums.loopNum, blockNums.msNum, blockNums.ckeNum, blockNums.xnNum, blockNums.gsaNum,
     162              :         devLogicId, dieId);
     163          324 :     return blockNums;
     164              : }
     165              : 
     166           16 : HcclResult CcuResBatchAllocator::GetAllocatableMaxBlockResNum(ResType resType,
     167              :     uint8_t dieId, uint32_t &num) const
     168              : {
     169           16 :     switch (resType) {
     170            7 :         case ResType::LOOP:
     171            7 :             num = maxResBlockNums_.loopNum * resStrategies_[dieId].loopNum;
     172            7 :             break;
     173            3 :         case ResType::MS:
     174            3 :             num = maxResBlockNums_.msNum * resStrategies_[dieId].msNum;
     175            3 :             break;
     176            2 :         case ResType::CKE:
     177            2 :             num = maxResBlockNums_.ckeNum * resStrategies_[dieId].ckeNum;
     178            2 :             break;
     179            2 :         case ResType::XN:
     180            2 :             num = maxResBlockNums_.xnNum * resStrategies_[dieId].xnNum;
     181            2 :             break;
     182            2 :         case ResType::GSA:
     183            2 :             num = maxResBlockNums_.gsaNum * resStrategies_[dieId].gsaNum;
     184            2 :             break;
     185            0 :         default:
     186            0 :             HCCL_ERROR("[CcuResBatchAllocator][%s] unsupported block res type[%s], devLogicId[%d] dieId[%u].",
     187              :                 __func__, resType.Describe().c_str(), devLogicId_, dieId);
     188            0 :             return HcclResult::HCCL_E_PARA;
     189              :     }
     190           16 :     return HcclResult::HCCL_SUCCESS;
     191              : }
     192              : 
     193           81 : HcclResult CcuResBatchAllocator::PreAllocBlockRes()
     194              : {
     195           81 :     CcuComponent &ccuComponent = CcuComponent::GetInstance(devLogicId_);
     196           81 :     const auto serveMode = CcuResSpecifications::GetInstance(devLogicId_).GetServeMode();
     197          243 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     198          162 :         if (!dieEnableFlags_[dieId]) {
     199            0 :             HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d] dieId[%u] is not enable, "
     200              :                 "will not pre-allocate block resource.", __func__, devLogicId_, dieId);
     201            0 :             continue;
     202              :         }
     203              : 
     204          162 :         maxResBlockNums_ = GetPreAllocatedMaxBlockNums(devLogicId_, dieId, resStrategies_);
     205              :         const std::array<std::tuple<ResType, uint32_t, uint32_t>, BLOCK_RES_TYPE_NUM> blockResReqs = {
     206          162 :             std::make_tuple(ResType::LOOP, maxResBlockNums_.loopNum, resStrategies_[dieId].loopNum),
     207          162 :             std::make_tuple(ResType::MS, maxResBlockNums_.msNum, resStrategies_[dieId].msNum),
     208          162 :             std::make_tuple(ResType::CKE, maxResBlockNums_.ckeNum, resStrategies_[dieId].ckeNum),
     209          162 :             std::make_tuple(ResType::XN, maxResBlockNums_.xnNum, resStrategies_[dieId].xnNum),
     210          162 :             std::make_tuple(ResType::GSA, maxResBlockNums_.gsaNum, resStrategies_[dieId].gsaNum),
     211          810 :         };
     212              : 
     213          972 :         for (auto &resReq : blockResReqs) {
     214          810 :             const ResType resType = std::get<0>(resReq);
     215          810 :             const uint32_t blockNum = std::get<1>(resReq);
     216          810 :             const uint32_t blockSize = std::get<2>(resReq);
     217          810 :             const uint32_t reqNum = blockNum * blockSize; // 生成时已保证不会溢出
     218          810 :             if (reqNum == 0) {
     219           28 :                 HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d] dieId[%u], "
     220              :                     "resType[%s], request num is 0, passed.", __func__,
     221              :                     devLogicId_, dieId, resType.Describe().c_str());
     222           28 :                 continue;
     223              :             }
     224              : 
     225          782 :             std::vector<ResInfo> tempResInfos;
     226          782 :             auto ret = ccuComponent.AllocRes(dieId, resType, reqNum, true, tempResInfos);
     227          782 :             if (ret == HcclResult::HCCL_E_UNAVAIL) {
     228            0 :                 HCCL_WARNING("[CcuResBatchAllocator][%s] failed, devLogicId[%d] dieId[%u], "
     229              :                     "failed to pre allocate block type resource, resType[%s], num[%u].",
     230              :                     __func__, devLogicId_, dieId, resType.Describe().c_str(), reqNum);
     231            0 :                 return ret;
     232              :             }
     233          782 :             CHK_RET(ret);
     234              : 
     235          782 :             const bool avoidCcu0Flag = (serveMode == ServeMode::ARMX86 && dieId == 0 && resType == ResType::MS);
     236          782 :             std::vector<BlockInfo> tempBlocks;
     237          782 :             const uint32_t startId = tempResInfos[0].startId;
     238        52112 :             for (uint32_t k = 0; k < blockNum; k++) {
     239        51330 :                 BlockInfo blockInfo;
     240        51330 :                 blockInfo.id        = k;
     241        51330 :                 blockInfo.startId   = startId + k * blockSize;
     242        51330 :                 blockInfo.num       = blockSize;
     243              :                 // A+X形态,PCIE连接到IOdie0,导致IOdie0上连接PCIE的CCUA0无法使用,分配MS资源时需要跳过CCUA0
     244              :                 // 给要分给CCUA0的块,设置成已分配过,防止后续分给算法使用
     245        51330 :                 blockInfo.allocated = avoidCcu0Flag ? k % CCUA_NUM == 0 : false;
     246        51330 :                 blockInfo.handle    = 0;
     247        51330 :                 tempBlocks.emplace_back(blockInfo);
     248              :             }
     249          782 :             resBlocks_[dieId][resType] = std::move(tempBlocks);
     250          782 :         }
     251              :     }
     252              : 
     253           81 :     return HcclResult::HCCL_SUCCESS;
     254              : }
     255              : 
     256          206 : static bool CheckReqValid(const CcuResReq &req, int32_t devLogicId,
     257              :     std::array<bool, CCU_MAX_IODIE_NUM> &dieEnableFlags)
     258              : {
     259          206 :     bool ifValid = false;
     260          618 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     261              :         const std::array<uint32_t, REQ_RES_TYPE_NUM> reqs = {
     262          412 :             req.loopEngineReq[i],
     263          412 :             req.blockLoopEngineReq[i],
     264          412 :             req.msReq[i],
     265          412 :             req.blockMsReq[i],
     266          412 :             req.ckeReq[i],
     267          412 :             req.blockCkeReq[i],
     268          412 :             req.xnReq[i],
     269          412 :             req.blockXnReq[i],
     270          412 :             req.gsaReq[i],
     271          412 :             req.blockGsaReq[i],
     272          412 :             req.missionReq.req[i]
     273          412 :         };
     274              : 
     275          824 :         const bool ifReqEmpty = std::all_of(std::begin(reqs), std::end(reqs),
     276         2672 :             [](uint32_t x) { return x == 0; });
     277          412 :         if (!dieEnableFlags[i] && !ifReqEmpty) { // 当前die未使能,但请求资源
     278            0 :             HCCL_ERROR("[CcuResBatchAllocator][%s] failed, dieId[%u] is not enable, "
     279              :                 "but resource request is not empty, devLogicId[%d].",
     280              :                 __func__, i, devLogicId);
     281            0 :             return false;
     282              :         }
     283              : 
     284              :         // 当前die使能,并且请求资源即合法
     285          412 :         if (dieEnableFlags[i] && !ifReqEmpty) {
     286          258 :             ifValid = true;
     287              :         }
     288              :     }
     289              : 
     290          206 :     if (!ifValid) {
     291            0 :         HCCL_ERROR("[CcuResBatchAllocator][%s] all dies resource request is empty, "
     292              :             "devLogicId[%d].", __func__, devLogicId);
     293              :     }
     294              : 
     295          206 :     return ifValid;
     296              : }
     297              : 
     298          206 : HcclResult CcuResBatchAllocator::AllocResHandle(const CcuResReq &resReq,
     299              :     CcuResHandle &resHandle)
     300              : {
     301          206 :     if (!CheckReqValid(resReq, devLogicId_, dieEnableFlags_)) {
     302            0 :         resHandle = nullptr;
     303            0 :         HCCL_ERROR("[CcuResBatchAllocator][%s] failed, devLogicId[%d], invalid resource "
     304              :             "request, all resource request is empty.", __func__, devLogicId_);
     305            0 :         return HcclResult::HCCL_E_PARA;
     306              :     }
     307              : 
     308          206 :     std::unique_ptr<CcuResRepository> resRepoPtr = nullptr;
     309          206 :     resRepoPtr.reset(new (std::nothrow) CcuResRepository());
     310          206 :     CHK_PTR_NULL(resRepoPtr);
     311          206 :     const uintptr_t handleKey = reinterpret_cast<uintptr_t>(resRepoPtr.get());
     312              :     // 申请分配临时资源
     313          206 :     HcclResult ret = TryAllocResHandle(handleKey, resReq, resRepoPtr);
     314          206 :     if (ret != HcclResult::HCCL_SUCCESS) {
     315            0 :         resHandle = nullptr;
     316            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] failed, devLogicId[%d], failed to "
     317              :             "allocate resource handle, release temporary resources of this request.",
     318              :             __func__, devLogicId_);
     319              : 
     320              :         // 释放申请的临时资源,由CcuResRepo对象对应的智能指针管理
     321            0 :         HcclResult releaseRet = ReleaseResource(resRepoPtr);
     322            0 :         if (releaseRet != HcclResult::HCCL_SUCCESS) {
     323            0 :             HCCL_ERROR("[CcuResBatchAllocator][%s] failed, devLogicId[%d], "
     324              :                 "failed to release temporary resources of this request.",
     325              :                 __func__, devLogicId_);
     326            0 :             return releaseRet;
     327              :         }
     328              : 
     329            0 :         HCCL_INFO("[CcuResBatchAllocator][%s] devLogicId[%d], "
     330              :             "temporary resources released.", __func__, devLogicId_);
     331            0 :         return ret;
     332              :     }
     333              :     // 保存资源信息
     334          206 :     resHandle = reinterpret_cast<CcuResHandle>(resRepoPtr.get());
     335          206 :     handleMap_[handleKey] = std::move(resRepoPtr);
     336              : 
     337          206 :     return HcclResult::HCCL_SUCCESS;
     338          206 : }
     339              : 
     340          544 : static HcclResult HandleBlockRes(const uintptr_t handleKey, const uint32_t num,
     341              :     const uint32_t blockSize, std::vector<BlockInfo> &blocks,
     342              :     std::vector<ResInfo> &resInfos)
     343              : {
     344          544 :     uint32_t blockNum     = 1 + (num - 1) / blockSize;
     345          544 :     uint32_t blockMaxSize = blocks.size();
     346          544 :     uint32_t blockStartId = blockMaxSize;
     347          544 :     uint32_t freeNum      = 0;
     348          544 :     bool     allocatable  = false;
     349         8425 :     for (size_t k = 0; k < blockMaxSize; k++) {
     350              :         // 如果当前块已分配,说明当前分配不够,重置分配数量与起始id
     351         8425 :         if (blocks[k].allocated) {
     352            0 :             blockStartId = blockMaxSize;
     353            0 :             freeNum = 0;
     354            0 :             continue;
     355              :         }
     356              :         // 如果是首个可分配块,记录起始id
     357         8425 :         if (blockStartId == blockMaxSize) {
     358          544 :             blockStartId = k;
     359              :         }
     360              :         // 当前块未分配,更新可分配数量
     361         8425 :         freeNum++;
     362              :         // 可分配数量足够则分配成功
     363         8425 :         if (freeNum >= blockNum) {
     364          544 :             allocatable = true;
     365          544 :             break;
     366              :         }
     367              :     }
     368          544 :     if (!allocatable) {
     369            0 :         return HcclResult::HCCL_E_UNAVAIL;
     370              :     }
     371              :     // 更新所有新分配的块的信息
     372         8969 :     for (size_t k = blockStartId; k < blockStartId + blockNum; k++) {
     373         8425 :         blocks[k].handle    = handleKey;
     374         8425 :         blocks[k].allocated = true;
     375              :     }
     376          544 :     resInfos.emplace_back(ResInfo{blocks[blockStartId].startId, blockNum * blockSize});
     377          544 :     return HcclResult::HCCL_SUCCESS;
     378              : }
     379              : 
     380            0 : static void DumpBlockResInfo(ResType resType, const std::vector<BlockInfo> &blocks)
     381              : {
     382            0 :     HCCL_INFO("Dump ResType[%s] block resources info: ", resType.Describe().c_str());
     383            0 :     uint32_t blockNum = blocks.size();
     384            0 :     for (size_t k = 0; k < blockNum; k++) {
     385            0 :         HCCL_INFO("Block[id[%u], startId[%u], num[%u], handle(uintptr_t)[%llu], allocated[%d]]",
     386              :             blocks[k].id, blocks[k].startId, blocks[k].num, static_cast<unsigned long long>(blocks[k].handle),
     387              :             static_cast<int>(blocks[k].allocated));
     388              :     }
     389            0 : }
     390              : 
     391          206 : HcclResult CcuResBatchAllocator::AllocBlockRes(const uintptr_t handleKey,
     392              :     const CcuResReq &resReq, std::unique_ptr<CcuResRepository> &resRepoPtr)
     393              : {
     394              :     using ResTypeReqNumBlockNumFunc =
     395              :         std::tuple<ResType::Value, uint32_t, uint32_t, std::vector<ResInfo> &>;
     396              : 
     397          618 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     398          412 :         if (!dieEnableFlags_[dieId]) {
     399            0 :             HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d] dieId[%u] is not enable, "
     400              :                 "will not allocate block resource.", __func__, devLogicId_, dieId);
     401            0 :             continue;
     402              :         }
     403              : 
     404              :         std::array<ResTypeReqNumBlockNumFunc, BLOCK_RES_TYPE_NUM> blockReqParas = {
     405            0 :             std::make_tuple(ResType::LOOP, resReq.blockLoopEngineReq[dieId],
     406          412 :                 resStrategies_[dieId].loopNum, std::ref(resRepoPtr->blockLoopEngine[dieId])),
     407            0 :             std::make_tuple(ResType::MS, resReq.blockMsReq[dieId],
     408          412 :                 resStrategies_[dieId].msNum, std::ref(resRepoPtr->blockMs[dieId])),
     409            0 :             std::make_tuple(ResType::CKE, resReq.blockCkeReq[dieId],
     410          412 :                 resStrategies_[dieId].ckeNum, std::ref(resRepoPtr->blockCke[dieId])),
     411            0 :             std::make_tuple(ResType::XN, resReq.blockXnReq[dieId],
     412          412 :                 resStrategies_[dieId].xnNum, std::ref(resRepoPtr->blockXn[dieId])),
     413            0 :             std::make_tuple(ResType::GSA, resReq.blockGsaReq[dieId],
     414          412 :                 resStrategies_[dieId].gsaNum, std::ref(resRepoPtr->blockGsa[dieId]))
     415         2060 :         };
     416              :         
     417         2472 :         for (uint32_t blockType = 0; blockType < BLOCK_RES_TYPE_NUM; blockType++) {
     418         2060 :             const auto &req = blockReqParas[blockType];
     419         2060 :             const uint32_t num = std::get<1>(req);
     420         2060 :             if (num == 0) {
     421         1568 :                 continue;
     422              :             }
     423              : 
     424          492 :             const ResType resType = std::get<0>(req);
     425          492 :             const uint32_t blockSize = std::get<2>(req);
     426          492 :             auto &blocks = resBlocks_[dieId][resType];
     427          492 :             auto &resInfos = std::get<3>(req);
     428          492 :             auto ret = HandleBlockRes(handleKey, num, blockSize, blocks, resInfos);
     429          492 :             if (ret != HcclResult::HCCL_SUCCESS) {
     430            0 :                 HCCL_WARNING("[CcuResBatchAllocator][%s] failed, devLogicId[%d] dieId[%u], "
     431              :                     "failed to allocate [%s] block resource, remaining block resources are "
     432              :                     "not enough, request num[%u].", __func__, devLogicId_, dieId,
     433              :                     resType.Describe().c_str(), num);
     434            0 :                 DumpBlockResInfo(resType, resBlocks_[dieId][resType]);
     435            0 :                 return ret;
     436              :             }
     437              :         }
     438              :     }
     439          206 :     return HcclResult::HCCL_SUCCESS;
     440              : }
     441              : 
     442          206 : HcclResult CcuResBatchAllocator::AllocConsecutiveRes(const CcuResReq &resReq,
     443              :     std::unique_ptr<CcuResRepository> &resRepoPtr) const
     444              : {
     445              :     using ResTypeReqNumResInfoTuple = std::tuple<ResType, uint32_t, std::vector<ResInfo>&>;
     446              : 
     447          206 :     CcuComponent &ccuComponent = CcuComponent::GetInstance(devLogicId_);
     448          618 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     449          412 :         if (!dieEnableFlags_[dieId]) {
     450            0 :             HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d] dieId[%u] is not enable, "
     451              :                 "will not allocate consecutive resource.", __func__, devLogicId_, dieId);
     452            0 :             continue;
     453              :         }
     454              : 
     455              :         std::array<ResTypeReqNumResInfoTuple, CONS_RES_TYPE_NUM> reqParas = {
     456          412 :             std::make_tuple(ResType::XN, resReq.xnReq[dieId],
     457          412 :                 std::ref(resRepoPtr->xn[dieId]))
     458          412 :         };
     459              : 
     460          824 :         for (const auto &req : reqParas) {
     461          412 :             if (std::get<1>(req) == 0) {
     462          258 :                 continue;
     463              :             }
     464              : 
     465          154 :             std::vector<ResInfo> resInfos;
     466          154 :             auto ret = ccuComponent.AllocRes(dieId, std::get<0>(req), std::get<1>(req),
     467              :                 true, resInfos);
     468          154 :             if (ret == HcclResult::HCCL_E_UNAVAIL) {
     469            0 :                 HCCL_WARNING("[CcuResBatchAllocator][%s] failed, devLogicId[%d] dieId[%u], "
     470              :                     "failed to allocate %s resource, num[%u].", __func__, devLogicId_, dieId,
     471              :                     std::get<0>(req).Describe().c_str(), std::get<1>(req));
     472            0 :                 return ret;
     473              :             }
     474          154 :             CHK_RET(ret);
     475              : 
     476          154 :             std::get<2>(req) = resInfos;
     477          154 :         }
     478              :     }
     479              : 
     480          206 :     return HcclResult::HCCL_SUCCESS;
     481              : }
     482              : 
     483          206 : HcclResult CcuResBatchAllocator::AllocDiscreteRes(const CcuResReq &resReq,
     484              :     std::unique_ptr<CcuResRepository> &resRepoPtr) const
     485              : {
     486              :     using ResTypeReqNumResInfoTuple = std::tuple<ResType, uint32_t, std::vector<ResInfo>&>;
     487              : 
     488          206 :     CcuComponent &ccuComponent = CcuComponent::GetInstance(devLogicId_);
     489          618 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     490          412 :         if (!dieEnableFlags_[dieId]) {
     491            0 :             HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d] dieId[%u] is not enable, "
     492              :                 "will not allocate discrete resource.", __func__, devLogicId_, dieId);
     493            0 :             continue;
     494              :         }
     495              : 
     496              :         std::array<ResTypeReqNumResInfoTuple, DISCRETE_RES_TYPE_NUM> reqParas = {
     497          412 :             std::make_tuple(ResType::LOOP, resReq.loopEngineReq[dieId],
     498          412 :                 std::ref(resRepoPtr->loopEngine[dieId])),
     499          412 :             std::make_tuple(ResType::MS, resReq.msReq[dieId], std::ref(resRepoPtr->ms[dieId])),
     500          412 :             std::make_tuple(ResType::CKE, resReq.ckeReq[dieId], std::ref(resRepoPtr->cke[dieId])),
     501          412 :             std::make_tuple(ResType::GSA, resReq.gsaReq[dieId], std::ref(resRepoPtr->gsa[dieId]))
     502         1648 :         };
     503              : 
     504         2060 :         for (const auto &req : reqParas) {
     505         1648 :             if (std::get<1>(req) == 0) {
     506         1368 :                 continue;
     507              :             }
     508              : 
     509          280 :             std::vector<ResInfo> resInfos;
     510          280 :             auto ret = ccuComponent.AllocRes(dieId, std::get<0>(req), std::get<1>(req),
     511              :                 false, resInfos);
     512          280 :             if (ret == HcclResult::HCCL_E_UNAVAIL) {
     513            0 :                 HCCL_WARNING("[CcuResBatchAllocator][%s] failed, devLogicId[%d] dieId[%u], "
     514              :                     "failed to allocate %s resource, num[%u].", __func__, devLogicId_, dieId,
     515              :                     std::get<0>(req).Describe().c_str(), std::get<1>(req));
     516            0 :                 return ret;
     517              :             }
     518          280 :             CHK_RET(ret);
     519              : 
     520          280 :             std::get<2>(req) = resInfos; // 2: resRepotPtr to resource
     521          280 :         }
     522              :     }
     523              : 
     524          206 :     return HcclResult::HCCL_SUCCESS;
     525              : }
     526              : 
     527          206 : HcclResult CcuResBatchAllocator::TryAllocResHandle(const uintptr_t handleKey,
     528              :     const CcuResReq &resReq, std::unique_ptr<CcuResRepository> &resRepoPtr)
     529              : {
     530          206 :     std::unique_lock<std::mutex> lock(innerMutex_);
     531              : 
     532          206 :     HcclResult ret = AllocBlockRes(handleKey, resReq, resRepoPtr);
     533          206 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
     534            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] failed, devLogicId[%d], "
     535              :             "failed to allocate block type resource.", __func__, devLogicId_);
     536            0 :         return ret;
     537              :     }
     538          206 :     CHK_RET(ret);
     539              : 
     540          206 :     ret = missionMgr_.Alloc(handleKey, resReq.missionReq, resRepoPtr->mission);
     541          206 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
     542            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d], failed to allocate "
     543              :             "mission resource, remaining block resources are not enough.",
     544              :             __func__, devLogicId_);
     545            0 :         return ret;
     546              :     }
     547          206 :     CHK_RET(ret);
     548              : 
     549          206 :     ret = AllocConsecutiveRes(resReq, resRepoPtr);
     550          206 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
     551            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d], failed to allocate "
     552              :             "consecutive resource.", __func__, devLogicId_);
     553            0 :         return ret;
     554              :     }
     555          206 :     CHK_RET(ret);
     556              : 
     557          206 :     ret = AllocDiscreteRes(resReq, resRepoPtr);
     558          206 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
     559            0 :         HCCL_WARNING("[CcuResBatchAllocator][%s] devLogicId[%d], failed to allocate "
     560              :             "discrete resource.", __func__, devLogicId_);
     561            0 :         return ret;
     562              :     }
     563          206 :     CHK_RET(ret);
     564              : 
     565          206 :     return HcclResult::HCCL_SUCCESS;
     566          206 : }
     567              : 
     568          544 : static void ReleaseBlockRes(const uint32_t blockSize, std::vector<BlockInfo> &blocks,
     569              :     std::vector<ResInfo> &resInfos)
     570              : {
     571          544 :     uint32_t startId = resInfos[0].startId;
     572          544 :     uint32_t num     = resInfos[0].num;
     573          544 :     uint32_t startBlockId = (startId - blocks[0].startId) / blockSize;
     574          544 :     uint32_t blockNum     = num / blockSize;
     575              : 
     576         8969 :     for (uint32_t k = startBlockId; k < startBlockId + blockNum; k++) {
     577         8425 :         blocks[k].handle    = 0;
     578         8425 :         blocks[k].allocated = false;
     579              :     }
     580          544 :     resInfos.clear();
     581          544 : }
     582              : 
     583           52 : HcclResult CcuResBatchAllocator::ReleaseResHandle(const CcuResHandle &handle)
     584              : {
     585           52 :     std::unique_lock<std::mutex> lock(innerMutex_);
     586              : 
     587           52 :     uintptr_t handleKey = reinterpret_cast<uintptr_t>(handle);
     588           52 :     if (handleMap_.find(handleKey) == handleMap_.end()) {
     589            0 :         HCCL_ERROR("[CcuResBatchAllocator][%s] failed, devLogicId[%d], "
     590              :             "failed to find resource repository, invalid resource handle(uintptr_t)[%llu]",
     591              :             __func__, devLogicId_, static_cast<unsigned long long>(handleKey));
     592            0 :         return HcclResult::HCCL_E_PARA;
     593              :     }
     594              : 
     595           52 :     std::unique_ptr<CcuResRepository> &resRepoPtr = handleMap_[handleKey];
     596              : 
     597           52 :     auto ret = ReleaseResource(resRepoPtr);
     598           52 :     if (ret != HcclResult::HCCL_SUCCESS) {
     599            0 :         HCCL_ERROR("[CcuResBatchAllocator][%s] failed, devLogicId[%d], "
     600              :             "failed[%u] to release resource.", __func__, devLogicId_, ret);
     601            0 :         return ret;
     602              :     }
     603              : 
     604           52 :     handleMap_.erase(handleKey);
     605           52 :     return HcclResult::HCCL_SUCCESS;
     606           52 : }
     607              : 
     608           52 : HcclResult CcuResBatchAllocator::ReleaseResource(std::unique_ptr<CcuResRepository> &resRepoPtr)
     609              : {
     610           52 :     ReleaseBlockResource(resRepoPtr);
     611           52 :     missionMgr_.Release(resRepoPtr->mission);
     612           52 :     HcclResult ret = ReleaseNonBlockTypeRes(resRepoPtr);
     613           52 :     if (ret != HcclResult::HCCL_SUCCESS) {
     614            0 :         HCCL_ERROR("[CcuResBatchAllocator][%s] failed, devLogicId[%d], "
     615              :             "failed[%u] to release discrete resource.", __func__, devLogicId_, ret);
     616            0 :         return ret;
     617              :     }
     618              : 
     619           52 :     return HcclResult::HCCL_SUCCESS;
     620              : }
     621              : 
     622           52 : void CcuResBatchAllocator::ReleaseBlockResource(std::unique_ptr<CcuResRepository> &resRepoPtr)
     623              : {
     624              :     using BlockSizeResNum = std::tuple<ResType, uint32_t, std::vector<ResInfo>&>;
     625              : 
     626          156 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     627          104 :         if (!dieEnableFlags_[i]) {
     628            0 :             continue;
     629              :         }
     630              : 
     631              :         const std::array<BlockSizeResNum, BLOCK_RES_TYPE_NUM> blockReqParas = {
     632          104 :             std::make_tuple(ResType::LOOP, resStrategies_[i].loopNum, std::ref(resRepoPtr->blockLoopEngine[i])),
     633          104 :             std::make_tuple(ResType::MS, resStrategies_[i].msNum, std::ref(resRepoPtr->blockMs[i])),
     634          104 :             std::make_tuple(ResType::CKE, resStrategies_[i].ckeNum, std::ref(resRepoPtr->blockCke[i])),
     635          104 :             std::make_tuple(ResType::XN, resStrategies_[i].xnNum, std::ref(resRepoPtr->blockXn[i])),
     636          104 :             std::make_tuple(ResType::GSA, resStrategies_[i].gsaNum, std::ref(resRepoPtr->blockGsa[i]))
     637          520 :         };
     638              : 
     639          624 :         for (uint32_t j = 0; j < BLOCK_RES_TYPE_NUM; j++) {
     640          520 :             auto req = blockReqParas[j];
     641          520 :             std::vector<ResInfo> &resInfos = std::get<2>(req);
     642          520 :             auto resType = std::get<0>(req);
     643          520 :             std::vector<BlockInfo> &blocks = resBlocks_[i][resType];
     644          520 :             if (resInfos.size() == 0 || blocks.size() == 0) {
     645           28 :                 continue;
     646              :             }
     647          492 :             ReleaseBlockRes(std::get<1>(req), blocks, resInfos);
     648              :         }
     649              :     }
     650           52 : }
     651              : 
     652              : using ResTypeResInfo = std::pair<ResType, std::vector<ResInfo>*>;
     653            0 : static auto EraseReverse(std::vector<ResInfo>& vec,
     654              :                          std::vector<ResInfo>::reverse_iterator it)
     655              :     -> std::vector<ResInfo>::reverse_iterator
     656              : {
     657              :     return std::vector<ResInfo>::reverse_iterator(
     658            0 :         vec.erase(std::next(it).base())
     659            0 :     );
     660              : }
     661              : 
     662          104 : static HcclResult DoReleaseNonBlockTypeRes(
     663              :     int32_t devLogicId, uint8_t dieId,
     664              :     std::array<ResTypeResInfo, NON_BLOCK_TYPE_NUM>& infoParas)
     665              : {
     666          104 :     CcuComponent& ccuComponent = CcuComponent::GetInstance(devLogicId);
     667              : 
     668          624 :     for (auto& infos : infoParas) {
     669          520 :         const ResType resType = infos.first;
     670          520 :         std::vector<ResInfo>* resInfosPtr = infos.second;
     671          520 :         if (resInfosPtr == nullptr || resInfosPtr->empty()) {
     672          520 :             continue;
     673              :         }
     674            0 :         std::vector<ResInfo>& resInfos = *resInfosPtr;
     675              :         // 倒序删除,减少vector元素移动
     676            0 :         for (auto it = resInfos.rbegin(); it != resInfos.rend(); ) {
     677            0 :             const uint32_t num = it->num;
     678            0 :             if (num == 0) {
     679            0 :                 it = EraseReverse(resInfos, it);
     680            0 :                 continue;
     681              :             }
     682              : 
     683            0 :             const uint32_t startId = it->startId;
     684            0 :             auto ret = ccuComponent.ReleaseRes(dieId, resType, startId, num);
     685            0 :             if (ret != HcclResult::HCCL_SUCCESS) {
     686            0 :                 HCCL_ERROR("[CcuResBatchAllocator][%s] failed, devLogicId[%d] dieId[%u], "
     687              :                     "failed to release %s resource, startId[%u], num[%u].", __func__,
     688              :                     devLogicId, dieId, resType.Describe().c_str(), startId, num);
     689            0 :                 return ret;
     690              :             }
     691              : 
     692            0 :             it = EraseReverse(resInfos, it);
     693              :         }
     694              :     }
     695          104 :     return HcclResult::HCCL_SUCCESS;
     696              : }
     697              : 
     698           52 : HcclResult CcuResBatchAllocator::ReleaseNonBlockTypeRes(
     699              :     std::unique_ptr<CcuResRepository>& resRepoPtr) const
     700              : {
     701          156 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     702          104 :         if (!dieEnableFlags_[dieId]) {
     703            0 :             continue;
     704              :         }
     705              : 
     706              :         std::array<ResTypeResInfo, NON_BLOCK_TYPE_NUM> infoParas = {{
     707          104 :             {ResType::LOOP, &resRepoPtr->loopEngine[dieId]},
     708          104 :             {ResType::MS,   &resRepoPtr->ms[dieId]},
     709          104 :             {ResType::CKE,  &resRepoPtr->cke[dieId]},
     710          104 :             {ResType::XN,   &resRepoPtr->xn[dieId]},
     711          104 :             {ResType::GSA,  &resRepoPtr->gsa[dieId]}
     712          520 :         }};
     713              :     
     714          104 :         CHK_RET(DoReleaseNonBlockTypeRes(devLogicId_, dieId, infoParas));
     715              :     }
     716              : 
     717           52 :     return HcclResult::HCCL_SUCCESS;
     718              : }
     719              : 
     720          327 : HcclResult CcuResBatchAllocator::GetResource(const CcuResHandle &handle,
     721              :     CcuResRepository &ccuResRepo)
     722              : {
     723          327 :     std::unique_lock<std::mutex> lock(innerMutex_);
     724              : 
     725          327 :     uintptr_t handleKey = reinterpret_cast<uintptr_t>(handle);
     726          327 :     if (handleMap_.find(handleKey) == handleMap_.end()) {
     727            0 :         HCCL_ERROR("[CcuResBatchAllocator][%s] devLogicId[%d], failed to find "
     728              :             "resource repository, invalid resource handle(uintptr_t)[%lu]",
     729              :             __func__, devLogicId_, handleKey);
     730            0 :         return HcclResult::HCCL_E_PARA;
     731              :     }
     732              : 
     733          327 :     ccuResRepo = *(handleMap_[handleKey].get());
     734          327 :     return HcclResult::HCCL_SUCCESS;
     735          327 : }
     736              : 
     737           81 : static HcclResult PreAllocMissionRes(int32_t devLogicId,
     738              :     std::array<bool, CCU_MAX_IODIE_NUM> &dieEnableFlags,
     739              :     std::array<uint32_t, CCU_MAX_IODIE_NUM> &missionNums,
     740              :     std::array<uint32_t, CCU_MAX_IODIE_NUM> &missionStartIds)
     741              : {
     742           81 :     auto &ccuResSepcs = CcuResSpecifications::GetInstance(devLogicId);
     743           81 :     auto &ccuComponent = CcuComponent::GetInstance(devLogicId);
     744          243 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     745          162 :         if (!dieEnableFlags[i]) {
     746            0 :             missionNums[i]     = 0;
     747            0 :             missionStartIds[i] = 0;
     748            0 :             continue;
     749              :         }
     750              : 
     751          162 :         (void)ccuResSepcs.GetMissionNum(i, missionNums[i]);
     752          162 :         std::vector<ResInfo> tempResInfos;
     753          162 :         auto ret = ccuComponent.AllocRes(i, ResType::MISSION, missionNums[i],
     754              :             true, tempResInfos);
     755          162 :         if (ret == HcclResult::HCCL_E_UNAVAIL) {
     756            0 :             HCCL_WARNING("[CcuMissionMgr][%s] devLogicId[%d] dieId[%u], failed[%u] "
     757              :                 "to pre allocate mission resource, num[%u]", __func__, devLogicId,
     758              :                 i, ret, missionNums[i]);
     759            0 :             return ret;
     760              :         }
     761          162 :         CHK_RET(ret);
     762              : 
     763          162 :         missionStartIds[i] = tempResInfos[0].startId;
     764          162 :     }
     765              : 
     766           81 :     return HcclResult::HCCL_SUCCESS;
     767              : }
     768              : 
     769           81 : HcclResult CcuResBatchAllocator::CcuMissionMgr::PreAlloc(const int32_t devLogicId,
     770              :     const uint32_t blockSize, const std::array<bool, CCU_MAX_IODIE_NUM> &dieFlags)
     771              : {
     772           81 :     dieEnableFlags_ = dieFlags;
     773              :     std::array<uint32_t, CCU_MAX_IODIE_NUM> missionNums;
     774              :     std::array<uint32_t, CCU_MAX_IODIE_NUM> missionStartIds;
     775              : 
     776           81 :     auto ret = PreAllocMissionRes(devLogicId, dieEnableFlags_,
     777              :         missionNums, missionStartIds);
     778           81 :     if (ret != HcclResult::HCCL_SUCCESS) {
     779            0 :         return ret;
     780              :     }
     781              : 
     782           81 :     uint32_t missionNum = 0;
     783           81 :     if (dieEnableFlags_[0]) {
     784           81 :         missionNum = missionNums[0];
     785            0 :     } else if (dieEnableFlags_[1]) {
     786            0 :         missionNum = missionNums[1];
     787              :     }
     788              : 
     789          162 :     if (dieEnableFlags_[0] && dieEnableFlags_[1] &&
     790           81 :         missionStartIds[0] != missionStartIds[1]) {
     791              :         // 当前 FUSION_MULTIPLE_DIE 要求多Die ID一致
     792            0 :         HCCL_ERROR("[CcuMissionMgr][%s] devLogicId[%d] die 0 allocated missions "
     793              :             "start with id %u, die 1 allocated missions start with id %u, the start "
     794              :             "id should be same.", __func__, devLogicId, missionStartIds[0],
     795              :             missionStartIds[1]);
     796            0 :         return HcclResult::HCCL_E_INTERNAL;
     797              :     }
     798              : 
     799           81 :     stragtegy_ = blockSize;
     800           81 :     uint32_t blockNum = missionNum / stragtegy_;
     801          729 :     for (uint32_t i = 0; i < blockNum; i++) {
     802          648 :         BlockInfo blockInfo;
     803          648 :         blockInfo.id        = i;
     804          648 :         blockInfo.startId   = missionStartIds[0] + i * stragtegy_;
     805          648 :         blockInfo.num       = stragtegy_;
     806          648 :         blockInfo.allocated = false;
     807          648 :         blockInfo.handle    = 0;
     808          648 :         blocks_.emplace_back(blockInfo);
     809              :     }
     810              : 
     811           81 :     return HcclResult::HCCL_SUCCESS;
     812              : }
     813              : 
     814          208 : static uint32_t Check2DieMissionReqNum(const MissionReq &missionReq,
     815              :     const std::array<bool, CCU_MAX_IODIE_NUM> &dieEnableFlags)
     816              : {
     817          208 :     uint32_t die0ReqNum = missionReq.req[0];
     818          208 :     uint32_t die1ReqNum = missionReq.req[1];
     819              : 
     820          208 :     if (dieEnableFlags[0] && dieEnableFlags[1]) {
     821          206 :         if (die0ReqNum != die1ReqNum) {
     822            0 :             HCCL_WARNING("[CcuMissionMgr][Alloc] die 0 request %u, die 1 request %u, "
     823              :                          "will choose the larger one.", die0ReqNum, die1ReqNum);
     824            0 :             return std::max(die0ReqNum, die1ReqNum);
     825              :         }
     826              : 
     827          206 :         return die0ReqNum;
     828              :     }
     829              : 
     830            2 :     if (dieEnableFlags[0]) {
     831            0 :         return die0ReqNum;
     832              :     }
     833              : 
     834            2 :     if (dieEnableFlags[1]) {
     835            0 :         return die1ReqNum;
     836              :     }
     837              : 
     838            2 :     return 0;
     839              : }
     840              : 
     841          208 : HcclResult CcuResBatchAllocator::CcuMissionMgr::Alloc(const uintptr_t handleKey,
     842              :     const MissionReq &missionReq, MissionResInfo &missionInfos)
     843              : {
     844          208 :     MissionReqType reqType = missionReq.reqType;
     845          208 :     constexpr MissionReqType defaultReqType = MissionReqType::FUSION_MULTIPLE_DIE;
     846          208 :     if (missionReq.reqType != MissionReqType::FUSION_MULTIPLE_DIE) {
     847            1 :         HCCL_WARNING("[CcuMissionMgr][%s] mission reqType[%d], mission resources "
     848              :             "now only support %d.", __func__, reqType,
     849              :             defaultReqType);
     850            1 :         reqType = MissionReqType::FUSION_MULTIPLE_DIE;
     851              :     }
     852              : 
     853          208 :     uint32_t reqNum = Check2DieMissionReqNum(missionReq, dieEnableFlags_);
     854          208 :     if (reqNum == 0) {
     855          156 :         HCCL_INFO("[CcuMissionMgr][%s] passed, request mission num is 0, "
     856              :             "will not allocate mission resource.", __func__);
     857          156 :         return HcclResult::HCCL_SUCCESS;
     858              :     }
     859              : 
     860           52 :     std::vector<ResInfo> resInfos;
     861           52 :     auto ret = HandleBlockRes(handleKey, reqNum, stragtegy_, blocks_, resInfos);
     862           52 :     if (ret == HcclResult::HCCL_E_UNAVAIL) {
     863            0 :         HCCL_WARNING("[CcuMissionMgr][%s] failed, mission block resources are unavailable, "
     864              :             "reqNum[%u], stragtegy[%u], reqType[%d].", __func__, reqNum, stragtegy_,
     865              :             reqType);
     866            0 :         DumpBlockResInfo(ResType::MISSION, blocks_);
     867            0 :         return ret;
     868              :     }
     869           52 :     CHK_RET(ret);
     870              : 
     871           52 :     missionInfos.reqType = reqType;
     872              : 
     873          156 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     874          104 :         if (dieEnableFlags_[i]) {
     875          104 :             missionInfos.mission[i] = resInfos;
     876              :         }
     877              :     }
     878              : 
     879           52 :     return HcclResult::HCCL_SUCCESS;
     880           52 : }
     881              : 
     882           52 : void CcuResBatchAllocator::CcuMissionMgr::Release(MissionResInfo &missionInfos)
     883              : {
     884              :     // 目前支持 FUSION_MULTIPLE_DIE 类型,故多die同步释放
     885           52 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     886           52 :         if (dieEnableFlags_[i] && missionInfos.mission[i].size() != 0) {
     887           52 :             ReleaseBlockRes(stragtegy_, blocks_, missionInfos.mission[i]);
     888           52 :             break;
     889              :         }
     890              :     }
     891              : 
     892          156 :     for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
     893          104 :         missionInfos.mission[i].clear();
     894              :     }
     895           52 : }
     896              : 
     897          158 : void CcuResBatchAllocator::CcuMissionMgr::Reset()
     898              : {
     899          158 :     blocks_.clear();
     900          158 : }
     901              : 
     902              : // 根据 resType 解析对应的 blocks 指针,将 MISSION 与普通块类型的分支收敛至此
     903              : // GetAllocatableMaxBlockResNum 内部通过 switch 校验块类型,非法类型直接返回错误
     904            7 : HcclResult CcuResBatchAllocator::ResolveBlocksPtr(uint8_t dieId, ResType resType,
     905              :     const std::vector<BlockInfo>*& blocksPtr) const
     906              : {
     907            7 :     if (resType == ResType::MISSION) {
     908            1 :         blocksPtr = &missionMgr_.GetBlocks();
     909            1 :         return HCCL_SUCCESS;
     910              :     }
     911              : 
     912            6 :     uint32_t poolSize = 0;
     913            6 :     CHK_RET(GetAllocatableMaxBlockResNum(resType, dieId, poolSize));
     914            6 :     if (poolSize == 0) {
     915            0 :         blocksPtr = nullptr;
     916            0 :         return HCCL_SUCCESS;
     917              :     }
     918              : 
     919            6 :     auto it = resBlocks_[dieId].find(resType);
     920            6 :     if (it == resBlocks_[dieId].end()) {
     921            0 :         blocksPtr = nullptr;
     922            0 :         return HCCL_SUCCESS;
     923              :     }
     924            6 :     blocksPtr = &it->second;
     925            6 :     return HCCL_SUCCESS;
     926              : }
     927              : 
     928              : // 直接扫描 resBlocks 的 allocated 标志计算最大连续空闲块数 × blockSize
     929              : // Block 分配时 HandleBlockRes 同步更新 allocated, 无需绕道 handleMap
     930            7 : HcclResult CcuResBatchAllocator::QueryRemainRes(
     931              :     uint8_t dieId, ResType resType, uint32_t &remainNum) const
     932              : {
     933            7 :     const std::vector<BlockInfo> *blocksPtr = nullptr;
     934            7 :     uint32_t blockSize = 0;
     935              : 
     936            7 :     CHK_RET(ResolveBlocksPtr(dieId, resType, blocksPtr));
     937            7 :     if (blocksPtr == nullptr || blocksPtr->empty()) {
     938            0 :         remainNum = 0;
     939            0 :         return HCCL_SUCCESS;
     940              :     }
     941              : 
     942            7 :     blockSize = blocksPtr->front().num;
     943            7 :     uint32_t maxFreeBlocks = 0;
     944            7 :     uint32_t curFreeBlocks = 0;
     945           43 :     for (const auto &block : *blocksPtr) {
     946           36 :         if (!block.allocated) {
     947           21 :             curFreeBlocks++;
     948           21 :             continue;
     949              :         }
     950           15 :         maxFreeBlocks = curFreeBlocks > maxFreeBlocks ? curFreeBlocks : maxFreeBlocks;
     951           15 :         curFreeBlocks = 0;
     952              :     }
     953            7 :     if (curFreeBlocks > maxFreeBlocks) {
     954            3 :         maxFreeBlocks = curFreeBlocks;
     955              :     }
     956              : 
     957            7 :     remainNum = maxFreeBlocks * blockSize;
     958            7 :     HCCL_INFO("[CcuResBatchAllocator][%s] resType[%s] maxFreeBlocks[%u] blockSize[%u] remainNum[%u]",
     959              :         __func__, resType.Describe().c_str(), maxFreeBlocks, blockSize, remainNum);
     960            7 :     return HCCL_SUCCESS;
     961              : }
     962              : 
     963              : }; // namespace hcomm
        

Generated by: LCOV version 2.0-1