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