Line data Source code
1 : /**
2 : * Copyright (c) 2026 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.h"
12 :
13 : #include <array>
14 :
15 : #include "ccu_device_res.h"
16 : #include "ccu_device_pub.h"
17 :
18 : #include "ccu_log.h"
19 :
20 : #include "hcom_common.h"
21 : #include "op_base.h"
22 :
23 : #include "ccu_kernel_mgr.h"
24 : #include "ccu_instance_mgr.h"
25 : #include "ccu_res_desc.h"
26 : #include "ccu_res_desc_mgr.h"
27 : #include "ccu_res_type_converter.h"
28 :
29 154 : CcuResult HcommCcuInsResDescCreate(uint32_t dieId, HcommCcuResDescHandle* handle)
30 : {
31 154 : if (dieId >= hcomm::CCU_MAX_IODIE_NUM) {
32 1 : HCCL_ERROR("[%s] dieId[%u] is invalid, dieId should in [0, %u).", __func__, dieId, hcomm::CCU_MAX_IODIE_NUM);
33 1 : return CcuResult::CCU_E_PARA;
34 : }
35 :
36 153 : CCU_CHK_PTR_NULL(handle);
37 :
38 152 : int32_t devLogicId = INVALID_INT;
39 152 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
40 151 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr().Create(dieId, *handle));
41 150 : HCCL_INFO("[%s] success, handle[0x%llx] dieId[%u]", __func__, *handle, dieId);
42 150 : return CcuResult::CCU_SUCCESS;
43 : }
44 :
45 154 : CcuResult HcommCcuInsResDescDestroy(HcommCcuResDescHandle handle)
46 : {
47 154 : int32_t devLogicId = INVALID_INT;
48 154 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
49 153 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr().Destroy(handle));
50 150 : HCCL_INFO("[%s] success, handle[0x%llx]", __func__, handle);
51 150 : return CcuResult::CCU_SUCCESS;
52 : }
53 :
54 806 : CcuResult HcommCcuInsResDescSetNum(HcommCcuResDescHandle handle, HcommCcuResType resType, uint32_t resNum)
55 : {
56 806 : hcomm::ResType ccuResType{hcomm::ResType::INVALID};
57 806 : CCU_CHK_RET(hcomm::ConvertHcommCcuResTypeToHcclResType(resType, ccuResType));
58 :
59 805 : int32_t devLogicId = INVALID_INT;
60 805 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
61 804 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr().SetResNum(handle, ccuResType, resNum));
62 802 : HCCL_INFO("[%s] success, handle[0x%llx] resType[%d] resNum[%u]", __func__, handle, resType, resNum);
63 802 : return CcuResult::CCU_SUCCESS;
64 : }
65 :
66 22 : CcuResult HcommCcuInsResDescQueryNum(HcommCcuResDescHandle handle, HcommCcuResType resType, uint32_t* num)
67 : {
68 22 : CCU_CHK_PTR_NULL(num);
69 21 : hcomm::ResType ccuResType{hcomm::ResType::INVALID};
70 21 : CCU_CHK_RET(hcomm::ConvertHcommCcuResTypeToHcclResType(resType, ccuResType));
71 :
72 20 : int32_t devLogicId = INVALID_INT;
73 20 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
74 19 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr().QueryResNum(handle, ccuResType, *num));
75 17 : HCCL_INFO("[%s] success, handle[0x%llx] resType[%d] resNum[%u]", __func__, handle, resType, *num);
76 17 : return CcuResult::CCU_SUCCESS;
77 : }
78 :
79 8 : CcuResult HcommCcuInsResDescQueryDieId(HcommCcuResDescHandle handle, uint32_t* dieId)
80 : {
81 8 : CCU_CHK_PTR_NULL(dieId);
82 7 : int32_t devLogicId = INVALID_INT;
83 7 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
84 6 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr().QueryDieId(handle, *dieId));
85 4 : HCCL_INFO("[%s] success, handle[0x%llx] dieId[%u]", __func__, handle, *dieId);
86 4 : return CcuResult::CCU_SUCCESS;
87 : }
88 :
89 8 : CcuResult HcommCcuQueryRemainResDesc(HcommCcuResDescHandle handle)
90 : {
91 8 : int32_t devLogicId = INVALID_INT;
92 8 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
93 :
94 : // CCU 驱动未拉起时无法查询硬件资源, 提前返回
95 7 : if (!hcomm::CcuIsInited(devLogicId)) {
96 1 : HCCL_WARNING("[%s] failed, CCU feature is not inited, devLogicId[%d].", __func__, devLogicId);
97 1 : return CcuResult::CCU_E_UNAVAIL;
98 : }
99 :
100 6 : auto& resDescMgr = hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr();
101 :
102 : // die 合法性前置校验
103 6 : uint32_t dieId = 0;
104 6 : CCU_CHK_RET(resDescMgr.QueryDieId(handle, dieId));
105 4 : bool enableFlag = false;
106 : // CcuGetDieEnableInfo 中会做dieId合法性校验以及查询是否使能
107 4 : CCU_CHK_RET(hcomm::CcuGetDieEnableInfo(devLogicId, static_cast<uint8_t>(dieId), enableFlag));
108 4 : if (!enableFlag) {
109 1 : HCCL_WARNING("[%s] failed, dieId[%u] is not enabled.", __func__, dieId);
110 1 : return CcuResult::CCU_E_UNAVAIL;
111 : }
112 :
113 : // 委托 CcuResDescMgr 在锁内查询剩余资源,防止 Get→Destroy 的 use-after-free
114 3 : CCU_CHK_RET(resDescMgr.QueryRemainRes(handle, devLogicId));
115 :
116 3 : HCCL_INFO("[%s] success, handle[0x%llx] dieId[%u]", __func__, handle, dieId);
117 3 : return CcuResult::CCU_SUCCESS;
118 : }
119 :
120 10 : static CcuResult ConvertCcuResReqToResDesc(
121 : hcomm::CcuResDescMgr& resDescMgr, HcommCcuResDescHandle resDesc, const hcomm::CcuResReq& resReq,
122 : uint32_t instrCount, uint32_t selectedDie)
123 : {
124 10 : const uint32_t loopNum = resReq.loopEngineReq[selectedDie] + resReq.blockLoopEngineReq[selectedDie];
125 10 : const uint32_t msNum = resReq.msReq[selectedDie] + resReq.blockMsReq[selectedDie];
126 10 : const uint32_t xnNum = resReq.xnReq[selectedDie] + resReq.blockXnReq[selectedDie];
127 10 : const uint32_t gsaNum = resReq.gsaReq[selectedDie] + resReq.blockGsaReq[selectedDie];
128 10 : const uint32_t ckeNum = resReq.ckeReq[selectedDie] + resReq.blockCkeReq[selectedDie];
129 10 : const uint32_t missionNum = resReq.missionReq.req[selectedDie];
130 :
131 10 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::LOOP, loopNum));
132 10 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::MS, msNum));
133 10 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::XN, xnNum));
134 10 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::GSA, gsaNum));
135 9 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::CKE, ckeNum));
136 9 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::MISSION, missionNum));
137 9 : CCU_CHK_RET(resDescMgr.SetResNum(resDesc, hcomm::ResType::INS, instrCount));
138 :
139 9 : HCCL_INFO(
140 : "[HcommCcuKernelQueryResReq] success, aggregated resource request, not allocated resource, "
141 : "resDesc[0x%llx], dieId[%u], loop[%u], ms[%u], xn[%u], gsa[%u], cke[%u], mission[%u], ins[%u].",
142 : static_cast<unsigned long long>(resDesc), selectedDie, loopNum, msNum, xnNum, gsaNum, ckeNum, missionNum,
143 : instrCount);
144 9 : return CcuResult::CCU_SUCCESS;
145 : }
146 :
147 24 : CcuResult HcommCcuKernelQueryResReq(
148 : const void* kernelFunc, const void** kernelArgs, uint32_t argNum, HcommCcuResDescHandle resDesc)
149 : {
150 24 : HCCL_INFO(
151 : "[%s] begin, argNum[%u], resDesc[0x%llx], kernelFunc[%p].", __func__, argNum,
152 : static_cast<unsigned long long>(resDesc), kernelFunc);
153 24 : CCU_CHK_PTR_NULL(kernelFunc);
154 23 : if (resDesc == 0 || argNum > 1) {
155 2 : HCCL_ERROR(
156 : "[%s] failed, resDesc[0x%llx], argNum[%u].", __func__, static_cast<unsigned long long>(resDesc), argNum);
157 2 : return CcuResult::CCU_E_PARA;
158 : }
159 21 : if (argNum == 1) {
160 9 : CHK_PRT_RET(
161 : kernelArgs == nullptr, HCCL_ERROR("[%s] failed, kernelArgs is nullptr while argNum[%u].", __func__, argNum),
162 : CcuResult::CCU_E_PTR);
163 8 : CHK_PRT_RET(
164 : kernelArgs[0] == nullptr,
165 : HCCL_ERROR("[%s] failed, kernelArgs[0] is nullptr while argNum[%u].", __func__, argNum),
166 : CcuResult::CCU_E_PTR);
167 : }
168 :
169 19 : int32_t devLogicId = INVALID_INT;
170 19 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
171 18 : auto& resDescMgr = hcomm::CcuInstanceMgr::GetInstance(devLogicId).GetResDescMgr();
172 18 : uint32_t descriptorDieId = hcomm::CCU_MAX_IODIE_NUM;
173 18 : CCU_CHK_RET(resDescMgr.QueryDieId(resDesc, descriptorDieId));
174 16 : HCCL_INFO(
175 : "[%s] descriptor queried, resDesc[0x%llx], descriptorDieId[%u].", __func__,
176 : static_cast<unsigned long long>(resDesc), descriptorDieId);
177 16 : if (descriptorDieId >= hcomm::CCU_MAX_IODIE_NUM) {
178 1 : HCCL_ERROR("[%s] failed, descriptor dieId[%u] is invalid.", __func__, descriptorDieId);
179 1 : return CcuResult::CCU_E_PARA;
180 : }
181 :
182 : CCU_EXCEPTION_HANDLE_BEGIN
183 15 : hcomm::CcuResReq resReq{};
184 15 : uint32_t instrCount = 0;
185 15 : auto& kernelMgr = hcomm::CcuKernelMgr::GetInstance(devLogicId);
186 16 : CCU_CHK_RET(kernelMgr.GetKernelResourceRequest(
187 : descriptorDieId, "KernelForHcommCcuKernelQueryResReq", kernelFunc, kernelArgs, argNum, resReq, instrCount));
188 10 : CCU_CHK_RET(ConvertCcuResReqToResDesc(resDescMgr, resDesc, resReq, instrCount, descriptorDieId));
189 1 : CCU_EXCEPTION_HANDLE_END
190 :
191 9 : return CcuResult::CCU_SUCCESS;
192 : }
193 :
194 : // Deprecated: legacy internal CCU instance creation path.
195 7 : CcuResult HcommCcuInsCreateLegacy(const CcuInstanceType insType, CcuInsHandle* ccuInsHandle)
196 : {
197 7 : CCU_CHK_PTR_NULL(ccuInsHandle);
198 :
199 7 : int32_t devLogicId = INVALID_INT;
200 7 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
201 6 : auto& insMgr = hcomm::CcuInstanceMgr::GetInstance(devLogicId);
202 :
203 6 : CCU_CHK_RET(insMgr.CreateByInsType(insType, *ccuInsHandle));
204 :
205 6 : return CcuResult::CCU_SUCCESS;
206 : }
207 :
208 67 : CcuResult HcommCcuInsCreate(const HcommCcuResDescHandle* resDescs, uint32_t resDescNum, CcuInsHandle* ccuInsHandle)
209 : {
210 67 : CCU_CHK_PTR_NULL(resDescs);
211 67 : CCU_CHK_PTR_NULL(ccuInsHandle);
212 66 : if (resDescNum == 0 || resDescNum > hcomm::CCU_MAX_IODIE_NUM) {
213 1 : HCCL_ERROR(
214 : "[%s] failed, resDescNum[%u] is invalid, should be in (0, %u].", __func__, resDescNum,
215 : hcomm::CCU_MAX_IODIE_NUM);
216 1 : return CcuResult::CCU_E_PARA;
217 : }
218 :
219 65 : int32_t devLogicId = INVALID_INT;
220 65 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
221 64 : auto& insMgr = hcomm::CcuInstanceMgr::GetInstance(devLogicId);
222 :
223 : // 从 CcuResDescMgr 中用 resDesc 数组里的 Handle Get 获得 CcuResDesc,构造指针数组
224 64 : std::array<const hcomm::CcuResDesc*, hcomm::CCU_MAX_IODIE_NUM> descPtrs{};
225 192 : for (uint32_t i = 0; i < resDescNum; i++) {
226 128 : descPtrs[i] = insMgr.GetResDescMgr().Get(resDescs[i]);
227 128 : CCU_CHK_PTR_NULL(descPtrs[i]);
228 : }
229 :
230 : // 如果入参为 2 个 resDesc,里面的 dieId 不能重复
231 64 : if (resDescNum == 2 && descPtrs[0]->dieId == descPtrs[1]->dieId) {
232 1 : HCCL_ERROR("[%s] failed, dieId[%u] duplicated in resDescs.", __func__, descPtrs[0]->dieId);
233 1 : return CcuResult::CCU_E_PARA;
234 : }
235 :
236 63 : CCU_CHK_RET(insMgr.CreateByResDescs(descPtrs.data(), resDescNum, *ccuInsHandle));
237 60 : return CcuResult::CCU_SUCCESS;
238 : }
239 :
240 5 : CcuResult HcommCcuInsCreateDefault(const uint32_t* dieIds, uint32_t dieNum, CcuInsHandle* ccuInsHandle)
241 : {
242 : (void)dieIds;
243 : (void)dieNum;
244 : // dieIds/dieNum 为保留参数,当前版本申请当前 Device 上所有已使能 ioDie 的全部资源
245 5 : CCU_CHK_PTR_NULL(ccuInsHandle);
246 :
247 4 : int32_t devLogicId = INVALID_INT;
248 4 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
249 3 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).CreateByAllRes(*ccuInsHandle));
250 1 : return CcuResult::CCU_SUCCESS;
251 : }
252 :
253 5 : CcuResult HcommCcuInsQueryResDesc(CcuInsHandle ccuInsHandle, HcommCcuResDescHandle resDesc)
254 : {
255 5 : if (ccuInsHandle == 0 || resDesc == 0) {
256 2 : HCCL_ERROR("[%s] failed, invalid ccuInsHandle[%llu] resDesc[%llu].", __func__, ccuInsHandle, resDesc);
257 2 : return CcuResult::CCU_E_PARA;
258 : }
259 :
260 3 : int32_t devLogicId = INVALID_INT;
261 3 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
262 2 : auto& insMgr = hcomm::CcuInstanceMgr::GetInstance(devLogicId);
263 :
264 2 : auto& resDescMgr = insMgr.GetResDescMgr();
265 2 : uint32_t descriptorDieId = hcomm::CCU_MAX_IODIE_NUM;
266 2 : CCU_CHK_RET(resDescMgr.QueryDieId(resDesc, descriptorDieId));
267 2 : const uint8_t dieId = static_cast<uint8_t>(descriptorDieId);
268 2 : if (dieId >= hcomm::CCU_MAX_IODIE_NUM) {
269 0 : HCCL_ERROR("[%s] failed, dieId[%u] is invalid.", __func__, dieId);
270 0 : return CcuResult::CCU_E_PARA;
271 : }
272 :
273 2 : CCU_CHK_RET(insMgr.QueryInsResDesc(ccuInsHandle, dieId, resDesc));
274 :
275 2 : return CcuResult::CCU_SUCCESS;
276 : }
277 :
278 71 : CcuResult HcommCcuInsDestroy(CcuInsHandle insHandle)
279 : {
280 71 : int32_t devLogicId = INVALID_INT;
281 71 : CCU_CHK_RET(HcclDeviceRefresh(devLogicId));
282 70 : CCU_CHK_RET(hcomm::CcuInstanceMgr::GetInstance(devLogicId).Destroy(insHandle));
283 :
284 66 : return CcuResult::CCU_SUCCESS;
285 : }
|