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

Generated by: LCOV version 2.0-1