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
|