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

Generated by: LCOV version 2.0-1