LCOV - code coverage report
Current view: top level - aicpu_schedule/core - aicpusd_interface_process.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.4 % 378 319
Test Date: 2026-07-28 10:54:05 Functions: 93.1 % 29 27

            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_process.h"
      12              : #include <securec.h>
      13              : #include <unistd.h>
      14              : #include "aicpusd_info.h"
      15              : #include "ascend_hal.h"
      16              : #include "aicpusd_event_manager.h"
      17              : #include "aicpusd_event_process.h"
      18              : #include "aicpusd_threads_process.h"
      19              : #include "dump_task.h"
      20              : #include "ts_api.h"
      21              : #include "aicpu_context.h"
      22              : #include "aicpusd_common.h"
      23              : #include "aicpusd_context.h"
      24              : #include "aicpusd_util.h"
      25              : #include "aicpu_sched/common/aicpu_task_struct.h"
      26              : #include "aicpusd_resource_manager.h"
      27              : #include "aicpusd_drv_manager.h"
      28              : #include "aicpusd_model_execute.h"
      29              : #include "aicpu_engine.h"
      30              : #include "aicpusd_profiler.h"
      31              : #include "aicpusd_monitor.h"
      32              : #include "aicpusd_msg_send.h"
      33              : #include "aicpusd_worker.h"
      34              : #include "aicpusd_cust_so_manager.h"
      35              : #include "aicpusd_sub_module_interface.h"
      36              : #include "aicpusd_hal_interface_ref.h"
      37              : #include "aicpusd_cust_dump_process.h"
      38              : #include "aicpusd_mc2_maintenance_thread.h"
      39              : #include "aicpusd_period_statistic.h"
      40              : #include "aicpusd_model_statistic.h"
      41              : #include "aicpusd_feature_ctrl.h"
      42              : #include "aicpusd_msq_operator_manager.h"
      43              : #include "hwts_kernel_register.h"
      44              : #include "operator_kernel_register.h"
      45              : 
      46              : namespace {
      47              :     const std::map<EVENT_ID, SCHEDULE_PRIORITY> EVENT_PRIORITY = {
      48              :         {EVENT_ID::EVENT_RANDOM_KERNEL, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      49              :         {EVENT_ID::EVENT_SPLIT_KERNEL, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      50              :         {EVENT_ID::EVENT_DVPP_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      51              :         {EVENT_ID::EVENT_DVPP_MPI_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      52              :         {EVENT_ID::EVENT_FR_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      53              :         {EVENT_ID::EVENT_TS_HWTS_KERNEL, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      54              :         {EVENT_ID::EVENT_AICPU_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      55              :         {EVENT_ID::EVENT_TS_CTRL_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      56              :         {EVENT_ID::EVENT_FFTS_PLUS_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      57              :         {EVENT_ID::EVENT_QUEUE_EMPTY_TO_NOT_EMPTY, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      58              :         {EVENT_ID::EVENT_QUEUE_FULL_TO_NOT_FULL, SCHEDULE_PRIORITY::PRIORITY_LEVEL0},
      59              :         {EVENT_ID::EVENT_TDT_ENQUEUE, SCHEDULE_PRIORITY::PRIORITY_LEVEL2},
      60              :         {EVENT_ID::EVENT_ACPU_MSG_TYPE1, SCHEDULE_PRIORITY::PRIORITY_LEVEL1}
      61              :     };
      62              : 
      63              :     // first array index
      64              :     constexpr size_t FIRST_INDEX = 0LU;
      65              : 
      66              :     // max number of eatch device can split
      67              :     constexpr const uint32_t DEVICE_MAX_SPLIT_NUM = 16U;
      68              : 
      69              :     constexpr uint32_t MAX_AICPU_PROC_NUM = 48U;
      70              : 
      71              :     const std::string TSKERNEL_PREFIX = "tsKernel:";
      72              : }
      73              : namespace AicpuSchedule {
      74              :     /**
      75              :      * @ingroup AicpuScheduleCore
      76              :      * @brief it is used to construct a object of AicpuScheduleCore.
      77              :      */
      78            2 :     AicpuScheduleInterface::AicpuScheduleInterface()
      79            2 :         : profilingMode_(PROFILING_CLOSE),
      80            2 :           noThreadFlag_(true),
      81            2 :           initFlag_(false),
      82            2 :           eventBitMap_(0U),
      83            2 :           runMode_(aicpu::AicpuRunMode::THREAD_MODE),
      84            2 :           aicpuCustSdPid_(-1),
      85            2 :           isNeedBatchLoadSo_(true) {}
      86              : 
      87              :     /**
      88              :      * @ingroup AicpuScheduleCore
      89              :      * @brief it is used to destructor a object of AicpuScheduleCore.
      90              :      */
      91            2 :     AicpuScheduleInterface::~AicpuScheduleInterface() {}
      92              : 
      93          213 :     AicpuScheduleInterface &AicpuScheduleInterface::GetInstance()
      94              :     {
      95          213 :         static AicpuScheduleInterface instance;
      96          213 :         return instance;
      97              :     }
      98              : 
      99            6 :     int32_t AicpuScheduleInterface::LoadModelWithQueue(const void * const ptr) const
     100              :     {
     101            6 :         std::vector<QueInfo> queInfos;
     102            6 :         std::vector<AicpuTaskInfo> aicpuTaskInfos;
     103            6 :         std::vector<StreamInfo> streamInfos;
     104              :         AicpuModelInfo curAicpuModelInfo;
     105              : 
     106            6 :         if (ptr == nullptr) {
     107            1 :             aicpusd_err("the parameter is not valid in load model.");
     108            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     109              :         }
     110              : 
     111            5 :         const auto ret = AicpuModelManager::GetInstance().TransModelInfo(ptr, curAicpuModelInfo,
     112              :             aicpuTaskInfos, streamInfos, queInfos, nullptr);
     113            5 :         if (ret != AICPU_SCHEDULE_OK) {
     114            2 :             return ret;
     115              :         }
     116              : 
     117            3 :         if (queInfos.empty()) {
     118            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     119              :         }
     120            2 :         return LoadProcess(&curAicpuModelInfo);
     121            6 :     }
     122              : 
     123            0 :     int32_t AicpuScheduleInterface::LoadModelWithEvent(const void * const ptr) const
     124              :     {
     125            0 :         std::vector<QueInfo> queInfos;
     126            0 :         std::vector<AicpuTaskInfo> aicpuTaskInfos;
     127            0 :         std::vector<StreamInfo> streamInfos;
     128            0 :         std::vector<ModelCfgInfo> modelCfgs;
     129              :         AicpuModelInfo curAicpuModelInfo;
     130              : 
     131            0 :         if (ptr == nullptr) {
     132            0 :             aicpusd_err("the parameter is not valid in load model.");
     133            0 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     134              :         }
     135              : 
     136            0 :         const auto ret = AicpuModelManager::GetInstance().TransModelInfo(ptr, curAicpuModelInfo,
     137              :             aicpuTaskInfos, streamInfos, queInfos, &modelCfgs);
     138            0 :         if (ret != AICPU_SCHEDULE_OK) {
     139            0 :             return ret;
     140              :         }
     141              : 
     142            0 :         if (modelCfgs.empty()) {
     143            0 :             aicpusd_err("Invalid modelCfg");
     144            0 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     145              :         }
     146            0 :         return LoadProcess(&curAicpuModelInfo, &modelCfgs[0U]);
     147            0 :     }
     148              : 
     149              :     /**
     150              :      * @ingroup AicpuScheduleInterface
     151              :      * @brief it use to load the task and stream info.
     152              :      * @param [in] ptr : the address of the task and stream info
     153              :      * @return AICPU_SCHEDULE_OK: success
     154              :      */
     155           12 :     int32_t AicpuScheduleInterface::LoadProcess(const void * const ptr, const ModelCfgInfo * const cfg) const
     156              :     {
     157           12 :         if (ptr == nullptr) {
     158            1 :             aicpusd_err("the parameter is not valid in load model.");
     159            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     160              :         }
     161              : 
     162           11 :         const AicpuModelInfo * const infoTask = PtrToPtr<const void, const AicpuModelInfo>(ptr);
     163           11 :         const uint32_t modelId = infoTask->moduleID;
     164           11 :         aicpusd_info("Begin to load model[%u]", modelId);
     165           11 :         const int32_t ret = AicpuModelManager::GetInstance().ModelLoad(infoTask, cfg);
     166           11 :         if (ret != AICPU_SCHEDULE_OK) {
     167            2 :             aicpusd_err("Failed to load model[%u].", modelId);
     168            2 :             return ret;
     169              :         }
     170              : 
     171            9 :         aicpusd_info("Model[%u] queue size[%u]", modelId, infoTask->queueSize);
     172            9 :         if (static_cast<int32_t>(infoTask->queueSize) > 0) {
     173            0 :             AicpuEventProcess::GetInstance().InitQueueFlag();
     174            0 :             return ExecuteModelAsync(modelId);
     175              :         }
     176              : 
     177            9 :         if (cfg != nullptr) {
     178            0 :             return ExecuteModelAsync(modelId);
     179              :         }
     180            9 :         return AICPU_SCHEDULE_OK;
     181              :     }
     182              : 
     183              :     /**
     184              :      * @ingroup AicpuScheduleInterface
     185              :      * @brief it use to execute model.
     186              :      * @param [in] modelId : modelId
     187              :      * @return AICPU_SCHEDULE_OK: success
     188              :      */
     189            0 :     int32_t AicpuScheduleInterface::ExecuteModelAsync(const uint32_t modelId) const
     190              :     {
     191            0 :         aicpusd_info("Begin to execute model[%u] async", modelId);
     192            0 :         AICPUSubEventInfo subEventInfo = {};
     193            0 :         subEventInfo.modelId = modelId;
     194            0 :         const bool syncSendFlag = GetCpuMode();
     195            0 :         return AicpuMsgSend::SendAICPUSubEvent(PtrToPtr<AICPUSubEventInfo, const char_t>(&subEventInfo),
     196              :             static_cast<uint32_t>(sizeof(AICPUSubEventInfo)),
     197              :             AICPU_SUB_EVENT_EXECUTE_MODEL,
     198              :             CP_DEFAULT_GROUP_ID,
     199            0 :             syncSendFlag);
     200              :     }
     201              : 
     202              :     /**
     203              :      * @ingroup AicpuScheduleInterface
     204              :      * @brief it use to get the errorcode for external module by the model status.
     205              :      * @param [in] modelId : modelId
     206              :      * @return AICPU_SCHEDULE_SUCCESS: success, other: error code
     207              :      */
     208            7 :     ErrorCode AicpuScheduleInterface::GetErrorCode(const uint32_t modelId) const
     209              :     {
     210            7 :         const AicpuModelStatus status = AicpuModelManager::GetInstance().GetModelStatus(modelId);
     211            7 :         if (status == AicpuModelStatus::MODEL_STATUS_ERROR) {
     212            0 :             return AICPU_SCHEDULE_FAIL;
     213            7 :         } else if (status == AicpuModelStatus::MODEL_STATUS_ABORT) {
     214            0 :             return AICPU_SCHEDULE_ABORT;
     215              :         } else {
     216            7 :             return AICPU_SCHEDULE_SUCCESS;
     217              :         }
     218              :     }
     219              : 
     220              :     /**
     221              :      * @ingroup AicpuScheduleInterface
     222              :      * @brief it use to send message to tscpu.
     223              :      * @param [in] deviceId
     224              :      */
     225            6 :     void AicpuScheduleInterface::SendMsgToTsCpu(const uint32_t deviceId) const
     226              :     {
     227              :         // send msg to tscpu
     228            6 :         AicpuSqeAdapter aicpuadapter(FeatureCtrl::GetTsMsgVersion());
     229            6 :         const int32_t ret = aicpuadapter.AicpuNoticeTsPidResponse(deviceId);
     230            6 :         if (ret != AICPU_SCHEDULE_OK) {
     231            1 :             aicpusd_run_warn("AicpuNoticeTsPidResponse ret:%d.", ret);
     232              :         }
     233            6 :     }
     234              : 
     235            6 :     int32_t AicpuScheduleInterface::BindHostPid(const std::string &pidSign, const uint32_t vfId) const
     236              :     {
     237            6 :         int32_t ret = 0;
     238            6 :         if (runMode_ == aicpu::AicpuRunMode::THREAD_MODE) {
     239            1 :             constexpr int32_t mode = static_cast<int32_t>(AicpuPlat::AICPU_OFFLINE_PLAT);
     240            1 :             ret = AicpuDrvManager::GetInstance().BindHostPid(pidSign, mode,
     241              :                                                              vfId, DEVDRV_PROCESS_CP1);
     242            1 :             int32_t getRet = 0;
     243            1 :             getRet = AicpuDrvManager::GetInstance().BindHostPid(pidSign, mode,
     244              :                                                                 vfId, DEVDRV_PROCESS_CP2);
     245            1 :             aicpusd_warn("BindHostPid DEVDRV_PROCESS_CP2 ret[%d]", getRet);
     246              :         } else {
     247            5 :             ret = AicpuDrvManager::GetInstance().CheckBindHostPid();
     248              :         }
     249            6 :         return ret;
     250              :     }
     251              : 
     252              :     /**
     253              :      * @ingroup AicpuScheduleInterface
     254              :      * @brief it use to initialize aicpu schedule.
     255              :      * @param [in] deviceId
     256              :      * @param [in] hostPid : the process id of host
     257              :      * @param [in] pidSign : the signature of pid ,it is used in drv.
     258              :      * @param [in] profilingMode
     259              :      * @param [in] vfId : vf id
     260              :      * @param [in] isOnline: true-process mode; false-thread mode
     261              :      * @return AICPU_SCHEDULE_OK: success, other: error code
     262              :      */
     263           14 :     int32_t AicpuScheduleInterface::InitAICPUScheduler(const std::vector<uint32_t> &deviceVec,
     264              :                                                        const pid_t hostPid,
     265              :                                                        const std::string &pidSign,
     266              :                                                        const uint32_t profilingMode,
     267              :                                                        const uint32_t vfId,
     268              :                                                        const bool isOnline,
     269              :                                                        const std::string &hostProcName)
     270              :     {
     271           14 :         if (deviceVec.empty()) {
     272            0 :             aicpusd_err("device vector is empty");
     273            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     274              :         }
     275              : 
     276           14 :         if (IsInitialized(deviceVec[0])) {
     277            6 :             aicpusd_warn("Aicpu schedule is already init.");
     278            6 :             return AICPU_SCHEDULE_OK;
     279              :         }
     280            8 :         const std::unique_lock<std::mutex> lockForInit(mutexForInit_);
     281            8 :         UpdateOrInsertStartFlag(deviceVec[0], false);
     282            8 :         noThreadFlag_ = false;
     283              : 
     284              :         // get aicpu run mode
     285            8 :         const int32_t getRet = GetCurrentRunMode(isOnline);
     286            8 :         if (getRet != AICPU_SCHEDULE_OK) {
     287            0 :             aicpusd_err("getRet is not ok:%u", getRet);
     288            0 :             return getRet;
     289              :         }
     290            8 :         if (AicpuDrvManager::GetInstance().InitDrvMgr(deviceVec, hostPid, vfId,
     291            8 :                                                       true, runMode_, hostProcName) != AICPU_SCHEDULE_OK) {
     292            0 :             aicpusd_err("Failed to init aicpu drv manager");
     293            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     294              :         }
     295            8 :         (void)aicpu::SetAicpuRunMode(runMode_); // InitDrvSchedModule will use the runMode.
     296            8 :         DeployContext deployCtx = DeployContext::DEVICE;
     297            8 :         const StatusCode status = GetAicpuDeployContext(deployCtx);
     298            8 :         if (status != AICPU_SCHEDULE_OK) {
     299            0 :             aicpusd_err("Get current deploy ctx failed.");
     300            0 :             return status;
     301              :         }
     302            8 :         const bool cpuMode = GetCpuMode();
     303            8 :         if ((deployCtx == DeployContext::DEVICE) && (!cpuMode)) {
     304            6 :             const int32_t bindPidRet = BindHostPid(pidSign, vfId);
     305            6 :             if (bindPidRet != AICPU_SCHEDULE_OK) {
     306            0 :                 aicpusd_err("check bind pid sign failed, ret[%d].", bindPidRet);
     307            0 :                 return bindPidRet;
     308              :             }
     309            6 :             aicpusd_info("Bind pid sign success");
     310              :         }
     311              : 
     312            8 :         constexpr uint32_t groupId = CP_DEFAULT_GROUP_ID;
     313            8 :         int32_t ret = AicpuDrvManager::GetInstance().InitDrvSchedModule(groupId, EVENT_PRIORITY);
     314            8 :         if (ret != DRV_ERROR_NONE) {
     315            1 :             aicpusd_err("Failed to init the drv schedule module, ret[%d].", ret);
     316            1 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     317              :         }
     318            7 :         ret = AicpuSchedule::AicpuMonitor::GetInstance().InitMonitor(deviceVec[FIRST_INDEX], isOnline);
     319            7 :         if (ret != AICPU_SCHEDULE_OK) {
     320            0 :             aicpusd_err("aicpu monitor init failed, ret[%d]", ret);
     321            0 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     322              :         }
     323            7 :         const AicpuSchedMode schedMode = FeatureCtrl::GetAicpuSchedMode();
     324            7 :         AicpuEventManager::GetInstance().InitEventFunc(schedMode);
     325            7 :         (void)AicpuSchedule::AicpuEventProcess::GetInstance(); // Pre init instance
     326            7 :         const auto retCp = ComputeProcess::GetInstance().Start(deviceVec, hostPid, pidSign, profilingMode,
     327              :                                                                vfId, runMode_);
     328            7 :         if (retCp != AICPU_SCHEDULE_OK) {
     329            1 :             aicpusd_err("Compute process start failed, ret[%d].", retCp);
     330            1 :             ComputeProcess::GetInstance().Stop();
     331            1 :             AicpuSchedule::AicpuMonitor::GetInstance().StopMonitor();
     332            1 :             return AICPU_SCHEDULE_ERROR_INIT_CP_FAILED;
     333              :         }
     334            6 :         AicpuSchedule::AicpuSdPeriodStatistic::GetInstance().InitStatistic(deviceVec[FIRST_INDEX], hostPid, runMode_);
     335            6 :         AicpuSchedule::AicpuSdModelStatistic::GetInstance().InitModelStatInfo();
     336              :         // send message to tscpu, failure is not handled and does not affect the main process
     337            6 :         SendMsgToTsCpu(deviceVec[FIRST_INDEX]);
     338            6 :         const auto conRet = BuildAndSetContext(deviceVec[FIRST_INDEX], hostPid, vfId);
     339            6 :         if (conRet != AICPU_SCHEDULE_OK) {
     340            0 :             return conRet;
     341              :         }
     342              : 
     343              :         // init AicpuCustSoManager
     344            6 :         (void)AicpuSchedule::AicpuCustSoManager::GetInstance().InitAicpuCustSoManager(runMode_, schedMode);
     345            6 :         aicpusd_info("Successfully started compute process, deviceId[%u], hostPid[%d], runMode[%u]",
     346              :                      deviceVec[FIRST_INDEX], hostPid, runMode_);
     347            6 :         UpdateOrInsertStartFlag(deviceVec[0], true);
     348            6 :         return AICPU_SCHEDULE_OK;
     349            8 :     }
     350              : 
     351            7 :     int32_t AicpuScheduleInterface::BuildAndSetContext(
     352              :         const uint32_t deviceId, const pid_t hostPid, const uint32_t vfId)
     353              :     {
     354            7 :         aicpu::aicpuContext_t context = {
     355              :             .deviceId = deviceId,
     356              :             .tsId = 0U,
     357              :             .hostPid = hostPid,
     358              :             .vfId = vfId
     359            7 :         };
     360            7 :         uint32_t uniqueVfId = context.vfId;
     361            7 :         (void)aicpu::aicpuSetContext(&context);
     362            7 :         aicpu::SetUniqueVfId(uniqueVfId);
     363            7 :         if (FeatureCtrl::IsAosCore()) {
     364            1 :             return AICPU_SCHEDULE_OK;
     365              :         }
     366            6 :         if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
     367            0 :             uniqueVfId = deviceId;
     368              :         } else {
     369            6 :             if ((context.deviceId != 0U) && (context.vfId != 0U)) {
     370            1 :                 uint32_t maxNumSpDev = 0U;
     371            1 :                 const auto vfMaxRet = halGetDeviceVfMax(context.deviceId, &maxNumSpDev);
     372            1 :                 if ((vfMaxRet != DRV_ERROR_NONE) || (maxNumSpDev > DEVICE_MAX_SPLIT_NUM)) {
     373            0 :                     aicpusd_err("Failed to get device cat vf number, result[%d], max num[%u].", vfMaxRet, maxNumSpDev);
     374            0 :                     ComputeProcess::GetInstance().Stop();
     375            0 :                     AicpuSchedule::AicpuMonitor::GetInstance().StopMonitor();
     376            0 :                     return AICPU_SCHEDULE_ERROR_INIT_CP_FAILED;
     377              :                 } else {
     378            1 :                     uniqueVfId = (maxNumSpDev * context.deviceId) + context.vfId;
     379              :                 }
     380              :             }
     381              :         }
     382            6 :         aicpu::SetUniqueVfId(uniqueVfId);
     383            6 :         return AICPU_SCHEDULE_OK;
     384              :     }
     385              : 
     386              :     /**
     387              :      * @ingroup AicpuScheduleInterface
     388              :      * @param [in] modelId
     389              :      * @brief it use to destroy one model.
     390              :      * @return AICPU_SCHEDULE_OK: success, other: error code
     391              :      */
     392           10 :     int32_t AicpuScheduleInterface::Destroy(const uint32_t modelId) const
     393              :     {
     394           10 :         const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
     395           10 :         if (model == nullptr) {
     396            1 :             aicpusd_err("Model[%u] is not found.", modelId);
     397            1 :             return AICPU_SCHEDULE_ERROR_MODEL_NOT_FOUND;
     398              :         }
     399              : 
     400            9 :         const uint32_t tsId = model->GetModelTsId();
     401            9 :         if (tsId < static_cast<uint32_t>(TSIDFlag::AICPU_SCHEDULE_TS_ID)) {
     402            1 :             TsAicpuSqe tsAicpuSqe = {};
     403            1 :             tsAicpuSqe.pid = static_cast<uint32_t>(AicpuDrvManager::GetInstance().GetHostPid());
     404            1 :             tsAicpuSqe.cmd_type = AICPU_MODEL_OPERATE;
     405            1 :             tsAicpuSqe.vf_id = static_cast<uint8_t>(AicpuDrvManager::GetInstance().GetVfId());
     406            1 :             tsAicpuSqe.tid = static_cast<uint8_t>(0U); // no need tid
     407            1 :             tsAicpuSqe.ts_id = static_cast<uint8_t>(tsId);
     408            1 :             tsAicpuSqe.u.aicpu_model_operate.cmd_type = TS_AICPU_MODEL_DESTROY;
     409            1 :             tsAicpuSqe.u.aicpu_model_operate.model_id = static_cast<uint16_t>(modelId);
     410            1 :             tsAicpuSqe.u.aicpu_model_operate.arg_ptr = 0UL;
     411            1 :             tsAicpuSqe.u.aicpu_model_operate.task_id = static_cast<uint16_t>(0U);
     412              : 
     413            1 :             const int32_t drvRet = tsDevSendMsgAsync(AicpuDrvManager::GetInstance().GetDeviceId(), tsId,
     414              :                                                      PtrToPtr<TsAicpuSqe, char_t>(&tsAicpuSqe),
     415              :                                                      static_cast<uint32_t>(sizeof(TsAicpuSqe)), modelId);
     416            1 :             if (drvRet != DRV_ERROR_NONE) {
     417            0 :                 aicpusd_err("Failed to send destroy model[%u] to ts[%u] , result[%d].", modelId, tsId, drvRet);
     418              :             }
     419            1 :             aicpusd_info("Successfully destroyed tsDevSendMsgAsync.");
     420              :         }
     421              : 
     422            9 :         const auto ret =  model->ModelDestroy();
     423            9 :         AicpuModelManager::GetInstance().ModelConfigClear(modelId);
     424            9 :         return ret;
     425              :     }
     426              : 
     427              :     /**
     428              :      * @ingroup AicpuScheduleInterface
     429              :      * @param [in] modelId
     430              :      * @brief it use to stop one model.
     431              :      * @return AICPU_SCHEDULE_OK: success, other: error code
     432              :      */
     433            3 :     int32_t AicpuScheduleInterface::Stop(const uint32_t modelId) const
     434              :     {
     435            3 :         const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
     436            3 :         if (model == nullptr) {
     437            1 :             aicpusd_err("Model[%u] is not found.", modelId);
     438            1 :             return AICPU_SCHEDULE_ERROR_MODEL_NOT_FOUND;
     439              :         }
     440              : 
     441            2 :         const uint32_t tsId = model->GetModelTsId();
     442            2 :         if (tsId < static_cast<uint32_t>(TSIDFlag::AICPU_SCHEDULE_TS_ID)) {
     443            1 :             TsAicpuSqe tsAicpuSqe = {};
     444            1 :             tsAicpuSqe.pid = static_cast<uint32_t>(AicpuDrvManager::GetInstance().GetHostPid());
     445            1 :             tsAicpuSqe.cmd_type = AICPU_MODEL_OPERATE;
     446            1 :             tsAicpuSqe.vf_id = static_cast<uint8_t>(AicpuDrvManager::GetInstance().GetVfId());
     447            1 :             tsAicpuSqe.tid = static_cast<uint8_t>(0U); // no need tid
     448            1 :             tsAicpuSqe.ts_id = static_cast<uint8_t>(tsId);
     449            1 :             tsAicpuSqe.u.aicpu_model_operate.cmd_type = TS_AICPU_MODEL_DESTROY;
     450            1 :             tsAicpuSqe.u.aicpu_model_operate.model_id = static_cast<uint16_t>(modelId);
     451            1 :             tsAicpuSqe.u.aicpu_model_operate.arg_ptr = 0UL;
     452            1 :             tsAicpuSqe.u.aicpu_model_operate.task_id = static_cast<uint16_t>(0U);
     453              : 
     454            1 :             const int32_t drvRet = tsDevSendMsgAsync(AicpuDrvManager::GetInstance().GetDeviceId(), tsId,
     455              :                                                      PtrToPtr<TsAicpuSqe, char_t>(&tsAicpuSqe),
     456              :                                                      static_cast<uint32_t>(sizeof(TsAicpuSqe)), modelId);
     457            1 :             if (drvRet != DRV_ERROR_NONE) {
     458            1 :                 aicpusd_err("Failed to send destroy model[%u] to ts[%u] , result[%d].", modelId, tsId, drvRet);
     459              :             }
     460            1 :             aicpusd_info("Successfully destroyed tsDevSendMsgAsync.");
     461              :         }
     462              : 
     463            2 :         uint32_t retryCost = 0U;
     464            2 :         const uint32_t retryIntervalUs = 10000U;
     465            2 :         const uint32_t retryCostLimitUs = 1000000U;
     466            2 :         auto stopRet = model->ModelStop();
     467            2 :         while ((stopRet == AICPU_SCHEDULE_ERROR_IN_WORKING) && (retryCost < retryCostLimitUs)) {
     468            0 :             usleep(retryIntervalUs);
     469            0 :             retryCost += retryIntervalUs;
     470            0 :             stopRet = model->ModelStop();
     471              :         }
     472            2 :         aicpusd_run_info("Stop model[%u], ret is %d, retryCost is %u.", modelId, stopRet, retryCost);
     473            2 :         return stopRet;
     474              :     }
     475              : 
     476            2 :     int32_t AicpuScheduleInterface::Restart(const uint32_t modelId) const
     477              :     {
     478            2 :         const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
     479            2 :         if (model == nullptr) {
     480            1 :             aicpusd_err("Model[%u] is not found.", modelId);
     481            1 :             return AICPU_SCHEDULE_ERROR_MODEL_NOT_FOUND;
     482              :         }
     483              : 
     484            1 :         uint32_t retryCost = 0U;
     485            1 :         const uint32_t retryIntervalUs = 10000U;
     486            1 :         const uint32_t retryCostLimitUs = 1000000U;
     487            1 :         auto restartRet = model->ModelRestart();
     488            1 :         while ((restartRet == AICPU_SCHEDULE_ERROR_IN_WORKING) && (retryCost < retryCostLimitUs)) {
     489            0 :             usleep(retryIntervalUs);
     490            0 :             retryCost += retryIntervalUs;
     491            0 :             restartRet = model->ModelRestart();
     492              :         }
     493            1 :         aicpusd_run_info("Restart model[%u], ret is %d, retryCost is %u.", modelId, restartRet, retryCost);
     494            1 :         return restartRet;
     495              :     }
     496              : 
     497            6 :     int32_t AicpuScheduleInterface::CheckKernelSupported(const std::string &kernelName) const
     498              :     {
     499            6 :         const auto pos = kernelName.find(TSKERNEL_PREFIX);
     500            6 :         if (pos != kernelName.npos) {
     501            2 :             const std::string tsKernelName = kernelName.substr(TSKERNEL_PREFIX.length());
     502            2 :             return HwTsKernelRegister::Instance().CheckTsKernelSupported(tsKernelName);
     503            2 :         }
     504            4 :         return OperatorKernelRegister::Instance().CheckOperatorKernelSupported(kernelName);
     505              :     }
     506              : 
     507            2 :     int32_t AicpuScheduleInterface::ClearInput(const uint32_t modelId) const
     508              :     {
     509            2 :         const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
     510            2 :         if (model == nullptr) {
     511            1 :             aicpusd_err("Model[%u] is not found.", modelId);
     512            1 :             return AICPU_SCHEDULE_ERROR_MODEL_NOT_FOUND;
     513              :         }
     514              : 
     515            1 :         return model->ModelClearInput();
     516              :     }
     517              : 
     518              :     /**
     519              :      * @ingroup AicpuScheduleInterface
     520              :      * @brief it use to destroy all model.
     521              :      */
     522           24 :     int32_t AicpuScheduleInterface::Destroy() const
     523              :     {
     524           24 :         if (AicpuModelManager::IsUsed()) {
     525           21 :             return AicpuModelManager::GetInstance().Exit();
     526              :         }
     527            3 :         return AICPU_SCHEDULE_OK;
     528              :     }
     529              : 
     530              :     /**
     531              :      * @ingroup AicpuScheduleInterface
     532              :      * @brief it use to stop AICPU scheduler.
     533              :      * @param [in] deviceId
     534              :      * @param [in] hostPid :the process id of host
     535              :      * @return AICPU_SCHEDULE_OK: success, other: error code
     536              :      */
     537           23 :     int32_t AicpuScheduleInterface::StopAICPUScheduler(const std::vector<uint32_t> &deviceVec, const pid_t hostPid)
     538              :     {
     539           23 :         return StopAICPUSchedulerWithFlag(deviceVec, hostPid, false);
     540              :     }
     541              : 
     542           24 :     int32_t AicpuScheduleInterface::StopAICPUSchedulerWithFlag(const std::vector<uint32_t> &deviceVec,
     543              :         const pid_t hostPid, const bool waitThreadStop)
     544              :     {
     545           24 :         if (deviceVec.empty()) {
     546            0 :             aicpusd_err("deviceVec is empty.");
     547            0 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     548              :         }
     549           24 :         aicpusd_run_info("Begin to stop aicpu scheduler, hostPid[%d]", hostPid);
     550           24 :         const std::unique_lock<std::mutex> lockForInit(mutexForInit_);
     551           24 :         if (!noThreadFlag_) {
     552            5 :             ComputeProcess::GetInstance().Stop();
     553              :         }
     554              : 
     555           24 :         (void)Destroy();
     556           24 :         noThreadFlag_ = true;
     557           24 :         UpdateOrInsertStartFlag(deviceVec[0], false);
     558           24 :         AicpuSchedule::DumpSessionManager::GetInstance().CloseAllSessions();
     559           24 :         AicpuSchedule::AicpuMonitor::GetInstance().StopMonitor();
     560           24 :         AicpuSchedule::AicpuEventManager::GetInstance().SetRunningFlag(false);
     561           24 :         AicpuSchedule::AicpuSdPeriodStatistic::GetInstance().StopStatistic();
     562           24 :         AicpuSchedule::AicpuSdPeriodStatistic::GetInstance().PrintOutStatisticInfo(runMode_);
     563           24 :         AicpuSchedule::AicpuSdModelStatistic::GetInstance().PrintOutModelStatInfo();
     564           24 :         AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(0).UnitMc2MantenanceProcess();
     565           24 :         AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(1).UnitMc2MantenanceProcess();
     566           24 :         AicpuSchedule::AicpuSdCustDumpProcess::GetInstance().UnitCustDataDumpProcess();
     567           24 :         FeatureCtrl::ClearTsMsgVersionInfo();
     568           24 :         constexpr uint32_t sleepUsecs = 1000U;  // sleep 1ms to avoid SchedWaitEvent error
     569           24 :         (void)usleep(sleepUsecs);
     570           24 :         const int32_t ret = DettachDeviceInDestroy(deviceVec);
     571           24 :         if (ret != AICPU_SCHEDULE_OK) {
     572            2 :             aicpusd_err("DettachDeviceInDestroy error %d", ret);
     573            2 :             return ret;
     574              :         }
     575           22 :         if ((runMode_ == aicpu::AicpuRunMode::PROCESS_PCIE_MODE) ||
     576           22 :             (runMode_ == aicpu::AicpuRunMode::PROCESS_SOCKET_MODE) ||
     577              :             waitThreadStop) {
     578           21 :             AicpuSchedule::ThreadPool::Instance().WaitForStop();
     579              :         }
     580           22 :         MsqOperatorManager::Finalize();
     581           22 :         g_aicpuProfiler.Uninit();
     582           22 :         aicpusd_run_info("Successfully stopped AICPU scheduler, hostPid[%d]", hostPid);
     583           22 :         return AICPU_SCHEDULE_OK;
     584           24 :     }
     585              : 
     586            9 :     int32_t AicpuScheduleInterface::GetCurrentRunMode(const bool isOnline)
     587              :     {
     588            9 :         if (!isOnline) {
     589            1 :             runMode_ = aicpu::AicpuRunMode::THREAD_MODE;
     590            1 :             aicpusd_run_info("Current aicpu mode is offline (call by api).");
     591            1 :             return AICPU_SCHEDULE_OK;
     592              :         }
     593              : 
     594              :         drvHdcCapacity capacity;
     595            8 :         capacity.chanType = HDC_CHAN_TYPE_SOCKET;
     596            8 :         capacity.maxSegment = 0U;
     597            8 :         const hdcError_t hdcRet = drvHdcGetCapacity(&capacity);
     598            8 :         if (hdcRet != DRV_ERROR_NONE) {
     599            0 :             aicpusd_err("Aicpu scheduler get capacity failed, ret[%d].", hdcRet);
     600            0 :             return AICPU_SCHEDULE_ERROR_FROM_DRV;
     601              :         }
     602              : 
     603              :         // online: with host, offline: without host only device
     604            8 :         if (capacity.chanType == HDC_CHAN_TYPE_SOCKET) {
     605            7 :             runMode_ = aicpu::AicpuRunMode::PROCESS_SOCKET_MODE;
     606            7 :             aicpusd_run_info("Set aicpu online mode false. current mode is socket_mode.");
     607            7 :             return AICPU_SCHEDULE_OK;
     608              :         }
     609              : 
     610            1 :         runMode_ = aicpu::AicpuRunMode::PROCESS_PCIE_MODE;
     611            1 :         aicpusd_run_info("Current aicpu mode is online (call from host).");
     612            1 :         return AICPU_SCHEDULE_OK;
     613              :     }
     614              : 
     615           25 :     int32_t AicpuScheduleInterface::DettachDeviceInDestroy(const std::vector<uint32_t> &deviceVec) const
     616              :     {
     617           25 :         if (SubModuleInterface::GetInstance().GetStartFlag()) {
     618            0 :             aicpusd_run_info("sub module no need to detach device, main module do it");
     619            0 :             return AICPU_SCHEDULE_OK;
     620              :         }
     621              : 
     622           25 :         DeployContext deployCtx = DeployContext::DEVICE;
     623           25 :         (void)GetAicpuDeployContext(deployCtx);
     624           48 :         for (size_t i = 0LU; i < deviceVec.size(); i++) {
     625           25 :             if ((FeatureCtrl::ShouldInitDrvThread()) && (deployCtx == DeployContext::DEVICE) &&
     626              :                 (&halDrvEventThreadUninit != nullptr)) {
     627           25 :                 const auto unInitRet = halDrvEventThreadUninit(deviceVec[i]);
     628           25 :                 aicpusd_run_info("Uninit process drv queue msg on ccpu, ret is %d.", static_cast<int32_t>(unInitRet));
     629              :                 (void) unInitRet;
     630              :             }
     631           25 :             const drvError_t ret = halEschedDettachDevice(deviceVec[i]);
     632           25 :             if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_NOT_EXIST)) { // maybe is repeated detach
     633            2 :                 aicpusd_err("Failed to detach device[%u], result[%d].", deviceVec[i], ret);
     634            2 :                 return ret;
     635              :             }
     636           23 :             aicpusd_info("Successfully detached AICPU scheduler, device[%d].", deviceVec[i]);
     637              :         }
     638           23 :         return AICPU_SCHEDULE_OK;
     639              :     }
     640              : 
     641           25 :     bool AicpuScheduleInterface::IsInitialized(const uint32_t deviceId)
     642              :     {
     643           25 :         const std::unique_lock<std::mutex> lockForInit(mutexForInit_);
     644           25 :         auto initIter = aicpusdInitFlagMap_.find(deviceId);
     645           25 :         if (initIter != aicpusdInitFlagMap_.end()) {
     646           16 :             return (initIter->second);
     647              :         } else {
     648            9 :             return false;
     649              :         }
     650           25 :     }
     651              : 
     652           40 :     void AicpuScheduleInterface::UpdateOrInsertStartFlag(const uint32_t deviceId, const bool flag)
     653              :     {
     654           40 :         auto initIter = aicpusdInitFlagMap_.find(deviceId);
     655           40 :         if (initIter != aicpusdInitFlagMap_.end()) {
     656           34 :             initIter->second = flag;
     657              :         } else {
     658            6 :             aicpusdInitFlagMap_.insert(std::pair<uint32_t, bool>(deviceId, false));
     659              :         }
     660           40 :     }
     661              : 
     662            5 :     void AicpuScheduleInterface::SetAicpuCustSdProcId(const int32_t aicpuCustSdPid)
     663              :     {
     664            5 :         if (aicpuCustSdPid != -1) {
     665            5 :             aicpuCustSdPid_ = aicpuCustSdPid;
     666           10 :             aicpusd_info("set aicpucustsd pid:%d", aicpuCustSdPid_.load());
     667              :         }
     668            5 :     }
     669              : 
     670            2 :     int32_t AicpuScheduleInterface::GetAicpuCustSdProcId() const
     671              :     {
     672            4 :         return aicpuCustSdPid_.load();
     673              :     }
     674              : 
     675            9 :     int32_t AicpuScheduleInterface::ProcessException(const DataFlowExceptionNotify *const exceptionInfo) const
     676              :     {
     677            9 :         aicpusd_info("Begin to process data exception event.");
     678            9 :         if (exceptionInfo == nullptr) {
     679            1 :             aicpusd_err("Invalid exception info.");
     680            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     681              :         }
     682              : 
     683            8 :         const auto modelNum = exceptionInfo->modelIdNum;
     684            8 :         const auto modelIdsAddr = PtrToPtr<void, uint32_t>(ValueToPtr(exceptionInfo->modelIdsAddr));
     685            8 :         if ((modelNum > 0U) && (modelIdsAddr == nullptr)) {
     686            1 :             aicpusd_err("Invalid modelIds.");
     687            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     688              :         }
     689              : 
     690           18 :         for (uint32_t i = 0; i < modelNum; ++i) {
     691           13 :             const auto modelId = modelIdsAddr[static_cast<size_t>(i)];
     692           13 :             const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
     693           13 :             if (model == nullptr) {
     694            1 :                 aicpusd_err("Model[%u] is not found.", modelId);
     695            1 :                 return AICPU_SCHEDULE_ERROR_MODEL_NOT_FOUND;
     696              :             }
     697           12 :             const auto processRet = model->ProcessDataException(exceptionInfo->transId, exceptionInfo->type);
     698           12 :             if (processRet != AICPU_SCHEDULE_OK) {
     699            1 :                 return processRet;
     700              :             }
     701           11 :             aicpusd_run_info("Successfully processed kernel data exception for transid[%lu] of model[%u].",
     702              :                 exceptionInfo->transId, modelId);
     703              :         }
     704            5 :         aicpusd_info("Successfully processed kernel data exception event.");
     705            5 :         return AICPU_SCHEDULE_OK;
     706              :     }
     707              : 
     708           26 :     void AicpuScheduleInterface::SetBatchLoadMode(const uint32_t aicpuProcNum) 
     709              :     {
     710           26 :         if (aicpuProcNum >= MAX_AICPU_PROC_NUM) {
     711            1 :             isNeedBatchLoadSo_ = false;
     712            1 :             aicpusd_run_info("Not need batch load so, aicpuProcNum[%u], max num[%u]",
     713              :                              aicpuProcNum, MAX_AICPU_PROC_NUM);
     714              :         }
     715           26 :     }
     716              : 
     717           11 :     bool AicpuScheduleInterface::NeedLoadKernelSo() const
     718              :     {
     719           11 :         return isNeedBatchLoadSo_;
     720              :     } 
     721              : }
        

Generated by: LCOV version 2.0-1