LCOV - code coverage report
Current view: top level - aicpu_schedule/core - aicpusd_model.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 99.8 % 917 915
Test Date: 2026-07-28 10:54:05 Functions: 100.0 % 61 61

            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_model_execute.h"
      12              : 
      13              : #include <algorithm>
      14              : #include <stack>
      15              : #include <cstring>
      16              : 
      17              : #include "aicpusd_resource_manager.h"
      18              : #include "aicpusd_drv_manager.h"
      19              : #include "aicpusd_profiler.h"
      20              : #include "aicpusd_monitor.h"
      21              : #include "aicpusd_msg_send.h"
      22              : #include "aicpusd_info.h"
      23              : #include "aicpu_event_struct.h"
      24              : #include "type_def.h"
      25              : #include "profiling_adp.h"
      26              : #include "aicpusd_event_process.h"
      27              : #include "aicpusd_context.h"
      28              : #include "dump_task.h"
      29              : #include "operator_kernel_register.h"
      30              : #include "aicpusd_model_err_process.h"
      31              : 
      32              : namespace {
      33              :     // model operate values
      34              :     const std::string OPERATE_VALUE[static_cast<int32_t>(AicpuSchedule::AicpuModelOperate::MODEL_OPERATE_MAX)] = {
      35              :         "LOAD",
      36              :         "EXECUTE",
      37              :         "ABORT",
      38              :         "TASK_REPORT",
      39              :         "END_GRAPH",
      40              :         "RUN_TASK",
      41              :         "DESTROY",
      42              :         "STOP",
      43              :         "RESTART",
      44              :         "CLEAR_INPUT"
      45              :     };
      46              : 
      47              :     // model status values
      48              :     const std::string STATUS_VALUE[static_cast<int32_t>(AicpuSchedule::AicpuModelStatus::MODEL_STATUS_MAX)] = {
      49              :         "UNINIT",
      50              :         "IDLE",
      51              :         "LOADING",
      52              :         "RUNNING",
      53              :         "ERROR",
      54              :         "ABORT",
      55              :         "STOPPED"
      56              :     };
      57              :     constexpr uint32_t HCCL_QUERY_PREPARE_INTERVAL = 20000U; // us
      58              :     constexpr uint32_t HCCL_QUERY_LOG_INTERVAL = 500U;
      59              :     constexpr char_t const *REPORT_STATUS_TASK_NAME = "modelReportStatus";
      60              :     constexpr int32_t TIMES_MS_TO_NS = 1000;
      61              :     constexpr uint32_t ASYNC_TASK_INTERVAL = 2000U; // us
      62              :     constexpr uint32_t AICPU_STREAM_TASK_DUMP_MASK = 0x01U;
      63              : }
      64              : 
      65              : namespace AicpuSchedule {
      66              :     constexpr int32_t INVALID_TASK_INDEX = -1;
      67              :     // attention: if change AicpuModelStatus or AicpuModelOperate define, pls update this table together.
      68              :     const bool AicpuModel::modelOperatePermission[static_cast<int32_t>(AicpuModelStatus::MODEL_STATUS_MAX)]
      69              :         [static_cast<int32_t>(AicpuModelOperate::MODEL_OPERATE_MAX)] = {
      70              :             // load, execute, abort, taskReport, endGraph, runTask, destroy, stop, restart, clearInput
      71              :             {true,  false, false, false, false, false, true, true, false, false},      // uninit
      72              :             {false, true,  false, false, true,  true,  true, true, false, false},      // idle
      73              :             {false, true,  false, false, false, false, true, true, false, false},      // loading
      74              :             {false, false, true,  true,  true,  true,  true, true, false, false},     // running
      75              :             {false, true, true,  false, false, false, true, true, false, false},      // error
      76              :             {false, true,  false, false, false, false, true, true, false, false},     // abort
      77              :             {false, false,  false, false, false, false, true, false, true, true}      // stopped
      78              :     };
      79              : 
      80              :     // attention: if change AicpuModelStatus or AicpuModelOperate define, pls update this table together.
      81              :     const AicpuModelStatus AicpuModel::operateNextStatus[static_cast<int32_t>(AicpuModelOperate::MODEL_OPERATE_MAX)]
      82              :         = {
      83              :             AicpuModelStatus::MODEL_STATUS_LOADING,  // load
      84              :             AicpuModelStatus::MODEL_STATUS_RUNNING,  // execute
      85              :             AicpuModelStatus::MODEL_STATUS_ABORT,    // abort
      86              :             AicpuModelStatus::MODEL_STATUS_ERROR,    // taskReport
      87              :             AicpuModelStatus::MODEL_STATUS_IDLE,     // endGraph
      88              :             AicpuModelStatus::MODEL_STATUS_MAX,      // runTask
      89              :             AicpuModelStatus::MODEL_STATUS_UNINIT,  // destroy
      90              :             AicpuModelStatus::MODEL_STATUS_STOPPED,  // stop
      91              :             AicpuModelStatus::MODEL_STATUS_IDLE,  // restart
      92              :             AicpuModelStatus::MODEL_STATUS_STOPPED,  // clearInput
      93              :     };
      94              : 
      95           17 :     void AicpuStream::InitAicpuStream(const uint32_t streamId, const std::vector<const AicpuTaskInfo *> &tasks)
      96              :     {
      97           17 :         const std::unique_lock<std::mutex> lockForStream(mutexForStream_);
      98           17 :         streamId_ = streamId;
      99           17 :         nextTaskIndex_ = 0LU;
     100           17 :         (void)std::transform(tasks.begin(), tasks.end(), std::back_inserter(tasks_),
     101           97 :                              [](const AicpuTaskInfo * const taskPtr) {return *taskPtr;});
     102           17 :     }
     103              : 
     104            7 :     void AicpuStream::ResetToStart()
     105              :     {
     106            7 :         const std::unique_lock<std::mutex> lockForStream(mutexForStream_);
     107            7 :         nextTaskIndex_ = 0LU;
     108            7 :     }
     109              : 
     110           10 :     void AicpuStream::ResetTasks()
     111              :     {
     112           10 :         aicpusd_info("Stream[%u] clear load info begin.", streamId_);
     113           10 :         const std::unique_lock<std::mutex> lockForStream(mutexForStream_);
     114           10 :         tasks_.clear();
     115           10 :     }
     116              : 
     117           10 :     void AicpuStream::ShowProgress()
     118              :     {
     119           10 :         if (nextTaskIndex_ >= tasks_.size()) {
     120            7 :             aicpusd_run_info("Stream[%u] is finished", streamId_);
     121            7 :             return;
     122              :         }
     123            3 :         const auto kernelName = PtrToPtr<void, char_t>(ValueToPtr(tasks_[nextTaskIndex_].kernelName));
     124            3 :         if (kernelName != nullptr) {
     125            2 :             aicpusd_run_info("Stream[%u] is at %zu task[%s] now.", streamId_, nextTaskIndex_, kernelName);
     126              :         } else {
     127            1 :             aicpusd_run_info("Stream[%u] is at %zu task[invalid] now.", streamId_, nextTaskIndex_);
     128              :         }
     129              :     }
     130              : 
     131           93 :     int32_t AicpuStream::ExecuteNextTask(const RunContext &runContext, bool &streamEnd)
     132              :     {
     133              :         // need lock all execute period
     134           93 :         const std::unique_lock<std::mutex> lockForSteam(mutexForStream_);
     135           93 :         if (nextTaskIndex_ >= tasks_.size()) {
     136            2 :             aicpusd_err("Model[%u] stream[%u] has reach task end, total taskNum[%zu], nextTaskIndex[%zu].",
     137              :                         runContext.modelId, streamId_, tasks_.size(), nextTaskIndex_);
     138            2 :             streamEnd = true;
     139            2 :             return AICPU_SCHEDULE_OK;
     140              :         }
     141           91 :         const auto &taskInfo = tasks_[nextTaskIndex_];
     142           91 :         aicpusd_info("Model[%u] stream[%u] begin to execute %zuth task, taskId[%u], kernelType[%u].",
     143              :                      runContext.modelId, streamId_, nextTaskIndex_, taskInfo.taskID, taskInfo.kernelType);
     144           91 :         *(const_cast<int32_t *>(&runContext.gotoTaskIndex)) = INVALID_TASK_INDEX;
     145           91 :         const int32_t ret = ExecuteTask(taskInfo, runContext);
     146           91 :         if (ret != AICPU_SCHEDULE_OK) {
     147           18 :             const auto model = AicpuModelManager::GetInstance().GetModel(runContext.modelId);
     148           18 :             uint64_t transId = UINT64_MAX;
     149           18 :             if (model != nullptr) {
     150            3 :                 transId = model->GetModelTransId();
     151              :             }
     152           18 :             aicpusd_err("Model[%u] stream[%u] execute %zuth task failed, taskId[%u], ret[%d], transId[%lu].",
     153              :                         runContext.modelId, streamId_, nextTaskIndex_, taskInfo.taskID, ret, transId);
     154           18 :             nextTaskIndex_++;
     155           18 :             return ret;
     156              :         }
     157           73 :         if (runContext.pending) {
     158            1 :             aicpusd_info("Model[%u] stream[%u] pending on %zuth task, taskId[%u].",
     159              :                          runContext.modelId, streamId_, nextTaskIndex_, taskInfo.taskID);
     160           72 :         } else if (runContext.gotoTaskIndex != INVALID_TASK_INDEX) {
     161            2 :             nextTaskIndex_ = static_cast<size_t>(runContext.gotoTaskIndex);
     162            2 :             aicpusd_info("Model[%u] stream[%u] goto %zuth task, taskId[%u].",
     163              :                          runContext.modelId, streamId_, nextTaskIndex_, taskInfo.taskID);
     164              :         } else {
     165           70 :             aicpusd_info("Model[%u] stream[%u] execute %zuth task success, taskId[%u].",
     166              :                          runContext.modelId, streamId_, nextTaskIndex_, taskInfo.taskID);
     167           70 :             nextTaskIndex_++;
     168              :         }
     169           73 :         streamEnd = nextTaskIndex_ >= tasks_.size();
     170           73 :         return AICPU_SCHEDULE_OK;
     171           93 :     }
     172              : 
     173           91 :     int32_t AicpuStream::ExecuteTask(const AicpuTaskInfo &kernelTaskInfo, const RunContext &taskContext)
     174              :     {
     175           91 :         if (((kernelTaskInfo.kernelType == static_cast<uint32_t>(AicpuKernelType::CCE_KERNEL)) ||
     176           66 :             (kernelTaskInfo.kernelType == static_cast<uint32_t>(AicpuKernelType::CCE_KERNEL_HWTS))) &&
     177           25 :             (kernelTaskInfo.kernelSo == 0UL)) {
     178           25 :             const int32_t ret = OperatorKernelRegister::Instance().RunOperatorKernel(kernelTaskInfo, taskContext);
     179           25 :             if (ret != AICPU_SCHEDULE_OK) {
     180           17 :                 AicpuModelErrProc::GetInstance().RecordAicpuOpErrLog(taskContext, kernelTaskInfo, ret);
     181              :             }
     182              : 
     183           25 :             return ret;
     184              :         }
     185              : 
     186           66 :         aicpu::HwtsTsKernel aicpufwKernelInfo = {};
     187           66 :         const int32_t ret = ConvertToTsKernel(kernelTaskInfo, aicpufwKernelInfo);
     188           66 :         if (ret != AICPU_SCHEDULE_OK) {
     189            1 :             return ret;
     190              :         }
     191              : 
     192           65 :         AicpuMonitor::GetInstance().SetAicpuStreamTaskStartTime(taskContext.modelId);
     193           65 :         const int32_t retAicpu = aeCallInterface(&aicpufwKernelInfo);
     194           65 :         AicpuMonitor::GetInstance().SetAicpuStreamTaskEndTime(taskContext.modelId);
     195           65 :         if (retAicpu != AE_STATUS_SUCCESS) {
     196            1 :             aicpusd_err("Aicpu engine process failed, result[%d].", retAicpu);
     197            1 :             return retAicpu;
     198              :         }
     199           64 :         aicpusd_info("Aicpu engine process success.");
     200              :         // dump mask.
     201           64 :         if ((kernelTaskInfo.taskFlag & AICPU_STREAM_TASK_DUMP_MASK) != 0U) {
     202            1 :             OpDumpTaskManager &opDumpTaskMgr = OpDumpTaskManager::GetInstance();
     203            1 :             TaskInfoExt dumpTaskInfo(taskContext.streamId, kernelTaskInfo.taskID);
     204            1 :             DumpFileName dumpFileName(taskContext.streamId, kernelTaskInfo.taskID);
     205            1 :             if (opDumpTaskMgr.DumpOpInfo(dumpTaskInfo, dumpFileName) != AICPU_SCHEDULE_OK) {
     206            1 :                 aicpusd_warn("dump op info failed, modelId[%u], streamId[%u], taskID[%u].", taskContext.modelId,
     207              :                     taskContext.streamId, kernelTaskInfo.taskID);
     208              :             }
     209              :         }
     210           64 :         return AICPU_SCHEDULE_OK;
     211              :     }
     212              : 
     213           67 :     int32_t AicpuStream::ConvertToTsKernel(const AicpuTaskInfo &kernelTaskInfo,
     214              :                                            aicpu::HwtsTsKernel &aicpufwKernelInfo)
     215              :     {
     216           67 :         aicpufwKernelInfo.kernelType = kernelTaskInfo.kernelType;
     217           67 :         if (kernelTaskInfo.kernelType == static_cast<uint32_t>(AicpuKernelType::FWK_KERNEL)) {
     218           65 :             aicpufwKernelInfo.kernelBase.fwkKernel.kernel = kernelTaskInfo.paraBase;
     219            2 :         } else if ((kernelTaskInfo.kernelType == static_cast<uint32_t>(AicpuKernelType::CCE_KERNEL)) ||
     220            1 :                 (kernelTaskInfo.kernelType == static_cast<uint32_t>(AicpuKernelType::CCE_KERNEL_HWTS))) {
     221            1 :             aicpufwKernelInfo.kernelBase.cceKernel.kernelName = kernelTaskInfo.kernelName;
     222            1 :             aicpufwKernelInfo.kernelBase.cceKernel.kernelSo = kernelTaskInfo.kernelSo;
     223            1 :             aicpufwKernelInfo.kernelBase.cceKernel.paramBase = kernelTaskInfo.paraBase;
     224              :         } else {
     225            1 :             aicpusd_err("task[%u] kernelType[%u] is invalid.", kernelTaskInfo.taskID, kernelTaskInfo.kernelType);
     226            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     227              :         }
     228           66 :         return AICPU_SCHEDULE_OK;
     229              :     }
     230              : 
     231           14 :     int32_t AicpuStream::AttachReportStatusQueue()
     232              :     {
     233           14 :         const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
     234           96 :         for (auto &taskInfo : tasks_) {
     235           86 :             const auto kernelName = PtrToPtr<const void, const char_t>(ValueToPtr(taskInfo.kernelName));
     236           86 :             if (kernelName == nullptr) {
     237            2 :                 aicpusd_err("the name of kernel is nullptr.");
     238            4 :                 return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     239              :             }
     240          168 :             if (std::string(kernelName) == REPORT_STATUS_TASK_NAME) {
     241              :                 const ReportStatusInfo * const bufInfo =
     242            3 :                     PtrToPtr<void, ReportStatusInfo>(ValueToPtr(static_cast<uintptr_t>(taskInfo.paraBase)));
     243            3 :                 if (bufInfo == nullptr) {
     244            1 :                     aicpusd_err("ModelReportStatus kernelTaskInfo paramBase is null, streamId[%u], taskId[%u]",
     245              :                         taskInfo.streamID, taskInfo.taskID);
     246            1 :                     return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     247              :                 }
     248            2 :                 const uint32_t queueId = bufInfo->statusOutputQueue.queueId;
     249            2 :                 const auto drvRet = halQueueAttach(deviceId, queueId, 0);
     250            2 :                 if (drvRet != DRV_ERROR_NONE) {
     251            1 :                     aicpusd_err("Aicpusd attach report status queue[%u] failed, ret[%d]",
     252              :                         queueId, drvRet);
     253            1 :                     return AICPU_SCHEDULE_ERROR_FROM_DRV;
     254              :                 }
     255            1 :                 aicpusd_info("Attach report status queue[%u] success.", queueId);
     256              :             }
     257              :         }
     258           10 :         return AICPU_SCHEDULE_OK;
     259              :     }
     260              : 
     261              : 
     262           21 :     int32_t AicpuModel::ModelLoad(const AicpuModelInfo * const modelInfo, const ModelCfgInfo * const cfgInfo)
     263              :     {
     264              :         (void)cfgInfo;
     265           21 :         if (modelInfo == nullptr) {
     266            1 :             aicpusd_err("Model load failed, as param is null.");
     267            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     268              :         }
     269           20 :         const auto modelId = modelInfo->moduleID;
     270              :         // need lock all load period
     271           20 :         std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     272           20 :         if (!lockForModel.owns_lock()) {
     273            1 :             aicpusd_err("Model[%u] load failed, as get lock failed.", modelId);
     274            1 :             return AICPU_SCHEDULE_ERROR_IN_WORKING;
     275              :         }
     276              : 
     277           19 :         modelId_ = modelId;
     278           19 :         modelTsId_ = modelInfo->tsId;
     279           19 :         int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_LOAD);
     280           19 :         if (ret != AICPU_SCHEDULE_OK) {
     281            1 :             aicpusd_err("Model[%u] checkOperateAndUpdateStatus failed, ret[%d].", modelId, ret);
     282            1 :             return ret;
     283              :         }
     284           18 :         aicpusd_info("Model[%u] load begin.", modelId);
     285           18 :         ret = LoadStreamAndTask(modelInfo);
     286           18 :         if (ret != AICPU_SCHEDULE_OK) {
     287            4 :             lockForModel.unlock();
     288            4 :             aicpusd_err("Model[%u] load stream and task failed , ret[%d].", modelId, ret);
     289            4 :             const int32_t destroyRet = ModelDestroy();
     290            4 :             if (destroyRet != AICPU_SCHEDULE_OK) {
     291            1 :                 aicpusd_err("Model[%u] load stream and task failed and rollback failed, rollback ret[%d].",
     292              :                             modelId, destroyRet);
     293              :             }
     294            4 :             return ret;
     295              :         }
     296              : 
     297              :         // load queue info
     298           14 :         ret = LoadQueueInfo(modelInfo);
     299           14 :         if (ret != AICPU_SCHEDULE_OK) {
     300            2 :             lockForModel.unlock();
     301            2 :             aicpusd_err("Model[%u] load queue info failed, ret[%d].", modelId, ret);
     302            2 :             const int32_t destroyRet = ModelDestroy();
     303            2 :             if (destroyRet != AICPU_SCHEDULE_OK) {
     304            1 :                 aicpusd_err("Model[%u] load queue info failed and rollback failed, rollback ret[%d].",
     305              :                             modelId, destroyRet);
     306              :             }
     307            2 :             aicpusd_info("Model[%u] rollback end.", modelId);
     308            2 :             return ret;
     309              :         }
     310              : 
     311              :         // attach report status queue
     312           12 :         ret = AttachReportStatusQueue();
     313           12 :         if (ret != AICPU_SCHEDULE_OK) {
     314            2 :             lockForModel.unlock();
     315            2 :             aicpusd_err("Model[%u] attach report status queue failed, ret[%d].", modelId, ret);
     316            2 :             const int32_t destroyRet = ModelDestroy();
     317            2 :             if (destroyRet != AICPU_SCHEDULE_OK) {
     318            1 :                 aicpusd_err("Model[%u] attach report status queue failed and rollback failed, rollback ret[%d].",
     319              :                             modelId, destroyRet);
     320              :             }
     321            2 :             aicpusd_info("Model[%u] rollback end.", modelId);
     322            2 :             return ret;
     323              :         }
     324              : 
     325              :         // load success set isValid true;
     326           10 :         SetExtModelId(AicpuModelManager::GetInstance().GetExtModelId(modelId));
     327           10 :         isValid = true;
     328           10 :         endOfSequence_ = false;
     329           10 :         abnormalBreak_ = AicpuModelManager::GetInstance().AbnormalBreak(modelId);
     330           10 :         abnormalEnqueue_ = AicpuModelManager::GetInstance().AbnormalEnqueue(modelId);
     331           10 :         abnormalEnabled_ = AicpuModelManager::GetInstance().AbnormalEnabled(modelId);
     332           10 :         aicpusd_info("Model[%u] load success, abnormal break[%d], abnormal enqueue[%d], abnormal enabled[%d].",
     333              :                      modelId, static_cast<int32_t>(abnormalBreak_), static_cast<int32_t>(abnormalEnqueue_),
     334              :                      static_cast<int32_t>(abnormalEnabled_));
     335           10 :         int32_t msgQId = 0;
     336           10 :         if (AicpuModelManager::GetInstance().GetModelMsgQueues(modelId, true, msgQId) == AICPU_SCHEDULE_OK) {
     337            1 :             aicpusd_info("Model[%u]'s input msg queue is %d", modelId, msgQId);
     338            1 :             inputMsgQueueIds_.insert(static_cast<size_t>(msgQId));
     339              :         }
     340           10 :         if (AicpuModelManager::GetInstance().GetModelMsgQueues(modelId, false, msgQId) == AICPU_SCHEDULE_OK) {
     341            1 :             aicpusd_info("Model[%u]'s output msg queue is %d", modelId, msgQId);
     342            1 :             outputMsgQueueIds_.insert(static_cast<size_t>(msgQId));
     343              :         }
     344           10 :         return AICPU_SCHEDULE_OK;
     345           20 :     }
     346              : 
     347           13 :     int32_t AicpuModel::ModelExecute()
     348              :     {
     349              :         {
     350           13 :             const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     351           13 :             if (!lockForModel.owns_lock()) {
     352            1 :                 aicpusd_err("Model[%u] execute failed, as get lock failed.", modelId_);
     353            1 :                 return AICPU_SCHEDULE_ERROR_IN_WORKING;
     354              :             }
     355           12 :             const int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_EXECUTE);
     356           12 :             if (ret != AICPU_SCHEDULE_OK) {
     357            1 :                 aicpusd_err("Model[%u] checkOperateAndUpdateStatus failed, ret[%d].", modelId_, ret);
     358            1 :                 return ret;
     359              :             }
     360           13 :         }
     361              : 
     362           11 :         const int32_t ret = ResetModelForExecute();
     363           11 :         if (ret != AICPU_SCHEDULE_OK) {
     364            2 :             aicpusd_err("model[%u] ResetModelForExecute fail", modelId_);
     365            2 :             return ret;
     366              :         }
     367            9 :         const bool isProfOpen = (&(aicpu::IsModelProfOpen) == nullptr) ? false : aicpu::IsModelProfOpen();
     368            9 :         aicpusd_info("Model[%u] execute begin, prof model[%d].", modelId_, isProfOpen);
     369            9 :         const bool hasThread = AicpuDrvManager::GetInstance().HasThread();
     370              :         // if model id is invalid, do not report profiling
     371            9 :         if ((!isProfOpen) || (extModelId_ == INVALID_NUMBER)) {
     372            8 :             ActiveOtherAicpuStreams();
     373            8 :             return ExecuteStream(modelS0Stream_, !hasThread);
     374              :         }
     375              :         // report start tag
     376            1 :         aicpu::ProfModelMessage profModelMessage("AICPU_MODEL");
     377              :         (void)profModelMessage.SetAicpuModelId(extModelId_)
     378              :             ->SetDataTagId(MSPROF_AICPU_MODEL_TAG)
     379            1 :             ->SetAicpuModelIterId(static_cast<uint16_t>(iteratorCount_))
     380              :             ->SetAicpuModelTimeStamp(aicpu::GetSystemTick())
     381              :             ->SetAicpuTagId(aicpu::MODEL_EXECUTE_START)
     382              :             ->SetEventId(static_cast<uint16_t>(0U))
     383            1 :             ->SetDeviceId(AicpuDrvManager::GetInstance().GetDeviceId());
     384            1 :         (void)profModelMessage.ReportProfModelMessage();
     385              :         // has thread means no need execute inline
     386            1 :         ActiveOtherAicpuStreams();
     387            1 :         return ExecuteStream(modelS0Stream_, !hasThread);
     388            1 :     }
     389              : 
     390           11 :     void AicpuModel::ActiveOtherAicpuStreams()
     391              :     {
     392           11 :         const bool syncSendFlag = GetCpuMode();
     393           13 :         for (const auto aicpustreamId: otherAicpuStreams_) {
     394            2 :             AICPUSubEventInfo subEventInfo = {};
     395            2 :             subEventInfo.modelId = modelId_;
     396            2 :             subEventInfo.para.streamInfo.streamId = aicpustreamId;
     397              : 
     398            2 :             const int32_t ret = AicpuMsgSend::SendAICPUSubEvent(
     399              :                 PtrToPtr<AICPUSubEventInfo, const char_t>(&subEventInfo),
     400              :                 static_cast<uint32_t>(sizeof(AICPUSubEventInfo)),
     401              :                 AICPU_SUB_EVENT_ACTIVE_STREAM,
     402              :                 CP_DEFAULT_GROUP_ID,
     403              :                 syncSendFlag);
     404            2 :             if (ret != AICPU_SCHEDULE_OK) {
     405            1 :                 aicpusd_err("Send aicpu subevent failed. Event modelId is %d, streamId: %u", modelId_, aicpustreamId);
     406              :             };
     407              :         }
     408           11 :     }
     409              : 
     410            8 :     int32_t AicpuModel::TaskReport()
     411              :     {
     412            8 :         const int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_TASK_REPORT);
     413            8 :         if (ret != AICPU_SCHEDULE_OK) {
     414            5 :             aicpusd_err("Model[%u] taskReport failed, as CheckOperateAndUpdateStatus failed ret[%d].", modelId_, ret);
     415            5 :             return ret;
     416              :         }
     417              : 
     418            3 :         aicpusd_info("Model[%u] task report success", modelId_);
     419            3 :         return AICPU_SCHEDULE_OK;
     420              :     }
     421              : 
     422            7 :     int32_t AicpuModel::ModelAbort()
     423              :     {
     424              :         // need lock all abort period
     425            7 :         const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     426            7 :         if (!lockForModel.owns_lock()) {
     427            1 :             aicpusd_err("Model[%u] abort failed, as get lock failed.", modelId_);
     428            1 :             return AICPU_SCHEDULE_ERROR_IN_WORKING;
     429              :         }
     430            6 :         int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_ABORT);
     431            6 :         if (ret != AICPU_SCHEDULE_OK) {
     432            4 :             aicpusd_err("Model[%u] abort failed, as CheckOperateAndUpdateStatus failed ret[%d].", modelId_, ret);
     433            4 :             return ret;
     434              :         }
     435              : 
     436            2 :         aicpusd_info("Model[%u] abort begin.", modelId_);
     437            2 :         ret = ReleaseModelResource();
     438            2 :         if (ret != AICPU_SCHEDULE_OK) {
     439            1 :             aicpusd_err("Model[%u] abort failed, as ReleaseModelResource failed ret[%d].", modelId_, ret);
     440            1 :             return ret;
     441              :         }
     442              :         {
     443              :             // use write lock to wait stream execute end, don't remove it.
     444            1 :             (void)pthread_rwlock_wrlock(&rwlockForStream_);
     445            1 :             (void)pthread_rwlock_unlock(&rwlockForStream_);
     446              :         }
     447              : 
     448            1 :         aicpusd_info("Model[%u] abort success.", modelId_);
     449            1 :         return AICPU_SCHEDULE_OK;
     450            7 :     }
     451              : 
     452           17 :     int32_t AicpuModel::ModelDestroy()
     453              :     {
     454              :         // need lock all destroy period
     455           17 :         const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     456           17 :         if (!lockForModel.owns_lock()) {
     457            1 :             aicpusd_err("Model[%u] destroy failed, as get lock failed.", modelId_);
     458            1 :             return AICPU_SCHEDULE_ERROR_IN_WORKING;
     459              :         }
     460           16 :         int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_DESTROY);
     461           16 :         if (ret != AICPU_SCHEDULE_OK) {
     462            1 :             aicpusd_err("Model[%u] destroy failed, as CheckOperateAndUpdateStatus failed ret[%d].", modelId_, ret);
     463            1 :             return ret;
     464              :         }
     465              : 
     466           15 :         aicpusd_info("Model[%u] destroy begin, isValid=%d", modelId_, isValid);
     467           15 :         isValid = false;
     468              :         // destroy all resource.
     469           15 :         ret = ReleaseModelResource();
     470           15 :         if (ret != AICPU_SCHEDULE_OK) {
     471            1 :             aicpusd_err("Model[%u] destroy failed, as ReleaseModelResource failed ret[%d].", modelId_, ret);
     472            1 :             return ret;
     473              :         }
     474           14 :         ClearLoadInfo();
     475           14 :         aicpusd_info("Model[%u] destroy success", modelId_);
     476           14 :         return AICPU_SCHEDULE_OK;
     477           17 :     }
     478              : 
     479            4 :     int32_t AicpuModel::ModelStop()
     480              :     {
     481            4 :         aicpusd_info("Model[%u] Begin to stop", modelId_);
     482              :         // need lock all destroy period
     483            4 :         const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     484            4 :         if (!lockForModel.owns_lock()) {
     485            1 :             aicpusd_err("Model[%u] destroy failed, as get lock failed.", modelId_);
     486            1 :             return AICPU_SCHEDULE_ERROR_IN_WORKING;
     487              :         }
     488              :         // update status to stop
     489            3 :         int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_STOP);
     490            3 :         if (ret != AICPU_SCHEDULE_OK) {
     491            1 :             aicpusd_err("Model[%u] stop failed, as CheckOperateAndUpdateStatus failed, ret[%d].", modelId_, ret);
     492            1 :             return ret;
     493              :         }
     494              : 
     495            2 :         aicpusd_info("Model[%u] destroy begin, isValid=%d", modelId_, isValid);
     496              :         // destroy all resource.
     497            2 :         ret = ReleaseModelResource();
     498            2 :         if (ret != AICPU_SCHEDULE_OK) {
     499            1 :             aicpusd_err("Model[%u] stop failed, as ReleaseModelResource failed, ret[%d].", modelId_, ret);
     500            1 :             return ret;
     501              :         }
     502              : 
     503              :         // if getlock, then all streams in model is not running, so we can ensure model is stopped
     504            1 :         aicpusd_run_info("Model[%u] try to get stream lock", modelId_);
     505            1 :         (void)pthread_rwlock_wrlock(&rwlockForStream_);
     506            1 :         (void)pthread_rwlock_unlock(&rwlockForStream_);
     507            1 :         aicpusd_run_info("Model[%u] stop success", modelId_);
     508            1 :         return AICPU_SCHEDULE_OK;
     509            4 :     }
     510              : 
     511            4 :     int32_t AicpuModel::ModelRestart()
     512              :     {
     513            4 :         aicpusd_info("Model[%u] begin to restart", modelId_);
     514              :         {
     515              :             // need lock
     516            4 :             const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     517            4 :             if (!lockForModel.owns_lock()) {
     518            1 :                 aicpusd_err("Model[%u] restart failed, as get lock failed.", modelId_);
     519            1 :                 return AICPU_SCHEDULE_ERROR_IN_WORKING;
     520              :             }
     521              :             // update status to recover
     522            3 :             const int32_t updateRet = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_RESTART);
     523            3 :             if (updateRet != AICPU_SCHEDULE_OK) {
     524            1 :                 aicpusd_err("Model[%u] restart failed, as CheckOperateAndUpdateStatus failed, ret[%d].",
     525              :                     modelId_, updateRet);
     526            1 :                 return updateRet;
     527              :             }
     528            2 :             aicpusd_info("Model[%u] change status success", modelId_);
     529            4 :         }
     530              : 
     531            2 :         AICPUSubEventInfo subEventInfo = {};
     532            2 :         subEventInfo.modelId = modelId_;
     533            2 :         const auto ret = AicpuMsgSend::SendAICPUSubEvent(
     534              :             PtrToPtr<AICPUSubEventInfo, const char_t>(&subEventInfo),
     535              :             static_cast<uint32_t>(sizeof(AICPUSubEventInfo)),
     536              :             AICPU_SUB_EVENT_REPEAT_MODEL, CP_DEFAULT_GROUP_ID, true);
     537            2 :         if (ret != AICPU_SCHEDULE_OK) {
     538            1 :             aicpusd_err("Send aicpu subevent failed. Event modelId is %d", modelId_);
     539            1 :             return ret;
     540              :         }
     541            1 :         aicpusd_info("Model[%u] restart success", modelId_);
     542            1 :         return AICPU_SCHEDULE_OK;
     543              :     }
     544              : 
     545            6 :     int32_t AicpuModel::ModelClearInput()
     546              :     {
     547            6 :         aicpusd_info("Model[%u] begin to clearInput", modelId_);
     548              :         // need lock
     549            6 :         const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     550            6 :         if (!lockForModel.owns_lock()) {
     551            1 :             aicpusd_err("Model[%u] clear input failed, as get lock failed.", modelId_);
     552            1 :             return AICPU_SCHEDULE_ERROR_IN_WORKING;
     553              :         }
     554              :         // update status to recover
     555            5 :         const int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_CLEAR_INPUT);
     556            5 :         if (ret != AICPU_SCHEDULE_OK) {
     557            1 :             aicpusd_err("Model[%u] clear input failed, as CheckOperateAndUpdateStatus failed, ret[%d].", modelId_, ret);
     558            1 :             return ret;
     559              :         }
     560              : 
     561            4 :         const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
     562            4 :         auto clearRet = ModelClearInputQueues(inputQueueIds_, deviceId);
     563            4 :         if (clearRet != AICPU_SCHEDULE_OK) {
     564            2 :             aicpusd_err("Failed to clear input queues");
     565            2 :             return clearRet;
     566              :         }
     567              : 
     568            2 :         clearRet = ModelClearInputQueues(inputMsgQueueIds_, deviceId);
     569            2 :         if (clearRet != AICPU_SCHEDULE_OK) {
     570            1 :             aicpusd_err("Failed to clear input msg queues");
     571            1 :             return clearRet;
     572              :         }
     573              : 
     574            1 :         aicpusd_info("Model[%u] clearInput success", modelId_);
     575            1 :         return AICPU_SCHEDULE_OK;
     576            6 :     }
     577              : 
     578            5 :     int32_t AicpuModel::ModelClearInputQueues(const std::unordered_set<size_t> &queueIds, const uint32_t deviceId) const
     579              :     {
     580            8 :         for (const auto queueId : queueIds) {
     581              :             do {
     582            6 :                 void *mbuf = nullptr;
     583            6 :                 const auto ret = halQueueDeQueue(deviceId, queueId, &mbuf);
     584            6 :                 if (ret == DRV_ERROR_QUEUE_EMPTY) {
     585            3 :                     break;
     586              :                 }
     587            3 :                 if ((ret != DRV_ERROR_NONE) || (mbuf == nullptr)) {
     588            2 :                     aicpusd_err("Dequeue from queueId[%u], deviceId[%u] fail, ret is %d", queueId, deviceId,
     589              :                         static_cast<int32_t>(ret));
     590            2 :                     return AICPU_SCHEDULE_ERROR_FROM_DRV;
     591              :                 }
     592            1 :                 (void) halMbufFree(PtrToPtr<void, Mbuf>(mbuf));
     593            1 :             } while (true);
     594              :         }
     595            3 :         return AICPU_SCHEDULE_OK;
     596              :     }
     597              : 
     598        21506 :     int32_t AicpuModel::Exit()
     599              :     {
     600        21506 :         if (IsValid()) {
     601            2 :             isValid = false;
     602            2 :             const std::unique_lock<std::mutex> lockForModel(mutexForModel_);
     603              :             // destroy all resource.
     604            2 :             const int32_t ret = ReleaseModelResource();
     605            2 :             ClearLoadInfo();
     606            2 :             if (ret != AICPU_SCHEDULE_OK) {
     607            1 :                 aicpusd_err("Model[%u] Exit failed, as ReleaseModelResource failed ret[%d].", modelId_, ret);
     608            1 :                 return ret;
     609              :             }
     610            1 :             aicpusd_info("Model[%u] exit", modelId_);
     611            2 :         }
     612        21505 :         return AICPU_SCHEDULE_OK;
     613              :     }
     614              : 
     615            3 :     int32_t AicpuModel::EndGraph()
     616              :     {
     617            3 :         const std::unique_lock<std::mutex> lockForModel(mutexForModel_, std::try_to_lock);
     618            3 :         if (!lockForModel.owns_lock()) {
     619            1 :             aicpusd_err("Model[%u] end graph failed, as get lock failed.", modelId_);
     620            1 :             return AICPU_SCHEDULE_ERROR_IN_WORKING;
     621              :         }
     622            2 :         const int32_t ret = CheckOperateAndUpdateStatus(AicpuModelOperate::MODEL_OPERATE_END_GRAPH);
     623            2 :         if (ret != AICPU_SCHEDULE_OK) {
     624            1 :             aicpusd_err("Model[%u] end graph failed, as CheckOperateAndUpdateStatus failed ret[%d].", modelId_, ret);
     625            1 :             return ret;
     626              :         }
     627            1 :         aicpusd_info("Model[%u] end graph.", modelId_);
     628            1 :         return AICPU_SCHEDULE_OK;
     629            3 :     }
     630              : 
     631            1 :     int32_t AicpuModel::ActiveStream(const uint32_t streamId)
     632              :     {
     633            1 :         aicpusd_info("Model[%u] active stream[%u].", modelId_, streamId);
     634            1 :         return ExecuteStream(streamId, false);
     635              :     }
     636              : 
     637            1 :     int32_t AicpuModel::RecoverStream(const uint32_t streamId)
     638              :     {
     639            1 :         aicpusd_info("Model[%u] recover stream[%u].", modelId_, streamId);
     640            1 :         return ExecuteStream(streamId, false);
     641              :     }
     642              : 
     643           16 :     int32_t AicpuModel::ExecuteStream(const uint32_t streamId, const bool executeInline)
     644              :     {
     645           16 :         aicpusd_info("Model[%u] execute stream[%u] begin.", modelId_, streamId);
     646           16 :         uint32_t currentStreamId = streamId;
     647           16 :         (void)pthread_rwlock_rdlock(&rwlockForStream_);
     648           16 :         AicpuStream *stream = GetStreamByStreamId(currentStreamId);
     649           16 :         if (stream == nullptr) {
     650            4 :             (void)pthread_rwlock_unlock(&rwlockForStream_);
     651            4 :             aicpusd_err("Model[%u] execute stream[%u] failed, stream not found.", modelId_, currentStreamId);
     652            4 :             return AICPU_SCHEDULE_ERROR_STREAM_NOT_FOUND;
     653              :         }
     654           12 :         RunContext runContext = {.modelId = modelId_,
     655           12 :                                  .modelTsId = modelTsId_,
     656              :                                  .streamId = currentStreamId,
     657              :                                  .pending = false,
     658              :                                  .executeInline = executeInline,
     659           12 :                                  .gotoTaskIndex = 0};
     660           12 :         g_aicpuProfiler.SetModelId(modelId_);
     661           12 :         g_aicpuProfiler.SetStreamId(streamId);
     662           12 :         bool streamEnd = false;
     663           12 :         std::stack<uint32_t> streamStack;
     664           12 :         int32_t ret = AICPU_SCHEDULE_OK;
     665              :         while (true) {
     666           94 :             ret = CheckOperate(AicpuModelOperate::MODEL_OPERATE_RUN_TASK);
     667           94 :             if (ret != AICPU_SCHEDULE_OK) {
     668            1 :                 break;
     669              :             }
     670           93 :             ret = stream->ExecuteNextTask(runContext, streamEnd);
     671              :             // check if pending or if error
     672           93 :             if (((ret != AICPU_SCHEDULE_OK) && (!abnormalEnabled_.load())) ||
     673              :                 (ret == AICPU_SCHEDULE_ERROR_TASK_EXECUTE_FAILED)) {
     674            2 :                 break;
     675              :             }
     676              : 
     677              :             // update model ret code
     678           91 :             UpdateModelRetCode(ret);
     679           91 :             if (executeInline) {
     680           74 :                 uint32_t switchStreamId = INVALID_NUMBER;
     681           74 :                 if (currentStreamId != runContext.streamId) {
     682            2 :                     streamStack.emplace(currentStreamId);
     683            2 :                     switchStreamId = runContext.streamId;
     684           72 :                 } else if (streamEnd) {
     685            9 :                     if (!streamStack.empty()) {
     686            1 :                         switchStreamId = streamStack.top();
     687            1 :                         streamStack.pop();
     688              :                     }
     689              :                 } else {
     690              :                     // do nothing
     691              :                 }
     692           74 :                 if (switchStreamId != INVALID_NUMBER) {
     693            3 :                     currentStreamId = switchStreamId;
     694            3 :                     runContext.streamId = currentStreamId;
     695            3 :                     stream = GetStreamByStreamId(currentStreamId);
     696            3 :                     if (stream == nullptr) {
     697            1 :                         aicpusd_err("Model[%u] execute stream[%u] failed as stream[%u] not found.",
     698              :                                     modelId_, streamId, currentStreamId);
     699            1 :                         ret = AICPU_SCHEDULE_ERROR_STREAM_NOT_FOUND;
     700            1 :                         break;
     701              :                     }
     702            2 :                     continue;
     703              :                 }
     704              :             }
     705              :             // not inline, when pending or stream end, exit.
     706           88 :             if (runContext.pending || streamEnd) {
     707              :                 break;
     708              :             }
     709           82 :         }
     710           12 :         (void)pthread_rwlock_unlock(&rwlockForStream_);
     711           12 :         if (ret != AICPU_SCHEDULE_OK) {
     712            4 :             aicpusd_err("Model[%u] execute stream[%u] failed currentStreamId[%u], ret[%d].",
     713              :                         modelId_, streamId, currentStreamId, ret);
     714              :             // execute failed, need taskReport.
     715            4 :             (void)TaskReport();
     716            4 :             ProcessModelException(modelId_);
     717            4 :             return ret;
     718              :         }
     719            8 :         aicpusd_info("Model[%u] execute stream[%u] success.", modelId_, streamId);
     720            8 :         return AICPU_SCHEDULE_OK;
     721           12 :     }
     722              : 
     723           91 :     void AicpuModel::UpdateModelRetCode(const int32_t retCode)
     724              :     {
     725          107 :         if ((retCode != 0) && (abnormalEnabled_.load()) && (retCode_.load() == 0)) {
     726            1 :             retCode_ = retCode + INNER_ERROR_BASE;
     727            2 :             aicpusd_run_info("Update Model[%u] retCode to %d", modelId_, retCode_.load());
     728              :         }
     729           91 :     }
     730              : 
     731           12 :     int32_t AicpuModel::AttachReportStatusQueue()
     732              :     {
     733           12 :         int32_t ret = AICPU_SCHEDULE_OK;
     734           12 :         (void)pthread_rwlock_wrlock(&rwlockForStream_);
     735           22 :         for (auto &it : aicpuStreams_) {
     736           12 :             ret = it.second.AttachReportStatusQueue();
     737           12 :             if (ret != AICPU_SCHEDULE_OK) {
     738            2 :                 break;
     739              :             }
     740              :         }
     741           12 :         (void)pthread_rwlock_unlock(&rwlockForStream_);
     742           12 :         return ret;
     743              :     }
     744              : 
     745              : 
     746              :     // attention: must get rwlockForStream_ lock out side.
     747           13 :     AicpuStream *AicpuModel::GetStreamByStreamId(const uint32_t streamId)
     748              :     {
     749           13 :         const auto iter = aicpuStreams_.find(streamId);
     750           13 :         if (iter != aicpuStreams_.end()) {
     751           10 :             return &(iter->second);
     752              :         }
     753            3 :         return nullptr;
     754              :     }
     755              : 
     756            2 :     int32_t AicpuModel::ModelRepeat()
     757              :     {
     758            2 :         aicpusd_info("Model[%u] ExtModel[%u] repeat begin.", modelId_, extModelId_);
     759            2 :         const bool isProfOpen = (&(aicpu::IsModelProfOpen) == nullptr) ? false : aicpu::IsModelProfOpen();
     760            2 :         if (isProfOpen && (extModelId_ != INVALID_NUMBER)) {
     761              :             // report end tag
     762            1 :             aicpu::ProfModelMessage profModelMessage("AICPU_MODEL");
     763              :             (void)profModelMessage.SetAicpuModelId(extModelId_)
     764              :                 ->SetDataTagId(MSPROF_AICPU_MODEL_TAG)
     765            1 :                 ->SetAicpuModelIterId(static_cast<uint16_t>(iteratorCount_))
     766              :                 ->SetAicpuModelTimeStamp(aicpu::GetSystemTick())
     767              :                 ->SetAicpuTagId(aicpu::MODEL_EXECUTE_END)
     768              :                 ->SetEventId(static_cast<uint16_t>(0U))
     769            1 :                 ->SetDeviceId(AicpuDrvManager::GetInstance().GetDeviceId());
     770            1 :             (void)profModelMessage.ReportProfModelMessage();
     771            1 :             aicpusd_info("ReportProfModelMessage done, iterateId=%llu", iteratorCount_);
     772            1 :         }
     773            2 :         iteratorCount_++;
     774            2 :         return ModelExecute();
     775              :     }
     776              : 
     777            6 :     void AicpuModel::ProcessModelException(const uint32_t modelId) const
     778              :     {
     779            6 :         if (AbnormalNeedBreak()) {
     780            2 :             return;
     781              :         }
     782              :         uint32_t runMode;
     783            5 :         const aicpu::status_t ret = aicpu::GetAicpuRunMode(runMode);
     784            5 :         if (ret != aicpu::AICPU_ERROR_NONE) {
     785            1 :             aicpusd_err("GetAicpuRunMode returned [%u]", ret);
     786            1 :             return;
     787              :         }
     788              :         // continue to execute the model.
     789            4 :         if (runMode == aicpu::AicpuRunMode::PROCESS_SOCKET_MODE) {
     790            4 :             AICPUSubEventInfo subEventInfo = {};
     791            4 :             subEventInfo.modelId = modelId;
     792            4 :             const int32_t result = AicpuMsgSend::SendAICPUSubEvent(
     793              :                 PtrToPtr<AICPUSubEventInfo, const char_t>(&subEventInfo),
     794              :                 static_cast<uint32_t>(sizeof(AICPUSubEventInfo)),
     795              :                 AICPU_SUB_EVENT_REPEAT_MODEL, CP_DEFAULT_GROUP_ID, false);
     796            4 :             if (result != AICPU_SCHEDULE_OK) {
     797            1 :                 aicpusd_err("Send aicpu subevent failed. Event modelId is %d", modelId);
     798              :             }
     799              :         }
     800              :     }
     801              : 
     802           11 :     int32_t AicpuModel::ResetModelForExecute()
     803              :     {
     804           11 :         const int32_t ret = ReleaseModelResource();
     805           11 :         if (ret != AICPU_SCHEDULE_OK) {
     806            3 :             return ret;
     807              :         }
     808              : 
     809            8 :         SetModelRetCode(0);
     810            8 :         SetModelTransId(UINT64_MAX);
     811              : 
     812            8 :         (void)pthread_rwlock_wrlock(&rwlockForStream_);
     813           15 :         for (auto &it : aicpuStreams_) {
     814            7 :             it.second.ResetToStart();
     815              :         }
     816            8 :         (void)pthread_rwlock_unlock(&rwlockForStream_);
     817            8 :         return AICPU_SCHEDULE_OK;
     818              :     }
     819              : 
     820           47 :     int32_t AicpuModel::CheckOperateAndUpdateStatus(const AicpuModelOperate operate)
     821              :     {
     822           47 :         const std::unique_lock<std::mutex> lockForModelStatus(mutexForModelStatus_);
     823           47 :         const int32_t operateIndex = static_cast<int32_t>(operate);
     824           47 :         if (!modelOperatePermission[static_cast<int32_t>(modelStatus_)][operateIndex]) {
     825            7 :             aicpusd_err("Model[%u] status[%s] is not allow operate[%s].",
     826              :                         modelId_,
     827              :                         STATUS_VALUE[static_cast<int32_t>(modelStatus_)].c_str(),
     828              :                         OPERATE_VALUE[operateIndex].c_str());
     829            7 :             return AICPU_SCHEDULE_ERROR_MODEL_STATUS_NOT_ALLOW_OPERATE;
     830              :         }
     831           40 :         const AicpuModelStatus dstStatus = operateNextStatus[operateIndex];
     832           40 :         if ((dstStatus < AicpuModelStatus::MODEL_STATUS_MAX) && (dstStatus != modelStatus_)) {
     833           37 :             aicpusd_info("Model[%u] status change from [%s] to [%s] as operate[%s].",
     834              :                          modelId_,
     835              :                          STATUS_VALUE[static_cast<int32_t>(modelStatus_)].c_str(),
     836              :                          STATUS_VALUE[static_cast<int32_t>(dstStatus)].c_str(),
     837              :                          OPERATE_VALUE[operateIndex].c_str());
     838           37 :             modelStatus_ = dstStatus;
     839              :         }
     840           40 :         return AICPU_SCHEDULE_OK;
     841           47 :     }
     842              : 
     843           73 :     int32_t AicpuModel::CheckOperate(const AicpuSchedule::AicpuModelOperate operate)
     844              :     {
     845           73 :         const std::unique_lock<std::mutex> lockForModelStatus(mutexForModelStatus_);
     846           73 :         if (modelOperatePermission[static_cast<size_t>(modelStatus_)][static_cast<size_t>(operate)]) {
     847           71 :             return AICPU_SCHEDULE_OK;
     848              :         }
     849            2 :         aicpusd_err("Model[%u] status[%s] is not allow operate[%s].",
     850              :                     modelId_,
     851              :                     STATUS_VALUE[static_cast<size_t>(modelStatus_)].c_str(),
     852              :                     OPERATE_VALUE[static_cast<size_t>(operate)].c_str());
     853            2 :         return AICPU_SCHEDULE_ERROR_MODEL_STATUS_NOT_ALLOW_OPERATE;
     854           73 :     }
     855              : 
     856           29 :     int32_t AicpuModel::UnGardModelBuf(Mbuf *const mbuf)
     857              :     {
     858           29 :         const std::unique_lock<std::mutex> lockForBufFree(mutexForMbuffList_);
     859           58 :         return BufManager::GetInstance().UnGuardBuf(modelId_, mbuf);
     860           29 :     }
     861              : 
     862           28 :     int32_t AicpuModel::ReleaseModelResource()
     863              :     {
     864           28 :         prepareData_.dequeueIndex = 0U;
     865           28 :         prepareData_.lastInputMbuflistPtr = nullptr;
     866           28 :         inputDataPtrs_.clear();
     867           28 :         postpareData_.enqueueIndex = 0U;
     868           28 :         endOfSequence_ = false;
     869           28 :         retCode_ = 0;
     870           28 :         nullDataFlag_ = false;
     871              :         {
     872           28 :             const std::unique_lock<std::mutex> lockForBufFree(mutexForMbuffList_);
     873           28 :             BufManager::GetInstance().FreeBuf(modelId_);
     874           28 :         }
     875           56 :         (void)EventWaitManager::EndGraphWaitManager().ClearBatch({modelId_});
     876           56 :         (void)EventWaitManager::PrepareMemWaitManager().ClearBatch({modelId_});
     877           56 :         (void)EventWaitManager::AnyQueNotEmptyWaitManager().ClearBatch({modelId_});
     878           56 :         (void)EventWaitManager::TableUnlockWaitManager().ClearBatch({modelId_});
     879              :         {
     880           28 :             const std::unique_lock<std::mutex> lockForModelNotifyId(mutexForModelNotifyId_);
     881           28 :             (void)EventWaitManager::NotifyWaitManager().ClearBatch(modelNotifyId_);
     882           28 :         }
     883              :         {
     884           28 :             const std::unique_lock<std::mutex> lockForQueue(mutexForQueueEventSubscribed_);
     885           28 :             int32_t ret = EventWaitManager::QueueNotEmptyWaitManager().ClearBatch(inputQueueIds_);
     886           28 :             if (ret != AICPU_SCHEDULE_OK) {
     887            1 :                 return ret;
     888              :             }
     889           27 :             ret = EventWaitManager::QueueNotFullWaitManager().ClearBatch(outputQueueIds_);
     890           27 :             if (ret != AICPU_SCHEDULE_OK) {
     891            1 :                 return ret;
     892              :             }
     893           28 :         }
     894              : 
     895           26 :         int32_t msgRet = EventWaitManager::QueueNotEmptyWaitManager().ClearBatch(inputMsgQueueIds_);
     896           26 :         if (msgRet != AICPU_SCHEDULE_OK) {
     897            1 :             return msgRet;
     898              :         }
     899           25 :         msgRet = EventWaitManager::QueueNotFullWaitManager().ClearBatch(outputMsgQueueIds_);
     900           25 :         if (msgRet != AICPU_SCHEDULE_OK) {
     901            1 :             return msgRet;
     902              :         }
     903              : 
     904           24 :         ClearAllLockedTable();
     905           24 :         return AICPU_SCHEDULE_OK;
     906              :     }
     907              : 
     908           23 :     int32_t AicpuModel::LoadStreamAndTask(const AicpuModelInfo * const modelInfo)
     909              :     {
     910           23 :         if (static_cast<int32_t>(modelInfo->streamInfoNum) == 0) {
     911            3 :             aicpusd_err("Load model[%u] failed as stream num is 0.", modelId_);
     912            3 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     913              :         }
     914              : 
     915           20 :         const auto infoPtr = reinterpret_cast<const StreamInfo *>(static_cast<uintptr_t>(modelInfo->streamInfoPtr));
     916           20 :         if (infoPtr == nullptr) {
     917            1 :             aicpusd_err("Load model[%u] failed as streamInfoPtr is null.", modelId_);
     918            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     919              :         }
     920              : 
     921           19 :         (void)pthread_rwlock_wrlock(&rwlockForStream_);
     922           19 :         modelS0Stream_ = INVALID_NUMBER;
     923              :         // collect all stream information in the model.
     924          110 :         for (uint32_t i = 0U; i < static_cast<uint32_t>(modelInfo->streamInfoNum); i++) {
     925           92 :             auto &streamInfo = infoPtr[i];
     926           92 :             allStreams_.emplace_back(streamInfo);
     927           92 :             aicpusd_info("Load model[%u] stream[%u]", modelId_, streamInfo.streamID);
     928           92 :             if ((streamInfo.streamFlag & AICPU_STREAM_INDEX) != 0U) {
     929           17 :                 if ((streamInfo.streamFlag & HEAD_STREAM_INDEX) == 0U) {
     930            0 :                     otherAicpuStreams_.emplace_back(streamInfo.streamID);
     931            0 :                     continue;
     932              :                 }
     933           17 :                 if (modelS0Stream_ != INVALID_NUMBER) {
     934            1 :                     (void)pthread_rwlock_unlock(&rwlockForStream_);
     935            1 :                     aicpusd_err("load model[%u] failed as stream[%u] and stream[%u] are both s0 stream.",
     936              :                                 modelId_, modelS0Stream_, streamInfo.streamID);
     937            1 :                     return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     938              :                 }
     939           16 :                 aicpusd_info("Load model[%u] modelS0Stream[%u]", modelId_, streamInfo.streamID);
     940           16 :                 modelS0Stream_ = streamInfo.streamID;
     941              :             } else {
     942           75 :                 if (reportStream_ == INVALID_NUMBER) {
     943            6 :                     aicpusd_info("Load model[%u] reportStream[%u].", modelId_, streamInfo.streamID);
     944            6 :                     reportStream_ = streamInfo.streamID;
     945              :                 }
     946              :             }
     947              :         }
     948           18 :         if (modelS0Stream_ == INVALID_NUMBER) {
     949            3 :             (void)pthread_rwlock_unlock(&rwlockForStream_);
     950            3 :             aicpusd_err("load model[%u] failed as no s0 stream found.", modelId_);
     951            3 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     952              :         }
     953              : 
     954           15 :         ModelStreamManager::GetInstance().Reg(modelId_, allStreams_);
     955           15 :         const auto aicpuTaskNum = modelInfo->aicpuTaskNum;
     956           15 :         if (static_cast<int32_t>(aicpuTaskNum) == 0) {
     957            1 :             (void)pthread_rwlock_unlock(&rwlockForStream_);
     958            1 :             aicpusd_err("load model[%u] failed as aicpuTaskNum is 0.", modelId_);
     959            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     960              :         }
     961           14 :         const auto taskPtr = PtrToPtr<void, AicpuTaskInfo>(ValueToPtr(modelInfo->aicpuTaskPtr));
     962           14 :         if (taskPtr == nullptr) {
     963            1 :             (void)pthread_rwlock_unlock(&rwlockForStream_);
     964            1 :             aicpusd_err("Load model[%u] failed as aicpuTaskPtr is null.", modelId_);
     965            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     966              :         }
     967              : 
     968           13 :         std::unordered_map<uint32_t, std::vector<const AicpuTaskInfo *>> streamTasks;
     969           98 :         for (size_t i = 0U; i < aicpuTaskNum; i++) {
     970           85 :             const uint32_t streamId = taskPtr[i].streamID;
     971           85 :             LoadWaitNotifyId(taskPtr[i], modelNotifyId_);
     972           85 :             streamTasks[streamId].emplace_back(&taskPtr[i]);
     973           85 :             aicpusd_info("Task: taskID[%u], streamId[%u], kernelType[%u], "
     974              :                          "kernelName[%lu], kernelSo[%lu], taskFlag[%u].",
     975              :                          taskPtr[i].taskID, taskPtr[i].streamID, taskPtr[i].kernelType,
     976              :                          taskPtr[i].kernelName, taskPtr[i].kernelSo, taskPtr[i].taskFlag);
     977              :         }
     978              : 
     979           26 :         for (auto &streamTask : streamTasks) {
     980           13 :             aicpuStreams_[streamTask.first].InitAicpuStream(streamTask.first, streamTask.second);
     981           13 :             aicpusd_info("Model[%u] aicpu stream[%u] has %zu tasks.",
     982              :                          modelId_, streamTask.first, streamTask.second.size());
     983              :         }
     984           13 :         (void)pthread_rwlock_unlock(&rwlockForStream_);
     985           13 :         return AICPU_SCHEDULE_OK;
     986           13 :     }
     987              : 
     988           88 :     void AicpuModel::LoadWaitNotifyId(const AicpuTaskInfo &aicpuTaskInfo,
     989              :                                       std::unordered_set<size_t> &waitNotifyIdSet) const
     990              :     {
     991           88 :         if ((aicpuTaskInfo.kernelSo != 0U) || ((aicpuTaskInfo.kernelType != aicpu::KERNEL_TYPE_CCE) &&
     992           28 :                                               (aicpuTaskInfo.kernelType != aicpu::KERNEL_TYPE_AICPU))) {
     993           74 :             return;
     994              :         }
     995           14 :         const auto kernelName = PtrToPtr<void, char_t>(ValueToPtr(aicpuTaskInfo.kernelName));
     996           38 :         if ((kernelName == nullptr) || (std::string(kernelName) != "waitNotify")) {
     997           12 :             return;
     998              :         }
     999            2 :         const auto notifyId = PtrToPtr<void, uint32_t>(ValueToPtr(aicpuTaskInfo.paraBase));
    1000            2 :         if (notifyId == nullptr) {
    1001            1 :             aicpusd_warn("Stream[%u] taskId[%u] is waitNotify, but paraBase is null.",
    1002              :                          aicpuTaskInfo.streamID, aicpuTaskInfo.taskID);
    1003            1 :             return;
    1004              :         }
    1005            1 :         (void)waitNotifyIdSet.emplace(*notifyId);
    1006            1 :         aicpusd_info("Model[%u] stream[%u] taskId[%u] use notifyId[%u]",
    1007              :                      modelId_, aicpuTaskInfo.streamID, aicpuTaskInfo.taskID, *notifyId);
    1008              :     }
    1009              : 
    1010           28 :     int32_t AicpuModel::LoadQueueInfo(const AicpuModelInfo * const modelInfo)
    1011              :     {
    1012           28 :         aicpusd_info("LoadQueueInfo for model[%u] begin.", modelId_);
    1013           28 :         if (static_cast<int32_t>(modelInfo->queueSize) == 0) {
    1014           11 :             aicpusd_info("Model[%u] queueSize is 0, no need load queue info.", modelId_);
    1015           11 :             return AICPU_SCHEDULE_OK;
    1016              :         }
    1017           17 :         aicpusd_info("Task queue size[%u].", modelInfo->queueSize);
    1018           17 :         const auto infoPtr = PtrToPtr<void, QueInfo>(ValueToPtr(modelInfo->queueInfoPtr));
    1019           17 :         if (infoPtr == nullptr) {
    1020            3 :             aicpusd_info("Model[%u] load was not successful, as queueSize[%u] but queueInfoPtr is null.",
    1021              :                          modelId_, modelInfo->queueSize);
    1022            3 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
    1023              :         }
    1024              : 
    1025           14 :         const std::unique_lock<std::mutex> lockForQueue(mutexForQueueEventSubscribed_);
    1026           14 :         const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
    1027           14 :         auto drvRet = halQueueInit(deviceId);
    1028           14 :         if ((drvRet != DRV_ERROR_NONE) && (drvRet != DRV_ERROR_REPEATED_INIT)) {
    1029            1 :             aicpusd_err("halQueueInit error, deviceId[%u], ret[%d]", deviceId, drvRet);
    1030            1 :             return AICPU_SCHEDULE_ERROR_FROM_DRV;
    1031              :         }
    1032           13 :         int32_t ret = AICPU_SCHEDULE_OK;
    1033           21 :         for (int32_t i = 0; i < static_cast<int32_t>(modelInfo->queueSize); i++) {
    1034           13 :             if (infoPtr[i].flag == static_cast<uint32_t>(QueueDirectionFlag::QUEUE_CLIENT_INPUT_FLAG) ||
    1035           12 :                 infoPtr[i].flag == static_cast<uint32_t>(QueueDirectionFlag::QUEUE_CLIENT_OUTPUT_FLAG)) {
    1036            1 :                 aicpusd_info("it is qlient qs flag[%d] = [%u]", i, infoPtr[i].flag);
    1037            1 :                 continue;
    1038              :             }
    1039           12 :             if (infoPtr[i].flag == static_cast<uint32_t>(QueueDirectionFlag::QUEUE_INPUT_FLAG)) {
    1040            8 :                 QueueSetInputPara inPutParam = {};
    1041            8 :                 QueueSetInput inPut = {};
    1042            8 :                 inPut.queSetWorkMode.qid = infoPtr[i].queueID;
    1043            8 :                 inPut.queSetWorkMode.workMode = QUEUE_MODE_PULL;
    1044            8 :                 inPutParam.inBuff = static_cast<void *>(&inPut);
    1045            8 :                 inPutParam.inLen = static_cast<uint32_t>(sizeof(QueueSetInput));
    1046            8 :                 drvRet = halQueueAttach(deviceId, infoPtr[i].queueID, 0);
    1047            8 :                 if (drvRet != DRV_ERROR_NONE) {
    1048            1 :                     aicpusd_err("Aicpusd attached queue[%u] failed ret[%d]", infoPtr[i].queueID, drvRet);
    1049            2 :                     return AICPU_SCHEDULE_ERROR_FROM_DRV;
    1050              :                 }
    1051            7 :                 drvRet = halQueueSet(0U, QUEUE_SET_WORK_MODE, &inPutParam);
    1052            7 :                 if (drvRet != DRV_ERROR_NONE) {
    1053            1 :                     aicpusd_err("Aicpusd set work mode for queue[%u] failed ret[%d]", infoPtr[i].queueID,
    1054              :                         static_cast<int32_t>(drvRet));
    1055            1 :                     return AICPU_SCHEDULE_ERROR_FROM_DRV;
    1056              :                 }
    1057            6 :                 ret = AicpuDrvManager::GetInstance().SubscribeQueueNotEmptyEvent(infoPtr[i].queueID);
    1058            6 :                 (void) inputQueueIds_.insert(infoPtr[i].queueID);
    1059            6 :                 aicpusd_run_info("Load model, model[%u], input queue[%u].", modelId_, infoPtr[i].queueID);
    1060            4 :             } else if (infoPtr[i].flag == static_cast<uint32_t>(QueueDirectionFlag::QUEUE_OUTPUT_FLAG)) {
    1061            3 :                 drvRet = halQueueAttach(deviceId, infoPtr[i].queueID, 0);
    1062            3 :                 if (drvRet != DRV_ERROR_NONE) {
    1063            1 :                     aicpusd_err("Aicpusd attached queue[%u] failed ret[%d]", infoPtr[i].queueID, drvRet);
    1064            1 :                     return AICPU_SCHEDULE_ERROR_FROM_DRV;
    1065              :                 }
    1066            2 :                 ret = AicpuDrvManager::GetInstance().SubscribeQueueNotFullEvent(infoPtr[i].queueID);
    1067            2 :                 (void) outputQueueIds_.insert(infoPtr[i].queueID);
    1068            2 :                 aicpusd_run_info("Load model, model[%u], output queue[%u].", modelId_, infoPtr[i].queueID);
    1069              :             } else {
    1070            1 :                 aicpusd_err("queue[%u] flag[%u] is unknown.", infoPtr[i].queueID, infoPtr[i].flag);
    1071            1 :                 return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
    1072              :             }
    1073              : 
    1074            8 :             if (ret != AICPU_SCHEDULE_OK) {
    1075            1 :                 aicpusd_err("Failed to subscribe the event of queue, ret[%d].", ret);
    1076            1 :                 AicpuMonitor::GetInstance().SendKillMsgToTsd();
    1077            1 :                 return ret;
    1078              :             }
    1079            7 :             queueEventSubscribedInfo_.emplace_back(infoPtr[i]);
    1080              :         }
    1081            8 :         inputsIsDequeue_.resize(inputQueueIds_.size(), false);
    1082            8 :         aicpusd_info("LoadQueueInfo for model[%u] end.", modelId_);
    1083            8 :         return AICPU_SCHEDULE_OK;
    1084           14 :     }
    1085              : 
    1086           20 :     void AicpuModel::ClearLoadInfo()
    1087              :     {
    1088           20 :         aicpusd_info("Model[%u] clear load info begin.", modelId_);
    1089           20 :         isDestroyModel_ = true;
    1090           20 :         (void)pthread_rwlock_wrlock(&rwlockForStream_);
    1091           20 :         ModelStreamManager::GetInstance().UnReg(modelId_, allStreams_);
    1092           20 :         allStreams_.clear();
    1093           30 :         for (auto &it: aicpuStreams_) {
    1094           10 :             it.second.ShowProgress();
    1095           10 :             it.second.ResetTasks();
    1096              :         }
    1097           20 :         aicpuStreams_.clear();
    1098           20 :         otherAicpuStreams_.clear();
    1099              : 
    1100           20 :         (void)pthread_rwlock_unlock(&rwlockForStream_);
    1101              :         {
    1102           20 :             const std::unique_lock<std::mutex> lockForQueue(mutexForQueueEventSubscribed_);
    1103           24 :             for (QueInfo &itQueueInfo : queueEventSubscribedInfo_) {
    1104            4 :                 if (itQueueInfo.flag == static_cast<uint32_t>(QueueDirectionFlag::QUEUE_INPUT_FLAG)) {
    1105            2 :                     (void) AicpuDrvManager::GetInstance().UnSubscribeQueueNotEmptyEvent(itQueueInfo.queueID);
    1106              :                     QueueSetInputPara inPutParam;
    1107              :                     QueueSetInput inPut;
    1108            2 :                     inPut.queSetWorkMode.qid = itQueueInfo.queueID;
    1109            2 :                     inPut.queSetWorkMode.workMode = QUEUE_MODE_PUSH;
    1110            2 :                     inPutParam.inBuff = static_cast<void *>(&inPut);
    1111            2 :                     inPutParam.inLen = static_cast<uint32_t>(sizeof(QueueSetInput));
    1112            2 :                     (void)halQueueSet(0U, QUEUE_SET_WORK_MODE, &inPutParam);
    1113            2 :                 } else if (itQueueInfo.flag == static_cast<uint32_t>(QueueDirectionFlag::QUEUE_OUTPUT_FLAG)) {
    1114            1 :                     (void) AicpuDrvManager::GetInstance().UnSubscribeQueueNotFullEvent(itQueueInfo.queueID);
    1115              :                 } else {
    1116            1 :                     aicpusd_err("queue[%u] flag[%u] is unknown.", itQueueInfo.queueID, itQueueInfo.flag);
    1117              :                 }
    1118              :             }
    1119           20 :             queueEventSubscribedInfo_.clear();
    1120           20 :             inputQueueIds_.clear();
    1121           20 :             outputQueueIds_.clear();
    1122           20 :         }
    1123              :         {
    1124           20 :             const std::unique_lock<std::mutex> lockForModelNotifyId(mutexForModelNotifyId_);
    1125           20 :             modelNotifyId_.clear();
    1126           20 :         }
    1127              : 
    1128           20 :         ClearGatheredMbuf();
    1129              : 
    1130           21 :         for (const auto inputMsgQ : inputMsgQueueIds_) {
    1131            1 :             (void) AicpuDrvManager::GetInstance().UnSubscribeQueueNotEmptyEvent(static_cast<uint32_t>(inputMsgQ));
    1132              :         }
    1133           20 :         inputMsgQueueIds_.clear();
    1134           21 :         for (const auto outputMsgQ : outputMsgQueueIds_) {
    1135            1 :             (void) AicpuDrvManager::GetInstance().UnSubscribeQueueNotFullEvent(static_cast<uint32_t>(outputMsgQ));
    1136              :         }
    1137           20 :         outputMsgQueueIds_.clear();
    1138           20 :         iteratorCount_ = 0UL;
    1139           20 :         aicpusd_info("Model[%u] clear load info end.", modelId_);
    1140           20 :     }
    1141              : 
    1142           16 :     StoreResult AicpuModel::StoreDequedMbuf(const uint64_t transId, const uint32_t routeLabel,
    1143              :         const size_t qIndex, Mbuf *const mbuf, const uint32_t queueCount)
    1144              :     {
    1145              :         // first get exception transids, then discard mbuf which belong to exption transid
    1146              :         // if mbuf is not belong to exption transid, then store
    1147           16 :         if (IsTransIdException(transId)) {
    1148            1 :             aicpusd_info("Discard mbuf[%u:%u] in model[%u] for it was exception.", transId, routeLabel, modelId_);
    1149            1 :             halMbufFree(mbuf);
    1150            1 :             return StoreResult::ABORT_STORE;
    1151              :         }
    1152           30 :         if (gatheredMbuf_[transId][routeLabel].Init(queueCount) &&
    1153           15 :             gatheredMbuf_[transId][routeLabel].Store(qIndex, mbuf, gatheredMbufCntList_)) {
    1154           14 :             aicpusd_info("Model[%u] Store mbuf[%u:%u] into [%u]th queue, queuesize[%llu].", modelId_, transId,
    1155              :                          routeLabel, qIndex, gatheredMbufCntList_[qIndex]);
    1156           14 :             return StoreResult::SUCCESS_STORE;
    1157              :         }
    1158              : 
    1159            1 :         aicpusd_err("Failed to store mbuf in Model[%u] transId:%llu, routeLabel:%u", modelId_, transId, routeLabel);
    1160            1 :         return StoreResult::FAIL_STORE;
    1161              :     }
    1162              : 
    1163           15 :     void AicpuModel::ClearExceptionStore()
    1164              :     {
    1165           15 :         std::vector<int64_t> transIdsToClear;
    1166           15 :         GetExcptionTransIdsToClear(transIdsToClear);
    1167           17 :         for (const auto transId : transIdsToClear) {
    1168            2 :             auto transIdIter = gatheredMbuf_.find(transId);
    1169            2 :             if (transIdIter == gatheredMbuf_.end()) {
    1170            1 :                 continue;
    1171              :             }
    1172            2 :             for (auto &routeLabelIter : transIdIter->second) {
    1173            1 :                 auto &mbufStore = routeLabelIter.second;
    1174            1 :                 aicpusd_info("clear exception for transid[%lu], routelabel[%u]", transIdIter->first,
    1175              :                     routeLabelIter.first);
    1176            1 :                 mbufStore.Free(&gatheredMbufCntList_);
    1177              :             }
    1178            1 :             gatheredMbuf_.erase(transId);
    1179              :         }
    1180           15 :         UpdateExcptionTransIdsStatus(transIdsToClear);
    1181           15 :     }
    1182              : 
    1183           13 :     GatherResult AicpuModel::SelectGatheredMbuf(Mbuf ***const mbufPptr, const int32_t timeOut, const uint32_t cacheNum)
    1184              :     {
    1185           13 :         std::pair<uint64_t, uint32_t> mbufKey = {UINT64_MAX, UINT32_MAX};
    1186              :         // first get transids which need to clear, clear them, then mark transid to cleared
    1187           13 :         ClearExceptionStore();
    1188           13 :         const auto ret = GatherDequedMbuf(mbufPptr, mbufKey, timeOut, cacheNum);
    1189           13 :         if (ret != GatherResult::UN_SELECTED) {
    1190            3 :             aicpusd_info("[%u:%u] is selected in Model[%u], ret is %d", mbufKey.first, mbufKey.second,
    1191              :                          modelId_, static_cast<int32_t>(ret));
    1192            3 :             ClearDequedMbuf(mbufKey.first, mbufKey.second);
    1193              :         }
    1194           13 :         return ret;
    1195              :     }
    1196              : 
    1197           14 :     GatherResult AicpuModel::GatherDequedMbuf(Mbuf ***const mbufPptr, std::pair<uint64_t, uint32_t> &mbufKey,
    1198              :         const int32_t timeOutMs, const uint32_t cacheNum)
    1199              :     {
    1200           14 :         const uint32_t timeOutNs = static_cast<uint32_t>(timeOutMs * TIMES_MS_TO_NS);
    1201           14 :         AICPUSD_CHECK(timeOutNs < UINT_MAX, GatherResult::UN_SELECTED, "Invalid timeout value %ld ms.", timeOutMs);
    1202           14 :         const uint64_t minBirthDay = GetCurrentTime() - timeOutNs;
    1203           14 :         uint64_t count = 0U;
    1204           14 :         bool timeoutCandidate = false;
    1205           14 :         bool countoutCandidate = false;
    1206           14 :         std::pair<uint64_t, uint32_t> timeOutKey = {UINT64_MAX, UINT32_MAX};
    1207           14 :         std::pair<uint64_t, uint32_t> countOutKey = {UINT64_MAX, UINT32_MAX};
    1208           41 :         for (auto &transIdIter: gatheredMbuf_) {
    1209           28 :             auto &routeLabelMap = transIdIter.second;
    1210           63 :             for (auto &routeLabelIter: routeLabelMap) {
    1211           36 :                 count++;
    1212           36 :                 auto &mbufStore = routeLabelIter.second;
    1213           36 :                 if (!mbufStore.IsReady()) {
    1214           35 :                     if ((timeOutMs > 0) && (mbufStore.BirthDay() < minBirthDay)) {
    1215            1 :                         timeOutKey.first = transIdIter.first;
    1216            1 :                         timeOutKey.second = routeLabelIter.first;
    1217            1 :                         timeoutCandidate = true;
    1218              :                     }
    1219              : 
    1220           35 :                     if ((cacheNum > 0U) &&
    1221            5 :                         ((transIdIter.first <= countOutKey.first) && (routeLabelIter.first < countOutKey.second))) {
    1222            5 :                         countOutKey.first = transIdIter.first;
    1223            5 :                         countOutKey.second = routeLabelIter.first;
    1224            5 :                         countoutCandidate = true;
    1225              :                     }
    1226           35 :                     continue;
    1227              :                 }
    1228              : 
    1229            1 :                 mbufKey.first = transIdIter.first;
    1230            1 :                 mbufKey.second = routeLabelIter.first;
    1231            1 :                 if (mbufStore.Consume(mbufPptr, gatheredMbufCntList_)) {
    1232            1 :                     return GatherResult::SELECTED;
    1233              :                 }
    1234              :             }
    1235              :         }
    1236              : 
    1237           13 :         if ((countoutCandidate && (count > cacheNum))) {
    1238            2 :             mbufKey.first = countOutKey.first;
    1239            2 :             mbufKey.second = countOutKey.second;
    1240            2 :             if (gatheredMbuf_[mbufKey.first][mbufKey.second].Consume(mbufPptr, gatheredMbufCntList_)) {
    1241            2 :                 aicpusd_info("pass [%u:%u] for count[%u] > cache[%u]", mbufKey.first, mbufKey.second, count, cacheNum);
    1242            2 :                 return GatherResult::FAKE_SELECTED;
    1243              :             }
    1244              :         }
    1245           11 :         if (timeoutCandidate) {
    1246            1 :             mbufKey.first = timeOutKey.first;
    1247            1 :             mbufKey.second = timeOutKey.second;
    1248            1 :             if (gatheredMbuf_[mbufKey.first][mbufKey.second].Consume(mbufPptr, gatheredMbufCntList_)) {
    1249            1 :                 aicpusd_info("pass [%u:%u] for timeout[%d] ms", mbufKey.first, mbufKey.second, timeOutMs);
    1250            1 :                 return GatherResult::FAKE_SELECTED;
    1251              :             }
    1252              :         }
    1253              : 
    1254           10 :         return GatherResult::UN_SELECTED;
    1255              :     }
    1256              : 
    1257            3 :     void AicpuModel::ClearDequedMbuf(const uint64_t transId, const uint32_t routeLabel)
    1258              :     {
    1259            3 :         if (gatheredMbuf_[transId][routeLabel].IsEmpty()) {
    1260            3 :             (void)gatheredMbuf_[transId].erase(routeLabel);
    1261              :         }
    1262            3 :         if (gatheredMbuf_[transId].empty()) {
    1263            2 :             (void)gatheredMbuf_.erase(transId);
    1264              :         }
    1265            3 :     }
    1266              : 
    1267           21 :     void AicpuModel::ClearGatheredMbuf()
    1268              :     {
    1269           22 :         for (auto &transIdIter : gatheredMbuf_) {
    1270            2 :             for (auto &routeLabelIter : transIdIter.second) {
    1271            1 :                 routeLabelIter.second.Free(&gatheredMbufCntList_);
    1272              :             }
    1273              :         }
    1274           21 :         gatheredMbuf_.clear();
    1275           21 :         gatheredMbufCntList_.clear();
    1276           21 :     }
    1277              : 
    1278            5 :     void AicpuModel::RecordLockedTable(const uint32_t tableId)
    1279              :     {
    1280            5 :         if (tableLocked_.find(tableId) == tableLocked_.end()) {
    1281            4 :             tableLocked_[tableId] = 1U;
    1282              :         } else {
    1283            1 :             tableLocked_[tableId]++;
    1284              :         }
    1285            5 :     }
    1286              : 
    1287            2 :     void AicpuModel::ClearLockedTable(const uint32_t tableId)
    1288              :     {
    1289            2 :         if ((tableLocked_.find(tableId) == tableLocked_.end()) || (tableLocked_[tableId] == 0U)) {
    1290            1 :             return;
    1291              :         }
    1292              : 
    1293            1 :         if (--tableLocked_[tableId] == 0U) {
    1294            1 :             (void)tableLocked_.erase(tableId);
    1295              :         }
    1296              :     }
    1297              : 
    1298            2 :     bool AicpuModel::IsTableLocked(const uint32_t tableId)
    1299              :     {
    1300            2 :         return tableLocked_.find(tableId) != tableLocked_.end();
    1301              :     }
    1302              : 
    1303           26 :     void AicpuModel::ClearAllLockedTable()
    1304              :     {
    1305           28 :         for (auto iter = tableLocked_.begin(); iter != tableLocked_.end(); iter++) {
    1306            2 :             aicpusd_run_info("Model[%u] has locked table[%u] %u times.", modelId_, iter->first, iter->second);
    1307          204 :             for (uint32_t i = 0U; i < iter->second; i++) {
    1308          202 :                 TableLockManager::GetInstance().UnLockTable(iter->first);
    1309              :             }
    1310              :         }
    1311           26 :         tableLocked_.clear();
    1312           26 :         if (tableTryLock_ != INVALID_TABLE_ID) {
    1313            1 :             aicpusd_run_info("Model[%u] was trying to lock table[%d]", modelId_, tableTryLock_);
    1314            1 :             tableTryLock_ = INVALID_TABLE_ID;
    1315              :         }
    1316           26 :     }
    1317              : 
    1318            7 :     uint32_t &AicpuModel::GetInputConsumeNumRef()
    1319              :     {
    1320            7 :         return inputConsumeNum_;
    1321              :     }
    1322              : 
    1323           20 :     size_t AicpuModel::GetCurDequeIndex(const size_t qCnt)
    1324              :     {
    1325           20 :         if (gatheredMbufCntList_.empty()) {
    1326            5 :             aicpusd_info("store list empty use 0th index");
    1327            5 :             return 0UL;
    1328              :         }
    1329           15 :         size_t qIndex = gatheredMbufCntList_.begin()->first;
    1330           15 :         size_t minCnt = gatheredMbufCntList_.begin()->second;
    1331           67 :         for (size_t index = 0UL; index < qCnt; index++) {
    1332           52 :             size_t curCnt = 0UL;
    1333           52 :             auto iter = gatheredMbufCntList_.find(index);
    1334           52 :             if (iter != gatheredMbufCntList_.end()) {
    1335           44 :                 curCnt = iter->second;
    1336              :             }
    1337           52 :             if (curCnt < minCnt) {
    1338           11 :                 qIndex = index;
    1339           11 :                 minCnt = curCnt;
    1340           41 :             } else if ((curCnt == minCnt) && (index < qIndex)) {
    1341            1 :                 qIndex = index;
    1342            1 :                 minCnt = curCnt;
    1343              :             }
    1344           52 :             aicpusd_info("update modelId:%u, qIndex:%zu, cnt:%llu, index:%zu, curCnt:%zu",
    1345              :                          modelId_, qIndex, minCnt, index, curCnt);
    1346              :         }
    1347           15 :         return qIndex;
    1348              :     }
    1349              : 
    1350           13 :     int32_t AicpuModel::ProcessDataException(const uint64_t transId, const uint32_t type) {
    1351           13 :         std::unique_lock<std::mutex> lockForAsyncTask(mutexForExceptionTrans_);
    1352              :         // exception occur
    1353           13 :         if (type == static_cast<uint32_t>(ExceptionAction::ADD)) {
    1354            8 :             if (exceptionTranses_.find(transId) != exceptionTranses_.end()) {
    1355            2 :                 aicpusd_warn("Transid[%lu] is already in exception list.", transId);
    1356            2 :                 return AICPU_SCHEDULE_OK;
    1357              :             }
    1358            6 :             aicpusd_info("Add new exception transid[%lu] for Model[%u].", transId, modelId_);
    1359            6 :             exceptionTranses_[transId] = false;
    1360            6 :             AICPUSubEventInfo subEventInfo = {};
    1361            6 :             subEventInfo.modelId = modelId_;
    1362            6 :             const auto ret = AicpuMsgSend::SendAICPUSubEvent(
    1363              :                 PtrToPtr<AICPUSubEventInfo, const char_t>(&subEventInfo),
    1364              :                 static_cast<uint32_t>(sizeof(AICPUSubEventInfo)), AICPU_SUB_EVENT_SUPPLY_ENQUEUE,
    1365              :                 CP_DEFAULT_GROUP_ID, true);
    1366            6 :             if (ret != AICPU_SCHEDULE_OK) {
    1367            1 :                 aicpusd_warn("Send aicpu subevent failed. Event modelId is %d.", modelId_);
    1368              :             };
    1369            6 :             return AICPU_SCHEDULE_OK;
    1370              :         }
    1371              : 
    1372            5 :         if (type == static_cast<uint32_t>(ExceptionAction::EXPIRE)) {
    1373            4 :             if (exceptionTranses_.find(transId) == exceptionTranses_.end()) {
    1374            2 :                 aicpusd_warn("Transid[%lu] is not in exception list in model[%u], no need to expire.",
    1375              :                     transId, modelId_);
    1376              :             } else {
    1377            2 :                 aicpusd_info("Transid[%lu] is expired in model[%u]", transId, modelId_);
    1378            2 :                 exceptionTranses_.erase(transId);
    1379              :             }
    1380            4 :             return AICPU_SCHEDULE_OK;
    1381              :         }
    1382              : 
    1383            1 :         aicpusd_err("Model[%u] failed to process data exception of transid[%lu] for type[%u] is invalid.",
    1384              :             modelId_, transId, type);
    1385            1 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
    1386           13 :     }
    1387              : 
    1388           15 :     bool AicpuModel::IsTransIdException(const uint64_t transId)
    1389              :     {
    1390           15 :         std::unique_lock<std::mutex> lockForAsyncTask(mutexForExceptionTrans_);
    1391           30 :         return (exceptionTranses_.find(transId) != exceptionTranses_.end());
    1392           15 :     }
    1393              : 
    1394           15 :     void AicpuModel::GetExcptionTransIdsToClear(std::vector<int64_t> &excptionTransIdsToClear)
    1395              :     {
    1396           15 :         std::unique_lock<std::mutex> lockForAsyncTask(mutexForExceptionTrans_);
    1397           17 :         for (const auto &elem : exceptionTranses_) {
    1398            2 :             if (!elem.second) {
    1399            2 :                 excptionTransIdsToClear.emplace_back(elem.first);
    1400              :             }
    1401              :         }
    1402           15 :     }
    1403              : 
    1404           15 :     void AicpuModel::UpdateExcptionTransIdsStatus(const std::vector<int64_t> excptionTransIdsCleared) {
    1405           15 :         std::unique_lock<std::mutex> lockForAsyncTask(mutexForExceptionTrans_);
    1406           17 :         for (const auto transId : excptionTransIdsCleared) {
    1407            2 :             auto iter = exceptionTranses_.find(transId);
    1408            2 :             if (iter != exceptionTranses_.end()) {
    1409            2 :                 aicpusd_info("update transId[%lu] to cleared in model[%u]", transId, modelId_);
    1410            2 :                 iter->second = true;
    1411              :             }
    1412              :         }
    1413           15 :     }
    1414              : 
    1415           20 :     bool QueueMbufStore::Init(const size_t queueNum)
    1416              :     {
    1417           20 :         if (!queuesLists_.empty()) {
    1418            7 :             return true;
    1419              :         }
    1420           13 :         AICPUSD_EXCEPTION_CATCH(queuesLists_.resize(queueNum), return false);  
    1421           13 :         birthTimeStamp_ = GetCurrentTime();
    1422           13 :         return true;
    1423              :     }
    1424              : 
    1425           17 :     bool QueueMbufStore::Store(const size_t qIndex, Mbuf *const mbuf, std::map<size_t, uint64_t> &gCntList)
    1426              :     {
    1427           17 :         if (queuesLists_.empty()) {
    1428            1 :             aicpusd_err("QueueMbufStore has not been initialized");
    1429            1 :             return false;
    1430              :         }
    1431           16 :         if (qIndex >= queuesLists_.size()) {
    1432            1 :             aicpusd_err("qIndex [%zu] invalid", qIndex);
    1433            1 :             return false;
    1434              :         }
    1435           15 :         queuesLists_[qIndex].push_back(mbuf);
    1436           15 :         gCntList[qIndex]++;
    1437           15 :         aicpusd_info("store mbuf index:%zu, queue list size:%zu, buf cnt map cnt:%llu", qIndex,
    1438              :                      queuesLists_[qIndex].size(), gCntList[qIndex]);
    1439           15 :         return true;
    1440              :     }
    1441              : 
    1442            5 :     bool QueueMbufStore::Consume(Mbuf ***mbufPptr, std::map<size_t, uint64_t> &gCntList)
    1443              :     {
    1444            5 :         if (queuesLists_.empty()) {
    1445            1 :             aicpusd_err("QueueMbufStore has not been initialized");
    1446            1 :             return false;
    1447              :         }
    1448           15 :         for (size_t arrIndex = 0U; arrIndex < queuesLists_.size(); ++arrIndex) {
    1449           11 :             if (!queuesLists_[arrIndex].empty()) {
    1450            8 :                 *mbufPptr[arrIndex] = queuesLists_[arrIndex].front();
    1451            8 :                 queuesLists_[arrIndex].pop_front();
    1452            8 :                 if (gCntList[arrIndex] > 0) {
    1453            8 :                     gCntList[arrIndex]--;
    1454              :                 }
    1455            8 :                 aicpusd_info("consume mbuf index:%zu, queue list size:%zu, buf cnt map cnt:%llu", arrIndex,
    1456              :                              queuesLists_[arrIndex].size(), gCntList[arrIndex]);
    1457              :             } else {
    1458            3 :                 *mbufPptr[arrIndex] = nullptr;
    1459              :             }
    1460              :         }
    1461            4 :         return true;
    1462              :     }
    1463              : 
    1464           17 :     void QueueMbufStore::Free(std::map<size_t, uint64_t> *const gCntList)
    1465              :     {
    1466           49 :         for (size_t i = 0UL; i < queuesLists_.size(); i++) {
    1467           71 :             while (!queuesLists_[i].empty()) {
    1468            7 :                 Mbuf *tmpBuf = queuesLists_[i].front();
    1469            7 :                 if (tmpBuf != nullptr) {
    1470            5 :                     (void)halMbufFree(tmpBuf);
    1471              :                 }
    1472            7 :                 queuesLists_[i].pop_front();
    1473            7 :                 if ((gCntList != nullptr) && ((*gCntList)[i] > 0)) {
    1474            3 :                     (*gCntList)[i]--;
    1475              :                 }
    1476              :             }
    1477           32 :             if (gCntList != nullptr) {
    1478            3 :                 aicpusd_info("free store buffer index:%zu, buffer map count:%llu", i, (*gCntList)[i]);
    1479              :             }
    1480              :         }
    1481           17 :     }
    1482              : 
    1483           39 :     bool QueueMbufStore::IsReady() const
    1484              :     {
    1485           39 :         if (queuesLists_.empty()) {
    1486            1 :             return false;
    1487              :         }
    1488           74 :         for (size_t index = 0UL; index < queuesLists_.size(); index++) {
    1489           73 :             if (queuesLists_[index].empty()) {
    1490           37 :                 return false;
    1491              :             }
    1492              :         }
    1493            1 :         return true;
    1494              :     }
    1495           15 :     QueueMbufStore::~QueueMbufStore()
    1496              :     {
    1497           15 :         Free();
    1498           15 :     }
    1499              : 
    1500            6 :     bool QueueMbufStore::IsEmpty() const
    1501              :     {
    1502            6 :         if (queuesLists_.empty()) {
    1503            1 :             return true;
    1504              :         }
    1505           23 :         for (size_t index = 0UL; index < queuesLists_.size(); index++) {
    1506           19 :             if (!queuesLists_[index].empty()) {
    1507            1 :                 return false;
    1508              :             }
    1509              :         }
    1510            4 :         return true;
    1511              :     }
    1512              : }
        

Generated by: LCOV version 2.0-1