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