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()
47 1 : : noThreadFlag_(true),
48 1 : runningFlag_(true),
49 2 : groupId_(0U)
50 : {
51 1 : aicpuEventProcFunc_[EVENT_TS_CTRL_MSG] = &AicpuEventManager::ProcTsCtrlEvent;
52 1 : }
53 :
54 45 : AicpuEventManager &AicpuEventManager::GetInstance()
55 : {
56 45 : static AicpuEventManager instance;
57 45 : return instance;
58 : }
59 :
60 : /**
61 : * @ingroup AicpuEventManager
62 : * @brief it use to process control task from ts
63 : * @param [in] drvEventInfo : the event information from ts.
64 : * @return AICPU_SCHEDULE_OK: success, other: error code
65 : */
66 11 : int32_t AicpuEventManager::ProcessHWTSControlEvent(const event_info &drvEventInfo)
67 : {
68 : // for the msg is address of array, it is not a nullptr.
69 : // so the info is not used to judge whether is nullptr;
70 11 : const TsAicpuSqe * const ctrlMsg = PtrToPtr<const char_t, const TsAicpuSqe>(drvEventInfo.priv.msg);
71 11 : const uint16_t version = FeatureCtrl::GetTsMsgVersion();
72 11 : AicpuSqeAdapter aicpuSqeAdapter(*ctrlMsg, version);
73 11 : uint8_t cmdType = aicpuSqeAdapter.GetCmdType();
74 11 : aicpusd_info("Begin to process ctrl msg, cmd type[%u].", cmdType);
75 11 : int32_t ret = AICPU_SCHEDULE_OK;
76 11 : switch (cmdType) {
77 2 : case AICPU_DATADUMP_REPORT: // dump data
78 2 : ret = AicpuEventProcess::GetInstance().ProcessDumpDataEvent(aicpuSqeAdapter);
79 2 : break;
80 2 : case AICPU_DATADUMP_LOADINFO: // load op mapping info for dump
81 2 : ret = AicpuEventProcess::GetInstance().ProcessLoadOpMappingEvent(aicpuSqeAdapter);
82 2 : break;
83 :
84 2 : case AICPU_FFTS_PLUS_DATADUMP_REPORT: // dump FFTSPlus data
85 2 : ret = AicpuEventProcess::GetInstance().ProcessDumpFFTSPlusDataEvent(aicpuSqeAdapter);
86 2 : break;
87 5 : default:
88 5 : aicpusd_err("The event is not found, cmd type[%u]", cmdType);
89 5 : ret = AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
90 5 : break;
91 : }
92 11 : return ret;
93 11 : }
94 :
95 :
96 3 : int32_t AicpuEventManager::ProcTsCtrlEvent(const event_info &drvEventInfo, const uint32_t threadIndex)
97 : {
98 : (void)threadIndex;
99 3 : const int32_t ret = ProcessHWTSControlEvent(drvEventInfo);
100 3 : aicpusd_info("Finish to process CTRL event, eventid[%u], threadIndex[%u], ret[%d].",
101 : drvEventInfo.comm.event_id, threadIndex, ret);
102 3 : return ret;
103 : }
104 : /**
105 : * @ingroup AicpuEventManager
106 : * @brief it use to process all event.
107 : * @param [in] drvEventInfo : the event information from ts.
108 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
109 : * @return AICPU_SCHEDULE_OK: success, other: error code
110 : */
111 3 : int32_t AicpuEventManager::ProcessEvent(const event_info &drvEventInfo, const uint32_t threadIndex)
112 : {
113 3 : int32_t ret = AICPU_SCHEDULE_OK;
114 3 : if (drvEventInfo.comm.event_id >= EVENT_MAX_NUM) {
115 0 : aicpusd_err("Unknown event type, event_id[%u].", drvEventInfo.comm.event_id);
116 0 : ret = AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
117 0 : return ret;
118 : }
119 3 : const AicpuEventProc aicpuEventFunc = aicpuEventProcFunc_[drvEventInfo.comm.event_id];
120 3 : if (aicpuEventFunc != nullptr) {
121 0 : ret = (this->*aicpuEventFunc)(drvEventInfo, threadIndex);
122 : } else {
123 3 : aicpusd_err("Unknown event type, event_id[%u].", drvEventInfo.comm.event_id);
124 3 : ret = AICPU_SCHEDULE_ERROR_NOT_FOUND_EVENT;
125 : }
126 3 : return ret;
127 : }
128 : /**
129 : * @ingroup AicpuEventManager
130 : * @param [in] threadIndex : thread index assign by aicpu index, but when running time they are different.
131 : * @brief it is used to wait event for once.
132 : */
133 4 : int32_t AicpuEventManager::DoOnce(const uint32_t threadIndex, const uint32_t deviceId, const int32_t timeout)
134 : {
135 : event_info drvEventInfo;
136 4 : const int32_t retVal = halEschedWaitEvent(deviceId, groupId_, threadIndex, timeout, &drvEventInfo);
137 4 : if (retVal == DRV_ERROR_NONE) {
138 0 : (void) ProcessEvent(drvEventInfo, threadIndex);
139 4 : } else if (retVal == DRV_ERROR_SCHED_WAIT_TIMEOUT) { // if timeout, will continue wait event.
140 4 : } else if ((retVal == DRV_ERROR_SCHED_PROCESS_EXIT) || (retVal == DRV_ERROR_SCHED_PARA_ERR)) {
141 1 : if (runningFlag_) {
142 1 : runningFlag_ = false;
143 : }
144 1 : aicpusd_warn("Failed to get event, error code=%d, deviceId[%u], groupId[%u], threadIndex[%u]",
145 : retVal, deviceId, groupId_, threadIndex);
146 3 : } else if (retVal == DRV_ERROR_SCHED_RUN_IN_ILLEGAL_CPU) {
147 2 : runningFlag_ = false;
148 2 : aicpusd_err("Cpu Illegal get event, error code[%d], deviceId[%u], groupId[%u], threadIndex[%u]",
149 : retVal, deviceId, groupId_, threadIndex);
150 : } else {
151 : // record a error code
152 1 : aicpusd_err("Failed to get event, error code[%d], deviceId[%u], groupId[%u], threadIndex[%u]",
153 : retVal, deviceId, 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)
173 : {
174 20 : runningFlag_ = runningFlag;
175 20 : }
176 : }
|