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_kernel_mgr.h"
12 :
13 : #include <acl/acl.h>
14 :
15 : #include "hccl_common.h"
16 : #include "exception_handler.h"
17 : #include "adapter_rts.h"
18 : #include "ccu_assist_v1.h"
19 : #include "dev_buffer.h"
20 : #include "ccu_ins_generator_v1.h"
21 : #include "ccu_ins_generator_v2.h"
22 : #include "ccu_dev_mgr_imp.h"
23 :
24 : #include "ccu_rep_base_v1.h"
25 : #include "ccu_rep_block_v1.h"
26 : #include "ccu_rep_type_v1.h"
27 :
28 : #include "hcomm_adapter_hccp.h"
29 :
30 : #include "ccu_log.h"
31 : #include "ccu_kernel_func.h"
32 :
33 : namespace hcomm {
34 :
35 0 : HcclResult GetHcclVersionForCcuKernelMgr(int& hcclVersion)
36 : {
37 0 : char hcclPkgName[] = "hccl";
38 0 : aclError aclRet = aclsysGetVersionNum(hcclPkgName, &hcclVersion);
39 0 : CHK_PRT_RET(
40 : aclRet != ACL_SUCCESS,
41 : HCCL_ERROR("[GetHcclVersionForCcuKernelMgr] aclsysGetVersionNum failed, aclRet[%d].", aclRet), HCCL_E_INTERNAL);
42 0 : HCCL_RUN_INFO("[GetHcclVersionForCcuKernelMgr] hccl version is %d.", hcclVersion);
43 0 : return HCCL_SUCCESS;
44 : }
45 :
46 : constexpr int MAX_HCCL_VERSION_USING_CCU_RES_STATIC_ALLOC = 90100000;
47 :
48 198 : CcuKernelMgr::~CcuKernelMgr()
49 : {
50 198 : if (!initializedFlag_) {
51 198 : return;
52 : }
53 :
54 0 : if (instructionLoadDevMem_) {
55 0 : HCCL_RUN_INFO(
56 : "[CcuKernelMgr][~CcuKernelMgr]: deviceLogicId[%d], free addr[%p]", devLogicId_, instructionLoadDevMem_);
57 0 : (void)hrtFree(instructionLoadDevMem_);
58 0 : instructionLoadDevMem_ = nullptr;
59 : }
60 :
61 0 : (void)Deinit();
62 1188 : }
63 :
64 2871 : CcuKernelMgr& CcuKernelMgr::GetInstance(const int32_t deviceLogicId)
65 : {
66 3069 : static CcuKernelMgr kernelManager[MAX_MODULE_DEVICE_NUM + 1];
67 :
68 2871 : int32_t devLogicId = deviceLogicId;
69 2871 : if (devLogicId < 0 || static_cast<uint32_t>(devLogicId) >= MAX_MODULE_DEVICE_NUM) {
70 0 : HCCL_WARNING(
71 : "[CcuKernelMgr][%s] use the backup device, devLogicId[%d] should be "
72 : "less than %u.",
73 : __func__, devLogicId, MAX_MODULE_DEVICE_NUM);
74 0 : devLogicId = MAX_MODULE_DEVICE_NUM; // 使用备份设备
75 : }
76 :
77 2871 : kernelManager[devLogicId].devLogicId_ = devLogicId;
78 2871 : return kernelManager[devLogicId];
79 : }
80 :
81 92 : HcclResult CcuKernelMgr::Init()
82 : {
83 92 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
84 92 : if (initializedFlag_) {
85 0 : return HcclResult::HCCL_SUCCESS;
86 : }
87 :
88 276 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
89 184 : bool enableFlag = false;
90 184 : CHK_RET(static_cast<HcclResult>(CcuGetDieEnableInfo(devLogicId_, dieId, enableFlag)));
91 184 : if (!enableFlag) {
92 0 : continue;
93 : }
94 :
95 184 : CHK_RET(InstantiationTranslator(dieId));
96 : }
97 :
98 92 : initializedFlag_ = true;
99 92 : kernelMap_.clear();
100 :
101 92 : CHK_RET(CcuDevMgrImp::GetCcuVersion(devLogicId_, ccuVersion_));
102 92 : HCCL_INFO("[CcuKernelMgr] Get CcuVersion[%d](0: CcuV1, 1: CcuV2, 2: Invalid)", ccuVersion_);
103 92 : if (ccuVersion_ == CcuVersion::INVALID) {
104 0 : HCCL_ERROR("[CcuKernelMgr][%s] Invalid chip type, abort Init.", __func__);
105 0 : return HcclResult::HCCL_E_INTERNAL;
106 : }
107 :
108 92 : if (ccuVersion_ == CcuVersion::CCU_V2) {
109 15 : HCCL_INFO("[CcuKernelMgr] Init CcuInsGeneratorV2");
110 15 : insGenePtr = std::make_shared<CcuRep::CcuInsGeneratorV2>();
111 15 : return HcclResult::HCCL_SUCCESS;
112 : }
113 :
114 77 : HCCL_INFO("[CcuKernelMgr] Init CcuInsGeneratorV1");
115 77 : insGenePtr = std::make_shared<CcuRep::CcuInsGeneratorV1>();
116 77 : return HcclResult::HCCL_SUCCESS;
117 92 : }
118 :
119 173 : HcclResult CcuKernelMgr::Deinit()
120 : {
121 : // 不需要主动释放CCU指令空间等资源,因为设备管理与kernelMgr都为静态,生命周期一致
122 173 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
123 173 : translatorResPack.handles.clear();
124 173 : initializedFlag_ = false;
125 173 : kernelMap_.clear();
126 173 : translators.clear();
127 173 : referenceMgrs.clear();
128 173 : return HcclResult::HCCL_SUCCESS;
129 173 : }
130 :
131 55 : CcuResult CcuKernelMgr::Register(
132 : CcuResPack& resPack, const uint32_t dieId, const char* kernelFuncName, const void* kernelFunc,
133 : const void** kernelArgs, const uint32_t argNum, CcuKernelHandle& kernelHandle)
134 : {
135 : // 允许kernelFuncName为空,此时传递默认名称
136 55 : CCU_CHK_PTR_NULL(kernelFunc);
137 :
138 : // 当前argNum仅允许 0 或 1
139 55 : if (argNum > 1) {
140 0 : HCCL_ERROR("[%s] failed, argNum[%u] now only support 0 or 1.", __func__, argNum);
141 0 : return CcuResult::CCU_E_PARA;
142 : }
143 :
144 : // 注意处理时序,需要先重置后处理rep
145 55 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
146 55 : CCU_CHK_RET(BuildKernel(dieId, kernelFuncName, kernelFunc, kernelArgs, argNum));
147 :
148 44 : CcuResult ret = AllocRes(resPack);
149 44 : if (ret != CcuResult::CCU_SUCCESS) {
150 0 : HCCL_WARNING("[%s] AllocRes failed, maybe resource not enough, please check ret[%d]", __func__, ret);
151 0 : return ret;
152 : }
153 :
154 44 : kernelId_++;
155 44 : kernelMap_[kernelId_] = std::move(currKernel_);
156 :
157 44 : kernelHandle = kernelId_;
158 44 : return CcuResult::CCU_SUCCESS;
159 55 : }
160 :
161 70 : CcuResult CcuKernelMgr::BuildKernel(
162 : const uint32_t dieId, const char* kernelFuncName, const void* kernelFunc, const void** kernelArgs,
163 : const uint32_t argNum)
164 : {
165 70 : currKernel_ = std::make_unique<CcuKernel>(); // 重置待构建kernel
166 : // 执行算法流程时将资源占用临时记录在 die 0,后续确定实际 die 并迁移资源
167 70 : currKernel_->SetDieId(0);
168 70 : CCU_CHK_RET(currKernel_->SetupProfilingInfo(kernelFuncName));
169 :
170 : // 初始化翻译器(需在执行kernel func前设置,因为func执行时会创建rep对象)
171 70 : currKernel_->SetInsGenerater(insGenePtr.get());
172 70 : currKernel_->SetCcuVersion(ccuVersion_);
173 :
174 70 : if (argNum == 0) {
175 8 : auto ccuKernelFunc = reinterpret_cast<CcuKernelFuncNoArg>(kernelFunc);
176 8 : CCU_CHK_RET(ccuKernelFunc()); // 执行算法流程,生成rep和计算资源占用
177 : } else {
178 62 : CCU_CHK_PTR_NULL(kernelArgs);
179 62 : const void* kernelArg = kernelArgs[0];
180 62 : CCU_CHK_PTR_NULL(kernelArg);
181 62 : const auto ccuKernelArg = const_cast<CcuKernelArg>(kernelArg);
182 62 : auto ccuKernelFunc = reinterpret_cast<CcuKernelFuncOneArg>(kernelFunc);
183 62 : CCU_CHK_RET(ccuKernelFunc(ccuKernelArg)); // 执行算法流程,生成rep和计算资源占用
184 : }
185 :
186 57 : currKernel_->FlushClosablePendingIfs(); // 处理未闭合的if
187 57 : int hcclVersion = 0;
188 57 : CCU_CHK_RET(GetHcclVersionForCcuKernelMgr(hcclVersion));
189 57 : if (hcclVersion <= MAX_HCCL_VERSION_USING_CCU_RES_STATIC_ALLOC) {
190 : // 9.1.0 及之前版本的外部 dieId 始终为 0,需要从 channel 中获取实际 dieId
191 0 : CCU_CHK_RET(currKernel_->ApplyDieFromChannels());
192 : } else {
193 : // 校验所有 channel 使用相同的 die,然后将资源占用从 die 0 迁移到指定 die
194 57 : CCU_CHK_RET(currKernel_->ValidateAndApplyDie(dieId));
195 : }
196 54 : CCU_CHK_RET(PrepareConstValueResources()); // 记录翻译过程所需常量并申请对应资源
197 54 : return CcuResult::CCU_SUCCESS;
198 : }
199 :
200 15 : CcuResult CcuKernelMgr::GetKernelResourceRequest(
201 : const uint32_t dieId, const char* kernelFuncName, const void* kernelFunc, const void** kernelArgs,
202 : const uint32_t argNum, CcuResReq& resReq, uint32_t& instrCount)
203 : {
204 15 : CCU_CHK_PTR_NULL(kernelFunc);
205 15 : if (argNum > 1) {
206 0 : HCCL_ERROR("[%s] failed, argNum[%u] now only support 0 or 1.", __func__, argNum);
207 0 : return CcuResult::CCU_E_PARA;
208 : }
209 15 : if (argNum == 1) {
210 7 : CCU_CHK_PTR_NULL(kernelArgs);
211 7 : CCU_CHK_PTR_NULL(kernelArgs[0]);
212 : }
213 :
214 15 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
215 15 : currKernel_.reset();
216 : struct CurrentKernelGuard {
217 15 : explicit CurrentKernelGuard(std::unique_ptr<CcuKernel>& kernel) : kernel_(kernel) {}
218 15 : ~CurrentKernelGuard() { kernel_.reset(); }
219 : std::unique_ptr<CcuKernel>& kernel_;
220 15 : } guard(currKernel_);
221 :
222 15 : CCU_CHK_RET(BuildKernel(dieId, kernelFuncName, kernelFunc, kernelArgs, argNum));
223 10 : resReq = currKernel_->GetResourceRequest();
224 10 : const uint32_t kernelInstrCount = currKernel_->GetInstrCount();
225 10 : const uint32_t translatorInstrCount = CcuRepTranslator::GetInstrNum(devLogicId_);
226 10 : const uint32_t constInstrCount = currKernel_->GetConstValue2VarMap().size();
227 10 : instrCount = kernelInstrCount + translatorInstrCount + constInstrCount;
228 10 : HCCL_INFO(
229 : "[HcommCcuKernelQueryResReq][%s] resource request instruction count, kernelInstrCount[%u], "
230 : "translatorInstrCount[%u], constInstrCount[%u], totalInstrCount[%u].",
231 : __func__, kernelInstrCount, translatorInstrCount, constInstrCount, instrCount);
232 10 : return CcuResult::CCU_SUCCESS;
233 16 : }
234 :
235 272 : static void DumpResReqInfo(const CcuResReq& totalRes)
236 : {
237 816 : for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
238 1088 : if (totalRes.msReq[i] != 0 || totalRes.blockMsReq[i] != 0 || totalRes.ckeReq[i] != 0
239 266 : || totalRes.blockCkeReq[i] != 0 || totalRes.loopEngineReq[i] != 0 || totalRes.blockLoopEngineReq[i] != 0
240 255 : || totalRes.gsaReq[i] != 0 || totalRes.blockGsaReq[i] != 0 || totalRes.xnReq[i] != 0
241 1088 : || totalRes.blockXnReq[i] != 0 || totalRes.missionReq.req[i] != 0) {
242 316 : HCCL_INFO(
243 : "DumpResReqInfo: dieId[%u], msReq[%u], blockMsReq[%u], ckeReq[%u], blockCkeReq[%u], "
244 : "loopEngineReq[%u], blockLoopEngineReq[%u], gsaReq[%u], blockGsaReq[%u], xnReq[%u], blockXnReq[%u], "
245 : "missionReq[%u]",
246 : i, totalRes.msReq[i], totalRes.blockMsReq[i], totalRes.ckeReq[i], totalRes.blockCkeReq[i],
247 : totalRes.loopEngineReq[i], totalRes.blockLoopEngineReq[i], totalRes.gsaReq[i], totalRes.blockGsaReq[i],
248 : totalRes.xnReq[i], totalRes.blockXnReq[i], totalRes.missionReq.req[i]);
249 : }
250 : }
251 272 : }
252 :
253 968 : inline int32_t GetResTotalNum(const std::vector<ResInfo>& resInfos)
254 : {
255 968 : int32_t resNum = 0;
256 1466 : for (ResInfo resInfo : resInfos) {
257 498 : resNum += static_cast<int32_t>(resInfo.num);
258 : }
259 968 : return resNum;
260 : }
261 :
262 44 : static void GetResNumFromResPack(CcuResPack& resPack, CcuResReq& totalRes)
263 : {
264 : // 获取通信域当前所持有的资源
265 44 : const auto& tmpResRepository = resPack.GetCcuResRepo();
266 :
267 : // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes的第0个vector中
268 132 : for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
269 88 : totalRes.msReq[i] += GetResTotalNum(tmpResRepository.ms[i]);
270 88 : totalRes.blockMsReq[i] += GetResTotalNum(tmpResRepository.blockMs[i]);
271 88 : totalRes.ckeReq[i] += GetResTotalNum(tmpResRepository.cke[i]);
272 88 : totalRes.blockCkeReq[i] += GetResTotalNum(tmpResRepository.blockCke[i]);
273 88 : totalRes.loopEngineReq[i] += GetResTotalNum(tmpResRepository.loopEngine[i]);
274 88 : totalRes.blockLoopEngineReq[i] += GetResTotalNum(tmpResRepository.blockLoopEngine[i]);
275 88 : totalRes.gsaReq[i] += GetResTotalNum(tmpResRepository.gsa[i]);
276 88 : totalRes.blockGsaReq[i] += GetResTotalNum(tmpResRepository.blockGsa[i]);
277 88 : totalRes.xnReq[i] += GetResTotalNum(tmpResRepository.xn[i]);
278 88 : totalRes.blockXnReq[i] += GetResTotalNum(tmpResRepository.blockXn[i]);
279 88 : totalRes.missionReq.req[i] += GetResTotalNum(tmpResRepository.mission.mission[i]);
280 : }
281 :
282 44 : DumpResReqInfo(totalRes);
283 44 : HCCL_INFO("GetResPackTotalResNum:dumpInfos success.");
284 44 : }
285 :
286 968 : inline uint32_t GetReqResNum(const uint32_t reqRes, const uint32_t totalRes)
287 : {
288 968 : return ((reqRes > totalRes) ? (reqRes - totalRes) : 0);
289 : }
290 :
291 44 : static bool CheckResIfAvailable(const CcuResReq& totalRes, const CcuResReq& resReq)
292 : {
293 44 : DumpResReqInfo(resReq);
294 :
295 44 : CcuResReq needResReq{};
296 : // todo: 优化为遍历数组
297 132 : for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
298 88 : needResReq.msReq[i] = GetReqResNum(resReq.msReq[i], totalRes.msReq[i]);
299 88 : needResReq.blockMsReq[i] = GetReqResNum(resReq.blockMsReq[i], totalRes.blockMsReq[i]);
300 88 : needResReq.ckeReq[i] = GetReqResNum(resReq.ckeReq[i], totalRes.ckeReq[i]);
301 88 : needResReq.blockCkeReq[i] = GetReqResNum(resReq.blockCkeReq[i], totalRes.blockCkeReq[i]);
302 88 : needResReq.loopEngineReq[i] = GetReqResNum(resReq.loopEngineReq[i], totalRes.loopEngineReq[i]);
303 88 : needResReq.blockLoopEngineReq[i] = GetReqResNum(resReq.blockLoopEngineReq[i], totalRes.blockLoopEngineReq[i]);
304 88 : needResReq.gsaReq[i] = GetReqResNum(resReq.gsaReq[i], totalRes.gsaReq[i]);
305 88 : needResReq.blockGsaReq[i] = GetReqResNum(resReq.blockGsaReq[i], totalRes.blockGsaReq[i]);
306 88 : needResReq.xnReq[i] = GetReqResNum(resReq.xnReq[i], totalRes.xnReq[i]);
307 88 : needResReq.blockXnReq[i] = GetReqResNum(resReq.blockXnReq[i], totalRes.blockXnReq[i]);
308 88 : needResReq.missionReq.req[i] = GetReqResNum(resReq.missionReq.req[i], totalRes.missionReq.req[i]);
309 :
310 88 : if (needResReq.missionReq.req[i] > 0) {
311 0 : needResReq.missionReq.reqType = resReq.missionReq.reqType;
312 : }
313 :
314 176 : if (needResReq.msReq[i] != 0 || needResReq.blockMsReq[i] != 0 || needResReq.ckeReq[i] != 0
315 88 : || needResReq.blockCkeReq[i] != 0 || needResReq.loopEngineReq[i] != 0
316 88 : || needResReq.blockLoopEngineReq[i] != 0 || needResReq.gsaReq[i] != 0 || needResReq.blockGsaReq[i] != 0
317 176 : || needResReq.xnReq[i] != 0 || needResReq.blockXnReq[i] != 0 || needResReq.missionReq.req[i] != 0) {
318 0 : HCCL_WARNING(
319 : "[CcuKernelMgr][%s] dieId[%u] not enough, msReq[%u] blockMsReq[%u] ckeReq[%u]"
320 : "blockCkeReq[%u] loopEngineReq[%u] blockLoopEngineReq[%u] gsaReq[%u] blockGsaReq[%u] xnReq[%u]"
321 : "blockXnReq[%u] missionReq[%u].",
322 : __func__, i, needResReq.msReq[i], needResReq.blockMsReq[i], needResReq.ckeReq[i],
323 : needResReq.blockCkeReq[i], needResReq.loopEngineReq[i], needResReq.blockLoopEngineReq[i],
324 : needResReq.gsaReq[i], needResReq.blockGsaReq[i], needResReq.xnReq[i], needResReq.blockXnReq[i],
325 : needResReq.missionReq.req[i]);
326 0 : return false;
327 : }
328 : }
329 :
330 44 : return true;
331 : }
332 :
333 968 : static void MoveResInfo(std::vector<ResInfo>& dest, std::vector<ResInfo>& source, const uint32_t resNum)
334 : {
335 : // Register 前序流程已检查资源不足场景
336 968 : if (resNum == 0) {
337 848 : return;
338 : }
339 :
340 120 : dest.clear();
341 120 : auto iter = source.begin();
342 120 : uint32_t remain = resNum;
343 240 : while (remain > 0 && iter != source.end()) {
344 120 : auto& srcBlock = *iter;
345 120 : const uint32_t take = std::min(remain, srcBlock.num);
346 120 : dest.emplace_back(srcBlock.startId, take);
347 :
348 120 : if (take == srcBlock.num) {
349 : // 完全用掉这个资源,source中移除
350 0 : iter = source.erase(iter);
351 : } else {
352 : // 只用了部分,更新source中的资源
353 120 : srcBlock.startId += take;
354 120 : srcBlock.num -= take;
355 : }
356 :
357 120 : remain -= take; // 更新剩余需要的资源数量
358 : }
359 : }
360 :
361 44 : static void LoadRes(std::unique_ptr<CcuKernel>& kernel, CcuResPack& resPack)
362 : {
363 44 : const CcuResReq& resReq = kernel->GetResourceRequest();
364 44 : CcuResRepository& totalResRepo = resPack.GetCcuResRepo();
365 1012 : CcuResRepository kernelResRepo{};
366 :
367 132 : for (uint8_t i = 0; i < CCU_MAX_IODIE_NUM; i++) { // todo: 建议改成dieId
368 88 : MoveResInfo(kernelResRepo.loopEngine[i], totalResRepo.loopEngine[i], resReq.loopEngineReq[i]);
369 88 : MoveResInfo(kernelResRepo.blockLoopEngine[i], totalResRepo.blockLoopEngine[i], resReq.blockLoopEngineReq[i]);
370 88 : MoveResInfo(kernelResRepo.ms[i], totalResRepo.ms[i], resReq.msReq[i]);
371 88 : MoveResInfo(kernelResRepo.blockMs[i], totalResRepo.blockMs[i], resReq.blockMsReq[i]);
372 88 : MoveResInfo(kernelResRepo.cke[i], totalResRepo.cke[i], resReq.ckeReq[i]);
373 88 : MoveResInfo(kernelResRepo.blockCke[i], totalResRepo.blockCke[i], resReq.blockCkeReq[i]);
374 88 : MoveResInfo(kernelResRepo.blockXn[i], totalResRepo.blockXn[i], resReq.blockXnReq[i]);
375 88 : MoveResInfo(kernelResRepo.xn[i], totalResRepo.xn[i], resReq.xnReq[i]);
376 88 : MoveResInfo(kernelResRepo.gsa[i], totalResRepo.gsa[i], resReq.gsaReq[i]);
377 88 : MoveResInfo(kernelResRepo.blockGsa[i], totalResRepo.blockGsa[i], resReq.blockGsaReq[i]);
378 88 : MoveResInfo(kernelResRepo.mission.mission[i], totalResRepo.mission.mission[i], resReq.missionReq.req[i]);
379 : }
380 :
381 44 : kernel->SetResRepository(kernelResRepo);
382 44 : }
383 :
384 44 : static CcuResult AllocInstrRes(std::unique_ptr<CcuKernel>& kernel, const int32_t devLogicId)
385 : {
386 44 : const uint32_t instrCount = kernel->GetInstrCount() + CcuRep::CcuRepTranslator::GetInstrNum(devLogicId)
387 44 : + kernel->GetConstValue2VarMap().size();
388 44 : const uint32_t dieId = kernel->GetDieId();
389 44 : ResInfo insInfo(0, 0);
390 44 : CCU_CHK_RET(CcuDevMgrImp::AllocIns(devLogicId, dieId, instrCount, insInfo));
391 44 : HCCL_INFO(
392 : "[CcuKernelMgr][%s]: devLogicId[%d], dieId[%u], startId[%u], count[%u]", __func__, devLogicId, dieId,
393 : insInfo.startId, insInfo.num);
394 44 : kernel->SetInstrId(insInfo.startId);
395 :
396 44 : return CcuResult::CCU_SUCCESS;
397 : }
398 :
399 54 : CcuResult CcuKernelMgr::PrepareConstValueResources()
400 : {
401 : // insGenerator统计rep中常量,并填写当前kernel的常量表,当前只有A6有对应处理,A5没有常量处理需求
402 54 : CCU_CHK_PTR_NULL(currKernel_);
403 54 : const auto& repVec = currKernel_->GetRepSequence();
404 :
405 54 : const auto& translator = translators[currKernel_->GetDieId()][0];
406 54 : CCU_CHK_PTR_NULL(translator);
407 54 : const auto& transDep = translator->GetTransDep(); // 此时未分配missionid,取0对应的transDep读取常量
408 54 : CCU_CHK_PTR_NULL(insGenePtr);
409 1161 : for (uint32_t index = 0; index < repVec.size(); index++) {
410 1107 : const auto& curRepType = repVec[index]->Type();
411 1107 : CcuRep::CcuRepBase* curRepPtr = repVec[index].get();
412 1107 : CCU_CHK_PTR_NULL(curRepPtr);
413 1107 : HCCL_DEBUG("Current rep[%d] ptr[%p] repType[%d]", index, curRepPtr, curRepType);
414 :
415 : // 遍历每个rep,包括repBlock中的每个rep,将常量资源需求记录在currkernel中
416 1107 : CCU_CHK_RET(insGenePtr->PrepareConstValue(curRepPtr, transDep, currKernel_.get()));
417 1107 : if (curRepType == CcuRep::CcuRepType::BLOCK || curRepType == CcuRep::CcuRepType::FUNC_BLOCK
418 1103 : || curRepType == CcuRep::CcuRepType::LOOP_BLOCK) {
419 47 : CcuRep::CcuRepBlock* curRepBlockPtr = static_cast<CcuRep::CcuRepBlock*>(curRepPtr);
420 47 : CCU_CHK_PTR_NULL(curRepBlockPtr);
421 125 : for (const auto& repInBlock : curRepBlockPtr->GetReps()) {
422 78 : CCU_CHK_RET(insGenePtr->PrepareConstValue(repInBlock.get(), transDep, currKernel_.get()));
423 : }
424 : }
425 : }
426 54 : return CcuResult::CCU_SUCCESS;
427 : }
428 :
429 44 : CcuResult CcuKernelMgr::AllocRes(CcuResPack& resPack)
430 : {
431 44 : CcuResReq leftRes{};
432 44 : GetResNumFromResPack(resPack, leftRes);
433 :
434 44 : const CcuResReq& resReq = currKernel_->GetResourceRequest();
435 : // todo: 需要整改,传递资源不足的信息
436 44 : if (!CheckResIfAvailable(leftRes, resReq)) {
437 0 : HCCL_WARNING("[CcuKernelMgr][%s] resource is not enough.", __func__);
438 0 : return CcuResult::CCU_E_UNAVAIL;
439 : }
440 :
441 : // 申请指令空间资源
442 44 : CCU_CHK_RET(AllocInstrRes(currKernel_, devLogicId_));
443 :
444 : // 资源从respack转移至kernel
445 44 : LoadRes(currKernel_, resPack);
446 :
447 44 : return CcuResult::CCU_SUCCESS;
448 : }
449 :
450 : template <typename T1, typename T2>
451 : HcclResult
452 5016 : ResetRepResourceTemplate(std::vector<T1>& resource, const std::vector<T2>& repository, const uint32_t startIndex = 0)
453 : {
454 5016 : if (resource.size() > repository.size() - startIndex) {
455 0 : HCCL_ERROR(
456 : "[CcuKernelMgr][ResetRepResourceTemplate]resource size[%u] bigger "
457 : "repository size[%u] typeid[%s]",
458 : resource.size(), repository.size(), typeid(T1).name());
459 0 : return HcclResult::HCCL_E_INTERNAL;
460 : }
461 :
462 46220 : for (uint32_t j = 0; j < resource.size(); j++) {
463 41204 : resource[j].Reset(repository[j + startIndex].startId);
464 : }
465 :
466 5016 : return HcclResult::HCCL_SUCCESS;
467 : }
468 :
469 : static HcclResult
470 228 : ResetRepResourceToResRepository(CcuRepResource& totalRepRes, const CcuResRepository& totalResRepository)
471 : {
472 : // 遍历translatorRepRes, 将每个rep的虚拟资源翻译到实际物理资源上
473 684 : for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
474 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.ccubufs[i], totalResRepository.ms[i]));
475 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.blockCcubufs[i], totalResRepository.blockMs[i]));
476 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.executor[i], totalResRepository.loopEngine[i]));
477 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.blockExecutor[i], totalResRepository.blockLoopEngine[i]));
478 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.completedEvent[i], totalResRepository.cke[i]));
479 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.blockCompletedEvent[i], totalResRepository.blockCke[i]));
480 456 : CHK_RET(ResetRepResourceTemplate(
481 : totalRepRes.localNotify[i], totalResRepository.blockCke[i],
482 : totalRepRes.blockCompletedEvent[i].size())); // 两类资源都使用cke,需要调整起始分配位置
483 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.address[i], totalResRepository.gsa[i]));
484 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.blockAddress[i], totalResRepository.blockGsa[i]));
485 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.variable[i], totalResRepository.xn[i]));
486 456 : CHK_RET(ResetRepResourceTemplate(totalRepRes.continuousVariable[i], totalResRepository.blockXn[i]));
487 : }
488 228 : return HcclResult::HCCL_SUCCESS;
489 : }
490 :
491 : using DieResInfos = std::array<std::vector<ResInfo>, CCU_MAX_IODIE_NUM>;
492 44 : static HcclResult SaveKernelMissionInfo(CcuKernel* kernel, const DieResInfos& missionId, const int32_t devLogicId)
493 : {
494 44 : const uint32_t dieId = kernel->GetDieId();
495 44 : uint32_t missionKey{0};
496 44 : CHK_RET(CcuDevMgrImp::GetMissionKey(devLogicId, dieId, missionKey));
497 :
498 44 : HCCL_INFO("[CcuKernelMgr][%s] deviceLogicId[%d] dieId[%u]", __func__, devLogicId, dieId);
499 :
500 44 : kernel->SetMissionKey(missionKey);
501 : // 从missionId中获取一个元素并从missionId中删除,当前应只有一个元素,且无需删除
502 44 : if (missionId[dieId].empty()) {
503 0 : HCCL_ERROR("[%s] failed, devLogicId[%d] dieId[%u] do not have missions.", __func__, devLogicId, dieId);
504 0 : return HcclResult::HCCL_E_INTERNAL;
505 : }
506 :
507 44 : kernel->SetMissionId(missionId[dieId].back().startId);
508 44 : return HcclResult::HCCL_SUCCESS;
509 : }
510 :
511 320 : static void DumpResRepositoryInfo(const CcuResRepository& resRepo)
512 : {
513 960 : for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
514 1280 : if (resRepo.ms[i].size() != 0 || resRepo.blockMs[i].size() != 0 || resRepo.cke[i].size() != 0
515 266 : || resRepo.blockCke[i].size() != 0 || resRepo.loopEngine[i].size() != 0
516 265 : || resRepo.blockLoopEngine[i].size() != 0 || resRepo.gsa[i].size() != 0 || resRepo.blockGsa[i].size() != 0
517 1280 : || resRepo.xn[i].size() != 0 || resRepo.blockXn[i].size() != 0 || resRepo.mission.mission[i].size() != 0) {
518 412 : HCCL_INFO(
519 : "DumpResRepository: dieId[%u], ms size[%u], blockMs size[%u], cke size[%u], blockCke size[%u], "
520 : "loopEngine size[%u], blockLoopEngine size[%u], gsa size[%u], blockGsa size[%u], xn size[%u], "
521 : "block xn size[%u], mission size[%u]",
522 : i, resRepo.ms[i].size(), resRepo.blockMs[i].size(), resRepo.cke[i].size(), resRepo.blockCke[i].size(),
523 : resRepo.loopEngine[i].size(), resRepo.blockLoopEngine[i].size(), resRepo.gsa[i].size(),
524 : resRepo.blockGsa[i].size(), resRepo.xn[i].size(), resRepo.blockXn[i].size(),
525 : resRepo.mission.mission[i].size());
526 : }
527 : }
528 320 : }
529 :
530 7040 : inline void ExpandResInfo(std::vector<ResInfo>& expendResInfos, const std::vector<ResInfo>& resInfos)
531 : {
532 : // 将resInfo中的资源信息还原为单个资源粒度
533 7943 : for (auto& resInfo : resInfos) {
534 62039 : for (uint32_t id = 0; id < resInfo.num; id++) {
535 61136 : expendResInfos.push_back({(resInfo.startId + id), {1}});
536 : }
537 : }
538 7040 : }
539 :
540 320 : static CcuResult ExpandResRepo(CcuResRepository& totalRes, const CcuResRepository& tmpResRepository)
541 : {
542 : // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes中
543 960 : for (u32 i = 0; i < CCU_MAX_IODIE_NUM; i++) {
544 640 : ExpandResInfo(totalRes.ms[i], tmpResRepository.ms[i]);
545 640 : ExpandResInfo(totalRes.blockMs[i], tmpResRepository.blockMs[i]);
546 640 : ExpandResInfo(totalRes.loopEngine[i], tmpResRepository.loopEngine[i]);
547 640 : ExpandResInfo(totalRes.blockLoopEngine[i], tmpResRepository.blockLoopEngine[i]);
548 640 : ExpandResInfo(totalRes.cke[i], tmpResRepository.cke[i]);
549 640 : ExpandResInfo(totalRes.blockCke[i], tmpResRepository.blockCke[i]);
550 640 : ExpandResInfo(totalRes.gsa[i], tmpResRepository.gsa[i]);
551 640 : ExpandResInfo(totalRes.blockGsa[i], tmpResRepository.blockGsa[i]);
552 640 : ExpandResInfo(totalRes.xn[i], tmpResRepository.xn[i]);
553 640 : ExpandResInfo(totalRes.blockXn[i], tmpResRepository.blockXn[i]);
554 640 : ExpandResInfo(totalRes.mission.mission[i], tmpResRepository.mission.mission[i]);
555 : }
556 320 : DumpResRepositoryInfo(totalRes);
557 320 : return CcuResult::CCU_SUCCESS;
558 : }
559 :
560 : template <typename T>
561 44 : static HcclResult MergeExportedResources(
562 : const std::unordered_map<std::string, T>& inputRes, std::unordered_map<std::string, T>& outputRes)
563 : {
564 44 : for (const auto& item : inputRes) {
565 0 : const auto& resTag = item.first;
566 0 : if (outputRes.find(resTag) != outputRes.end()) {
567 0 : HCCL_ERROR(
568 : "[CcuKernelMgr][%s] failed, exported resource tag[%s] is already existed, "
569 : "please check.",
570 : __func__, resTag);
571 0 : return HcclResult::HCCL_E_PARA;
572 : }
573 :
574 0 : outputRes.insert(item);
575 : }
576 :
577 44 : return HcclResult::HCCL_SUCCESS;
578 : }
579 :
580 : template <typename T>
581 44 : static HcclResult ResetImportedResources(
582 : std::unordered_map<std::string, T>& importedRes, const std::unordered_map<std::string, T>& exportedRes)
583 : {
584 44 : for (auto& item : importedRes) {
585 0 : const auto& resTag = item.first;
586 0 : const auto& iter = exportedRes.find(resTag);
587 0 : if (iter == exportedRes.end()) {
588 0 : HCCL_ERROR("[CcuKernelMgr][%s] failed to find exported resources by tag[%s].", __func__, resTag.c_str());
589 0 : return HcclResult::HCCL_E_NOT_FOUND;
590 : }
591 :
592 0 : item.second.Reset(iter->second.Id(), iter->second.DieId());
593 : }
594 :
595 44 : return HcclResult::HCCL_SUCCESS;
596 : }
597 :
598 44 : static HcclResult ProcessInterCtxRes(const std::vector<CcuKernel*>& kernels)
599 : {
600 44 : std::unordered_map<std::string, CcuRep::LocalNotify> totalExportedNotifies;
601 :
602 88 : for (const auto kernel : kernels) {
603 44 : const auto& exportedRes = kernel->GetExportedRes();
604 44 : CHK_RET(MergeExportedResources(exportedRes.sharedNotifies, totalExportedNotifies));
605 : }
606 :
607 88 : for (auto kernel : kernels) {
608 44 : auto& importedRes = kernel->GetImportedRes();
609 44 : CHK_RET(ResetImportedResources(importedRes.sharedNotifies, totalExportedNotifies));
610 : }
611 :
612 44 : return HcclResult::HCCL_SUCCESS;
613 44 : }
614 :
615 44 : static HcclResult TransRepResToPhyRes(const std::vector<CcuKernel*>& kernels, const int32_t devLogicId)
616 : {
617 88 : for (auto kernel : kernels) {
618 44 : const auto& totalResRepository = kernel->GetResRepository();
619 44 : auto& totalRepRes = kernel->GetResource();
620 :
621 : // 将ccu kernel持有的物理资源赋给资源对象
622 1012 : CcuResRepository expandedResRepo{};
623 44 : ExpandResRepo(expandedResRepo, totalResRepository);
624 44 : CHK_RET(ResetRepResourceToResRepository(totalRepRes, expandedResRepo));
625 :
626 44 : CHK_RET(SaveKernelMissionInfo(kernel, totalResRepository.mission.mission, devLogicId));
627 44 : }
628 :
629 44 : CHK_RET(ProcessInterCtxRes(kernels));
630 :
631 44 : return HcclResult::HCCL_SUCCESS;
632 : }
633 :
634 45 : CcuResult CcuKernelMgr::Translate(const std::vector<CcuKernelHandle>& kernelHandles)
635 : {
636 45 : if (kernelHandles.empty()) {
637 1 : HCCL_INFO("[CcuKernelMgr][%s] passed, kernelHandles are empty.", __func__);
638 1 : return CcuResult::CCU_SUCCESS;
639 : }
640 :
641 44 : std::vector<CcuKernel*> kernels{};
642 44 : std::unique_lock<std::mutex> mapLock(kernelMapMutex_);
643 88 : for (const auto kernelHandle : kernelHandles) {
644 44 : const auto& iter = kernelMap_.find(kernelHandle);
645 44 : if (iter == kernelMap_.end()) {
646 0 : HCCL_ERROR(
647 : "[CcuKernelMgr][%s] failed to find kernel by ccu kernel handle[0x%llx].", __func__, kernelHandle);
648 0 : return CcuResult::CCU_E_NOT_FOUND;
649 : }
650 :
651 44 : kernels.push_back(iter->second.get());
652 : }
653 44 : mapLock.unlock();
654 :
655 44 : constexpr bool isFuncBlock = false; // 当前不支持MC2
656 :
657 44 : std::unique_lock<std::mutex> translateLock(translateMutex_);
658 44 : CCU_CHK_RET(TransRepResToPhyRes(kernels, devLogicId_));
659 44 : CCU_CHK_RET(TransRepSequenceToMicrocode(kernels, isFuncBlock));
660 :
661 129 : for (auto& referenceMgrMap : referenceMgrs) {
662 1462 : for (auto& referenceMgr : referenceMgrMap.second) {
663 1376 : referenceMgr.second->ClearRepReference();
664 : }
665 : }
666 43 : return CcuResult::CCU_SUCCESS;
667 44 : }
668 :
669 44 : static HcclResult ReleaseInstrRes(CcuKernel* kernel, const int32_t devLogicId)
670 : {
671 44 : const uint32_t instrCount = kernel->GetInstrCount() + CcuRep::CcuRepTranslator::GetInstrNum(devLogicId)
672 44 : + kernel->GetConstValue2VarMap().size();
673 44 : const ResInfo insInfo{kernel->GetInstrId(), instrCount};
674 44 : const uint8_t dieId = static_cast<uint8_t>(kernel->GetDieId());
675 44 : HCCL_INFO(
676 : "[CcuKernelMgr][%s] devLogicId[%d], dieId[%u], startId[%u], count[%u]", __func__, devLogicId, dieId,
677 : insInfo.startId, insInfo.num);
678 44 : CHK_RET(CcuDevMgrImp::ReleaseIns(devLogicId, dieId, insInfo));
679 :
680 44 : return HcclResult::HCCL_SUCCESS;
681 : }
682 :
683 44 : CcuResult CcuKernelMgr::UnRegister(const CcuKernelHandle kernelHandle)
684 : {
685 44 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
686 :
687 : // 校验kernelMap_中是否存在executorId对应的kernel
688 44 : auto it = kernelMap_.find(kernelHandle);
689 44 : CHK_PRT_RET(
690 : it == kernelMap_.end(),
691 : HCCL_ERROR("[CcuKernelMgr][%s] kernelHandle [%llu] does not exist", __func__, kernelHandle),
692 : CcuResult::CCU_E_NOT_FOUND);
693 :
694 44 : auto kernel = it->second.get();
695 44 : CCU_CHK_RET(ReleaseInstrRes(kernel, devLogicId_));
696 44 : kernelMap_.erase(kernelHandle);
697 44 : return CcuResult::CCU_SUCCESS;
698 44 : }
699 :
700 184 : HcclResult CcuKernelMgr::GetResPackTotalResRepository(
701 : const CcuKernelMgr::CcuTranslatResPack& resPack, CcuResRepository& totalRes) const
702 : {
703 4232 : CcuResRepository tmpResRepository{};
704 : // 获取通信域当前所持有的资源
705 460 : for (CcuResHandle resHandle : resPack.handles) {
706 276 : CHK_RET(CcuDevMgrImp::GetResource(devLogicId_, resHandle, tmpResRepository));
707 276 : ExpandResRepo(totalRes, tmpResRepository);
708 276 : HCCL_INFO("[%s] succeed, deviceLogicId[%d] resHandle[%p].", __func__, devLogicId_, resHandle);
709 : }
710 184 : return HcclResult::HCCL_SUCCESS;
711 184 : }
712 :
713 5888 : static void MergeCcuResReq(CcuResReq& resReqA, const CcuResReq& resReqB)
714 : {
715 : // 合并获取的所持有的资源信息, 按照类型合并资源总和到totalRes的第0个vector中
716 17664 : for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
717 11776 : resReqA.msReq[i] += resReqB.msReq[i];
718 11776 : resReqA.blockMsReq[i] += resReqB.blockMsReq[i];
719 11776 : resReqA.ckeReq[i] += resReqB.ckeReq[i];
720 11776 : resReqA.blockCkeReq[i] += resReqB.blockCkeReq[i];
721 11776 : resReqA.loopEngineReq[i] += resReqB.loopEngineReq[i];
722 11776 : resReqA.blockLoopEngineReq[i] += resReqB.blockLoopEngineReq[i];
723 11776 : resReqA.gsaReq[i] += resReqB.gsaReq[i];
724 11776 : resReqA.blockGsaReq[i] += resReqB.blockGsaReq[i];
725 11776 : resReqA.xnReq[i] += resReqB.xnReq[i];
726 11776 : resReqA.blockXnReq[i] += resReqB.blockXnReq[i];
727 11776 : resReqA.missionReq.req[i] += resReqB.missionReq.req[i];
728 :
729 11776 : if (resReqB.missionReq.req[i] > 0) {
730 0 : resReqA.missionReq.reqType = resReqB.missionReq.reqType;
731 : }
732 : }
733 5888 : }
734 :
735 184 : HcclResult CcuKernelMgr::InstantiationTranslator(const uint16_t dieId)
736 : {
737 184 : if (translators.find(dieId) != translators.end()) {
738 0 : return HcclResult::HCCL_SUCCESS;
739 : }
740 :
741 184 : std::array<uint16_t, CCU_MAX_IODIE_NUM> tmpChannelId{};
742 184 : uint32_t channelId = 0;
743 : // 获取innerDieChannelId
744 184 : auto ret = CcuDevMgrImp::GetLoopChannelId(devLogicId_, dieId, dieId, channelId);
745 184 : CHK_RET(ret);
746 :
747 184 : tmpChannelId[0] = channelId;
748 : // 获取interDieChannelId
749 184 : uint8_t dstDieId = ((dieId == 0) ? 1 : 0);
750 184 : ret = CcuDevMgrImp::GetLoopChannelId(devLogicId_, dieId, dstDieId, channelId);
751 184 : CHK_RET(ret);
752 184 : tmpChannelId[1] = channelId;
753 :
754 184 : uint64_t tokenId = 0;
755 184 : uint64_t tokenValue = 0;
756 184 : ret = CcuDevMgrImp::GetCcuResourceSpaceTokenInfo(devLogicId_, dieId, tokenId, tokenValue);
757 184 : CHK_RET(ret);
758 :
759 184 : std::pair<uint64_t, uint64_t> ccuTokenInfo(tokenId, tokenValue);
760 184 : Hccl::DevBuffer tmpDevMem{1}; // 临时申请device hbm内存用于查询token信息
761 184 : auto hbmTokenInfo = hcomm::CcuRep::GetTokenInfo(tmpDevMem.GetAddr(), 1);
762 :
763 184 : CcuResReq totalResReq{};
764 : // 实例化CcuRepReferenceManager和CcuRepTranslator,并为CcuRepReferenceManager绑定物理资源
765 3128 : for (uint32_t i = 0; i < 16; i++) { // mgr有16个
766 2944 : referenceMgrs[dieId][i] = std::make_shared<hcomm::CcuRep::CcuRepReferenceManager>(dieId);
767 5888 : translators[dieId][i] = std::make_shared<hcomm::CcuRep::CcuRepTranslator>(
768 5888 : devLogicId_, dieId, referenceMgrs[dieId][i], tmpChannelId, ccuTokenInfo, hbmTokenInfo);
769 :
770 : // 统计&合并refManager和translator所有资源REQ
771 2944 : auto refMangerResReq = CcuRep::CcuRepReferenceManager::GetResReq(dieId);
772 2944 : auto transLatorResReq = CcuRep::CcuRepTranslator::GetResReq(devLogicId_, dieId);
773 2944 : MergeCcuResReq(totalResReq, refMangerResReq);
774 2944 : MergeCcuResReq(totalResReq, transLatorResReq);
775 : }
776 184 : DumpResReqInfo(totalResReq);
777 :
778 : // 为refManager和translator申请物理资源
779 : CcuResHandle handle;
780 184 : CHK_RET(CcuDevMgrImp::AllocResHandle(devLogicId_, totalResReq, handle));
781 184 : translatorResPack.handles.push_back(handle);
782 :
783 184 : CcuRepResource translatorRepRes;
784 3128 : for (uint32_t i = 0; i < 16; i++) { // mgr有16个
785 2944 : referenceMgrs[dieId][i]->GetRes(translatorRepRes);
786 2944 : translators[dieId][i]->GetRes(translatorRepRes);
787 : }
788 :
789 184 : CcuResRepository totalResRepository;
790 184 : CHK_RET(GetResPackTotalResRepository(translatorResPack, totalResRepository));
791 : // 将kernel中的rep虚拟资源按类型进行和CCU物理资源映射
792 184 : CHK_RET(ResetRepResourceToResRepository(translatorRepRes, totalResRepository));
793 184 : return HcclResult::HCCL_SUCCESS;
794 184 : }
795 :
796 43 : HcclResult CcuKernelMgr::LoadInstruction(const CcuRep::CcuInstrInfo& instrInfo, const uint32_t dieId)
797 : {
798 43 : const uint64_t instrInfoSize = instrInfo.instrVec.size() * sizeof(hcomm::CcuRep::CcuInstr);
799 :
800 43 : if (!instructionLoadDevMem_) {
801 20 : uint32_t instrNum = 0;
802 20 : CHK_RET(CcuDevMgrImp::GetResSpecsInstructionNum(devLogicId_, 0, instrNum));
803 20 : HCCL_INFO("[CcuKernelMgr]LoadInstruction: deviceLogicId[%d], instrNum[%u]", devLogicId_, instrNum);
804 20 : CHK_RET(hrtMalloc(&instructionLoadDevMem_, instrNum * sizeof(hcomm::CcuRep::CcuInstr)));
805 : }
806 :
807 43 : CHK_RET(hrtMemcpy(
808 : instructionLoadDevMem_, instrInfoSize, instrInfo.instrVec.data(), instrInfoSize,
809 : HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
810 :
811 43 : uint32_t devPhyId = 0;
812 43 : CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(devLogicId_), devPhyId));
813 :
814 43 : CustomChannelInfoIn inBuff{};
815 43 : CustomChannelInfoOut outBuff{};
816 :
817 : // 设置操作码和通道数据
818 43 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_INSTRUCTION;
819 43 : inBuff.offsetStartIdx = instrInfo.startInstrId;
820 43 : inBuff.data.dataInfo.udieIdx = dieId;
821 43 : inBuff.data.dataInfo.dataArraySize = 1;
822 43 : inBuff.data.dataInfo.dataLen = instrInfoSize;
823 :
824 43 : CcuDataTypeUnion tmp{};
825 43 : tmp.insinfo.resourceAddr = reinterpret_cast<uint64_t>(instructionLoadDevMem_);
826 43 : (void)memcpy_s(inBuff.data.dataInfo.dataArray, sizeof(CcuDataTypeUnion), &tmp, sizeof(CcuDataTypeUnion));
827 :
828 43 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
829 43 : if (ret != HCCL_SUCCESS) {
830 0 : HCCL_ERROR(
831 : "[CcuResSpecifications][%s] failed to call ccu driver, "
832 : "devLogicId[%d] devPhyId[%u] dieId[%d] op[%s] ret[%d].",
833 : __func__, devLogicId_, devPhyId, dieId, "SET_INSTRUCTION", ret);
834 0 : return ret;
835 : }
836 :
837 43 : return HcclResult::HCCL_SUCCESS;
838 : }
839 :
840 44 : HcclResult CcuKernelMgr::TransRepSequenceToMicrocode(const std::vector<CcuKernel*>& kernels, bool isFuncBlock)
841 : {
842 87 : for (auto kernel : kernels) {
843 44 : const uint32_t dieId = kernel->GetDieId();
844 44 : const uint32_t missionId = kernel->GetMissionId();
845 :
846 : EXCEPTION_HANDLE_BEGIN
847 45 : const auto& instrInfo = translators[dieId][missionId]->Translate(
848 44 : kernel, kernel->GetRepSequence(), kernel->GetInstrId(), isFuncBlock);
849 :
850 43 : CHK_RET(LoadInstruction(instrInfo, dieId));
851 :
852 43 : kernel->SetCcuInstrInfo(instrInfo); // 指令下发成功后可以对kernel进行launch
853 44 : EXCEPTION_HANDLE_END
854 : }
855 :
856 43 : return HcclResult::HCCL_SUCCESS;
857 : }
858 :
859 18 : CcuKernel* CcuKernelMgr::GetKernel(const CcuKernelHandle kernelHandle)
860 : {
861 18 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
862 18 : auto it = kernelMap_.find(kernelHandle);
863 18 : if (it == kernelMap_.end()) {
864 4 : HCCL_ERROR("[CcuKernelMgr][%s] handle[%llx] is not existed.", __func__, kernelHandle);
865 4 : return nullptr;
866 : }
867 :
868 14 : return it->second.get();
869 18 : }
870 :
871 4 : CcuResult CcuKernelMgr::GetCcuKernelInfo(const CcuKernelHandle kernelHandle, CcuKernelInfo& info)
872 : {
873 4 : std::unique_lock<std::mutex> lock(kernelMapMutex_);
874 4 : auto it = kernelMap_.find(kernelHandle);
875 4 : if (it == kernelMap_.end()) {
876 1 : HCCL_ERROR("[CcuKernelMgr][%s] handle[%llx] is not existed.", __func__, kernelHandle);
877 1 : return CcuResult::CCU_E_NOT_FOUND;
878 : }
879 : // 在锁内填充 info,避免裸指针逃逸锁后 kernel 被 UnRegister 导致 use-after-free
880 3 : CCU_CHK_RET(it->second->GetCcuKernelInfo(info));
881 3 : return CcuResult::CCU_SUCCESS;
882 4 : }
883 :
884 2416 : CcuKernel* CcuKernelMgr::GetCurrentKernel() { return currKernel_.get(); }
885 :
886 : } // namespace hcomm
|