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_interface.h"
12 : #include "aicpusd_util.h"
13 : #include "profiling_adp.h"
14 : #include "core/aicpusd_interface_process.h"
15 : #include "core/aicpusd_event_manager.h"
16 : #include "core/aicpusd_threads_process.h"
17 : #include "core/aicpusd_cust_so_manager.h"
18 : #include "core/aicpusd_msg_send.h"
19 : #include "common/aicpusd_util.h"
20 : #include "common/aicpusd_context.h"
21 : #include "aicpusd_monitor.h"
22 : #include "aicpusd_lastword.h"
23 : #include "dump_task.h"
24 : #include "aicpu_engine.h"
25 : #include "type_def.h"
26 : #include "tsd.h"
27 : #include "aicpu_prof.h"
28 :
29 : extern "C" {
30 : /**
31 : * @brief it is used to load the task and stream info.
32 : * @param [in] ptr : the address of the task and stream info
33 : * @return AICPU_SCHEDULE_OK: success other: error code
34 : */
35 10 : int32_t AICPUModelLoad(void *ptr)
36 : {
37 10 : aicpusd_info("Begin store task information of model.");
38 10 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().LoadProcess(ptr);
39 10 : aicpusd_info("Finished store task information of model, ret[%d].", ret);
40 10 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
41 1 : return AICPU_SCHEDULE_FAIL;
42 : }
43 9 : return AICPU_SCHEDULE_SUCCESS;
44 : }
45 :
46 : /**
47 : * @brief it is used to destroy the model.
48 : * @param [in] modelId : The id of model will be destroy.
49 : * @return AICPU_SCHEDULE_OK: success other: error code
50 : */
51 10 : int32_t AICPUModelDestroy(uint32_t modelId)
52 : {
53 10 : aicpusd_info("Begin destroy task information of modelId[%u].", modelId);
54 10 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().Destroy(modelId);
55 10 : aicpusd_info("Finished destroy task information of modelId[%u], ret[%d].", modelId, ret);
56 10 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
57 1 : return AICPU_SCHEDULE_FAIL;
58 : }
59 9 : return AICPU_SCHEDULE_SUCCESS;
60 : }
61 :
62 : /**
63 : * @brief it is used to execute the model.
64 : * @param [in] modelId : The id of model will be run.
65 : * @return AICPU_SCHEDULE_OK: success other: error code
66 : */
67 8 : int32_t AICPUModelExecute(uint32_t modelId)
68 : {
69 8 : aicpusd_info("Begin execute task information of modelId[%u].", modelId);
70 8 : const int32_t ret = AicpuSchedule::AicpuEventManager::GetInstance().ExecuteProcess(modelId);
71 8 : aicpusd_info("Finished execute task information of modelId[%u], ret[%d].", modelId, ret);
72 8 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
73 1 : return AICPU_SCHEDULE_FAIL;
74 : }
75 :
76 7 : return AicpuSchedule::AicpuScheduleInterface::GetInstance().GetErrorCode(modelId);
77 : }
78 :
79 : /**
80 : * @ingroup AicpuScheduleInterface
81 : * @brief it use to execute the model from call interface.
82 : * @param [in] drvEventInfo : event info.
83 : * @param [out] drvEventAck : event ack.
84 : * @return 0: success, other: error code
85 : */
86 3 : int32_t AICPUExecuteTask(struct event_info *drvEventInfo, struct event_ack *drvEventAck)
87 : {
88 3 : if ((drvEventInfo == nullptr) || (drvEventAck == nullptr)) {
89 1 : return AICPU_SCHEDULE_FAIL;
90 : }
91 2 : const int32_t ret = AicpuSchedule::AicpuEventManager::GetInstance().ExecuteProcessSyc(drvEventInfo, drvEventAck);
92 2 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
93 1 : return AICPU_SCHEDULE_FAIL;
94 : }
95 1 : return AICPU_SCHEDULE_SUCCESS;
96 : }
97 :
98 : /**
99 : * @ingroup AicpuScheduleInterface
100 : * @brief it use to preload so.
101 : * @param [in] soName : so name.
102 : * @return 0: success, other: error code
103 : */
104 3 : int32_t AICPUPreOpenKernels(const char *soName)
105 : {
106 3 : if (soName == nullptr) {
107 1 : aicpusd_err("So name is null. Please check!");
108 1 : return AicpuSchedule::AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
109 : }
110 :
111 : // load so
112 2 : const uint32_t loadSoNum = 1U;
113 2 : const char *soNames[loadSoNum] = {soName};
114 2 : const aeStatus_t ret = aeBatchLoadKernelSo(aicpu::KERNEL_TYPE_AICPU, loadSoNum, &soNames[0U]);
115 2 : if (ret != AE_STATUS_SUCCESS) {
116 1 : aicpusd_err("Failed to preload aicpu so %s. Please check.", soName);
117 1 : return ret;
118 : }
119 1 : aicpusd_run_info("Preload so %s Successfully.", soName);
120 1 : return AicpuSchedule::AICPU_SCHEDULE_OK;
121 : }
122 :
123 : /**
124 : * @brief it is used to init aicpu scheduler for acl.
125 : * @param [in] deviceId : The id of self cpu.
126 : * @param [in] hostPid : The id of host
127 : * @param [in] profilingMode : it used to open or close profiling.
128 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
129 : */
130 4 : int32_t InitAICPUScheduler(const uint32_t deviceId, const pid_t hostPid, const ProfilingMode profilingMode)
131 : {
132 4 : if (AicpuSchedule::AicpuScheduleInterface::GetInstance().IsInitialized(deviceId)) {
133 1 : aicpusd_run_info("Aicpu Schedule is already init");
134 1 : return AicpuSchedule::AICPU_SCHEDULE_OK;
135 : }
136 :
137 6 : const std::string envNameAicpuAppLogSwitch = "AICPU_APP_LOG_SWITCH";
138 6 : if (AicpuSchedule::AicpuUtil::IsEnvValEqual(envNameAicpuAppLogSwitch, "0")) {
139 1 : aicpusd_info("%s is setted to 0 to switch off applog", envNameAicpuAppLogSwitch.c_str());
140 : } else {
141 2 : LogAttr logInfo = {};
142 2 : logInfo.type = APPLICATION;
143 2 : logInfo.pid = 0U;
144 2 : logInfo.deviceId = deviceId;
145 2 : logInfo.mode = 0U;
146 2 : if (DlogSetAttrAicpu(logInfo) != 0) {
147 1 : aicpusd_warn("Set log attr failed");
148 : }
149 : }
150 :
151 : // Make sure AicpusdLastword are created first,to ensure the last exit
152 3 : AicpuSchedule::AicpusdLastword::GetInstance();
153 3 : AicpuSchedule::AicpuEventManager::GetInstance().InitEventMgr(false, true, 0U);
154 6 : const std::vector<uint32_t> deviceVec{deviceId};
155 3 : auto deployContext = AicpuSchedule::DeployContext::DEVICE;
156 3 : const int32_t status = AicpuSchedule::GetAicpuDeployContext(deployContext);
157 3 : if (status != AicpuSchedule::AICPU_SCHEDULE_OK) {
158 1 : aicpusd_err("Get current deploy ctx failed.");
159 1 : return status;
160 : }
161 : process_sign pidSign;
162 2 : if (deployContext == AicpuSchedule::DeployContext::DEVICE) {
163 2 : const drvError_t ret = drvGetProcessSign(&pidSign);
164 2 : if (ret != DRV_ERROR_NONE) {
165 1 : aicpusd_err("Get process sign failed, ret[%d].", ret);
166 1 : return AICPU_SCHEDULE_FAIL;
167 : }
168 : } else {
169 0 : pidSign.sign[0U] = '\0';
170 : }
171 1 : aicpusd_info("Get process sign success");
172 6 : return AicpuSchedule::AicpuScheduleInterface::GetInstance().InitAICPUScheduler(deviceVec,
173 : hostPid,
174 : pidSign.sign,
175 : profilingMode,
176 : 0U,
177 1 : false);
178 3 : }
179 :
180 : /**
181 : * @brief it is used to update profiling mode for acl.
182 : * @param [in] deviceId : The id of self cpu.
183 : * @param [in] hostPid : The id of host
184 : * @param [in] flag : flag[0] == 1 means PROFILING_OPEN, otherwise PROFILING_CLOSE.
185 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
186 : */
187 2 : int32_t UpdateProfilingMode(uint32_t deviceId, pid_t hostPid, uint32_t flag)
188 : {
189 : // set or unset mode
190 2 : const bool isStart = (flag & (static_cast<uint32_t>(1U) <<
191 : static_cast<uint32_t>(aicpu::PROFILING_FEATURE_SWITCH))) > 0U;
192 : // if set or unset kernel profiling mode
193 2 : const bool kernelMode = (flag & (static_cast<uint32_t>(1U) <<
194 : static_cast<uint32_t>(aicpu::PROFILING_FEATURE_KERNEL_MODE))) > 0U;
195 : // if set or unset model profiling mode
196 2 : const bool modelMode = (flag & (static_cast<uint32_t>(1U) <<
197 : static_cast<uint32_t>(aicpu::PROFILING_FEATURE_MODEL_MODE))) > 0U;
198 2 : ProfilingMode mode = PROFILING_CLOSE;
199 2 : bool isModelModeOn = false;
200 2 : aicpu::LoadProfilingLib();
201 2 : aicpu::SetProfilingFlagForKFC(flag);
202 2 : if (isStart) {
203 2 : mode = PROFILING_OPEN;
204 2 : isModelModeOn = true;
205 : }
206 2 : if (kernelMode) {
207 0 : AicpuSchedule::ComputeProcess::GetInstance().UpdateProfilingMode(mode);
208 : }
209 2 : if (modelMode) {
210 0 : AicpuSchedule::ComputeProcess::GetInstance().UpdateProfilingModelMode(isModelModeOn);
211 : }
212 2 : aicpusd_info("Begin to update aicpu profiling mode, flag[%lu], deviceId[%u], hostPid[%d], isStart[%d], mode[%d],"
213 : " isModelModeOn[%d].", flag, deviceId, hostPid, isStart, mode, isModelModeOn);
214 2 : return AicpuSchedule::AICPU_SCHEDULE_OK;
215 : }
216 :
217 : /**
218 : * @brief it is used to stop the aicpu scheduler for acl.
219 : * @param [in] deviceId : The id of self cpu.
220 : * @param [in] hostPid : host pid
221 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
222 : */
223 1 : int32_t StopAICPUScheduler(uint32_t deviceId, pid_t hostPid)
224 : {
225 1 : (void)AicpuSchedule::AicpuCustSoManager::GetInstance().DeleteCustSoDir();
226 1 : AicpuSchedule::OpDumpTaskManager::GetInstance().ClearResource();
227 1 : AicpuSchedule::DumpSessionManager::GetInstance().CloseAllSessions();
228 2 : const std::vector<uint32_t> deviceVec = {deviceId};
229 1 : (void)AicpuSchedule::AicpuScheduleInterface::GetInstance().StopAICPUSchedulerWithFlag(deviceVec, hostPid, false);
230 1 : aicpusd_run_info("Successfully stopped AICPU scheduler, deviceId[%u], hostPid[%d].", deviceId, hostPid);
231 1 : return AicpuSchedule::AICPU_SCHEDULE_OK;
232 1 : }
233 :
234 : /**
235 : * @brief Check if the scheduling module stops running
236 : * @return true or false
237 : */
238 0 : bool AicpuIsStoped()
239 : {
240 0 : return !AicpuSchedule::AicpuEventManager::GetInstance().GetRunningFlag();
241 : }
242 :
243 : /**
244 : * @brief it is used to load op mapping info for data dump.
245 : * @param [in] infoAddr : The pointer of info.
246 : * @param [in] len : The length of info
247 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
248 : */
249 19 : int32_t LoadOpMappingInfo(const void *infoAddr, uint32_t len)
250 : {
251 19 : AicpuSchedule::OpDumpTaskManager &opDumpTaskMgr = AicpuSchedule::OpDumpTaskManager::GetInstance();
252 19 : AicpuSchedule::AicpuSqeAdapter aicpuSqeAdapter(0UL);
253 38 : return opDumpTaskMgr.LoadOpMappingInfo(PtrToPtr<const void, const char_t>(infoAddr), len, aicpuSqeAdapter);
254 19 : }
255 :
256 : /**
257 : * @brief it is used to set report callback function.
258 : * @param [in] reportCallback : report callback function.
259 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
260 : */
261 1 : int32_t AicpuSetMsprofReporterCallback(MsprofReporterCallback reportCallback)
262 : {
263 1 : return aicpu::SetMsprofReporterCallback(reportCallback);
264 : }
265 :
266 : /**
267 : * @brief it is used to init aicpu scheduler for helper.
268 : * @param [in] initParam : init param ptr.
269 : * @return AICPU_SCHEDULE_SUCCESS: success other: error code in ErrorCode
270 : */
271 2 : int32_t InitCpuScheduler(const CpuSchedInitParam * const initParam)
272 : {
273 2 : aicpusd_run_info("InitAICPUScheduler in heterogeneo1us mode.");
274 2 : AicpuSchedule::SetCpuMode(true);
275 2 : if (initParam == nullptr) {
276 1 : aicpusd_err("Init Param is null. Please check!");
277 1 : return AICPU_SCHEDULE_FAIL;
278 : }
279 2 : return InitAICPUScheduler(initParam->deviceId,
280 1 : initParam->hostPid,
281 1 : initParam->profilingMode);
282 : }
283 :
284 : /**
285 : * @brief it is used to stop the aicpu scheduler for helper.
286 : * @param [in] deviceId : The id of self cpu.
287 : * @param [in] hostPid : host pid
288 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
289 : */
290 1 : int32_t StopCPUScheduler(const uint32_t deviceId, const pid_t hostPid)
291 : {
292 1 : aicpusd_run_info("StopAICPUScheduler in heterogeneous mode.");
293 2 : std::vector<uint32_t> deviceVec = {deviceId};
294 2 : return AicpuSchedule::AicpuScheduleInterface::GetInstance().StopAICPUSchedulerWithFlag(deviceVec, hostPid, true);
295 1 : }
296 :
297 : /**
298 : * @brief it is used to load model with queue.
299 : * @param [in] ptr : the address of the model info
300 : * @return AICPU_SCHEDULE_OK: success other: error code
301 : */
302 7 : int32_t AicpuLoadModelWithQ(void *ptr)
303 : {
304 7 : aicpusd_info("Begin to load model with queue.");
305 7 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().LoadModelWithQueue(ptr);
306 7 : aicpusd_info("Finished load model with queue, ret[%d].", ret);
307 7 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
308 6 : return AICPU_SCHEDULE_FAIL;
309 : }
310 1 : return AICPU_SCHEDULE_SUCCESS;
311 : }
312 :
313 1 : int32_t AicpuLoadModel(void *ptr)
314 : {
315 1 : aicpusd_info("Begin to load model with event.");
316 1 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().LoadModelWithEvent(ptr);
317 1 : aicpusd_info("Finished load model with event, ret[%d].", ret);
318 1 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
319 1 : return AICPU_SCHEDULE_FAIL;
320 : }
321 0 : return static_cast<int32_t>(AICPU_SCHEDULE_SUCCESS);
322 : }
323 :
324 0 : void AicpuReportNotifyInfo(const aicpu::AsyncNotifyInfo ¬ifyInfo)
325 : {
326 0 : AicpuSchedule::AicpuMsgSend::AicpuReportNotifyInfo(notifyInfo);
327 0 : }
328 :
329 0 : uint32_t AicpuGetTaskDefaultTimeout()
330 : {
331 0 : return AicpuSchedule::AicpuMonitor::GetInstance().GetTaskDefaultTimeout();
332 : }
333 :
334 1 : void RegLastwordCallback(const std::string mark,
335 : std::function<void ()> callback, std::function<void ()> &cancelReg)
336 : {
337 1 : AicpuSchedule::AicpusdLastword::GetInstance().RegLastwordCallback(mark, callback, cancelReg);
338 1 : }
339 :
340 : /**
341 : * @brief it is used to stop the model.
342 : * @param [in] ptr : ptr which point to ReDeployConfig.
343 : * @return AICPU_SCHEDULE_OK: success other: error code
344 : */
345 4 : int32_t AICPUModelStop(const ReDeployConfig * const ptr)
346 : {
347 4 : aicpusd_run_info("Begin stop model.");
348 4 : if (ptr == nullptr) {
349 1 : aicpusd_err("AICPUModelStop ptr is null");
350 1 : return AICPU_SCHEDULE_FAIL;
351 : }
352 3 : const uint32_t modelIdNum = ptr->modelIdNum;
353 3 : const uint32_t *const modelIds = PtrToPtr<void, uint32_t>(ValueToPtr(ptr->modelIdsAddr));
354 3 : if ((modelIdNum != 0U) && (modelIds == nullptr)) {
355 1 : aicpusd_err("AICPUModelStop modelIds is null");
356 1 : return AICPU_SCHEDULE_FAIL;
357 : }
358 3 : for (uint32_t i = 0U; i < modelIdNum; ++i) {
359 2 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().Stop(modelIds[i]);
360 2 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
361 1 : aicpusd_err("Stop model[%u] failed, ret[%d].", modelIds[i], ret);
362 1 : return AICPU_SCHEDULE_FAIL;
363 : }
364 1 : aicpusd_info("Stop model[%u] success", modelIds[i]);
365 : }
366 1 : aicpusd_run_info("Finished stop model, %u models had been processed.", modelIdNum);
367 1 : return AICPU_SCHEDULE_SUCCESS;
368 : }
369 :
370 : /**
371 : * @brief it is used to restart the model.
372 : * @param [in] ptr : ptr which point to ReDeployConfig.
373 : * @return AICPU_SCHEDULE_OK: success other: error code
374 : */
375 5 : int32_t AICPUModelClearInputAndRestart(const ReDeployConfig * const ptr)
376 : {
377 5 : aicpusd_run_info("Begin ClearInputAndRestart model.");
378 5 : if (ptr == nullptr) {
379 1 : aicpusd_err("AICPUModelClearInputAndRestart ptr is null");
380 1 : return AICPU_SCHEDULE_FAIL;
381 : }
382 4 : const uint32_t modelIdNum = ptr->modelIdNum;
383 4 : const uint32_t *const modelIds = PtrToPtr<void, uint32_t>(ValueToPtr(ptr->modelIdsAddr));
384 4 : if ((modelIdNum != 0U) && (modelIds == nullptr)) {
385 1 : aicpusd_err("AICPUModelClearInputAndRestart modelIds is null");
386 1 : return AICPU_SCHEDULE_FAIL;
387 : }
388 4 : for (uint32_t i = 0U; i < modelIdNum; ++i) {
389 3 : int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().ClearInput(modelIds[i]);
390 3 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
391 1 : aicpusd_err("Clear model[%u] failed, ret[%d].", modelIds[i], ret);
392 1 : return AICPU_SCHEDULE_FAIL;
393 : }
394 2 : aicpusd_info("Clear model[%u] success", modelIds[i]);
395 :
396 2 : ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().Restart(modelIds[i]);
397 2 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
398 1 : aicpusd_err("Restart model[%u] failed, ret[%d].", modelIds[i], ret);
399 1 : return AICPU_SCHEDULE_FAIL;
400 : }
401 1 : aicpusd_info("Restart model[%u] success", modelIds[i]);
402 : }
403 1 : aicpusd_run_info("Finished ClearInputAndRestart, %u models had been processed.", modelIdNum);
404 1 : return AICPU_SCHEDULE_SUCCESS;
405 : }
406 :
407 : /**
408 : * @brief it is used to check kernel support.
409 : * @param [in] cfgPtr : cfgPtr which point to CheckKernelSupportedConfig.
410 : * @return AICPU_SCHEDULE_OK: supported other: not supported
411 : */
412 6 : int32_t CheckKernelSupported(const CheckKernelSupportedConfig * const cfgPtr)
413 : {
414 6 : aicpusd_run_info("begin run CheckKernelSupported model.");
415 6 : if (cfgPtr == nullptr) {
416 1 : aicpusd_err("CheckKernelSupported cfgPtr is null");
417 1 : return AICPU_SCHEDULE_FAIL;
418 : }
419 5 : const char *const kernelName = PtrToPtr<void, char_t>(ValueToPtr(cfgPtr->kernelNameAddr));
420 5 : const uint32_t kernelNameLen = cfgPtr->kernelNameLen;
421 5 : uint32_t *resultAddr = PtrToPtr<void, uint32_t>(ValueToPtr(cfgPtr->checkResultAddr));
422 5 : if ((kernelName == nullptr) || (kernelNameLen == 0) || (resultAddr == nullptr)) {
423 1 : aicpusd_err("CheckKernelSupportedConfig params error");
424 1 : return AICPU_SCHEDULE_FAIL;
425 : }
426 4 : std::string operatorKernelName(kernelName, kernelNameLen);
427 4 : aicpusd_run_info("Task kernel name[%s].", operatorKernelName.c_str());
428 4 : const int32_t retCode = AicpuSchedule::AicpuScheduleInterface::GetInstance().CheckKernelSupported(operatorKernelName);
429 4 : *resultAddr = static_cast<uint32_t>(retCode);
430 4 : aicpusd_run_info("finished run CheckKernelSupported model retCode[%d].", retCode);
431 4 : return AICPU_SCHEDULE_SUCCESS;
432 4 : }
433 :
434 8 : int32_t AICPUModelProcessDataException(const DataFlowExceptionNotify *const exceptionInfo)
435 : {
436 8 : return AicpuSchedule::AicpuScheduleInterface::GetInstance().ProcessException(exceptionInfo);
437 : }
438 : }
|