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_launch.h"
12 :
13 : #include <algorithm>
14 : #include <iterator>
15 : #include <memory>
16 : #include <utility>
17 : #include <vector>
18 :
19 : #include "adapter_rts_common.h"
20 : #include "ccu_res.h"
21 :
22 : #include "ccu_log.h"
23 :
24 : #include "hcom_common.h"
25 :
26 : #include "ccu_kernel_mgr.h"
27 : #include "ccu_instance_mgr.h"
28 :
29 : #include "thread.h"
30 :
31 : #include "env_config/env_config.h" // 暂时引用orion的环境变量处理模块
32 :
33 : #include "hcomm_adapter_rts.h"
34 :
35 : #include "task_param.h"
36 :
37 : #include "ccu_assist_v1.h"
38 :
39 : #include "unified_platform/pub_inc/config_plf_log.h"
40 : using Hccl::PLF_TASK;
41 :
42 44 : CcuResult HcommCcuKernelRegisterStart(CcuInsHandle insHandle)
43 : {
44 44 : const uint32_t devLogicId = HcclGetThreadDeviceId();
45 44 : auto *ccuIns = hcomm::CcuInstanceMgr::GetInstance(devLogicId).Get(insHandle);
46 44 : CCU_CHK_PTR_NULL(ccuIns);
47 :
48 44 : CCU_CHK_RET(ccuIns->BeginRegister());
49 :
50 44 : CcuResult ret = ccuIns->Reset();
51 44 : if (ret != CcuResult::CCU_SUCCESS) {
52 0 : (void)ccuIns->EndRegister();
53 0 : HCCL_ERROR("[%s] failed, Reset failed[%d], rollback register state.", __func__, ret);
54 0 : return ret;
55 : }
56 44 : return CcuResult::CCU_SUCCESS;
57 : }
58 :
59 44 : static CcuResult CcuKernelTryRegister(hcomm::CcuInstance *ccuIns, hcomm::CcuResPack *resPack,
60 : uint32_t devLogicId, uint32_t dieId, const char *kernelFuncName, const void *kernelFunc,
61 : const void **kernelArgs, uint32_t argNum, CcuKernelHandle &newHandle)
62 : {
63 : CCU_EXCEPTION_HANDLE_BEGIN
64 44 : auto &kernelMgr = hcomm::CcuKernelMgr::GetInstance(devLogicId);
65 44 : CCU_CHK_RET(kernelMgr.Register(*resPack, dieId, kernelFuncName,
66 : kernelFunc, kernelArgs, argNum, newHandle));
67 33 : CCU_CHK_RET(ccuIns->SaveKernel(newHandle));
68 8 : CCU_EXCEPTION_HANDLE_END
69 33 : return CcuResult::CCU_SUCCESS;
70 : }
71 :
72 44 : CcuResult HcommCcuKernelRegister(CcuInsHandle insHandle, uint32_t dieId,
73 : const char *kernelFuncName, const void *kernelFunc,
74 : const void **kernelArgs, uint32_t argNum,
75 : CcuKernelHandle *kernelHandle)
76 : {
77 44 : HCCL_RUN_INFO("Entry-%s", __func__);
78 44 : HcclUs startut = TIME_NOW();
79 :
80 44 : CCU_CHK_PTR_NULL(kernelFunc);
81 44 : CCU_CHK_PTR_NULL(kernelHandle);
82 :
83 44 : if (argNum != 0) {
84 44 : CCU_CHK_PTR_NULL(kernelArgs);
85 : }
86 :
87 44 : const uint32_t devLogicId = HcclGetThreadDeviceId();
88 44 : auto *ccuIns = hcomm::CcuInstanceMgr::GetInstance(devLogicId).Get(insHandle);
89 44 : CCU_CHK_PTR_NULL(ccuIns);
90 :
91 44 : CCU_CHK_RET(ccuIns->CheckRegistering());
92 :
93 44 : auto *resPack = ccuIns->GetResPack();
94 44 : CCU_CHK_PTR_NULL(resPack);
95 :
96 44 : CcuKernelHandle newHandle{0};
97 44 : CcuResult ret = CcuKernelTryRegister(ccuIns, resPack, devLogicId, dieId, kernelFuncName,
98 : kernelFunc, kernelArgs, argNum, newHandle);
99 44 : if (ret != CcuResult::CCU_SUCCESS) {
100 11 : ccuIns->AbortRegister();
101 11 : if (CCU_CHK_RES_UNAVAIL(ret)) {
102 0 : HCCL_WARNING("[%s] register kernel resource unavailable[%d], current register round aborted.",
103 : __func__, ret);
104 0 : return CcuResult::CCU_E_UNAVAIL;
105 : } else {
106 11 : HCCL_ERROR("[%s] failed, register kernel failed[%d], current register round aborted.",
107 : __func__, ret);
108 11 : return ret;
109 : }
110 : }
111 :
112 33 : *kernelHandle = newHandle;
113 33 : HCCL_INFO("[%s] success, take time [%lld]us.",
114 : __func__, DURATION_US(TIME_NOW() - startut).count());
115 33 : return CcuResult::CCU_SUCCESS;
116 : }
117 :
118 34 : CcuResult HcommCcuKernelRegisterEnd(CcuInsHandle insHandle)
119 : {
120 34 : const uint32_t devLogicId = HcclGetThreadDeviceId();
121 34 : auto *ccuIns = hcomm::CcuInstanceMgr::GetInstance(devLogicId).Get(insHandle);
122 34 : CCU_CHK_PTR_NULL(ccuIns);
123 :
124 34 : CCU_CHK_RET(ccuIns->EndRegister());
125 34 : const auto &newKernels = ccuIns->GetUntranslatedKernels();
126 :
127 34 : auto &kernelMgr = hcomm::CcuKernelMgr::GetInstance(devLogicId);
128 : // 当前翻译内部流程可能抛异常
129 : CCU_EXCEPTION_HANDLE_BEGIN
130 34 : CCU_CHK_RET(kernelMgr.Translate(newKernels));
131 0 : CCU_EXCEPTION_HANDLE_END
132 :
133 33 : return CcuResult::CCU_SUCCESS;
134 : }
135 :
136 5 : static std::shared_ptr<std::vector<Hccl::CcuProfilingInfo>> ConstructCcuDetailInfo(
137 : const std::vector<hcomm::CcuProfilingInfo> &allCcuProfilingInfo, bool isSaveProfilingData)
138 : {
139 5 : if (allCcuProfilingInfo.empty() || !isSaveProfilingData) {
140 0 : return nullptr;
141 : }
142 :
143 5 : std::vector<Hccl::CcuProfilingInfo> converted(allCcuProfilingInfo.size());
144 19 : for (u32 idx = 0; idx < allCcuProfilingInfo.size(); ++idx) {
145 14 : auto &src = allCcuProfilingInfo[idx];
146 14 : auto &dst = converted[idx];
147 14 : dst.name = src.name;
148 14 : dst.type = src.type;
149 14 : dst.dieId = src.dieId;
150 14 : dst.missionId = src.missionId;
151 14 : dst.instrId = src.instrId;
152 14 : dst.reduceOpType = src.reduceOpType;
153 14 : dst.inputDataType = src.inputDataType;
154 14 : dst.outputDataType = src.outputDataType;
155 14 : dst.dataSize = src.dataSize;
156 14 : dst.ckeId = src.ckeId;
157 14 : dst.mask = src.mask;
158 14 : (void)memcpy_s(dst.channelId, sizeof(dst.channelId), src.channelId, sizeof(src.channelId));
159 14 : (void)memcpy_s(dst.channelHandle, sizeof(dst.channelHandle), src.channelHandle, sizeof(src.channelHandle));
160 : }
161 5 : return std::make_shared<std::vector<Hccl::CcuProfilingInfo>>(std::move(converted));
162 5 : }
163 :
164 8 : static Hccl::TaskParam ConstructCcuTaskParam(const hcomm::CcuTaskParam &ccuParam,
165 : const CcuKernelHandle kernelHandle,
166 : const std::shared_ptr<std::vector<Hccl::CcuProfilingInfo>> &ccuDetailInfo,
167 : u64 beginTime, u64 endTime, bool isMaster)
168 : {
169 8 : Hccl::TaskParam taskParam{};
170 8 : taskParam.beginTime = beginTime;
171 8 : taskParam.endTime = endTime;
172 8 : taskParam.taskType = Hccl::TaskParamType::TASK_CCU;
173 8 : taskParam.taskPara.Ccu.dieId = ccuParam.dieId;
174 8 : taskParam.taskPara.Ccu.missionId = ccuParam.missionId;
175 8 : taskParam.taskPara.Ccu.execMissionId = ccuParam.missionId;
176 8 : taskParam.taskPara.Ccu.instrId = ccuParam.instStartId;
177 8 : taskParam.taskPara.Ccu.executeId = kernelHandle;
178 8 : taskParam.taskPara.Ccu.ccuKernelHandle = kernelHandle;
179 8 : taskParam.isMaster = isMaster;
180 8 : taskParam.ccuDetailInfo = ccuDetailInfo;
181 8 : return taskParam;
182 : }
183 :
184 5 : static void LogCcuTaskInfo(const std::vector<hcomm::CcuTaskParam> &ccuParams,
185 : const CcuKernelHandle kernelHandle)
186 : {
187 5 : if (!HcclCheckLogLevel(HCCL_LOG_INFO)) {
188 0 : return;
189 : }
190 5 : const uint32_t execTimeOutSec = Hccl::EnvConfig::GetInstance().GetRtsConfig().GetExecTimeOut();
191 13 : for (u32 idx = 0; idx < ccuParams.size(); idx++) {
192 8 : const auto ¶m = ccuParams[idx];
193 8 : PLF_CONFIG_INFO(PLF_TASK, "[%s] start ccu task, dieId[%u], missionId[%u], execMissionId[%u], instStartId[%u], instCnt[%u], "
194 : "argSize[%u], timeout[%u]s, executeId[0x%llx], ccuKernelHandle[0x%llx]",
195 : __func__, param.dieId, param.missionId, param.missionId,
196 : param.instStartId, param.instCnt, param.argSize, execTimeOutSec,
197 : kernelHandle, kernelHandle);
198 : }
199 : }
200 :
201 5 : static void ConstructProfilingInfoLog(
202 : const std::vector<hcomm::CcuProfilingInfo> &allCcuProfilingInfo)
203 : {
204 5 : if (!HcclCheckLogLevel(HCCL_LOG_INFO)) {
205 0 : return;
206 : }
207 19 : for (const hcomm::CcuProfilingInfo& profInfo : allCcuProfilingInfo) {
208 20 : for (int idx = 0; idx < hcomm::CCU_MAX_CHANNEL_NUM; idx++) {
209 20 : if (profInfo.channelId[idx] == hcomm::INVALID_VALUE_CHANNELID) {
210 14 : break;
211 : }
212 6 : HCCL_INFO("[%s]idx[%d]: channelId[%u], channelHandle[0x%llx]",
213 : __func__, idx, profInfo.channelId[idx], profInfo.channelHandle[idx]);
214 : }
215 : }
216 : }
217 :
218 5 : static CcuResult ConstructProfilingInfo(hcomm::CcuKernel *kernel,
219 : const uint64_t *taskArgs, uint32_t argNum,
220 : std::vector<hcomm::CcuProfilingInfo> &allCcuProfilingInfo, bool isSaveProfilingData)
221 : {
222 5 : if (!isSaveProfilingData) {
223 0 : return CcuResult::CCU_SUCCESS;
224 : }
225 :
226 5 : CCU_CHK_RET(kernel->GetCcuProfilingInfo(taskArgs, argNum, allCcuProfilingInfo));
227 5 : if (allCcuProfilingInfo.empty()) {
228 0 : return CcuResult::CCU_SUCCESS;
229 : }
230 5 : ConstructProfilingInfoLog(allCcuProfilingInfo);
231 5 : return CcuResult::CCU_SUCCESS;
232 : }
233 :
234 8 : static CcuResult ReportCcuTaskDfx(const ThreadHandle threadHandle,
235 : const Hccl::TaskParam &taskParam)
236 : {
237 8 : auto *rtsThread = reinterpret_cast<hccl::Thread *>(threadHandle);
238 8 : CCU_CHK_PTR_NULL(rtsThread);
239 :
240 8 : auto callback = rtsThread->GetCallback();
241 8 : if (!callback) {
242 8 : HCCL_WARNING("[%s] task info callback is not registered on thread, skip ccu profiling report.", __func__);
243 8 : return CcuResult::CCU_SUCCESS;
244 : }
245 0 : u32 streamId = INVALID_UINT;
246 0 : u32 taskId = INVALID_UINT;
247 0 : CCU_CHK_RET(hrtGetTaskIdAndStreamID(taskId, streamId));
248 0 : CCU_CHK_RET(callback(streamId, taskId, taskParam, INVALID_U64));
249 0 : return CcuResult::CCU_SUCCESS;
250 8 : }
251 :
252 8 : static HcclResult LaunchCcuTasks(const hcomm::CcuTaskParam ¶m, const aclrtStream stream)
253 : {
254 8 : const uint32_t execTimeOutSec = Hccl::EnvConfig::GetInstance().GetRtsConfig().GetExecTimeOut();
255 8 : rtCcuTaskInfo_t taskInfo{};
256 8 : taskInfo.dieId = param.dieId;
257 8 : taskInfo.missionId = param.missionId;
258 8 : taskInfo.instStartId = param.instStartId;
259 8 : taskInfo.instCnt = param.instCnt;
260 8 : taskInfo.key = param.key;
261 8 : taskInfo.argSize = param.argSize;
262 8 : taskInfo.timeout = execTimeOutSec;
263 24 : std::copy(std::begin(param.args), std::end(param.args), std::begin(taskInfo.args));
264 :
265 8 : auto ret = rtCCULaunch(&taskInfo, stream);
266 8 : if (ret != RT_ERROR_NONE) {
267 0 : HCCL_ERROR("[%s] failed to launch ccu, ret[%d]", __func__, ret);
268 0 : return HcclResult::HCCL_E_RUNTIME;
269 : }
270 :
271 8 : return HcclResult::HCCL_SUCCESS;
272 : }
273 :
274 5 : CcuResult HcommCcuKernelLaunch(ThreadHandle threadHandle,
275 : CcuKernelHandle kernelHandle, const void *taskArgs, uint32_t argNum)
276 : {
277 5 : const auto &startus = TIME_NOW();
278 :
279 5 : CHK_PRT_RET(threadHandle == 0, HCCL_ERROR("[%s] failed, thread handle is empty.", __func__), CcuResult::CCU_E_PARA);
280 5 : CHK_PRT_RET(kernelHandle == 0, HCCL_ERROR("[%s] failed, kernel handle is empty.", __func__), CcuResult::CCU_E_PARA);
281 5 : CHK_PRT_RET(argNum > 0 && taskArgs == nullptr, HCCL_ERROR("[%s] failed, taskArgs is nullptr while argNum[%u] > 0.", __func__, argNum), CcuResult::CCU_E_PTR);
282 :
283 5 : PLF_CONFIG_INFO(PLF_TASK, "[HcommCcuKernelLaunch] threadHandle[0x%llx] kernelHandle[0x%llx].", threadHandle, kernelHandle);
284 :
285 5 : const auto *rtsThread = reinterpret_cast<hccl::Thread *>(threadHandle);
286 5 : const auto *threadStream = rtsThread->GetStream();
287 5 : CCU_CHK_PTR_NULL(threadStream);
288 5 : auto *streamPtr = threadStream->ptr();
289 5 : CCU_CHK_PTR_NULL(streamPtr);
290 :
291 5 : const uint32_t devLogicId = HcclGetThreadDeviceId();
292 5 : auto &kernelMgr = hcomm::CcuKernelMgr::GetInstance(devLogicId);
293 5 : auto *kernel = kernelMgr.GetKernel(kernelHandle);
294 5 : CCU_CHK_PTR_NULL(kernel);
295 :
296 : CCU_EXCEPTION_HANDLE_BEGIN
297 5 : std::vector<hcomm::CcuTaskParam> taskParams{};
298 5 : auto ret = kernel->GeneTaskParams(static_cast<const uint64_t *>(taskArgs), argNum, taskParams);
299 5 : CHK_PRT_RET(ret != CcuResult::CCU_SUCCESS,
300 : HCCL_ERROR("[%s] failed, threadHandle[0x%llx] kernelHandle[0x%llx].",
301 : __func__, threadHandle, kernelHandle),
302 : ret);
303 :
304 5 : if (taskParams.empty()) {
305 0 : HCCL_INFO("[%s] passed, ccu params are empty.", __func__);
306 0 : return CcuResult::CCU_SUCCESS;
307 : }
308 5 : bool isProfilingEnabledL1 = Hccl::ProfilingHandler::GetInstance().GetHcclL1State();
309 5 : bool isProfilingEnabledL0 = Hccl::ProfilingHandler::GetInstance().GetHcclL0State();
310 5 : bool isOpbase = Hccl::ProfilingHandler::GetInstance().GetIsOpbase();
311 5 : bool isSaveProfilingData = !(!isProfilingEnabledL1 && !isProfilingEnabledL0 && isOpbase);
312 :
313 5 : std::vector<hcomm::CcuProfilingInfo> allCcuProfilingInfo;
314 5 : CCU_CHK_RET(ConstructProfilingInfo(kernel, static_cast<const uint64_t *>(taskArgs), argNum, allCcuProfilingInfo, isSaveProfilingData));
315 5 : LogCcuTaskInfo(taskParams, kernelHandle);
316 5 : auto ccuDetailInfo = ConstructCcuDetailInfo(allCcuProfilingInfo, isSaveProfilingData);
317 13 : for (u32 idx = 0; idx < taskParams.size(); idx++) {
318 8 : u64 beginTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
319 8 : CCU_CHK_RET(LaunchCcuTasks(taskParams[idx], streamPtr));
320 8 : u64 endTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
321 8 : Hccl::TaskParam taskParam = ConstructCcuTaskParam(taskParams[idx], kernelHandle, ccuDetailInfo,
322 8 : beginTime, endTime, rtsThread->GetMaster());
323 8 : CCU_CHK_RET(ReportCcuTaskDfx(threadHandle, taskParam));
324 8 : }
325 5 : CCU_EXCEPTION_HANDLE_END
326 5 : HCCL_INFO("[%s] success, take time [%lld]us.",
327 : __func__, DURATION_US(TIME_NOW() - startus).count());
328 5 : return CcuResult::CCU_SUCCESS;
329 : }
330 :
331 0 : CcuResult HcommCcuGetMemToken(uint64_t srcVa, uint64_t size, uint64_t *tokenInfo)
332 : {
333 0 : CCU_CHK_PTR_NULL(tokenInfo);
334 :
335 0 : if (srcVa == 0 || size == 0) {
336 0 : HCCL_ERROR("[%s] failed, srcVa[0x%llx] size[%llu] should not be 0.",
337 : __func__, static_cast<unsigned long long>(srcVa), static_cast<unsigned long long>(size));
338 0 : return CcuResult::CCU_E_PARA;
339 : }
340 : // 注意token信息属于安全信息,均不允许打印
341 0 : hcomm::rtMemUbTokenInfo info{};
342 0 : info.va = srcVa;
343 0 : info.size = size;
344 0 : CCU_CHK_RET(hcomm::RtsUbDevQueryInfo(QUERY_PROCESS_TOKEN, info));
345 0 : *tokenInfo = hcomm::CcuRep::CcuCombineTokenInfo(info.tokenId, info.tokenValue, 1);
346 :
347 0 : return CcuResult::CCU_SUCCESS;
348 : }
|