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

Generated by: LCOV version 2.0-1