LCOV - code coverage report
Current view: top level - aicpu_schedule/statistic - aicpusd_model_statistic.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 147 147
Test Date: 2026-07-28 10:54:05 Functions: 93.3 % 15 14

            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              : #include "aicpusd_model_statistic.h"
      11              : 
      12              : #include <sstream>
      13              : namespace AicpuSchedule {
      14           14 :     std::string AicpuSdModelStatistic::FormatShapeToString(const std::vector<int64_t> &shape) const
      15              :     {
      16           14 :         bool first = true;
      17           14 :         std::stringstream ss;
      18           14 :         ss << "[";
      19           28 :         for (const int64_t &x : shape) {
      20           14 :             if (first) {
      21           10 :                 first = false;
      22           10 :                 ss << x;
      23              :             } else {
      24            4 :                 ss << ", " << x;
      25              :             }
      26              :         }
      27           14 :         ss << "]";
      28           28 :         return ss.str();
      29           14 :     }
      30              : 
      31            2 :     std::string AicpuSdModelStatistic::GetRangeString(const std::vector<InAndOutParamStatInfo> &statInfos,
      32              :                                                       size_t startIdx, size_t endIdx) const
      33              :     {
      34            2 :         std::stringstream minSizeStream;
      35            2 :         std::stringstream maxSizeStream;
      36            2 :         std::stringstream minShapeStream;
      37            2 :         std::stringstream maxShapeStream;
      38            9 :         for (size_t idx = startIdx; idx <= endIdx; ++idx) {
      39            7 :             const auto &curInfo = statInfos[idx];
      40            7 :             if (idx != startIdx) {
      41            5 :                 minSizeStream << ", ";
      42            5 :                 maxSizeStream << ", ";
      43            5 :                 minShapeStream << ", ";
      44            5 :                 maxShapeStream << ", ";
      45              :             }
      46            7 :             minSizeStream << curInfo.minSize;
      47            7 :             maxSizeStream << curInfo.maxSize;
      48            7 :             minShapeStream << FormatShapeToString(curInfo.minShape);
      49            7 :             maxShapeStream << FormatShapeToString(curInfo.maxShape);
      50              :         }
      51            2 :         std::stringstream strStream;
      52            2 :         strStream << "min_size=[" << minSizeStream.str() << "], max_size=[" << maxSizeStream.str() <<
      53            2 :             "], min_shape=[" << minShapeStream.str() << "], max_shape=[" << maxShapeStream.str() << "]";
      54            4 :         return strStream.str();
      55            2 :     }
      56              : 
      57         2050 :     AicpuSdModelStatistic::~AicpuSdModelStatistic()
      58              :     {
      59         2050 :     }
      60              : 
      61         2050 :     AicpuSdModelStatistic::AicpuSdModelStatistic()
      62              :     {
      63            2 :     }
      64              :  
      65           66 :     AicpuSdModelStatistic &AicpuSdModelStatistic::GetInstance()
      66              :     {
      67           66 :         static AicpuSdModelStatistic instance;
      68           66 :         return instance;
      69              :     }
      70              : 
      71            4 :     void AicpuSdModelStatistic::StatNNModelExecTime(const uint32_t modelId)
      72              :     {
      73            4 :         if (modelId >= MAX_MODEL_COUNT) {
      74            1 :             aicpusd_err("invalid modelId:%u, max:%u", modelId, MAX_MODEL_COUNT);
      75            3 :             return;
      76              :         }
      77            3 :         aicpusd_info("enter curMax:%llu, curMin:%llu", modelStatArray_[modelId].maxExecTime,
      78              :                      modelStatArray_[modelId].minExecTime);
      79            3 :         if (!modelStatArray_[modelId].useFlag) {
      80            2 :             aicpusd_info("only stat static model, dynamic model no need stat");
      81            2 :             return;
      82              :         }
      83            1 :         modelStatArray_[modelId].totalCnt++;
      84            1 :         auto curTime = std::chrono::steady_clock::now();
      85            1 :         auto timeGap = curTime - modelStatArray_[modelId].modelStartTime;
      86              :         const uint64_t curExecTime =
      87            1 :             static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(timeGap).count());
      88            1 :         modelStatArray_[modelId].totalTime += curExecTime;
      89            1 :         AicpuUtil::UpdateMaxAndSubMaxData(modelStatArray_[modelId].maxExecTime,
      90            1 :                                           modelStatArray_[modelId].subMaxExecTime,
      91              :                                           curExecTime);
      92            1 :         AicpuUtil::UpdateMinData(modelStatArray_[modelId].minExecTime, curExecTime);
      93            1 :         aicpusd_info("after update curMax:%llu, curMin:%llu, curStat:%llu", modelStatArray_[modelId].maxExecTime,
      94              :                      modelStatArray_[modelId].minExecTime, curExecTime);
      95              :     }
      96              : 
      97            4 :     void AicpuSdModelStatistic::UpdateStatVecInfo(InAndOutParamStatInfo &dstStat, const uint64_t totalSize,
      98              :                                                   const int64_t *shapes) const
      99              :     {
     100            4 :         if ((dstStat.minSize == 0) || (totalSize < dstStat.minSize)) {
     101            1 :             dstStat.minSize = totalSize;
     102            1 :             dstStat.minShape.assign(&(shapes[1]), &(shapes[1]) + shapes[0]);
     103              :         }
     104              : 
     105            4 :         if (totalSize > dstStat.maxSize) {
     106            2 :             dstStat.maxSize = totalSize;
     107            2 :             dstStat.maxShape.assign(&(shapes[1]), &(shapes[1]) + shapes[0]);
     108              :         }
     109            4 :     }
     110              : 
     111            5 :     void AicpuSdModelStatistic::AddNewDataToStatVec(std::vector<InAndOutParamStatInfo> &delVec,
     112              :                                                     const uint64_t totalSize,
     113              :                                                     const int64_t *shapes) const
     114              :     {
     115            5 :         InAndOutParamStatInfo tempNode;
     116            5 :         tempNode.minSize = totalSize;
     117            5 :         tempNode.minShape.assign(&(shapes[1]), &(shapes[1]) + shapes[0]);
     118            5 :         tempNode.maxSize = totalSize;
     119            5 :         tempNode.maxShape.assign(&(shapes[1]), &(shapes[1]) + shapes[0]);
     120            5 :         aicpusd_info("max size:%llu, min size:%llu, min shape size:%zu, max shape size:%zu",
     121              :                      tempNode.maxSize, tempNode.minSize, tempNode.minShape.size(), tempNode.maxShape.size());
     122            5 :         delVec.emplace_back(tempNode);
     123            5 :     }
     124              : 
     125            4 :     void AicpuSdModelStatistic::StatNNModelInput(const uint32_t modelId,
     126              :                                                  const std::vector<uint64_t> &totalSizeList,
     127              :                                                  std::vector<ModelConfigTensorDesc> &curStatVec)
     128              :     {
     129            4 :         if ((modelId >= MAX_MODEL_COUNT) || (totalSizeList.size() != curStatVec.size())) {
     130            1 :             aicpusd_err("invalid modelId:%u, max:%u, size list:%zu, stat list:%zu", modelId, MAX_MODEL_COUNT,
     131              :                         totalSizeList.size(), curStatVec.size());
     132            1 :             return;
     133              :         }
     134            3 :         std::vector<InAndOutParamStatInfo> &delVec = modelStatArray_[modelId].inputStatVec;
     135            3 :         const size_t delVecSize = delVec.size();
     136            3 :         const size_t curVecSize = curStatVec.size();
     137            3 :         const size_t curMinSize = delVecSize < curVecSize ? delVecSize : curVecSize;
     138            5 :         for (size_t index = 0; index < curMinSize; index++) {
     139            2 :             UpdateStatVecInfo(delVec[index], totalSizeList[index], &(curStatVec[index].shape[0]));
     140            2 :             aicpusd_info("index:%zu max size:%llu, min size:%llu, min shape size:%zu, max shape size:%zu", index,
     141              :                          delVec[index].maxSize, delVec[index].minSize,
     142              :                          delVec[index].minShape.size(), delVec[index].maxShape.size());
     143              :         }
     144              : 
     145            3 :         if (delVecSize < curVecSize) {
     146            4 :             for (size_t i = curMinSize; i < curVecSize; i++) {
     147            2 :                 AddNewDataToStatVec(delVec, totalSizeList[i], &(curStatVec[i].shape[0]));
     148              :             }
     149              :         }
     150              :     }
     151              : 
     152            7 :     void AicpuSdModelStatistic::InitModelStatInfo()
     153              :     {
     154         7175 :         for (uint32_t index = 0; index < MAX_MODEL_COUNT; index++) {
     155         7168 :             modelStatArray_[index].useFlag     = false;
     156         7168 :             modelStatArray_[index].maxExecTime = 0UL;
     157         7168 :             modelStatArray_[index].minExecTime = 0UL;
     158         7168 :             modelStatArray_[index].subMaxExecTime = 0UL;
     159         7168 :             modelStatArray_[index].totalTime = 0UL;
     160         7168 :             modelStatArray_[index].totalCnt = 0UL;
     161         7168 :             modelStatArray_[index].inputStatVec.clear();
     162         7168 :             modelStatArray_[index].outputStatVec.clear();
     163              :         }
     164            7 :     }
     165              : 
     166           10 :     void AicpuSdModelStatistic::MarNNModelStartTime(const uint32_t modelId)
     167              :     {
     168           10 :         if (modelId >= MAX_MODEL_COUNT) {
     169            1 :             aicpusd_err("invalid modelId:%u, max:%u", modelId, MAX_MODEL_COUNT);
     170            1 :             return;
     171              :         }
     172            9 :         modelStatArray_[modelId].modelStartTime = std::chrono::steady_clock::now();
     173            9 :         modelStatArray_[modelId].useFlag = true;
     174            9 :         aicpusd_info("mark mode:%u started", modelId);
     175              :     }
     176              : 
     177            7 :     void AicpuSdModelStatistic::StatNNModelOutput(const uint32_t modelId, const RuntimeTensorDesc * const tensorDesc,
     178              :                                                   const int32_t nextIndex)
     179              :     {
     180            7 :         if ((modelId >= MAX_MODEL_COUNT) || (nextIndex <= 0) || (tensorDesc == nullptr)) {
     181            1 :             aicpusd_err("invalid modelId:%u, max:%u, nextIndex:%d", modelId, MAX_MODEL_COUNT, nextIndex);
     182            2 :             return;
     183              :         }
     184            6 :         const uint32_t curIndex = static_cast<uint32_t>(nextIndex) - 1U;
     185            6 :         std::vector<InAndOutParamStatInfo> &delVec = modelStatArray_[modelId].outputStatVec;
     186            6 :         const size_t curDelSize = delVec.size();
     187            6 :         int64_t curTotalSize = 0;
     188           12 :         const int32_t ret = AicpuUtil::CalcDataSizeByShape(&(tensorDesc->shape[1]), tensorDesc->shape[0],
     189            6 :                                                            tensorDesc->dtype, curTotalSize);
     190            6 :         if ((ret != AICPU_SCHEDULE_OK) || (curTotalSize < 0)) {
     191            1 :             aicpusd_warn("cannot get size from tensordesc, ret[%d], size[%lld]", ret, curTotalSize);
     192            1 :             return;
     193              :         }
     194            5 :         const uint64_t dataSize = static_cast<uint64_t>(curTotalSize);
     195            5 :         if (curIndex < curDelSize) {
     196            2 :             UpdateStatVecInfo(delVec[curIndex], dataSize, &(tensorDesc->shape[0]));
     197            2 :             aicpusd_info("max size:%llu, min size:%llu, min shape size:%zu, max shape size:%zu",
     198              :                          delVec[curIndex].maxSize, delVec[curIndex].minSize,
     199              :                          delVec[curIndex].minShape.size(), delVec[curIndex].maxShape.size());
     200            3 :         } else if (curIndex == curDelSize) {
     201            2 :             AddNewDataToStatVec(delVec, dataSize, &(tensorDesc->shape[0]));
     202              :         } else {
     203            1 :             delVec.resize(curIndex);
     204            1 :             AddNewDataToStatVec(delVec, dataSize, &(tensorDesc->shape[0]));
     205              :         }
     206              :     }
     207              : 
     208           25 :     void AicpuSdModelStatistic::PrintOutModelStatInfo()
     209              :     {
     210        25625 :         for (uint32_t modelId = 0U; modelId < MAX_MODEL_COUNT; modelId++) {
     211        25600 :             if (modelStatArray_[modelId].useFlag) {
     212            1 :                 DumpOutModelMetrics(modelId);
     213              :             }
     214              :         }
     215           25 :     }
     216            1 :     void AicpuSdModelStatistic::DumpOutModelMetrics(const uint32_t modelId)
     217              :     {
     218            1 :         ModelStatInfo &curModeInfo = modelStatArray_[modelId];
     219            1 :         aicpusd_run_info("model_metrics:name=%s, min_exec_time=%llu us, max_exec_time=%llu us, "
     220              :                          "sub_max_exec_time=%llu us, total_exec_time=%llu us, total_exec_num=%llu.",
     221              :                          std::to_string(modelId).c_str(), curModeInfo.minExecTime, curModeInfo.maxExecTime,
     222              :                          curModeInfo.subMaxExecTime, curModeInfo.totalTime, curModeInfo.totalCnt);
     223            1 :         constexpr size_t maxCntPrintPreLine = 10;
     224            1 :         const size_t inputSize = curModeInfo.inputStatVec.size();
     225            1 :         const size_t outputSize = curModeInfo.outputStatVec.size();
     226            2 :         for (size_t inputIdx = 0; inputIdx < inputSize; inputIdx += maxCntPrintPreLine) {
     227            1 :             const size_t startIdx = inputIdx;
     228            1 :             const size_t endIdx = (inputIdx + maxCntPrintPreLine) > inputSize ?
     229              :                                   (inputSize - 1) : (inputIdx + maxCntPrintPreLine - 1);
     230            1 :             aicpusd_run_info("model_metrics:name=%s, input[%zu-%zu], %s.", std::to_string(modelId).c_str(),
     231              :                              startIdx, endIdx, GetRangeString(curModeInfo.inputStatVec, startIdx, endIdx).c_str());
     232              :         }
     233              : 
     234            2 :         for (size_t outputIdx = 0; outputIdx < outputSize; outputIdx += maxCntPrintPreLine) {
     235            1 :             const size_t startIdx = outputIdx;
     236            1 :             const size_t endIdx = (outputIdx + maxCntPrintPreLine) > outputSize ?
     237              :                                   (outputSize - 1) : (outputIdx + maxCntPrintPreLine - 1);
     238            1 :             aicpusd_run_info("model_metrics:name=%s, output[%zu-%zu], %s.", std::to_string(modelId).c_str(),
     239              :                              startIdx, endIdx, GetRangeString(curModeInfo.outputStatVec, startIdx, endIdx).c_str());
     240              :         }
     241            1 :     }
     242              : }
        

Generated by: LCOV version 2.0-1