LCOV - code coverage report
Current view: top level - adump/dump_statistics/dump_stat_fw - dump_stats_process.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.0 % 200 182
Test Date: 2026-08-31 10:09:28 Functions: 100.0 % 13 13

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 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 <atomic>
      11              : 
      12              : #include "dump_stats_process.h"
      13              : #include "adx_log.h"
      14              : 
      15              : namespace kfc_dump_stats {
      16              : static std::atomic<bool> g_isInitialized(false);
      17              : static PrintSqeInfo g_printSqeInfo = nullptr;
      18              : static AddOneStatDumpTask g_addOneStatDumpTask = nullptr;
      19              : uint32_t g_tensorCount = 0;
      20              : KfcDumpOpInitParam g_dumpParam;
      21              : KfcDumpContext g_dumpContext;
      22              : KfcDumpStreamCtx g_kfcDumpStreamInfo;
      23              : 
      24           24 : bool KfcDumpProcess::GetStatsOpInitStatus() { return g_isInitialized; }
      25              : 
      26           54 : void KfcDumpProcess::ResetForTest()
      27              : {
      28           54 :     g_isInitialized = false;
      29           54 :     g_printSqeInfo = nullptr;
      30           54 :     g_addOneStatDumpTask = nullptr;
      31           54 :     g_tensorCount = 0;
      32           54 :     g_dumpParam = {};
      33           54 :     g_dumpContext = {};
      34           54 :     g_kfcDumpStreamInfo = {};
      35           54 : }
      36              : 
      37           36 : KfcDumpResult InitSqCqFunction()
      38              : {
      39           36 :     if (g_kfcDumpStreamInfo.chipType == CHIP_DC) {
      40            2 :         g_addOneStatDumpTask = AddOneStatDumpTaskV2;
      41            2 :         g_printSqeInfo = KfcDumpPrintf::PrintSqeV2;
      42           34 :     } else if (g_kfcDumpStreamInfo.chipType == CHIP_CLOUD_V2) {
      43           27 :         g_addOneStatDumpTask = AddOneStatDumpTaskV1;
      44           27 :         g_printSqeInfo = KfcDumpPrintf::PrintSqeV1;
      45            7 :     } else if (g_kfcDumpStreamInfo.chipType == CHIP_CLOUD_V4) {
      46            2 :         g_addOneStatDumpTask = AddStatDumpTaskCloudV4;
      47            2 :         g_printSqeInfo = KfcDumpPrintf::PrintSqeCloudV4;
      48            5 :     } else if (g_kfcDumpStreamInfo.chipType == CHIP_CLOUD_V5) {
      49            2 :         g_addOneStatDumpTask = AddStatDumpTaskCloudV5;
      50            2 :         g_printSqeInfo = KfcDumpPrintf::PrintSqeCloudV5;
      51              :     } else {
      52            3 :         IDE_LOGE(
      53              :             "Kfc dump does not support chip type[%u], only chip type[%d,%d,%d,%d] are supported",
      54              :             g_kfcDumpStreamInfo.chipType, CHIP_DC, CHIP_CLOUD_V2, CHIP_CLOUD_V4, CHIP_CLOUD_V5);
      55            3 :         return KFC_DUMP_E_NOT_SUPPORT;
      56              :     }
      57           33 :     return KFC_DUMP_SUCCESS;
      58              : }
      59              : 
      60           47 : KfcDumpResult KfcDumpProcess::InitKfcDumpInfo(KfcDumpOpInitParam* dumpParam)
      61              : {
      62           47 :     KfcDumpPrintf::PrintKfcDumpInitParam(dumpParam);
      63           47 :     g_isInitialized = false;
      64           47 :     IDE_CTRL_VALUE_FAILED(
      65              :         dumpParam->kfcWorkSpace.outputSize >= STAT_LEN, return KFC_DUMP_E_PARA,
      66              :         "Output buffer size[%lu] is less than the required statistics length[%zu]", dumpParam->kfcWorkSpace.outputSize,
      67              :         STAT_LEN);
      68              :     // 不能用 constexpr:vectorCoreNum 是运行期入参。msgQ 布局为
      69              :     // msgBody + syncSpace(每核 SYNC_SPACE_BYTES_PER_CORE) + 尾部 KfcDumpContext,故下限随核数变化。
      70           46 :     const uint64_t minMsgQSize =
      71           46 :         MSG_BODY_SIZE + dumpParam->config.vectorCoreNum * SYNC_SPACE_BYTES_PER_CORE + sizeof(KfcDumpContext);
      72           46 :     IDE_CTRL_VALUE_FAILED(
      73              :         dumpParam->kfcWorkSpace.msgQSize >= minMsgQSize, return KFC_DUMP_E_PARA,
      74              :         "Msg queue size[%lu] is less than the required minimum[%lu]", dumpParam->kfcWorkSpace.msgQSize, minMsgQSize);
      75           44 :     IDE_CTRL_VALUE_FAILED(
      76              :         dumpParam->config.vectorCoreNum != 0U && dumpParam->config.ubSize != 0U, return KFC_DUMP_E_PARA,
      77              :         "Invalid platform config, vectorCoreNum[%lu] and ubSize[%lu] must be positive", dumpParam->config.vectorCoreNum,
      78              :         dumpParam->config.ubSize);
      79              : 
      80           42 :     g_dumpParam = *dumpParam;
      81           42 :     g_kfcDumpStreamInfo.chipType = g_dumpParam.config.chipType;
      82           42 :     g_kfcDumpStreamInfo.streamId = g_dumpParam.streamInfo.streamIds;
      83           42 :     g_kfcDumpStreamInfo.sqId = g_dumpParam.streamInfo.sqIds;
      84           42 :     g_kfcDumpStreamInfo.cqId = g_dumpParam.streamInfo.cqIds;
      85           42 :     g_kfcDumpStreamInfo.logicCqId = g_dumpParam.streamInfo.logicCqIds;
      86           42 :     IDE_CTRL_VALUE_FAILED(
      87              :         drvGetLocalDevIDByHostDevID != nullptr, return KFC_DUMP_E_NOT_SUPPORT,
      88              :         "drvGetLocalDevIDByHostDevID is unresolved, driver does not support device id conversion");
      89              : 
      90           42 :     drvError_t drvRet = drvGetLocalDevIDByHostDevID(g_dumpParam.streamInfo.deviceId, &(g_kfcDumpStreamInfo.devId));
      91           42 :     IDE_CTRL_VALUE_FAILED(
      92              :         drvRet == DRV_ERROR_NONE, return KFC_DUMP_E_DRIVE,
      93              :         "Failed to convert host device id[%u] to local device id, ret[%d]", g_dumpParam.streamInfo.deviceId,
      94              :         static_cast<int32_t>(drvRet));
      95              :     uint64_t sqAddr;
      96           41 :     DUMP_STATS_CHK_RET(
      97              :         KfcDumpTaskDispatcher::QuerySqBaseAddr(g_kfcDumpStreamInfo.devId, g_kfcDumpStreamInfo.sqId, sqAddr));
      98           40 :     g_kfcDumpStreamInfo.sqBaseAddr = reinterpret_cast<void*>(sqAddr);
      99           40 :     DUMP_STATS_CHK_RET(KfcDumpTaskDispatcher::QuerySqStatusByType(
     100              :         g_kfcDumpStreamInfo.devId, g_kfcDumpStreamInfo.sqId, DRV_SQCQ_PROP_SQ_DEPTH, g_kfcDumpStreamInfo.sqDepth));
     101           39 :     IDE_CTRL_VALUE_FAILED(
     102              :         g_kfcDumpStreamInfo.sqDepth != 0U, return KFC_DUMP_E_DRIVE,
     103              :         "Invalid sq depth[0] queried from driver, devId[%u] sqId[%u]", g_kfcDumpStreamInfo.devId,
     104              :         g_kfcDumpStreamInfo.sqId);
     105              : 
     106           38 :     DUMP_STATS_CHK_RET(KfcDumpTaskDispatcher::QuerySqStatusByType(
     107              :         g_kfcDumpStreamInfo.devId, g_kfcDumpStreamInfo.sqId, DRV_SQCQ_PROP_SQ_HEAD, g_kfcDumpStreamInfo.sqHead));
     108           37 :     DUMP_STATS_CHK_RET(KfcDumpTaskDispatcher::QuerySqStatusByType(
     109              :         g_kfcDumpStreamInfo.devId, g_kfcDumpStreamInfo.sqId, DRV_SQCQ_PROP_SQ_TAIL, g_kfcDumpStreamInfo.sqTail));
     110           36 :     KfcDumpPrintf::PrintKfcDumpStreamCtx(&g_kfcDumpStreamInfo);
     111           36 :     DUMP_STATS_CHK_RET(InitSqCqFunction());
     112           33 :     g_isInitialized = true;
     113           33 :     IDE_LOGI("Success to initialize the kfc dump server");
     114           33 :     return KFC_DUMP_SUCCESS;
     115              : }
     116              : 
     117           32 : KfcDumpResult KfcDumpProcess::GetAivDumpContext()
     118              : {
     119           32 :     g_dumpContext.msgQ = g_dumpParam.kfcWorkSpace.msgQ;
     120           32 :     g_dumpContext.workspace = g_dumpParam.kfcWorkSpace.workspace;
     121           32 :     g_dumpContext.workspaceSize = g_dumpParam.kfcWorkSpace.workspaceSize;
     122           32 :     g_dumpContext.aiCoreNum = g_dumpParam.config.vectorCoreNum;
     123           32 :     g_dumpContext.ubSize = g_dumpParam.config.ubSize;
     124           32 :     g_dumpContext.syncSpace = g_dumpParam.kfcWorkSpace.msgQ + MSG_BODY_SIZE;
     125           64 :     errno_t ret = memset_s(
     126           32 :         reinterpret_cast<uint8_t*>(g_dumpParam.kfcWorkSpace.msgQ),
     127           32 :         static_cast<size_t>(g_dumpParam.kfcWorkSpace.msgQSize), 0,
     128           32 :         static_cast<size_t>(g_dumpParam.kfcWorkSpace.msgQSize));
     129           32 :     if (ret != EOK) {
     130            0 :         IDE_LOGE("Failed to reset kfc dump message queue, ret[%d]", ret);
     131            0 :         return KFC_DUMP_E_MEMORY;
     132              :     }
     133           32 :     return KFC_DUMP_SUCCESS;
     134              : }
     135              : 
     136           43 : KfcDumpResult KfcDumpProcess::PostDumpResults(OpStatsResult& opStatsResult, KfcDumpTask* dumpTask, uint32_t resultNum)
     137              : {
     138           43 :     if (AicpuDumpOpTaskData == nullptr) {
     139            0 :         IDE_LOGE("AicpuDumpOpTaskData is unresolved, statistics result cannot be reported");
     140            0 :         return KFC_DUMP_E_NOT_SUPPORT;
     141              :     }
     142           43 :     auto dumpOpTaskDataStartTime = GetCurCpuTimestamp();
     143           43 :     opStatsResult.tensorNum = resultNum;
     144           43 :     uint32_t ret = AicpuDumpOpTaskData(*dumpTask, &opStatsResult, sizeof(OpStatsResult));
     145           43 :     if (ret != 0) {
     146            1 :         IDE_LOGE("Failed to report statistics result to aicpu scheduler, ret[%u]", ret);
     147            1 :         return KFC_DUMP_E_INTERNAL;
     148              :     }
     149           42 :     IDE_LOGI(
     150              :         "Report[%u] statistics results, time cost[%lu us]", resultNum,
     151              :         (GetCurCpuTimestamp() - dumpOpTaskDataStartTime) / NSEC_PER_USEC);
     152           42 :     return KFC_DUMP_SUCCESS;
     153              : }
     154              : 
     155           32 : KfcDumpResult KfcDumpProcess::FillAivArgs(KfcDumpContext* kfcAivArgs)
     156              : {
     157           32 :     g_dumpContext.workspaceSizeAddr = reinterpret_cast<uint64_t>(&kfcAivArgs->workspaceSize);
     158           32 :     g_dumpContext.aiCoreNumAddr = reinterpret_cast<uint64_t>(&kfcAivArgs->aiCoreNum);
     159           32 :     g_dumpContext.ubSizeAddr = reinterpret_cast<uint64_t>(&kfcAivArgs->ubSize);
     160           32 :     errno_t ret = memcpy_s(kfcAivArgs, sizeof(KfcDumpContext), &g_dumpContext, sizeof(KfcDumpContext));
     161           32 :     if (ret != EOK) {
     162            0 :         IDE_LOGE("Failed to fill statistics operator arguments, ret[%d]", ret);
     163            0 :         return KFC_DUMP_E_MEMORY;
     164              :     }
     165           32 :     KfcDumpPrintf::PrintDumpContext(kfcAivArgs);
     166           32 :     return KFC_DUMP_SUCCESS;
     167              : }
     168              : 
     169           30 : KfcDumpResult KfcDumpProcess::WaitTaskFinish()
     170              : {
     171           30 :     uint32_t curSqHead = g_kfcDumpStreamInfo.sqHead;
     172           30 :     auto waitTaskTimeStart = GetCurCpuTimestamp();
     173           60 :     while (g_kfcDumpStreamInfo.sqHead <= curSqHead) {
     174           30 :         DUMP_STATS_CHK_RET(KfcDumpTaskDispatcher::QuerySqStatusByType(
     175              :             g_kfcDumpStreamInfo.devId, g_kfcDumpStreamInfo.sqId, DRV_SQCQ_PROP_SQ_HEAD, g_kfcDumpStreamInfo.sqHead));
     176           30 :         if ((curSqHead == (g_kfcDumpStreamInfo.sqDepth - 1)) && g_kfcDumpStreamInfo.sqHead == 0) {
     177            0 :             IDE_LOGD("Sq head wrapped around to[%u]", g_kfcDumpStreamInfo.sqHead);
     178            0 :             break;
     179              :         }
     180           30 :         if (CheckTimeOut(waitTaskTimeStart) != KFC_DUMP_SUCCESS) {
     181            0 :             IDE_LOGE(
     182              :                 "Wait for statistics task finish timeout, devId[%u] sqId[%u] sqHead[%u]", g_kfcDumpStreamInfo.devId,
     183              :                 g_kfcDumpStreamInfo.sqId, g_kfcDumpStreamInfo.sqHead);
     184            0 :             return KFC_DUMP_E_TIMEOUT;
     185              :         }
     186              :     }
     187           30 :     IDE_LOGI("Statistics dump task finished, sqHead[%u]", g_kfcDumpStreamInfo.sqHead);
     188           30 :     return KFC_DUMP_SUCCESS;
     189              : }
     190              : 
     191           34 : KfcDumpResult KfcDumpProcess::KfcDumpRunStatServer(KfcDumpTask* dumpTask, KfcDumpInfo* dumpInfo)
     192              : {
     193           34 :     if (!g_isInitialized) {
     194            1 :         IDE_LOGE("Kfc dump server is not initialized, cannot launch dump statistics task");
     195            1 :         return KFC_DUMP_E_INTERNAL;
     196              :     }
     197              : 
     198           33 :     OpStatsResult dumpResult = {};
     199           33 :     dumpResult.statItem = g_dumpParam.config.statsType;
     200           33 :     uint32_t tensorNum = dumpInfo->inputDumpInfo.size() + dumpInfo->outputDumpInfo.size();
     201           33 :     if (tensorNum == 0) {
     202            1 :         return KFC_DUMP_SUCCESS;
     203              :     }
     204           32 :     IDE_LOGI("Kfc dump server received %u tensors to dump", tensorNum);
     205           32 :     DUMP_STATS_CHK_RET(GetAivDumpContext());
     206              :     static KfcDumpStatsServer dump;
     207           32 :     dump.Init(g_dumpParam.kfcWorkSpace.msgQ);
     208              : 
     209           32 :     if (g_addOneStatDumpTask == nullptr || g_printSqeInfo == nullptr) {
     210            0 :         IDE_LOGE("Sqe construct function is null, chip type may be unsupported");
     211            0 :         return KFC_DUMP_E_INTERNAL;
     212              :     }
     213           32 :     uint8_t sqeBuffer[AC_SQE_SIZE] = {0};
     214              :     // msgQ长度1M,后半部分(+0x800)分配给syncSpace,尾部72B(KfcDumpContext)分配给kfc算子作为输入参数
     215           32 :     KfcDumpContext* kfcStatOpArgs = reinterpret_cast<KfcDumpContext*>(
     216           32 :         g_dumpParam.kfcWorkSpace.msgQ + g_dumpParam.kfcWorkSpace.msgQSize - sizeof(KfcDumpContext));
     217           32 :     DUMP_STATS_CHK_RET(FillAivArgs(kfcStatOpArgs));
     218              :     // 根据不同的芯片类型构造Sqe参数
     219           32 :     g_addOneStatDumpTask(sqeBuffer, &g_dumpParam, kfcStatOpArgs);
     220           32 :     g_printSqeInfo(sqeBuffer);
     221              :     // 下发Sqe拉起kfc算子
     222           32 :     DUMP_STATS_CHK_RET(KfcDumpTaskDispatcher::LaunchTask(sqeBuffer, &g_kfcDumpStreamInfo));
     223              : 
     224              :     // 算子已拉起:此后无论统计阶段成败,都必须发 FINISHED 让 AIV 退出循环,
     225              :     // 否则该实例永久占核,且下一次 Launch 拉起的新实例会与它争抢同一消息队列。
     226           30 :     KfcDumpResult statsRet = RunStatsExchange(dumpTask, dumpInfo, dump, dumpResult, tensorNum);
     227           30 :     KfcDumpResult finishRet = FinishStatsTask(dump);
     228              :     // 保留首个业务错误码,避免被收尾结果掩盖
     229           30 :     return (statsRet != KFC_DUMP_SUCCESS) ? statsRet : finishRet;
     230              : }
     231              : 
     232           30 : KfcDumpResult KfcDumpProcess::RunStatsExchange(
     233              :     KfcDumpTask* dumpTask, KfcDumpInfo* dumpInfo, KfcDumpStatsServer& dump, OpStatsResult& dumpResult,
     234              :     uint32_t tensorNum)
     235              : {
     236              :     // 通知kfc算子做tensor统计任务。
     237           30 :     g_tensorCount = 0;
     238           30 :     DUMP_STATS_CHK_RET(
     239              :         KfcDumpStatClientProcess(dumpTask, dumpInfo->inputDumpInfo, dump, dumpResult, TENSOR_TYPE_INPUT));
     240           23 :     DUMP_STATS_CHK_RET(
     241              :         KfcDumpStatClientProcess(dumpTask, dumpInfo->outputDumpInfo, dump, dumpResult, TENSOR_TYPE_OUTPUT));
     242              : 
     243              :     // 未满STEP上报给aicpu
     244           23 :     if (tensorNum % STEP_COUNT != 0) {
     245            0 :         DUMP_STATS_CHK_RET(PostDumpResults(dumpResult, dumpTask, tensorNum % STEP_COUNT));
     246              :     }
     247           23 :     return KFC_DUMP_SUCCESS;
     248              : }
     249              : 
     250           30 : KfcDumpResult KfcDumpProcess::FinishStatsTask(KfcDumpStatsServer& dump)
     251              : {
     252              :     // 通知kfc算子结束退出
     253           30 :     IDE_LOGD("All tensor dump finished, unlaunch dump statistics task");
     254           30 :     KfcDumpStatsMsg gMsg = {};
     255           30 :     gMsg.msgType = DumpStatMsgType::KFC_DUMP_MSG_FINISHED;
     256              :     // PostMsg 失败也要继续 WaitTaskFinish:AIV 可能已消费到 FINISHED 而仅是本次投递超时,
     257              :     // 直接返回会漏掉等待,使下一次 Launch 与未退出的实例重叠。
     258           30 :     KfcDumpResult postRet = dump.PostMsg(&gMsg);
     259           30 :     if (postRet != KFC_DUMP_SUCCESS) {
     260            0 :         IDE_LOGE("Failed to post KFC_DUMP_MSG_FINISHED, result=%d", postRet);
     261              :     }
     262           30 :     KfcDumpResult waitRet = KfcDumpProcess::WaitTaskFinish();
     263           60 :     return (postRet != KFC_DUMP_SUCCESS) ? postRet : waitRet;
     264              : }
     265              : 
     266           53 : KfcDumpResult KfcDumpProcess::KfcDumpStatClientProcess(
     267              :     KfcDumpTask* dumpTask, const std::vector<InputOutputKfcDumpInfo>& dumpTensorList, KfcDumpStatsServer& dump,
     268              :     OpStatsResult& dumpResult, TensorType tensorType)
     269              : {
     270           53 :     if (dumpTensorList.size() == 0) {
     271            4 :         IDE_LOGW(
     272              :             "No tensor in this task, streamId=%u, taskId=%u, index=%u, tensorType=%u", dumpTask->streamId_,
     273              :             dumpTask->taskId_, dumpTask->index_, static_cast<uint32_t>(tensorType));
     274            4 :         return KFC_DUMP_SUCCESS;
     275              :     }
     276              : 
     277           49 :     KfcDumpStatsMsg gMsg = {};
     278          478 :     for (size_t tensorIndex = 0; tensorIndex < dumpTensorList.size(); tensorIndex++) {
     279          436 :         const auto& dumpTensor = dumpTensorList[tensorIndex];
     280          436 :         gMsg.msgType = DumpStatMsgType::KFC_DUMP_MSG_REQUEST;
     281          436 :         gMsg.dataType = dumpTensor.data_type;
     282          436 :         gMsg.dataCount = dumpTensor.size;
     283          436 :         gMsg.dataAddr = dumpTensor.address;
     284          436 :         gMsg.dumpStatClass = g_dumpParam.config.statsType;
     285          436 :         gMsg.outputAddr = g_dumpParam.kfcWorkSpace.output;
     286          436 :         gMsg.outputAddrSize = g_dumpParam.kfcWorkSpace.outputSize;
     287          436 :         KfcDumpPrintf::PrintMsg(gMsg);
     288          436 :         uint64_t computeStartTime = GetCurCpuTimestamp();
     289          436 :         DUMP_STATS_CHK_RET(dump.PostMsg(&gMsg));
     290          436 :         DUMP_STATS_CHK_RET(dump.RcvMsg(&gMsg));
     291          435 :         IDE_LOGI(
     292              :             "Aiv statistics computation finished, time cost[%lu us]",
     293              :             (GetCurCpuTimestamp() - computeStartTime) / NSEC_PER_USEC);
     294          435 :         KfcDumpPrintf::PrintMsg(gMsg);
     295          435 :         if (gMsg.msgType != KFC_DUMP_MSG_RESPONSE) {
     296            3 :             IDE_LOGW("Received unexpected msgType[%u], expect KFC_DUMP_MSG_RESPONSE[2]", gMsg.msgType);
     297            3 :             return KFC_DUMP_E_PARA;
     298              :         }
     299          432 :         dump.CheckDumpResult(&gMsg);
     300          432 :         DUMP_STATS_CHK_RET(
     301              :             UpdateDumpResult(dumpTensor, dumpResult.stat[g_tensorCount % STEP_COUNT], &gMsg, tensorType));
     302          430 :         g_tensorCount++;
     303              :         // 满STEP上报给aicpu
     304          430 :         if (g_tensorCount % STEP_COUNT == 0) {
     305           43 :             DUMP_STATS_CHK_RET(PostDumpResults(dumpResult, dumpTask, STEP_COUNT));
     306              :         }
     307              :     }
     308           42 :     return KFC_DUMP_SUCCESS;
     309              : }
     310              : 
     311          432 : KfcDumpResult KfcDumpProcess::UpdateDumpResult(
     312              :     const InputOutputKfcDumpInfo& dumpTensor, TensorStatsResult& statsResult, KfcDumpStatsMsg* gMsg,
     313              :     TensorType tensorType)
     314              : {
     315          432 :     IDE_LOGI("Update statistics result of one tensor");
     316          432 :     if (dumpTensor.shape.size() > SHAPE_SIZE) {
     317            2 :         IDE_LOGE(
     318              :             "Tensor shape size[%zu] exceeds the upper limit[%u], index[%d]", dumpTensor.shape.size(), SHAPE_SIZE,
     319              :             dumpTensor.index);
     320            2 :         return KFC_DUMP_E_PARA;
     321              :     }
     322          430 :     if (gMsg->outputAddr != g_dumpParam.kfcWorkSpace.output) {
     323            0 :         IDE_LOGE(
     324              :             "Aiv returned unexpected output address, expect[0x%lx] actual[0x%lx]", g_dumpParam.kfcWorkSpace.output,
     325              :             gMsg->outputAddr);
     326            0 :         return KFC_DUMP_E_PARA;
     327              :     }
     328          430 :     statsResult.size = gMsg->dataCount;
     329          430 :     statsResult.dType = gMsg->dataType;
     330          430 :     statsResult.format = dumpTensor.format;
     331          430 :     statsResult.shapeSize = static_cast<int32_t>(dumpTensor.shape.size());
     332         2160 :     for (size_t index = 0; index < dumpTensor.shape.size(); ++index) {
     333         1730 :         statsResult.shape[index] = static_cast<uint32_t>(dumpTensor.shape[index]);
     334              :     }
     335          430 :     statsResult.result = gMsg->result;
     336          430 :     statsResult.statsLen = STAT_LEN;
     337          430 :     statsResult.io = static_cast<int32_t>(tensorType);
     338          430 :     statsResult.index = dumpTensor.index;
     339          430 :     IDE_LOGD(
     340              :         "dataSize[%ld] dataType[%u] shapeSize[%d] tensorType[%u] index[%d]", statsResult.size, statsResult.dType,
     341              :         statsResult.shapeSize, static_cast<uint32_t>(tensorType), statsResult.index);
     342          860 :     errno_t ret = memcpy_s(
     343          430 :         reinterpret_cast<uint8_t*>(statsResult.stats), STAT_LEN,
     344          430 :         reinterpret_cast<uint8_t*>(g_dumpParam.kfcWorkSpace.output), STAT_LEN);
     345          430 :     if (ret != EOK) {
     346            0 :         IDE_LOGE("Failed to copy statistics data to result buffer, ret[%d]", ret);
     347            0 :         return KFC_DUMP_E_MEMORY;
     348              :     }
     349          430 :     return KFC_DUMP_SUCCESS;
     350              : }
     351              : } // namespace kfc_dump_stats
        

Generated by: LCOV version 2.0-1