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(
173 1 : deviceVec, hostPid, pidSign.sign, profilingMode, 0U, false);
174 3 : }
175 :
176 : /**
177 : * @brief it is used to update profiling mode for acl.
178 : * @param [in] deviceId : The id of self cpu.
179 : * @param [in] hostPid : The id of host
180 : * @param [in] flag : flag[0] == 1 means PROFILING_OPEN, otherwise PROFILING_CLOSE.
181 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
182 : */
183 2 : int32_t UpdateProfilingMode(uint32_t deviceId, pid_t hostPid, uint32_t flag)
184 : {
185 : // set or unset mode
186 2 : const bool isStart =
187 2 : (flag & (static_cast<uint32_t>(1U) << static_cast<uint32_t>(aicpu::PROFILING_FEATURE_SWITCH))) > 0U;
188 : // if set or unset kernel profiling mode
189 2 : const bool kernelMode =
190 2 : (flag & (static_cast<uint32_t>(1U) << static_cast<uint32_t>(aicpu::PROFILING_FEATURE_KERNEL_MODE))) > 0U;
191 : // if set or unset model profiling mode
192 2 : const bool modelMode =
193 2 : (flag & (static_cast<uint32_t>(1U) << static_cast<uint32_t>(aicpu::PROFILING_FEATURE_MODEL_MODE))) > 0U;
194 2 : ProfilingMode mode = PROFILING_CLOSE;
195 2 : bool isModelModeOn = false;
196 2 : aicpu::LoadProfilingLib();
197 2 : aicpu::SetProfilingFlagForKFC(flag);
198 2 : if (isStart) {
199 2 : mode = PROFILING_OPEN;
200 2 : isModelModeOn = true;
201 : }
202 2 : if (kernelMode) {
203 0 : AicpuSchedule::ComputeProcess::GetInstance().UpdateProfilingMode(mode);
204 : }
205 2 : if (modelMode) {
206 0 : AicpuSchedule::ComputeProcess::GetInstance().UpdateProfilingModelMode(isModelModeOn);
207 : }
208 2 : aicpusd_info(
209 : "Begin to update aicpu profiling mode, flag[%lu], deviceId[%u], hostPid[%d], isStart[%d], mode[%d],"
210 : " isModelModeOn[%d].",
211 : flag, deviceId, hostPid, isStart, mode, isModelModeOn);
212 2 : return AicpuSchedule::AICPU_SCHEDULE_OK;
213 : }
214 :
215 : /**
216 : * @brief it is used to stop the aicpu scheduler for acl.
217 : * @param [in] deviceId : The id of self cpu.
218 : * @param [in] hostPid : host pid
219 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
220 : */
221 1 : int32_t StopAICPUScheduler(uint32_t deviceId, pid_t hostPid)
222 : {
223 1 : (void)AicpuSchedule::AicpuCustSoManager::GetInstance().DeleteCustSoDir();
224 1 : AicpuSchedule::OpDumpTaskManager::GetInstance().ClearResource();
225 1 : AicpuSchedule::DumpSessionManager::GetInstance().CloseAllSessions();
226 2 : const std::vector<uint32_t> deviceVec = {deviceId};
227 1 : (void)AicpuSchedule::AicpuScheduleInterface::GetInstance().StopAICPUSchedulerWithFlag(deviceVec, hostPid, false);
228 1 : aicpusd_run_info("Successfully stopped AICPU scheduler, deviceId[%u], hostPid[%d].", deviceId, hostPid);
229 1 : return AicpuSchedule::AICPU_SCHEDULE_OK;
230 1 : }
231 :
232 : /**
233 : * @brief Check if the scheduling module stops running
234 : * @return true or false
235 : */
236 0 : bool AicpuIsStoped() { return !AicpuSchedule::AicpuEventManager::GetInstance().GetRunningFlag(); }
237 :
238 : /**
239 : * @brief it is used to load op mapping info for data dump.
240 : * @param [in] infoAddr : The pointer of info.
241 : * @param [in] len : The length of info
242 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
243 : */
244 19 : int32_t LoadOpMappingInfo(const void* infoAddr, uint32_t len)
245 : {
246 19 : AicpuSchedule::OpDumpTaskManager& opDumpTaskMgr = AicpuSchedule::OpDumpTaskManager::GetInstance();
247 19 : AicpuSchedule::AicpuSqeAdapter aicpuSqeAdapter(0UL);
248 38 : return opDumpTaskMgr.LoadOpMappingInfo(PtrToPtr<const void, const char_t>(infoAddr), len, aicpuSqeAdapter);
249 19 : }
250 :
251 : /**
252 : * @brief it is used to set report callback function.
253 : * @param [in] reportCallback : report callback function.
254 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
255 : */
256 1 : int32_t AicpuSetMsprofReporterCallback(MsprofReporterCallback reportCallback)
257 : {
258 1 : return aicpu::SetMsprofReporterCallback(reportCallback);
259 : }
260 :
261 : /**
262 : * @brief it is used to init aicpu scheduler for helper.
263 : * @param [in] initParam : init param ptr.
264 : * @return AICPU_SCHEDULE_SUCCESS: success other: error code in ErrorCode
265 : */
266 2 : int32_t InitCpuScheduler(const CpuSchedInitParam* const initParam)
267 : {
268 2 : aicpusd_run_info("InitAICPUScheduler in heterogeneo1us mode.");
269 2 : AicpuSchedule::SetCpuMode(true);
270 2 : if (initParam == nullptr) {
271 1 : aicpusd_err("Init Param is null. Please check!");
272 1 : return AICPU_SCHEDULE_FAIL;
273 : }
274 1 : return InitAICPUScheduler(initParam->deviceId, initParam->hostPid, initParam->profilingMode);
275 : }
276 :
277 : /**
278 : * @brief it is used to stop the aicpu scheduler for helper.
279 : * @param [in] deviceId : The id of self cpu.
280 : * @param [in] hostPid : host pid
281 : * @return AICPU_SCHEDULE_OK: success other: error code in StatusCode
282 : */
283 1 : int32_t StopCPUScheduler(const uint32_t deviceId, const pid_t hostPid)
284 : {
285 1 : aicpusd_run_info("StopAICPUScheduler in heterogeneous mode.");
286 2 : std::vector<uint32_t> deviceVec = {deviceId};
287 2 : return AicpuSchedule::AicpuScheduleInterface::GetInstance().StopAICPUSchedulerWithFlag(deviceVec, hostPid, true);
288 1 : }
289 :
290 : /**
291 : * @brief it is used to load model with queue.
292 : * @param [in] ptr : the address of the model info
293 : * @return AICPU_SCHEDULE_OK: success other: error code
294 : */
295 7 : int32_t AicpuLoadModelWithQ(void* ptr)
296 : {
297 7 : aicpusd_info("Begin to load model with queue.");
298 7 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().LoadModelWithQueue(ptr);
299 7 : aicpusd_info("Finished load model with queue, ret[%d].", ret);
300 7 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
301 6 : return AICPU_SCHEDULE_FAIL;
302 : }
303 1 : return AICPU_SCHEDULE_SUCCESS;
304 : }
305 :
306 1 : int32_t AicpuLoadModel(void* ptr)
307 : {
308 1 : aicpusd_info("Begin to load model with event.");
309 1 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().LoadModelWithEvent(ptr);
310 1 : aicpusd_info("Finished load model with event, ret[%d].", ret);
311 1 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
312 1 : return AICPU_SCHEDULE_FAIL;
313 : }
314 0 : return static_cast<int32_t>(AICPU_SCHEDULE_SUCCESS);
315 : }
316 :
317 0 : void AicpuReportNotifyInfo(const aicpu::AsyncNotifyInfo& notifyInfo)
318 : {
319 0 : AicpuSchedule::AicpuMsgSend::AicpuReportNotifyInfo(notifyInfo);
320 0 : }
321 :
322 0 : uint32_t AicpuGetTaskDefaultTimeout() { return AicpuSchedule::AicpuMonitor::GetInstance().GetTaskDefaultTimeout(); }
323 :
324 1 : void RegLastwordCallback(const std::string mark, std::function<void()> callback, std::function<void()>& cancelReg)
325 : {
326 1 : AicpuSchedule::AicpusdLastword::GetInstance().RegLastwordCallback(mark, callback, cancelReg);
327 1 : }
328 :
329 : /**
330 : * @brief it is used to stop the model.
331 : * @param [in] ptr : ptr which point to ReDeployConfig.
332 : * @return AICPU_SCHEDULE_OK: success other: error code
333 : */
334 4 : int32_t AICPUModelStop(const ReDeployConfig* const ptr)
335 : {
336 4 : aicpusd_run_info("Begin stop model.");
337 4 : if (ptr == nullptr) {
338 1 : aicpusd_err("AICPUModelStop ptr is null");
339 1 : return AICPU_SCHEDULE_FAIL;
340 : }
341 3 : const uint32_t modelIdNum = ptr->modelIdNum;
342 3 : const uint32_t* const modelIds = PtrToPtr<void, uint32_t>(ValueToPtr(ptr->modelIdsAddr));
343 3 : if ((modelIdNum != 0U) && (modelIds == nullptr)) {
344 1 : aicpusd_err("AICPUModelStop modelIds is null");
345 1 : return AICPU_SCHEDULE_FAIL;
346 : }
347 3 : for (uint32_t i = 0U; i < modelIdNum; ++i) {
348 2 : const int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().Stop(modelIds[i]);
349 2 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
350 1 : aicpusd_err("Stop model[%u] failed, ret[%d].", modelIds[i], ret);
351 1 : return AICPU_SCHEDULE_FAIL;
352 : }
353 1 : aicpusd_info("Stop model[%u] success", modelIds[i]);
354 : }
355 1 : aicpusd_run_info("Finished stop model, %u models had been processed.", modelIdNum);
356 1 : return AICPU_SCHEDULE_SUCCESS;
357 : }
358 :
359 : /**
360 : * @brief it is used to restart the model.
361 : * @param [in] ptr : ptr which point to ReDeployConfig.
362 : * @return AICPU_SCHEDULE_OK: success other: error code
363 : */
364 5 : int32_t AICPUModelClearInputAndRestart(const ReDeployConfig* const ptr)
365 : {
366 5 : aicpusd_run_info("Begin ClearInputAndRestart model.");
367 5 : if (ptr == nullptr) {
368 1 : aicpusd_err("AICPUModelClearInputAndRestart ptr is null");
369 1 : return AICPU_SCHEDULE_FAIL;
370 : }
371 4 : const uint32_t modelIdNum = ptr->modelIdNum;
372 4 : const uint32_t* const modelIds = PtrToPtr<void, uint32_t>(ValueToPtr(ptr->modelIdsAddr));
373 4 : if ((modelIdNum != 0U) && (modelIds == nullptr)) {
374 1 : aicpusd_err("AICPUModelClearInputAndRestart modelIds is null");
375 1 : return AICPU_SCHEDULE_FAIL;
376 : }
377 4 : for (uint32_t i = 0U; i < modelIdNum; ++i) {
378 3 : int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().ClearInput(modelIds[i]);
379 3 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
380 1 : aicpusd_err("Clear model[%u] failed, ret[%d].", modelIds[i], ret);
381 1 : return AICPU_SCHEDULE_FAIL;
382 : }
383 2 : aicpusd_info("Clear model[%u] success", modelIds[i]);
384 :
385 2 : ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().Restart(modelIds[i]);
386 2 : if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
387 1 : aicpusd_err("Restart model[%u] failed, ret[%d].", modelIds[i], ret);
388 1 : return AICPU_SCHEDULE_FAIL;
389 : }
390 1 : aicpusd_info("Restart model[%u] success", modelIds[i]);
391 : }
392 1 : aicpusd_run_info("Finished ClearInputAndRestart, %u models had been processed.", modelIdNum);
393 1 : return AICPU_SCHEDULE_SUCCESS;
394 : }
395 :
396 : /**
397 : * @brief it is used to check kernel support.
398 : * @param [in] cfgPtr : cfgPtr which point to CheckKernelSupportedConfig.
399 : * @return AICPU_SCHEDULE_OK: supported other: not supported
400 : */
401 6 : int32_t CheckKernelSupported(const CheckKernelSupportedConfig* const cfgPtr)
402 : {
403 6 : aicpusd_run_info("begin run CheckKernelSupported model.");
404 6 : if (cfgPtr == nullptr) {
405 1 : aicpusd_err("CheckKernelSupported cfgPtr is null");
406 1 : return AICPU_SCHEDULE_FAIL;
407 : }
408 5 : const char* const kernelName = PtrToPtr<void, char_t>(ValueToPtr(cfgPtr->kernelNameAddr));
409 5 : const uint32_t kernelNameLen = cfgPtr->kernelNameLen;
410 5 : uint32_t* resultAddr = PtrToPtr<void, uint32_t>(ValueToPtr(cfgPtr->checkResultAddr));
411 5 : if ((kernelName == nullptr) || (kernelNameLen == 0) || (resultAddr == nullptr)) {
412 1 : aicpusd_err("CheckKernelSupportedConfig params error");
413 1 : return AICPU_SCHEDULE_FAIL;
414 : }
415 4 : std::string operatorKernelName(kernelName, kernelNameLen);
416 4 : aicpusd_run_info("Task kernel name[%s].", operatorKernelName.c_str());
417 : const int32_t retCode =
418 4 : AicpuSchedule::AicpuScheduleInterface::GetInstance().CheckKernelSupported(operatorKernelName);
419 4 : *resultAddr = static_cast<uint32_t>(retCode);
420 4 : aicpusd_run_info("finished run CheckKernelSupported model retCode[%d].", retCode);
421 4 : return AICPU_SCHEDULE_SUCCESS;
422 4 : }
423 :
424 8 : int32_t AICPUModelProcessDataException(const DataFlowExceptionNotify* const exceptionInfo)
425 : {
426 8 : return AicpuSchedule::AicpuScheduleInterface::GetInstance().ProcessException(exceptionInfo);
427 : }
428 : }
|