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 : #include <cstdint>
12 : #include <securec.h>
13 : #include <sstream>
14 : #include "ascend_hal.h"
15 : #include "aicpusd_interface_process.h"
16 : #include "aicpusd_event_process.h"
17 : #include "aicpusd_threads_process.h"
18 : #include "dump_task.h"
19 : #include "aicpu_context.h"
20 : #include "aicpu_async_event.h"
21 : #include "aicpu_sched/common/aicpu_task_struct.h"
22 : #include "aicpusd_resource_manager.h"
23 : #include "aicpusd_drv_manager.h"
24 : #include "aicpusd_model_execute.h"
25 : #include "aicpu_engine.h"
26 : #include "aicpusd_monitor.h"
27 : #include "aicpusd_lastword.h"
28 : #include "task_queue.h"
29 : #include "aicpusd_profiler.h"
30 : #include "aicpusd_msg_send.h"
31 : #include "common/aicpusd_util.h"
32 : #include "aicpusd_mpi_mgr.h"
33 : #include "aicpu_pulse.h"
34 : #include "aicpusd_queue_event_process.h"
35 : #include "type_def.h"
36 :
37 : namespace AicpuSchedule {
38 : namespace {
39 : constexpr uint32_t AICPU_TIMEOUT_INTERVAL = 3000U;
40 : }
41 :
42 : /**
43 : * @ingroup AicpuEventManager
44 : * @brief it is used to construct a object of AicpuEventManager.
45 : */
46 1 : AicpuEventManager::AicpuEventManager() : noThreadFlag_(true), runningFlag_(true), groupId_(0U)
47 : {
48 1 : aicpuEventProcFunc_[EVENT_TS_CTRL_MSG] = &AicpuEventManager::ProcTsCtrlEvent;
49 1 : }
50 :
51 45 : AicpuEventManager& AicpuEventManager::GetInstance()
52 : {
53 45 : static AicpuEventManager instance;
54 45 : return instance;
55 : }
56 :
57 : /**
58 : * @ingroup AicpuEventManager
59 : * @brief it use to process control task from ts
60 : * @param [in] drvEventInfo : the event information from ts.
61 : * @return AICPU_SCHEDULE_OK: success, other: error code
62 : */
63 11 : int32_t AicpuEventManager::ProcessHWTSControlEvent(const event_info& drvEventInfo)
64 : {
65 : // for the msg is address of array, it is not a nullptr.
66 : // so the info is not used to judge whether is nullptr;
67 11 : const TsAicpuSqe* const ctrlMsg = PtrToPtr<const char_t, const TsAicpuSqe>(drvEventInfo.priv.msg);
68 11 : const uint16_t version = FeatureCtrl::GetTsMsgVersion();
69 11 : AicpuSqeAdapter aicpuSqeAdapter(*ctrlMsg, version);
70 11 : uint8_t cmdType = aicpuSqeAdapter.GetCmdType();
71 11 : aicpusd_info("Begin to process ctrl msg, cmd type[%u].", cmdType);
72 11 : int32_t ret = AICPU_SCHEDULE_OK;
73 11 : switch (cmdType) {
74 2 : case AICPU_DATADUMP_REPORT: // dump data
75 2 : ret = AicpuEventProcess::GetInstance().ProcessDumpDataEvent(aicpuSqeAdapter);
76 2 : break;
77 2 : case AICPU_DATADUMP_LOADINFO: // load op mapping info for dump
78 2 : ret = AicpuEventProcess::GetInstance().ProcessLoadOpMappingEvent(aicpuSqeAdapter);
79 2 : break;
80 :
81 2 : case AICPU_FFTS_PLUS_DATADUMP_REPORT: // dump FFTSPlus data
82 2 : ret = AicpuEventProcess::GetInstance().ProcessDumpFFTSPlusDataEvent(aicpuSqeAdapter);
83 2 : break;
84 5 : default:
85 5 : aicpusd_err("The event is not found, cmd type[%u]", cmdType);
86 5 : ret = AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
87 5 : break;
88 : }
89 11 : return ret;
90 11 : }
91 :
92 3 : int32_t AicpuEventManager::ProcTsCtrlEvent(const event_info& drvEventInfo, const uint32_t threadIndex)
93 : {
94 : (void)threadIndex;
95 3 : const int32_t ret = ProcessHWTSControlEvent(drvEventInfo);
96 3 : aicpusd_info(
97 : "Finish to process CTRL event, eventid[%u], threadIndex[%u], ret[%d].", drvEventInfo.comm.event_id, threadIndex,
98 : ret);
99 3 : return ret;
100 : }
101 : /**
102 : * @ingroup AicpuEventManager
103 : * @brief it use to process all event.
104 : * @param [in] drvEventInfo : the event information from ts.
105 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
106 : * @return AICPU_SCHEDULE_OK: success, other: error code
107 : */
108 3 : int32_t AicpuEventManager::ProcessEvent(const event_info& drvEventInfo, const uint32_t threadIndex)
109 : {
110 3 : int32_t ret = AICPU_SCHEDULE_OK;
111 3 : if (drvEventInfo.comm.event_id >= EVENT_MAX_NUM) {
112 0 : aicpusd_err("Unknown event type, event_id[%u].", drvEventInfo.comm.event_id);
113 0 : ret = AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
114 0 : return ret;
115 : }
116 3 : const AicpuEventProc aicpuEventFunc = aicpuEventProcFunc_[drvEventInfo.comm.event_id];
117 3 : if (aicpuEventFunc != nullptr) {
118 0 : ret = (this->*aicpuEventFunc)(drvEventInfo, threadIndex);
119 : } else {
120 3 : aicpusd_err("Unknown event type, event_id[%u].", drvEventInfo.comm.event_id);
121 3 : ret = AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
122 : }
123 3 : return ret;
124 : }
125 : /**
126 : * @ingroup AicpuEventManager
127 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
128 : * @brief it is used to wait event for once.
129 : */
130 4 : int32_t AicpuEventManager::DoOnce(const uint32_t threadIndex, const uint32_t deviceId, const int32_t timeout)
131 : {
132 : event_info drvEventInfo;
133 4 : const int32_t retVal = halEschedWaitEvent(deviceId, groupId_, threadIndex, timeout, &drvEventInfo);
134 4 : if (retVal == DRV_ERROR_NONE) {
135 0 : (void)ProcessEvent(drvEventInfo, threadIndex);
136 4 : } else if (retVal == DRV_ERROR_SCHED_WAIT_TIMEOUT) { // if timeout, will continue wait event.
137 4 : } else if ((retVal == DRV_ERROR_SCHED_PROCESS_EXIT) || (retVal == DRV_ERROR_SCHED_PARA_ERR)) {
138 1 : if (runningFlag_) {
139 1 : runningFlag_ = false;
140 : }
141 1 : aicpusd_warn(
142 : "Failed to get event, error code=%d, deviceId[%u], groupId[%u], threadIndex[%u]", retVal, deviceId,
143 : groupId_, threadIndex);
144 3 : } else if (retVal == DRV_ERROR_SCHED_RUN_IN_ILLEGAL_CPU) {
145 2 : runningFlag_ = false;
146 2 : aicpusd_err(
147 : "Cpu Illegal get event, error code[%d], deviceId[%u], groupId[%u], threadIndex[%u]", retVal, deviceId,
148 : groupId_, threadIndex);
149 : } else {
150 : // record a error code
151 1 : aicpusd_err(
152 : "Failed to get event, error code[%d], deviceId[%u], groupId[%u], threadIndex[%u]", retVal, deviceId,
153 : groupId_, threadIndex);
154 : }
155 4 : return retVal;
156 : }
157 :
158 : /**
159 : * @ingroup AicpuEventManager
160 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
161 : * @brief it is used in multi-thread.
162 : */
163 4 : void AicpuEventManager::LoopProcess(const uint32_t threadIndex)
164 : {
165 4 : const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
166 4 : while (runningFlag_) {
167 0 : (void)DoOnce(threadIndex, deviceId);
168 : }
169 4 : aicpusd_info("The loop of getting event is exit in thread[%u].", threadIndex);
170 4 : }
171 :
172 20 : void AicpuEventManager::SetRunningFlag(const bool runningFlag) { runningFlag_ = runningFlag; }
173 : } // namespace AicpuSchedule
|