LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_device - ccu_res_batch_allocator.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.3 % 516 440
Test Date: 2026-08-04 10:52:23 Functions: 100.0 % 31 31

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

Generated by: LCOV version 2.0-1