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

Generated by: LCOV version 2.0-1