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 : #include "aicpusd_event_manager.h"
11 :
12 : #include <string>
13 : #include <securec.h>
14 : #include <sstream>
15 : #include "aicpusd_status.h"
16 : #include "aicpusd_util.h"
17 : #include "aicpu_context.h"
18 : #include "aicpusd_monitor.h"
19 : #include "aicpusd_drv_manager.h"
20 : #include "aicpusd_event_process.h"
21 : #include "aicpusd_threads_process.h"
22 : #include "dump_task.h"
23 : #include "aicpu_engine.h"
24 : #include "aicpu_cust_sd_dump_process.h"
25 : #include "aicpusd_interface.h"
26 :
27 : namespace {
28 : // stream id
29 : const std::string CONTEXT_KEY_STREAM_ID = "streamId";
30 : static constexpr uint64_t CONVER_DRIVER_2_AICPU = 0x0000FFFFFFFFFFFFU;
31 : }
32 :
33 : namespace AicpuSchedule {
34 : constexpr uint32_t TIMEOUT_INTERVAL = 2000U;
35 : /**
36 : * @ingroup AicpuEventManager
37 : * @brief it is used to construct a object of AicpuEventManager.
38 : */
39 1 : AicpuEventManager::AicpuEventManager()
40 1 : : noThreadFlag_(true),
41 2 : runningFlag_(true) {}
42 :
43 : /**
44 : * @ingroup AicpuEventManager
45 : * @brief it is used to destructor a object of AicpuEventManager.
46 : */
47 1 : AicpuEventManager::~AicpuEventManager() {}
48 :
49 104 : AicpuEventManager &AicpuEventManager::GetInstance()
50 : {
51 104 : static AicpuEventManager instance;
52 104 : return instance;
53 : }
54 :
55 : /**
56 : * @ingroup AicpuEventManager
57 : * @brief it use to init.
58 : * @param [in] noThreadFlag : have thread flag.
59 : * @param [in] runningFlag : running flag.
60 : * @return AICPU_SCHEDULE_OK: success, other: error code
61 : */
62 21 : void AicpuEventManager::InitEventManager(const bool noThreadFlag, const bool runningFlag)
63 : {
64 21 : noThreadFlag_ = noThreadFlag;
65 21 : runningFlag_ = runningFlag;
66 21 : }
67 :
68 : /**
69 : * @ingroup AicpuEventManager
70 : * @brief it is used to parse the struct and get some parameter.
71 : * @param [in] eventInfo : the event information from mailbox.
72 : * @param [in] mailboxId : mail box id
73 : * @param [in] info : the info is used to execute task.
74 : * @param [in] serialNo : the serial no. in mailbox, which is need to use in response package.
75 : * @param [out] streamId : streamId is used to cache task.
76 : * @return AICPU_SCHEDULE_OK: success, other: error code
77 : */
78 11 : int32_t AicpuEventManager::HWTSKernelEventMessageParse(const event_info &eventInfo,
79 : uint32_t &mailboxId,
80 : aicpu::HwtsTsKernel &info,
81 : uint64_t &serialNo,
82 : uint32_t &streamId,
83 : uint64_t &taskId,
84 : uint16_t &dataDumpEnableMode) const
85 : {
86 : // for the msg is address of array, it is not a nullptr.
87 11 : const hwts_ts_task * const eventMsg = PtrToPtr<const char_t, const hwts_ts_task>(eventInfo.priv.msg);
88 11 : mailboxId = eventMsg->mailbox_id;
89 11 : serialNo = eventMsg->serial_no;
90 11 : return HWTSConverMsgFromDriver2Aicpu(eventInfo, info, streamId, taskId, dataDumpEnableMode);
91 : }
92 :
93 : /**
94 : * @ingroup AicpuEventManager
95 : * @brief it use to get stream id and task id form event info
96 : */
97 11 : void AicpuEventManager::GetStreamIdAndTaskIdFromEvent(const hwts_ts_kernel &tsKernel, uint32_t &streamId,
98 : uint64_t &taskId, uint32_t subevent_id) const
99 : {
100 11 : uint32_t tmpStreamId = 0U;
101 11 : aicpusd_info("Get stream id[%u] and task id[%u] from hwts.", tsKernel.streamID, tsKernel.taskID);
102 11 : tmpStreamId = static_cast<uint32_t>(tsKernel.streamID);
103 11 : if (subevent_id != EVENT_FFTS_PLUS_MSG) {
104 10 : taskId = static_cast<uint32_t>(tsKernel.taskID);
105 : }
106 11 : uint16_t version = FeatureCtrl::GetTsMsgVersion();
107 11 : if (version == VERSION_0) {
108 10 : streamId = tmpStreamId;
109 : } else {
110 1 : streamId = INVALID_VAL;
111 : }
112 11 : aicpusd_info("Get stream id[%u] and task id[%u] in version[%hu].",
113 : streamId, taskId, version);
114 11 : return;
115 : }
116 : /**
117 : * @ingroup AicpuEventManager
118 : * @brief it is used to convert hwts_ts_kernel to cceKernel or fwkKernel.
119 : * @param [in] eventInfo : the event information from mailbox.
120 : * @param [in] info : the info is used to execute task.
121 : * @param [out] streamId : streamId is used to cache task.
122 : * @return AICPU_SCHEDULE_OK: success, other: error code
123 : */
124 11 : int32_t AicpuEventManager::HWTSConverMsgFromDriver2Aicpu(const event_info &eventInfo,
125 : aicpu::HwtsTsKernel &info,
126 : uint32_t &streamId,
127 : uint64_t &taskId,
128 : uint16_t &dataDumpEnableMode) const
129 : {
130 11 : int32_t ret = AICPU_SCHEDULE_OK;
131 : // for the msg is address of array, it is not a nullptr.
132 11 : const hwts_ts_task * const eventMsg = PtrToPtr<const char_t, const hwts_ts_task>(eventInfo.priv.msg);
133 11 : const hwts_ts_kernel tsKernel = eventMsg->kernel_info;
134 11 : GetStreamIdAndTaskIdFromEvent(tsKernel, streamId, taskId, eventInfo.comm.subevent_id);
135 11 : dataDumpEnableMode = static_cast<uint16_t>((tsKernel.l2Ctrl >> DATADUMP_ENABLE_MODE_OFFSET) & 1U);
136 11 : const uint32_t eventKernelType = static_cast<uint32_t>(tsKernel.kernel_type);
137 11 : aicpusd_info("Kernel type of current task is [%u], dataDumpEnableMode[%u].",
138 : eventKernelType, dataDumpEnableMode);
139 11 : if (eventKernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM_KFC) {
140 2 : info.kernelType = eventKernelType;
141 2 : info.kernelBase.cceKernel.kernelName = static_cast<uint64_t>(tsKernel.kernelName & CONVER_DRIVER_2_AICPU);
142 2 : info.kernelBase.cceKernel.kernelSo = static_cast<uint64_t>(tsKernel.kernelSo & CONVER_DRIVER_2_AICPU);
143 2 : info.kernelBase.cceKernel.paramBase = static_cast<uint64_t>(tsKernel.paramBase & CONVER_DRIVER_2_AICPU);
144 2 : info.kernelBase.cceKernel.blockId = tsKernel.blockId;
145 2 : info.kernelBase.cceKernel.blockNum = tsKernel.blockNum;
146 9 : } else if (eventKernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM) {
147 8 : info.kernelType = eventKernelType;
148 8 : info.kernelBase.cceKernel.kernelName = static_cast<uint64_t>(tsKernel.kernelName & CONVER_DRIVER_2_AICPU);
149 8 : info.kernelBase.cceKernel.kernelSo = static_cast<uint64_t>(tsKernel.kernelSo & CONVER_DRIVER_2_AICPU);
150 8 : info.kernelBase.cceKernel.paramBase = static_cast<uint64_t>(tsKernel.paramBase & CONVER_DRIVER_2_AICPU);
151 8 : info.kernelBase.cceKernel.l2VaddrBase = static_cast<uint64_t>(tsKernel.l2VaddrBase & CONVER_DRIVER_2_AICPU);
152 8 : info.kernelBase.cceKernel.blockId = tsKernel.blockId;
153 8 : info.kernelBase.cceKernel.blockNum = tsKernel.blockNum;
154 8 : info.kernelBase.cceKernel.l2Size = 0U;
155 8 : info.kernelBase.cceKernel.l2InMain = tsKernel.l2InMain;
156 : } else {
157 1 : aicpusd_err("Don't support kernel_type[%u].", eventKernelType);
158 1 : ret = AICPU_SCHEDULE_ERROR_DRV_ERR;
159 : }
160 11 : return ret;
161 : }
162 :
163 : /**
164 : * @ingroup AicpuEventManager
165 : * @brief it use to init control event version function map
166 : */
167 11 : void AicpuEventManager::InitControlVersionFunc()
168 : {
169 11 : controlEventVersionFuncMap_[VERSION_0] = &AicpuEventManager::ProcessHWTSControlEventV0;
170 11 : controlEventVersionFuncMap_[VERSION_1] = &AicpuEventManager::ProcessHWTSControlEventV1;
171 11 : return;
172 : }
173 :
174 : /**
175 : * @ingroup AicpuEventManager
176 : * @brief it use to process control task from ts
177 : * @param [in] drvEventInfo : the event information from ts.
178 : * @return AICPU_SCHEDULE_OK: success, other: error code
179 : */
180 11 : int32_t AicpuEventManager::ProcessHWTSControlEvent(const event_info &drvEventInfo)
181 : {
182 11 : uint16_t version = FeatureCtrl::GetTsMsgVersion();
183 11 : aicpusd_info("Begin to process version[%hu] ctrl msg.", version);
184 11 : InitControlVersionFunc();
185 11 : int32_t ret = AICPU_SCHEDULE_OK;
186 11 : if (controlEventVersionFuncMap_.find(version) == controlEventVersionFuncMap_.end()) {
187 1 : aicpusd_err("The version[%hu] does not have a corresponding processing function.", version);
188 1 : return AICPU_SCHEDULE_ERROR_NOT_FOUND_VERSION;
189 : }
190 10 : ret = (this->*controlEventVersionFuncMap_[version])(drvEventInfo);
191 10 : return ret;
192 : }
193 :
194 : /**
195 : * @ingroup AicpuEventManager
196 : * @brief it use to process control task from ts version 0
197 : * @param [in] drvEventInfo : the event information from ts.
198 : * @return AICPU_SCHEDULE_OK: success, other: error code
199 : */
200 5 : int32_t AicpuEventManager::ProcessHWTSControlEventV0(const event_info &drvEventInfo)
201 : {
202 : // for the msg is address of array, it is not a nullptr.
203 : // so the info is not used to judge whether is nullptr;
204 5 : const TsAicpuSqe * const ctrlMsg = PtrToPtr<const char_t, const TsAicpuSqe>(drvEventInfo.priv.msg);
205 5 : const uint16_t version = FeatureCtrl::GetTsMsgVersion();
206 5 : AicpuSqeAdapter aicpuSqeAdapter(*ctrlMsg, version);
207 5 : uint8_t cmdType = aicpuSqeAdapter.GetCmdType();
208 5 : aicpusd_info("Begin to process version[%hu] ctrl msg, cmd type[%u].", version, cmdType);
209 5 : int32_t ret = AICPU_SCHEDULE_OK;
210 5 : switch (cmdType) {
211 2 : case AICPU_MSG_VERSION : {
212 2 : ret = AicpuEventProcess::GetInstance().ProcessMsgVersionEvent(aicpuSqeAdapter);
213 2 : break;
214 : }
215 1 : case AICPU_DATADUMP_LOADINFO: // load op mapping info for dump
216 1 : ret = AicpuEventProcess::GetInstance().ProcessLoadOpMappingEvent(aicpuSqeAdapter);
217 1 : break;
218 :
219 2 : default:
220 2 : aicpusd_err("The event is not found, cmd type[%u]", cmdType);
221 2 : return AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
222 : }
223 3 : return ret;
224 5 : }
225 :
226 : /**
227 : * @ingroup AicpuEventManager
228 : * @brief it use to process control task from ts version 1
229 : * @param [in] drvEventInfo : the event information from ts.
230 : * @return AICPU_SCHEDULE_OK: success, other: error code
231 : */
232 5 : int32_t AicpuEventManager::ProcessHWTSControlEventV1(const event_info &drvEventInfo)
233 : {
234 : // for the msg is address of array, it is not a nullptr.
235 : // so the info is not used to judge whether is nullptr;
236 5 : const TsAicpuMsgInfo * const msgInfo = PtrToPtr<const char_t, const TsAicpuMsgInfo>(drvEventInfo.priv.msg);
237 5 : const uint16_t version = FeatureCtrl::GetTsMsgVersion();
238 5 : AicpuSqeAdapter aicpuSqeAdapter(*msgInfo, version);
239 5 : uint8_t cmdType = aicpuSqeAdapter.GetCmdType();
240 5 : aicpusd_info("Begin to process version[%hu] ctrl msg, cmd type[%u].", version, cmdType);
241 5 : int32_t ret = AICPU_SCHEDULE_OK;
242 5 : switch (cmdType) {
243 3 : case TS_AICPU_MSG_VERSION : {
244 3 : ret = AicpuEventProcess::GetInstance().ProcessMsgVersionEvent(aicpuSqeAdapter);
245 3 : break;
246 : }
247 1 : case TS_AICPU_DATADUMP_INFO_LOAD: // load op mapping info for dump
248 1 : ret = AicpuEventProcess::GetInstance().ProcessLoadOpMappingEvent(aicpuSqeAdapter);
249 1 : break;
250 1 : default:
251 1 : aicpusd_err("The event is not found, cmd type[%u]", cmdType);
252 1 : return AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
253 : }
254 4 : return ret;
255 5 : }
256 :
257 :
258 11 : int32_t AicpuEventManager::ProcTsCtrlEvent(const event_info &drvEventInfo, const uint32_t threadIndex)
259 : {
260 : (void)threadIndex;
261 11 : const int32_t ret = ProcessHWTSControlEvent(drvEventInfo);
262 11 : if (ret != AICPU_SCHEDULE_OK) {
263 8 : aicpusd_err("Process CTRL event failed, eventId=%u, ret=%d.", drvEventInfo.comm.event_id, ret);
264 8 : return ret;
265 : }
266 :
267 3 : aicpusd_info("Finish to process CTRL event, eventid[%u], threadIndex[%u], ret[%d].",
268 : drvEventInfo.comm.event_id, threadIndex, ret);
269 3 : return ret;
270 : }
271 2 : int32_t AicpuEventManager::ExecuteHWTSKFCEventTask(const event_info &drvEventInfo,
272 : const aicpu::HwtsTsKernel &aicpufwKernelInfo,
273 : const uint32_t threadIndex,
274 : const uint32_t streamId,
275 : const uint64_t taskId) const
276 : {
277 2 : aicpusd_info("custom kfc task, streamId[%u], taskId[%lu].", streamId, taskId);
278 2 : std::shared_ptr<aicpu::ProfMessage> profMsg = nullptr;
279 2 : const bool profFlag = aicpu::IsProfOpen();
280 2 : uint64_t tickBeforeRun = 0LLU;
281 2 : (void)aicpu::SetTaskAndStreamId(taskId, streamId);
282 2 : if (profFlag) {
283 2 : aicpusd_info("Profiling is open, start malloc.");
284 : try {
285 2 : profMsg = std::make_shared<aicpu::ProfMessage>("AICPU");
286 0 : } catch (std::exception &threadException) {
287 0 : aicpusd_err("make shared for ProfMessage failed. Exception[%s]", threadException.what());
288 0 : return TASK_FAIL;
289 0 : }
290 2 : (void)aicpu::SetProfHandle(profMsg);
291 2 : tickBeforeRun = aicpu::GetSystemTick();
292 : }
293 2 : const int32_t ret = aeCallInterface(&aicpufwKernelInfo);
294 2 : if (profFlag) {
295 2 : aicpu::aicpuProfContext_t aicpuProfCtx = {
296 : .tickBeforeRun = tickBeforeRun,
297 2 : .drvSubmitTick = static_cast<uint64_t>(drvEventInfo.comm.submit_timestamp),
298 2 : .drvSchedTick = static_cast<uint64_t>(drvEventInfo.comm.sched_timestamp),
299 : .kernelType = aicpu::KERNEL_TYPE_AICPU_CUSTOM_KFC
300 2 : };
301 2 : AicpuUtil::SetProfData(profMsg, aicpuProfCtx, threadIndex, streamId, taskId);
302 : }
303 2 : return ret;
304 2 : }
305 : /**
306 : * @ingroup AicpuEventManager
307 : * @brief it is used to parse the struct and get some parameter.
308 : * @param [in] eventInfo : the event information from mailbox.
309 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
310 : * @return AICPU_SCHEDULE_OK: success, other: error code
311 : */
312 11 : int32_t AicpuEventManager::ProcessHWTSKernelEvent(const event_info &eventInfo, const uint32_t threadIndex) const
313 : {
314 11 : aicpu::HwtsTsKernel aicpufwKernelInfo = { };
315 11 : uint32_t mailboxId = 0U;
316 11 : uint32_t streamId = 0U;
317 11 : uint64_t taskId = 0U;
318 11 : uint64_t serialNo = 0U;
319 11 : uint16_t dataDumpEnableMode = 0U;
320 11 : int32_t ret = HWTSKernelEventMessageParse(eventInfo, mailboxId, aicpufwKernelInfo,
321 : serialNo, streamId, taskId, dataDumpEnableMode);
322 11 : if (ret != AICPU_SCHEDULE_OK) {
323 1 : return ret;
324 : }
325 : hwts_response_t hwtsResponse;
326 10 : hwtsResponse.mailbox_id = mailboxId;
327 10 : hwtsResponse.serial_no = serialNo;
328 10 : const auto kernelType = aicpufwKernelInfo.kernelType;
329 10 : if (kernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM_KFC) {
330 2 : ret = ExecuteHWTSKFCEventTask(eventInfo, aicpufwKernelInfo, threadIndex, streamId, taskId);
331 2 : hwtsResponse.status = (ret == AICPU_SCHEDULE_OK) ? static_cast<uint32_t>(TASK_SUCC) :
332 : static_cast<uint32_t>(TASK_FAIL);
333 : } else {
334 8 : const TaskInfoForMonitor taskInfoForMonitor = {
335 : .serialNo = serialNo,
336 : .taskId = taskId,
337 : .streamId = streamId,
338 : .isHwts = true
339 8 : };
340 : // GetInstance is not null, checked in InitAICPUScheduler
341 8 : AicpuMonitor::GetInstance().SetTaskInfo(static_cast<uint64_t>(threadIndex), taskInfoForMonitor);
342 :
343 : const EventInfoForExecute eventInfoForExecute = {
344 : .threadIndex = threadIndex,
345 : .streamId = streamId,
346 : .taskId = taskId,
347 : .dataDumpEnableMode = dataDumpEnableMode,
348 : .serialNo = serialNo,
349 : .mailboxId = mailboxId
350 8 : };
351 8 : ret = ExecuteHWTSEventTask(eventInfoForExecute, aicpufwKernelInfo, eventInfo, hwtsResponse);
352 : }
353 10 : hwtsResponse.result = static_cast<uint32_t>(AicpuSchedule::AicpuUtil::TransformInnerErrCode(ret));
354 10 : const uint32_t subeventId = eventInfo.comm.subevent_id;
355 10 : aicpusd_info("Begin send ack to ts, subevent_id[%u], mailboxId[%u], serialNo[%lu], " \
356 : "streamId[%u], taskId[%lu], result[%d], originResult[%d], status[%d].",
357 : subeventId, mailboxId, serialNo, streamId, taskId, hwtsResponse.result,
358 : ret, hwtsResponse.status);
359 10 : const auto drvRet = halEschedAckEvent(AicpuDrvManager::GetInstance().GetDeviceId(), EVENT_TS_HWTS_KERNEL,
360 : subeventId, PtrToPtr<hwts_response_t, char_t>(&hwtsResponse),
361 : static_cast<uint32_t>(sizeof(hwts_response_t)));
362 10 : if (drvRet != DRV_ERROR_NONE) {
363 1 : aicpusd_err("Failed to send ack to Ts,"
364 : "subevent_id[%u], mailboxId[%u], serialNo[%lu], result[%d], originResult[%d], " \
365 : "status[%d], error[%d].", subeventId, mailboxId, serialNo, hwtsResponse.result,
366 : ret, hwtsResponse.status, drvRet);
367 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
368 : }
369 9 : if (hwtsResponse.result != 0) {
370 2 : aicpusd_err("Failed to execute the task, subevent id[%u], mailbox id[%u], serial number[%lu], " \
371 : "stream id[%u], task id[%lu], result[%d], originResult[%d], status[%d], error[%d].",
372 : subeventId, mailboxId, serialNo, streamId, taskId, hwtsResponse.result,
373 : ret, hwtsResponse.status, drvRet);
374 : }
375 9 : aicpusd_info("End send ack to Ts, subevent_id[%u], mailboxId[%u], serialNo[%lu], result[%d], " \
376 : "originResult[%d], status[%d].",
377 : subeventId, mailboxId, serialNo, hwtsResponse.result, ret, hwtsResponse.status);
378 :
379 9 : return AICPU_SCHEDULE_OK;
380 : }
381 8 : int32_t AicpuEventManager::ExecuteHWTSEventTask(const EventInfoForExecute &executeEventInfo,
382 : aicpu::HwtsTsKernel &aicpufwKernelInfo,
383 : const event_info &drvEventInfo,
384 : hwts_response_t &hwtsResponse) const
385 : {
386 8 : (void)aicpu::SetThreadLocalCtx(CONTEXT_KEY_STREAM_ID, std::to_string(executeEventInfo.streamId));
387 8 : const hwts_ts_kernel tsKernel = (PtrToPtr<const char_t, const hwts_ts_task>(drvEventInfo.priv.msg))->kernel_info;
388 8 : const uint32_t debugDumpEnableMode =
389 8 : static_cast<uint32_t>((tsKernel.l2Ctrl >> DEBUGDUMP_ENABLE_MODE_OFFSET) & 1U);
390 8 : aicpusd_info("Begin to ExecuteTsKernelTask, mailboxId[%u], serialNo[%lu], streamId[%u], taskId[%lu], " \
391 : "dataDumpEnableMode[%u], debugDumpEnableMode[%u].",
392 : executeEventInfo.mailboxId, executeEventInfo.serialNo, executeEventInfo.streamId,
393 : executeEventInfo.taskId, static_cast<uint32_t>(executeEventInfo.dataDumpEnableMode),
394 : debugDumpEnableMode);
395 8 : int32_t ret = AicpuEventProcess::GetInstance().ExecuteTsKernelTask(aicpufwKernelInfo,
396 8 : executeEventInfo.threadIndex,
397 8 : drvEventInfo.comm.submit_timestamp,
398 8 : drvEventInfo.comm.sched_timestamp,
399 8 : executeEventInfo.streamId,
400 8 : executeEventInfo.taskId);
401 8 : hwtsResponse.status = (ret == AICPU_SCHEDULE_OK) ? static_cast<uint32_t>(TASK_SUCC) :
402 : static_cast<uint32_t>(TASK_FAIL);
403 8 : uint32_t dataDumpEnableMode = static_cast<uint32_t>(executeEventInfo.dataDumpEnableMode);
404 :
405 8 : if ((ret == AICPU_SCHEDULE_OK) && (dataDumpEnableMode == 1U)) {
406 7 : aicpusd_info("Datadump. Begin Dump Self.");
407 7 : const int32_t dumpRet = AicpuSchedule::AicpuCustDumpProcess::GetInstance().
408 7 : BeginDatadumpTask(aicpu::GetAicpuThreadIndex(), executeEventInfo.streamId,
409 7 : static_cast<uint32_t>(executeEventInfo.taskId));
410 7 : ret = (dumpRet != AICPU_SCHEDULE_OK) ? dumpRet : ret;
411 : }
412 8 : return ret;
413 : }
414 :
415 3 : int32_t AicpuEventManager::ProcSplitKernelEvent(const event_info &drvEventInfo, const uint32_t threadIndex) const
416 : {
417 : (void)threadIndex;
418 3 : const AICPUSubEventInfo * const eventInfo = PtrToPtr<const char_t, const AICPUSubEventInfo>(drvEventInfo.priv.msg);
419 3 : aicpusd_info("Begin to process split kernel event. parallelId=%u, type=wait",
420 : eventInfo->para.sharderTaskInfo.parallelId);
421 :
422 3 : const bool ret = ComputeProcess::GetInstance().DoSplitKernelTask(eventInfo->para.sharderTaskInfo);
423 3 : if (!ret) {
424 1 : aicpusd_err("Process split kernel event failed. parallelId=%u, type=wait",
425 : eventInfo->para.sharderTaskInfo.parallelId);
426 1 : return static_cast<int32_t>(AICPU_SCHEDULE_FAIL);
427 : }
428 :
429 2 : return AICPU_SCHEDULE_OK;
430 : }
431 :
432 2 : int32_t AicpuEventManager::ProcRandomKernelEvent(const event_info &drvEventInfo, const uint32_t threadIndex) const
433 : {
434 : (void)drvEventInfo;
435 : (void)threadIndex;
436 2 : aicpusd_info("Begin to process random kernel event. threadIndex=%u", threadIndex);
437 2 : const bool ret = ComputeProcess::GetInstance().DoRandomKernelTask();
438 2 : if (!ret) {
439 1 : aicpusd_err("Process random kernel event failed. threadIndex=%u", threadIndex);
440 1 : return static_cast<int32_t>(AICPU_SCHEDULE_FAIL);
441 : }
442 :
443 1 : return AICPU_SCHEDULE_OK;
444 : }
445 :
446 : /**
447 : * @ingroup AicpuEventManager
448 : * @brief it use to process all event.
449 : * @param [in] eventInfo : the event information from ts.
450 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
451 : * @return AICPU_SCHEDULE_OK: success, other: error code
452 : */
453 34 : int32_t AicpuEventManager::ProcessEvent(const event_info &eventInfo, const uint32_t threadIndex)
454 : {
455 34 : int32_t ret = AICPU_SCHEDULE_OK;
456 34 : switch (eventInfo.comm.event_id) {
457 11 : case EVENT_TS_HWTS_KERNEL: {
458 11 : aicpusd_info("Begin to process HWTS event.");
459 11 : ret = ProcessHWTSKernelEvent(eventInfo, threadIndex);
460 11 : aicpusd_info("Finish to process HWTS event, ret[%d].", ret);
461 11 : break;
462 : }
463 7 : case EVENT_AICPU_MSG: {
464 7 : aicpusd_info("Begin to process AICPU event.");
465 7 : ret = AicpuEventProcess::GetInstance().ProcessAICPUEvent(eventInfo);
466 7 : aicpusd_info("Finish to process AICPU event, ret[%d].", ret);
467 7 : break;
468 : }
469 2 : case EVENT_SPLIT_KERNEL:
470 2 : ret = ProcSplitKernelEvent(eventInfo, threadIndex);
471 2 : break;
472 1 : case EVENT_RANDOM_KERNEL: {
473 1 : ret = ProcRandomKernelEvent(eventInfo, threadIndex);
474 1 : break;
475 : }
476 11 : case EVENT_TS_CTRL_MSG: {
477 11 : aicpusd_info("Begin to process ProcTsCtrlEvent event.");
478 11 : ret = ProcTsCtrlEvent(eventInfo, threadIndex);
479 11 : aicpusd_info("Finish to process ProcTsCtrlEvent event.");
480 11 : break;
481 : }
482 2 : default: {
483 2 : aicpusd_err("Unknown event type, event_id[%d].", eventInfo.comm.event_id);
484 2 : ret = AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
485 2 : break;
486 : }
487 : }
488 :
489 34 : if (ret != AICPU_SCHEDULE_OK) {
490 19 : aicpusd_err("Process event failed. eventId=%d, threadIdx=%u, ret=%d",
491 : static_cast<int32_t>(eventInfo.comm.event_id), threadIndex, ret);
492 : }
493 :
494 34 : return ret;
495 : }
496 :
497 : /**
498 : * @ingroup AicpuEventManager
499 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
500 : * @brief it is used to wait event for once.
501 : */
502 5 : void AicpuEventManager::DoOnce(const uint32_t threadIndex)
503 : {
504 5 : const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
505 5 : const uint32_t groupId = AicpuDrvManager::GetInstance().GetGroupId();
506 : event_info eventInfo;
507 5 : const auto retVal = halEschedWaitEvent(deviceId, groupId, threadIndex,
508 : static_cast<int32_t>(TIMEOUT_INTERVAL), &eventInfo);
509 5 : if (retVal == DRV_ERROR_NONE) {
510 1 : (void) ProcessEvent(eventInfo, threadIndex);
511 4 : } else if (retVal == DRV_ERROR_SCHED_WAIT_TIMEOUT) { // if timeout, will continue wait event.
512 4 : } else if ((retVal == DRV_ERROR_SCHED_PROCESS_EXIT) || (retVal == DRV_ERROR_SCHED_PARA_ERR)) {
513 2 : if (runningFlag_) {
514 1 : runningFlag_ = false;
515 1 : aicpusd_warn("Failed to get event, error code=%d, deviceId[%u], groupId[%u], threadIndex[%u]",
516 : retVal, deviceId, groupId, threadIndex);
517 : }
518 : } else {
519 : // record a error code
520 3 : aicpusd_err("Failed to get event, error code[%d], deviceId[%u], groupId[%u], threadIndex[%u]",
521 : retVal, deviceId, groupId, threadIndex);
522 : }
523 5 : }
524 :
525 : /**
526 : * @ingroup AicpuEventManager
527 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
528 : * @brief it is used in multi-thread.
529 : */
530 3 : void AicpuEventManager::LoopProcess(const uint32_t threadIndex)
531 : {
532 3 : while (runningFlag_) {
533 0 : DoOnce(threadIndex);
534 : }
535 3 : aicpusd_info("The loop of getting event is exit in thread[%u].", threadIndex);
536 3 : }
537 :
538 17 : void AicpuEventManager::SetRunningFlag(const bool runningFlag)
539 : {
540 17 : runningFlag_ = runningFlag;
541 17 : }
542 :
543 10 : int32_t AicpuEventManager::SendCtrlCpuMsg(int32_t aicpuPid, const uint32_t eventType, char_t *msg,
544 : const uint32_t msgLen) const
545 : {
546 : (void)eventType;
547 : (void)msg;
548 : (void)msgLen;
549 10 : return AicpuEventProcess::GetInstance().SendCtrlCpuMsg(
550 10 : aicpuPid, static_cast<uint32_t>(TsdSubEventType::TSD_EVENT_STOP_AICPU_PROCESS_WAIT), nullptr, 0U);
551 : }
552 : }
|