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 :
11 : #include "aicpusd_event_process.h"
12 :
13 : #include <iomanip>
14 : #ifndef _AOSCORE_
15 : #endif
16 : #include "ascend_hal.h"
17 : #include "aicpusd_monitor.h"
18 : #include "aicpusd_drv_manager.h"
19 : #include "aicpusd_op_executor.h"
20 : #include "aicpu_context.h"
21 : #include "aicpusd_common.h"
22 : #include "profiling_adp.h"
23 : #include "aicpusd_hal_interface_ref.h"
24 : #include "common/aicpusd_util.h"
25 : #include "dump_task.h"
26 : #include "ts_api.h"
27 : #include "aicpusd_interface_process.h"
28 : #include "tsd.h"
29 : #include "aicpu_prof.h"
30 :
31 : namespace AicpuSchedule {
32 : constexpr uint32_t CCPU_DEFAULT_GROUP_ID = 30U;
33 : constexpr uint16_t VALID_MAGIC_NUM = 0x5A5A;
34 : static constexpr uint8_t VERSION_0 = 0;
35 : static constexpr uint8_t VERSION_1 = 1;
36 : std::set<uint8_t> allVersion = {VERSION_0, VERSION_1};
37 : /**
38 : * @ingroup AicpuEventProcess
39 : * @brief it is used to construct a object of AicpuEventProcess.
40 : */
41 1 : AicpuEventProcess::AicpuEventProcess()
42 : {
43 1 : eventTaskProcess_[AICPU_SUB_EVENT_BIND_SD_PID] = &AicpuEventProcess::AICPUEventBindSdPid;
44 1 : eventTaskProcess_[AICPU_SUB_EVENT_OPEN_CUSTOM_SO] = &AicpuEventProcess::AICPUEventOpenCustomSo;
45 1 : eventTaskProcess_[AICPU_SUB_EVENT_CUST_UPDATE_PROFILING_MODE] =
46 : &AicpuEventProcess::AICPUEventCustUpdateProfilingMode;
47 1 : }
48 :
49 : /**
50 : * @ingroup AicpuEventProcess
51 : * @brief it is used to destructor a object of AicpuEventProcess.
52 : */
53 1 : AicpuEventProcess::~AicpuEventProcess() {}
54 :
55 37 : AicpuEventProcess &AicpuEventProcess::GetInstance()
56 : {
57 37 : static AicpuEventProcess instance;
58 37 : return instance;
59 : }
60 :
61 : /**
62 : * @ingroup AicpuEventProcess
63 : * @brief it use to process the AICPU event.
64 : * @param [in] eventInfo : the event information from ts.
65 : * @return AICPU_SCHEDULE_OK: success, other: error code
66 : */
67 7 : int32_t AicpuEventProcess::ProcessAICPUEvent(const event_info &eventInfo)
68 : {
69 7 : aicpusd_info("Begin to process the aicpu event, eventId[%d].", eventInfo.comm.subevent_id);
70 :
71 7 : int32_t ret = AICPU_SCHEDULE_OK;
72 : // find process function of the subevent id.
73 7 : const AICPUCustSubEvent custEventId = static_cast<AICPUCustSubEvent>(eventInfo.comm.subevent_id);
74 7 : const auto it = eventTaskProcess_.find(custEventId);
75 7 : if (it != eventTaskProcess_.end()) {
76 6 : const EventProcess pFunction = it->second;
77 6 : ret = (this->*pFunction)(eventInfo.priv);
78 : } else {
79 1 : aicpusd_err("The subevent id is invalid, id[%u].", eventInfo.comm.subevent_id);
80 1 : return AICPU_SCHEDULE_ERROR_UNKNOW_AICPU_EVENT;
81 : }
82 : // Failed to execute the task , it needs to handle error.
83 6 : if (ret != AICPU_SCHEDULE_OK) {
84 4 : aicpusd_err("Failed to process aicpu event, eventId[%d].", custEventId);
85 4 : return ret;
86 : }
87 2 : aicpusd_info("Successfully processed AICPU event, eventId[%d].", custEventId);
88 2 : return AICPU_SCHEDULE_OK;
89 : }
90 :
91 8 : int32_t AicpuEventProcess::ExecuteTsKernelTask(aicpu::HwtsTsKernel &tsKernelInfo, const uint32_t threadIndex,
92 : const uint64_t drvSubmitTick, const uint64_t drvSchedTick,
93 : const uint64_t streamId, const uint64_t taskId)
94 : {
95 8 : std::shared_ptr<aicpu::ProfMessage> profMsg = nullptr;
96 8 : if (aicpu::IsProfOpen()) {
97 8 : aicpusd_info("Profiling is open, start malloc.");
98 : try {
99 8 : profMsg = std::make_shared<aicpu::ProfMessage>("AICPU");
100 0 : } catch (std::exception &threadException) {
101 0 : aicpusd_err("make shared for ProfMessage failed. Exception[%s]", threadException.what());
102 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
103 0 : }
104 8 : (void)aicpu::SetProfHandle(profMsg);
105 : }
106 8 : const uint64_t tickBeforeRun = aicpu::GetSystemTick();
107 : const aicpu::aicpuProfContext_t aicpuProfCtx = {
108 : .tickBeforeRun = tickBeforeRun,
109 : .drvSubmitTick = drvSubmitTick,
110 : .drvSchedTick = drvSchedTick,
111 8 : .kernelType = tsKernelInfo.kernelType
112 8 : };
113 8 : (void)aicpu::aicpuSetProfContext(aicpuProfCtx);
114 8 : AicpuMonitor::GetInstance().SetTaskStartTime(static_cast<uint64_t>(threadIndex));
115 8 : const auto retAicpu = CustomOpExecutor::GetInstance().ExecuteKernel(tsKernelInfo);
116 8 : AicpuMonitor::GetInstance().SetTaskEndTime(static_cast<uint64_t>(threadIndex));
117 8 : AicpuUtil::SetProfData(profMsg, aicpuProfCtx, threadIndex, streamId, taskId);
118 8 : if (retAicpu != AICPU_SCHEDULE_OK) {
119 1 : std::string opName;
120 1 : (void)aicpu::GetOpname(threadIndex, opName);
121 1 : aicpusd_err("Execute aicpu custom kernel failed, result[%d], opName[%s], streamId[%llu], taskId[%llu].",
122 : retAicpu, opName.c_str(), streamId, taskId);
123 1 : }
124 :
125 8 : (void)aicpu::SetOpname("null");
126 8 : return retAicpu;
127 8 : }
128 :
129 6 : int32_t AicpuEventProcess::AICPUEventBindSdPid(const event_info_priv &privEventInfo) const
130 : {
131 6 : if (privEventInfo.msg_len != sizeof(AICPUBindSdPidEventMsg)) {
132 2 : aicpusd_err("The event msg len[%u] is not correct[%zu].",
133 : privEventInfo.msg_len, sizeof(AICPUBindSdPidEventMsg));
134 2 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
135 : }
136 : const AICPUBindSdPidEventMsg * const info =
137 4 : PtrToPtr<const char_t, const AICPUBindSdPidEventMsg>(privEventInfo.msg);
138 4 : const pid_t hostPid = AicpuDrvManager::GetInstance().GetHostPid();
139 4 : const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
140 4 : const uint32_t vfId = AicpuDrvManager::GetInstance().GetVfId();
141 4 : if (&halMemBindSibling == nullptr) {
142 0 : aicpusd_err("Interface halMemBindSibling is not supported in current device");
143 0 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
144 : }
145 4 : drvError_t drvRet = DRV_ERROR_NONE;
146 4 : if (AicpuSchedule::AicpuDrvManager::GetInstance().GetSafeVerifyFlag()) {
147 1 : drvRet = halMemBindSibling(hostPid, info->pid, vfId, deviceId, SVM_MEM_BIND_SVM_GRP);
148 : } else {
149 : //new
150 3 : drvRet = halMemBindSibling(hostPid, info->pid, vfId, deviceId, SVM_MEM_BIND_SVM_GRP | SVM_MEM_BIND_SP_GRP_NO_ALLOC);
151 : }
152 4 : if (drvRet != DRV_ERROR_NONE) {
153 1 : aicpusd_err("Failed to halMemBindSibling, hostpid=%d, aicpuSdPid=%d, deviceId=%u, ret=%d.\n",
154 : hostPid, info->pid, deviceId, drvRet);
155 1 : return drvRet;
156 : }
157 3 : aicpusd_info("Bind Sibling pid success, hostpid=%d, aicpuSdPid=%d, deviceId=%u.",
158 : hostPid, info->pid, deviceId);
159 3 : return AICPU_SCHEDULE_OK;
160 : }
161 :
162 2 : int32_t AicpuEventProcess::AICPUEventOpenCustomSo(const event_info_priv &privEventInfo) const
163 : {
164 2 : const int32_t ret = CustomOpExecutor::GetInstance().OpenKernelSo(privEventInfo);
165 2 : if (ret != AICPU_SCHEDULE_OK) {
166 1 : aicpusd_err("Open custom kernel so failed.");
167 1 : return ret;
168 : }
169 1 : return AICPU_SCHEDULE_OK;
170 : }
171 :
172 1 : int32_t AicpuEventProcess::AICPUEventCustUpdateProfilingMode(const event_info_priv &privEventInfo) const
173 : {
174 1 : const AICPUSubEventInfo * const info = PtrToPtr<const char_t, const AICPUSubEventInfo>(privEventInfo.msg);
175 1 : const uint32_t modelInfoFlag = (*info).para.modeInfo.flag;
176 1 : aicpusd_info("Get profiling flag success, flag[%u]", modelInfoFlag);
177 :
178 1 : ProfilingMode profilingMode = PROFILING_CLOSE;
179 1 : bool kernelFlag = false;
180 1 : AicpuUtil::GetProfilingInfo(modelInfoFlag, profilingMode, kernelFlag);
181 1 : aicpusd_info("Update aicpu profiling mode success, profilingMode[%u], kernelFlag[%d]",
182 : profilingMode, kernelFlag);
183 1 : aicpu::LoadProfilingLib();
184 1 : aicpu::SetProfilingFlagForKFC(modelInfoFlag);
185 1 : if (kernelFlag) {
186 1 : aicpu::UpdateMode(profilingMode == PROFILING_OPEN);
187 : }
188 1 : if (SendUpdateProfilingRspToTsd(AicpuDrvManager::GetInstance().GetDeviceId(),
189 : static_cast<uint32_t>(TsdWaitType::TSD_CUSTOM_COMPUTE),
190 1 : static_cast<uint32_t>(AicpuDrvManager::GetInstance().GetHostPid()),
191 2 : AicpuDrvManager::GetInstance().GetVfId()) != AICPU_SCHEDULE_OK) {
192 0 : aicpusd_err("send profilling response to tsd failed");
193 0 : return AICPU_SCHEDULE_ERROR_TASK_EXECUTE_FAILED;
194 : }
195 1 : return AICPU_SCHEDULE_OK;
196 : }
197 :
198 : /**
199 : * @ingroup AicpuEventProcess
200 : * @brief it is used to process the msg version.
201 : * @param [in] info : the information of task.
202 : * @return AICPU_SCHEDULE_OK: success, other: error code
203 : */
204 5 : int32_t AicpuEventProcess::ProcessMsgVersionEvent(AicpuSqeAdapter &aicpuSqeAdapter) const
205 : {
206 5 : aicpusd_info("Begin to process msg version event.");
207 5 : AicpuSqeAdapter::AicpuMsgVersionInfo info {};
208 5 : aicpuSqeAdapter.GetAicpuMsgVersionInfo(info);
209 5 : int32_t ret = AICPU_SCHEDULE_OK;
210 5 : if (info.magic_num != VALID_MAGIC_NUM) {
211 3 : aicpusd_err("Magic num[%u] is not valid.", info.magic_num);
212 3 : return AICPU_SCHEDULE_ERROR_INVALID_MAGIC_NUM;
213 : } else {
214 2 : uint16_t version = info.version;
215 2 : if (allVersion.find(version) == allVersion.end()) {
216 0 : aicpusd_err("Version is incorrect, version[%hu]", version);
217 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
218 : }
219 2 : FeatureCtrl::SetTsMsgVersion(version);
220 2 : aicpusd_info("Set msg version [%hu].", version);
221 : }
222 2 : aicpusd_info("Begin to send response msg version.");
223 2 : int32_t rspRet = aicpuSqeAdapter.AicpuMsgVersionResponseToTs(ret);
224 2 : aicpusd_info("Finished to send response msg version information, ret[%d].", rspRet);
225 2 : if (rspRet != AICPU_SCHEDULE_OK) {
226 1 : aicpusd_err("Failed to response info, ret[%d]", ret);
227 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
228 : }
229 1 : return AICPU_SCHEDULE_OK;
230 : }
231 : /**
232 : * @ingroup AicpuEventProcess
233 : * @brief it use to process op mapping load event.
234 : * @param [in] ctrlMsg : the struct of control task.
235 : * @return AICPU_SCHEDULE_OK: success, other: error code
236 : */
237 2 : int32_t AicpuEventProcess::ProcessLoadOpMappingEvent(AicpuSqeAdapter &aicpuSqeAdapter) const
238 : {
239 2 : aicpusd_info("Begin to load op mapping event.");
240 2 : AicpuSqeAdapter::AicpuDataDumpInfoLoad info {};
241 2 : aicpuSqeAdapter.GetAicpuDataDumpInfoLoad(info);
242 2 : const void * const opMappingInfo = ValueToPtr(info.dumpinfoPtr);
243 2 : const uint32_t len = info.length;
244 2 : AicpuSchedule::OpDumpTaskManager &opDumpTaskMgr = AicpuSchedule::OpDumpTaskManager::GetInstance();
245 2 : int32_t ret = opDumpTaskMgr.LoadOpMappingInfo(PtrToPtr<const void, const char_t>(opMappingInfo), len);
246 2 : aicpusd_info("Begin to send response information using tsDevSendMsgAsync function; load ret[%d].", ret);
247 2 : int32_t res = aicpuSqeAdapter.AicpuDataDumpLoadResponseToTs(ret);
248 2 : aicpusd_info("Finished to send dump load info report info, ret=%d", ret);
249 :
250 2 : if (res != AICPU_SCHEDULE_OK) {
251 0 : aicpusd_err("Failed to response info, ret[%d]", ret);
252 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
253 : }
254 :
255 2 : return AICPU_SCHEDULE_OK;
256 : }
257 :
258 11 : int32_t AicpuEventProcess::SendCtrlCpuMsg(int32_t aicpuPid, const uint32_t eventType, char_t *msg,
259 : const uint32_t msgLen) const
260 : {
261 11 : event_summary eventInfoSummary = {};
262 11 : eventInfoSummary.pid = aicpuPid;
263 11 : eventInfoSummary.event_id = EVENT_CCPU_CTRL_MSG;
264 11 : eventInfoSummary.subevent_id = eventType;
265 11 : eventInfoSummary.msg = msg;
266 11 : eventInfoSummary.msg_len = msgLen;
267 11 : eventInfoSummary.grp_id = CCPU_DEFAULT_GROUP_ID;
268 11 : eventInfoSummary.dst_engine = CCPU_DEVICE;
269 11 : const drvError_t ret = halEschedSubmitEvent(AicpuDrvManager::GetInstance().GetDeviceId(),
270 : &eventInfoSummary);
271 11 : if (ret != DRV_ERROR_NONE) {
272 1 : aicpusd_err("Failed to submit aicpu event. ret is %d.", ret);
273 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
274 : }
275 10 : aicpusd_info("Send ctrl cpu msg success, eventType=%u", eventType);
276 10 : return AICPU_SCHEDULE_OK;
277 : }
278 : }
|