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(
92 : aicpu::HwtsTsKernel& tsKernelInfo, const uint32_t threadIndex, const uint64_t drvSubmitTick,
93 : const uint64_t drvSchedTick, 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 : (void)aicpu::aicpuSetProfContext(aicpuProfCtx);
113 8 : AicpuMonitor::GetInstance().SetTaskStartTime(static_cast<uint64_t>(threadIndex));
114 8 : const auto retAicpu = CustomOpExecutor::GetInstance().ExecuteKernel(tsKernelInfo);
115 8 : AicpuMonitor::GetInstance().SetTaskEndTime(static_cast<uint64_t>(threadIndex));
116 8 : AicpuUtil::SetProfData(profMsg, aicpuProfCtx, threadIndex, streamId, taskId);
117 8 : if (retAicpu != AICPU_SCHEDULE_OK) {
118 1 : std::string opName;
119 1 : (void)aicpu::GetOpname(threadIndex, opName);
120 1 : aicpusd_err(
121 : "Execute aicpu custom kernel failed, result[%d], opName[%s], streamId[%llu], taskId[%llu].", retAicpu,
122 : 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(
133 : "The event msg len[%u] is not correct[%zu].", privEventInfo.msg_len, sizeof(AICPUBindSdPidEventMsg));
134 2 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
135 : }
136 4 : const AICPUBindSdPidEventMsg* const info = PtrToPtr<const char_t, const AICPUBindSdPidEventMsg>(privEventInfo.msg);
137 4 : const pid_t hostPid = AicpuDrvManager::GetInstance().GetHostPid();
138 4 : const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
139 4 : const uint32_t vfId = AicpuDrvManager::GetInstance().GetVfId();
140 4 : if (&halMemBindSibling == nullptr) {
141 0 : aicpusd_err("Interface halMemBindSibling is not supported in current device");
142 0 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
143 : }
144 4 : drvError_t drvRet = DRV_ERROR_NONE;
145 4 : if (AicpuSchedule::AicpuDrvManager::GetInstance().GetSafeVerifyFlag()) {
146 1 : drvRet = halMemBindSibling(hostPid, info->pid, vfId, deviceId, SVM_MEM_BIND_SVM_GRP);
147 : } else {
148 : // new
149 : drvRet =
150 3 : 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(
154 : "Failed to halMemBindSibling, hostpid=%d, aicpuSdPid=%d, deviceId=%u, ret=%d.\n", hostPid, info->pid,
155 : deviceId, drvRet);
156 1 : return drvRet;
157 : }
158 3 : aicpusd_info("Bind Sibling pid success, hostpid=%d, aicpuSdPid=%d, deviceId=%u.", 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 3 : int32_t AicpuEventProcess::AICPUEventCustCloseMonitor(const TsdSubEventInfo* const eventInfo)
173 : {
174 3 : if (eventInfo == nullptr) {
175 1 : aicpusd_err("Close monitor event info is nullptr.");
176 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
177 : }
178 2 : const auto msg = PtrToPtr<const char_t, const AICPUCloseMonitorEventMsg>(eventInfo->priMsg);
179 2 : AicpuMonitor::GetInstance().SetCloseMonitorFlag(msg->closeFlag == 1U);
180 2 : aicpusd_info("Cust receive close monitor event, closeFlag[%u].", msg->closeFlag);
181 2 : return AICPU_SCHEDULE_OK;
182 : }
183 :
184 1 : int32_t AicpuEventProcess::AICPUEventCustUpdateProfilingMode(const event_info_priv& privEventInfo) const
185 : {
186 1 : const AICPUSubEventInfo* const info = PtrToPtr<const char_t, const AICPUSubEventInfo>(privEventInfo.msg);
187 1 : const uint32_t modelInfoFlag = (*info).para.modeInfo.flag;
188 1 : aicpusd_info("Get profiling flag success, flag[%u]", modelInfoFlag);
189 :
190 1 : ProfilingMode profilingMode = PROFILING_CLOSE;
191 1 : bool kernelFlag = false;
192 1 : AicpuUtil::GetProfilingInfo(modelInfoFlag, profilingMode, kernelFlag);
193 1 : aicpusd_info("Update aicpu profiling mode success, profilingMode[%u], kernelFlag[%d]", profilingMode, kernelFlag);
194 1 : aicpu::LoadProfilingLib();
195 1 : aicpu::SetProfilingFlagForKFC(modelInfoFlag);
196 1 : if (kernelFlag) {
197 1 : aicpu::UpdateMode(profilingMode == PROFILING_OPEN);
198 : }
199 1 : if (SendUpdateProfilingRspToTsd(
200 1 : AicpuDrvManager::GetInstance().GetDeviceId(), static_cast<uint32_t>(TsdWaitType::TSD_CUSTOM_COMPUTE),
201 1 : static_cast<uint32_t>(AicpuDrvManager::GetInstance().GetHostPid()),
202 2 : AicpuDrvManager::GetInstance().GetVfId()) != AICPU_SCHEDULE_OK) {
203 0 : aicpusd_err("send profilling response to tsd failed");
204 0 : return AICPU_SCHEDULE_ERROR_TASK_EXECUTE_FAILED;
205 : }
206 1 : return AICPU_SCHEDULE_OK;
207 : }
208 :
209 : /**
210 : * @ingroup AicpuEventProcess
211 : * @brief it is used to process the msg version.
212 : * @param [in] info : the information of task.
213 : * @return AICPU_SCHEDULE_OK: success, other: error code
214 : */
215 5 : int32_t AicpuEventProcess::ProcessMsgVersionEvent(AicpuSqeAdapter& aicpuSqeAdapter) const
216 : {
217 5 : aicpusd_info("Begin to process msg version event.");
218 5 : AicpuSqeAdapter::AicpuMsgVersionInfo info{};
219 5 : aicpuSqeAdapter.GetAicpuMsgVersionInfo(info);
220 5 : int32_t ret = AICPU_SCHEDULE_OK;
221 5 : if (info.magic_num != VALID_MAGIC_NUM) {
222 3 : aicpusd_err("Magic num[%u] is not valid.", info.magic_num);
223 3 : return AICPU_SCHEDULE_ERROR_INVALID_MAGIC_NUM;
224 : } else {
225 2 : uint16_t version = info.version;
226 2 : if (allVersion.find(version) == allVersion.end()) {
227 0 : aicpusd_err("Version is incorrect, version[%hu]", version);
228 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
229 : }
230 2 : FeatureCtrl::SetTsMsgVersion(version);
231 2 : aicpusd_info("Set msg version [%hu].", version);
232 : }
233 2 : aicpusd_info("Begin to send response msg version.");
234 2 : int32_t rspRet = aicpuSqeAdapter.AicpuMsgVersionResponseToTs(ret);
235 2 : aicpusd_info("Finished to send response msg version information, ret[%d].", rspRet);
236 2 : if (rspRet != AICPU_SCHEDULE_OK) {
237 1 : aicpusd_err("Failed to response info, ret[%d]", ret);
238 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
239 : }
240 1 : return AICPU_SCHEDULE_OK;
241 : }
242 : /**
243 : * @ingroup AicpuEventProcess
244 : * @brief it use to process op mapping load event.
245 : * @param [in] ctrlMsg : the struct of control task.
246 : * @return AICPU_SCHEDULE_OK: success, other: error code
247 : */
248 2 : int32_t AicpuEventProcess::ProcessLoadOpMappingEvent(AicpuSqeAdapter& aicpuSqeAdapter) const
249 : {
250 2 : aicpusd_info("Begin to load op mapping event.");
251 2 : AicpuSqeAdapter::AicpuDataDumpInfoLoad info{};
252 2 : aicpuSqeAdapter.GetAicpuDataDumpInfoLoad(info);
253 2 : const void* const opMappingInfo = ValueToPtr(info.dumpinfoPtr);
254 2 : const uint32_t len = info.length;
255 2 : AicpuSchedule::OpDumpTaskManager& opDumpTaskMgr = AicpuSchedule::OpDumpTaskManager::GetInstance();
256 2 : int32_t ret = opDumpTaskMgr.LoadOpMappingInfo(PtrToPtr<const void, const char_t>(opMappingInfo), len);
257 2 : aicpusd_info("Begin to send response information using tsDevSendMsgAsync function; load ret[%d].", ret);
258 2 : int32_t res = aicpuSqeAdapter.AicpuDataDumpLoadResponseToTs(ret);
259 2 : aicpusd_info("Finished to send dump load info report info, ret=%d", ret);
260 :
261 2 : if (res != AICPU_SCHEDULE_OK) {
262 0 : aicpusd_err("Failed to response info, ret[%d]", ret);
263 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
264 : }
265 :
266 2 : return AICPU_SCHEDULE_OK;
267 : }
268 :
269 11 : int32_t AicpuEventProcess::SendCtrlCpuMsg(
270 : int32_t aicpuPid, const uint32_t eventType, char_t* msg, const uint32_t msgLen) const
271 : {
272 11 : event_summary eventInfoSummary = {};
273 11 : eventInfoSummary.pid = aicpuPid;
274 11 : eventInfoSummary.event_id = EVENT_CCPU_CTRL_MSG;
275 11 : eventInfoSummary.subevent_id = eventType;
276 11 : eventInfoSummary.msg = msg;
277 11 : eventInfoSummary.msg_len = msgLen;
278 11 : eventInfoSummary.grp_id = CCPU_DEFAULT_GROUP_ID;
279 11 : eventInfoSummary.dst_engine = CCPU_DEVICE;
280 11 : const drvError_t ret = halEschedSubmitEvent(AicpuDrvManager::GetInstance().GetDeviceId(), &eventInfoSummary);
281 11 : if (ret != DRV_ERROR_NONE) {
282 1 : aicpusd_err("Failed to submit aicpu event. ret is %d.", ret);
283 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
284 : }
285 10 : aicpusd_info("Send ctrl cpu msg success, eventType=%u", eventType);
286 10 : return AICPU_SCHEDULE_OK;
287 : }
288 : } // namespace AicpuSchedule
|