LCOV - code coverage report
Current view: top level - aicpu_cust_schedule/core/dfx - dump_task.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.5 % 765 639
Test Date: 2026-08-12 11:05:02 Functions: 97.6 % 42 41

            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 "dump_task.h"
      11              : 
      12              : #include <algorithm>
      13              : #include <regex>
      14              : #include <sstream>
      15              : #include <vector>
      16              : #include <sys/time.h>
      17              : 
      18              : #include "aicpusd_drv_manager.h"
      19              : #include "aicpusd_status.h"
      20              : #include "common/aicpusd_util.h"
      21              : #include "securec.h"
      22              : #include "metadef_types.h"
      23              : 
      24              : namespace AicpuSchedule {
      25              : // slice size for dump file, 128MByes
      26              : const uint64_t DUMP_SLICE_SIZE = 128UL << 20U;
      27              : const size_t INTERNAL_STEP_SIZE = 2U;
      28              : 
      29            2 : static inline uint64_t GetCurrentTime()
      30              : {
      31            2 :     uint64_t ret = 0U;
      32              :     struct timeval tv;
      33            2 :     if (gettimeofday(&tv, nullptr) == 0) {
      34            2 :         ret = (static_cast<uint64_t>(tv.tv_sec) * 1000000UL) + static_cast<uint64_t>(tv.tv_usec);
      35              :     }
      36              : 
      37            2 :     return ret;
      38              : }
      39              : 
      40           22 : OpDumpTask::OpDumpTask(const int32_t hostPid, const uint32_t deviceId)
      41           22 :     : taskDumpNum_(0U),
      42           22 :       endGraph_(false),
      43           22 :       inputTotalSize_(0U),
      44           22 :       outputTotalSize_(0U),
      45           22 :       opBufferTotalSize_(0U),
      46           22 :       opWorkspaceTotalSize_(0U),
      47           22 :       buff_(nullptr),
      48           22 :       buffSize_(0U),
      49           22 :       offset_(0U),
      50           22 :       skipAddressConversion_(false),
      51           22 :       hostPid_(hostPid),
      52           22 :       deviceId_(deviceId)
      53           22 : {}
      54              : 
      55           16 : static inline void ReplaceStringElem(std::string& str)
      56              : {
      57           16 :     (void)for_each(str.begin(), str.end(), [](char_t& ch) {
      58          206 :         if ((ch == ' ') || (ch == '.') || (ch == '/') || (ch == '\\')) {
      59           66 :             ch = '_';
      60              :         }
      61          206 :     });
      62           16 : }
      63              : 
      64            8 : StatusCode OpDumpTask::GetDumpNumber(uint64_t& dumpNum)
      65              : {
      66            8 :     if (optionalParam_.hasStepId) {
      67            7 :         if (optionalParam_.stepIdAddr == nullptr) {
      68            1 :             aicpusd_err("op name[%s], step id addr is null", opName_.c_str());
      69            1 :             return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
      70              :         }
      71              : 
      72            6 :         const uint64_t stepId = *(optionalParam_.stepIdAddr);
      73            6 :         aicpusd_info("op name[%s], step id is[%llu]", opName_.c_str(), stepId);
      74            6 :         uint64_t iterationsPerLoop = 0U;
      75            6 :         uint64_t loopCond = 0U;
      76            6 :         if (optionalParam_.hasIterationsPerLoop) {
      77            5 :             if (optionalParam_.iterationsPerLoopAddr == nullptr) {
      78            1 :                 aicpusd_err("op name[%s], iterations per loop addr is null", opName_.c_str());
      79            1 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
      80              :             }
      81            4 :             iterationsPerLoop = *(optionalParam_.iterationsPerLoopAddr);
      82            4 :             aicpusd_info("op name[%s], iterations per loop is[%llu]", opName_.c_str(), iterationsPerLoop);
      83              :         }
      84            5 :         if (optionalParam_.hasLoopCond) {
      85            3 :             if (optionalParam_.loopCondAddr == nullptr) {
      86            2 :                 aicpusd_err("op name[%s], loop cond addr is null", opName_.c_str());
      87            2 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
      88              :             }
      89            1 :             loopCond = *(optionalParam_.loopCondAddr);
      90            1 :             aicpusd_info("op name[%s], loop cond is[%llu]", opName_.c_str(), loopCond);
      91              :         }
      92            3 :         aicpusd_info(
      93              :             "op name[%s], step id[%llu], iterations per loop[%llu], loop cond[%llu]", opName_.c_str(), stepId,
      94              :             iterationsPerLoop, loopCond);
      95              :         // overflow does not matter
      96            3 :         dumpNum = (stepId * (iterationsPerLoop + 1U)) + loopCond;
      97              :     } else {
      98            1 :         dumpNum = taskDumpNum_;
      99              :     }
     100              : 
     101            4 :     return AICPU_SCHEDULE_OK;
     102              : }
     103              : 
     104            7 : StatusCode OpDumpTask::PreProcessOutput(const aicpu::dump::Task& task, ::toolkit::dumpdata::DumpData& dumpData)
     105              : {
     106            7 :     const auto& outputsFromMapInfo = task.output();
     107           17 :     for (int32_t index = 0; index < outputsFromMapInfo.size(); ++index) {
     108           10 :         const auto& item = outputsFromMapInfo.at(index);
     109           10 :         ::toolkit::dumpdata::OpOutput* const opOutput = dumpData.add_output();
     110           10 :         if (opOutput == nullptr) {
     111            0 :             aicpusd_err("op name[%s], call protobuf function to add output elem failed", opName_.c_str());
     112            0 :             return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     113              :         }
     114           10 :         opOutput->set_data_type(static_cast<::toolkit::dumpdata::OutputDataType>(item.data_type()));
     115           10 :         const auto format = item.format();
     116           10 :         opOutput->set_format(static_cast<::toolkit::dumpdata::OutputFormat>(ge::GetPrimaryFormat(format)));
     117           10 :         opOutput->set_sub_format(ge::GetSubFormat(format));
     118           10 :         const auto dims = item.shape().dim();
     119           10 :         ::toolkit::dumpdata::Shape* const outShape = opOutput->mutable_shape();
     120           30 :         for (const auto dim : dims) {
     121           20 :             outShape->add_dim(dim);
     122              :         }
     123           10 :         const auto originalDims = item.origin_shape().dim();
     124           10 :         ::toolkit::dumpdata::Shape* const outOriginalShape = opOutput->mutable_original_shape();
     125           15 :         for (const auto dim : originalDims) {
     126            5 :             outOriginalShape->add_dim(dim);
     127              :         }
     128           10 :         if (!item.original_name().empty()) {
     129            7 :             ::toolkit::dumpdata::OriginalOp* const orgOp = opOutput->mutable_original_op();
     130            7 :             orgOp->set_name(item.original_name());
     131            7 :             orgOp->set_output_index(static_cast<uint32_t>(item.original_output_index()));
     132            7 :             orgOp->set_data_type(static_cast<::toolkit::dumpdata::OutputDataType>(item.original_output_data_type()));
     133            7 :             orgOp->set_format(static_cast<::toolkit::dumpdata::OutputFormat>(item.original_output_format()));
     134              :         }
     135           10 :         const auto& dim_rangeFromOutput = item.dim_range();
     136           14 :         for (int32_t i = 0; i < dim_rangeFromOutput.size(); ++i) {
     137            4 :             const auto& item = dim_rangeFromOutput.at(i);
     138            4 :             ::toolkit::dumpdata::DimRange* const dimRange = opOutput->add_dim_range();
     139            4 :             if (dimRange == nullptr) {
     140            0 :                 aicpusd_err(
     141              :                     "op name[%s], call protobuf function to add dim_range elem failed, i[%d],"
     142              :                     " dim_range_size[%zu]",
     143              :                     opName_.c_str(), i, dim_rangeFromOutput.size());
     144            0 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     145              :             }
     146            4 :             dimRange->set_dim_start(item.dim_start());
     147            4 :             dimRange->set_dim_end(item.dim_end());
     148              :         }
     149           10 :         opOutput->set_size(item.size());
     150           10 :         outputTotalSize_ += item.size();
     151           10 :         outputsBaseAddr_.push_back(item.address());
     152           10 :     }
     153            7 :     return AICPU_SCHEDULE_OK;
     154              : }
     155              : 
     156            7 : StatusCode OpDumpTask::PreProcessInput(const aicpu::dump::Task& task, ::toolkit::dumpdata::DumpData& dumpData)
     157              : {
     158            7 :     const auto& inputsFromMapInfo = task.input();
     159           14 :     for (int32_t i = 0; i < inputsFromMapInfo.size(); ++i) {
     160            7 :         const auto& item = inputsFromMapInfo.at(i);
     161            7 :         ::toolkit::dumpdata::OpInput* const opInput = dumpData.add_input();
     162            7 :         if (opInput == nullptr) {
     163            0 :             aicpusd_err("op name[%s], call protobuf function to add input elem failed", opName_.c_str());
     164            0 :             return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     165              :         }
     166            7 :         opInput->set_data_type(static_cast<::toolkit::dumpdata::OutputDataType>(item.data_type()));
     167            7 :         const auto format = item.format();
     168            7 :         opInput->set_format(static_cast<::toolkit::dumpdata::OutputFormat>(ge::GetPrimaryFormat(format)));
     169            7 :         opInput->set_sub_format(ge::GetSubFormat(format));
     170            7 :         const auto dims = item.shape().dim();
     171            7 :         ::toolkit::dumpdata::Shape* const inShape = opInput->mutable_shape();
     172           21 :         for (const auto dim : dims) {
     173           14 :             inShape->add_dim(dim);
     174              :         }
     175            7 :         const auto originalDims = item.origin_shape().dim();
     176            7 :         ::toolkit::dumpdata::Shape* const inOriginalShape = opInput->mutable_original_shape();
     177           12 :         for (const auto dim : originalDims) {
     178            5 :             inOriginalShape->add_dim(dim);
     179              :         }
     180              : 
     181            7 :         opInput->set_size(item.size());
     182            7 :         inputTotalSize_ += item.size();
     183            7 :         inputsBaseAddr_.push_back(item.address());
     184            7 :     }
     185            7 :     return AICPU_SCHEDULE_OK;
     186              : }
     187              : 
     188            7 : StatusCode OpDumpTask::PreProcessOpBuffer(const aicpu::dump::Task& task, ::toolkit::dumpdata::DumpData& dumpData)
     189              : {
     190            7 :     const auto& opsBufferFromMapInfo = task.buffer();
     191           11 :     for (int32_t i = 0; i < opsBufferFromMapInfo.size(); ++i) {
     192            4 :         const auto& item = opsBufferFromMapInfo.at(i);
     193            4 :         ::toolkit::dumpdata::OpBuffer* const opBuffer = dumpData.add_buffer();
     194            4 :         if (opBuffer == nullptr) {
     195            0 :             aicpusd_err("op name[%s], call protobuf function to add op buffer elem failed", opName_.c_str());
     196            0 :             return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     197              :         }
     198              : 
     199            4 :         opBuffer->set_buffer_type(static_cast<::toolkit::dumpdata::BufferType>(item.buffer_type()));
     200            4 :         opBuffer->set_size(item.size());
     201            4 :         opBufferTotalSize_ += item.size();
     202            4 :         opBufferAddr_.push_back(item.address());
     203              :     }
     204            7 :     return AICPU_SCHEDULE_OK;
     205              : }
     206              : 
     207            8 : StatusCode OpDumpTask::PreProcessWorkspace(const aicpu::dump::Task& task, ::toolkit::dumpdata::DumpData& dumpData)
     208              : {
     209            8 :     const auto& opsWorkspaceFromMapInfo = task.space();
     210           10 :     for (int64_t i = 0; i < opsWorkspaceFromMapInfo.size(); ++i) {
     211            2 :         const auto& item = opsWorkspaceFromMapInfo.at(i);
     212            2 :         ::toolkit::dumpdata::Workspace* const opWorkspace = dumpData.add_space();
     213            2 :         if (opWorkspace == nullptr) {
     214            0 :             aicpusd_err("op name[%s], call protobuf function to add op Workspace elem failed", opName_.c_str());
     215            0 :             return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     216              :         }
     217              : 
     218            2 :         opWorkspace->set_type(static_cast<::toolkit::dumpdata::Workspace::SpaceType>(item.type()));
     219            2 :         opWorkspace->set_size(item.size());
     220            2 :         opWorkspaceTotalSize_ += item.size();
     221            2 :         opWorkspaceAddr_.push_back(item.data_addr());
     222              :     }
     223            8 :     return AICPU_SCHEDULE_OK;
     224              : }
     225              : 
     226            6 : StatusCode OpDumpTask::PreProcessOpMappingInfo(
     227              :     const aicpu::dump::Task& task, const std::string& basePath, const MappingInfoOptionalParam& param,
     228              :     const DumpStep& dumpStep, const bool skipAddressConversion)
     229              : {
     230            6 :     aicpusd_info(
     231              :         "Base path[%s], has model name[%d], model name[%s], has model id[%d], model id[%u].", basePath.c_str(),
     232              :         static_cast<int32_t>(param.hasModelName), param.modelName.c_str(), static_cast<int32_t>(param.hasModelId),
     233              :         param.modelId);
     234            6 :     aicpusd_debug("task info[%s].", task.DebugString().c_str());
     235            6 :     const std::lock_guard<std::mutex> queLock(dumpMtx_);
     236            6 :     baseDumpPath_ = basePath;
     237            6 :     optionalParam_ = param;
     238            6 :     dumpStep_ = dumpStep;
     239            6 :     skipAddressConversion_ = skipAddressConversion;
     240              :     // single op no task id and stream id
     241            6 :     taskInfo_.taskId_ = (skipAddressConversion_ && optionalParam_.hasStepId) ? 0U : task.task_id();
     242            6 :     taskInfo_.streamId_ = (skipAddressConversion_ && optionalParam_.hasStepId) ? 0U : task.stream_id();
     243            6 :     endGraph_ = task.end_graph();
     244              : 
     245            6 :     ::toolkit::dumpdata::DumpData dumpData;
     246              :     // version 2.0
     247              :     dumpData.set_version("2.0");
     248            6 :     StatusCode ret = PreProcessInput(task, dumpData);
     249            6 :     if (ret != AICPU_SCHEDULE_OK) {
     250            0 :         return ret;
     251              :     }
     252            6 :     ret = PreProcessOutput(task, dumpData);
     253            6 :     if (ret != AICPU_SCHEDULE_OK) {
     254            0 :         return ret;
     255              :     }
     256            6 :     ret = PreProcessOpBuffer(task, dumpData);
     257            6 :     if (ret != AICPU_SCHEDULE_OK) {
     258            0 :         return ret;
     259              :     }
     260            6 :     ret = PreProcessWorkspace(task, dumpData);
     261            6 :     if (ret != AICPU_SCHEDULE_OK) {
     262            0 :         return ret;
     263              :     }
     264            6 :     opName_ = task.op().op_name();
     265            6 :     opType_ = task.op().op_type();
     266            6 :     dumpData.set_op_name(opName_);
     267            6 :     aicpusd_info(
     268              :         "[stream id:%u, task id:%u], op name[%s], op type[%s]", taskInfo_.streamId_, taskInfo_.taskId_, opName_.c_str(),
     269              :         opType_.c_str());
     270            6 :     baseDumpData_ = std::move(dumpData);
     271            6 :     taskDumpNum_ = 0U;
     272              : 
     273            6 :     return AICPU_SCHEDULE_OK;
     274            6 : }
     275              : 
     276            6 : StatusCode OpDumpTask::ProcessInputDump(
     277              :     const ::toolkit::dumpdata::DumpData& dumpData, const std::string& path, const IDE_SESSION ideSession)
     278              : {
     279            6 :     uint64_t dumpedSize = 0U;
     280           11 :     for (int32_t i = 0; i < dumpData.input_size(); ++i) {
     281            6 :         auto& input = dumpData.input(i);
     282            6 :         const uint64_t len = input.size();
     283            6 :         if (len == 0U) {
     284            1 :             aicpusd_info("op name[%s], input[%d] data size is zero", opName_.c_str(), i);
     285            1 :             continue;
     286              :         }
     287            5 :         const uint64_t baseAddr = inputsBaseAddr_.at(static_cast<size_t>(i));
     288            5 :         uint64_t dataAddr = baseAddr;
     289            5 :         if (!skipAddressConversion_) {
     290            3 :             if (baseAddr == 0U) {
     291            1 :                 aicpusd_info("op name[%s], input[%d] base addr is null", opName_.c_str(), i);
     292            1 :                 continue;
     293              :             }
     294              :             // baseAddr is a pointer point to data addr
     295            2 :             dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(baseAddr)));
     296              :         }
     297            4 :         aicpusd_info("op name[%s], input[%d] size[%llu]", opName_.c_str(), i, len);
     298            4 :         if (dataAddr == 0U) {
     299            1 :             aicpusd_info("op name[%s], input[%d] addr is null", opName_.c_str(), i);
     300            1 :             continue;
     301              :         }
     302            3 :         uint64_t innerOffset = 0U;
     303            5 :         while (innerOffset < len) {
     304            3 :             const uint64_t emptyBufferSize = buffSize_ - offset_;
     305            3 :             const uint64_t actSize = std::min(emptyBufferSize, len - innerOffset);
     306            3 :             const uint64_t srcAddr = dataAddr + innerOffset;
     307            3 :             aicpusd_info(
     308              :                 "op name[%s], begin to copy data from HBM to DDR for input[%d], size[%llu]", opName_.c_str(), i,
     309              :                 actSize);
     310            3 :             const errno_t eRet = memcpy_s(buff_.get() + offset_, emptyBufferSize, ValueToPtr(srcAddr), actSize);
     311            3 :             if (eRet != EOK) {
     312            0 :                 aicpusd_err(
     313              :                     "op name[%s], input[%d] memcpy failed, desSize[%llu], srcSize[%llu]", opName_.c_str(), i,
     314              :                     emptyBufferSize, actSize);
     315            1 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     316              :             }
     317            3 :             aicpusd_info(
     318              :                 "op name[%s], end of copy data from HBM to DDR for input[%d], size[%llu]", opName_.c_str(), i, actSize);
     319            3 :             offset_ += actSize;
     320            3 :             innerOffset += actSize;
     321            3 :             dumpedSize += actSize;
     322            2 :             const bool isLastSilce = (dumpedSize == inputTotalSize_) && (outputTotalSize_ == 0U) &&
     323            5 :                                      (opBufferTotalSize_ == 0U) && (opWorkspaceTotalSize_ == 0U);
     324            3 :             if ((offset_ >= buffSize_) || isLastSilce) {
     325            1 :                 const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
     326            1 :                 if (ret != AICPU_SCHEDULE_OK) {
     327            1 :                     aicpusd_err("op name[%s], dump input failed", opName_.c_str());
     328            1 :                     return ret;
     329              :                 }
     330            0 :                 offset_ = 0U;
     331              :             }
     332              :         }
     333            2 :         aicpusd_info("op name[%s], process input[%d] data dump success.", opName_.c_str(), i);
     334              :     }
     335            5 :     return AICPU_SCHEDULE_OK;
     336              : }
     337              : 
     338            2 : StatusCode OpDumpTask::ProcessOutputDump(
     339              :     const ::toolkit::dumpdata::DumpData& dumpData, const std::string& path, const IDE_SESSION ideSession)
     340              : {
     341            2 :     uint64_t dumpedSize = 0U;
     342            4 :     for (int32_t i = 0; i < dumpData.output_size(); ++i) {
     343            2 :         auto& output = dumpData.output(i);
     344            2 :         const uint64_t len = output.size();
     345            2 :         if (len == 0U) {
     346            0 :             aicpusd_info("op name[%s], output[%d] data size is zero", opName_.c_str(), i);
     347            0 :             continue;
     348              :         }
     349            2 :         const uint64_t baseAddr = outputsBaseAddr_.at(static_cast<size_t>(i));
     350            2 :         uint64_t dataAddr = baseAddr;
     351            2 :         if (!skipAddressConversion_) {
     352            1 :             if (baseAddr == 0U) {
     353            0 :                 aicpusd_info("op name[%s], output[%d] base addr is null.", opName_.c_str(), i);
     354            0 :                 continue;
     355              :             }
     356              :             // baseAddr is a pointer point to data addr
     357            1 :             dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(baseAddr)));
     358            1 :             aicpusd_info("op name[%s], output[%d].", opName_.c_str(), i);
     359              :         }
     360            2 :         aicpusd_info("op name[%s], output[%d] size[%llu].", opName_.c_str(), i, len);
     361              : 
     362            2 :         if (dataAddr == 0U) {
     363            0 :             aicpusd_info("op name[%s], output[%d] addr is null", opName_.c_str(), i);
     364            0 :             continue;
     365              :         }
     366            2 :         uint64_t innerOffset = 0U;
     367            4 :         while (innerOffset < len) {
     368            2 :             const uint64_t emptyBufferSize = buffSize_ - offset_;
     369            2 :             const uint64_t actSize = std::min(emptyBufferSize, len - innerOffset);
     370            2 :             const uint64_t srcAddr = dataAddr + innerOffset;
     371            2 :             aicpusd_info(
     372              :                 "op name[%s], begin to copy data from HBM to DDR for output[%d], size[%llu]", opName_.c_str(), i,
     373              :                 actSize);
     374            2 :             const errno_t eRet = memcpy_s(buff_.get() + offset_, emptyBufferSize, ValueToPtr(srcAddr), actSize);
     375            2 :             if (eRet != EOK) {
     376            0 :                 aicpusd_err(
     377              :                     "op name[%s], output[%d] memcpy failed, des[%llu], src[%llu]", opName_.c_str(), i,
     378              :                     PtrToValue(buff_.get() + offset_), srcAddr);
     379            0 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     380              :             }
     381            2 :             aicpusd_info(
     382              :                 "op name[%s], end of copy data from HBM to DDR for output[%d], size[%llu]", opName_.c_str(), i,
     383              :                 actSize);
     384            2 :             offset_ += actSize;
     385            2 :             innerOffset += actSize;
     386            2 :             dumpedSize += actSize;
     387            2 :             const bool isLastSilce =
     388            2 :                 (offset_ >= buffSize_) ||
     389            0 :                 ((dumpedSize == outputTotalSize_) && (opBufferTotalSize_ == 0U) && (opWorkspaceTotalSize_ == 0U));
     390            2 :             if (isLastSilce) {
     391            2 :                 const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
     392            2 :                 if (ret != AICPU_SCHEDULE_OK) {
     393            0 :                     aicpusd_err("op name[%s], dump output failed", opName_.c_str());
     394            0 :                     return ret;
     395              :                 }
     396            2 :                 offset_ = 0U;
     397              :             }
     398              :         }
     399              : 
     400            2 :         aicpusd_info("op name[%s], process output[%d] data dump success.", opName_.c_str(), i);
     401              :     }
     402            2 :     return AICPU_SCHEDULE_OK;
     403              : }
     404              : 
     405            4 : StatusCode OpDumpTask::ProcessOpBufferDump(
     406              :     const ::toolkit::dumpdata::DumpData& dumpData, const std::string& path, const IDE_SESSION ideSession)
     407              : {
     408            4 :     uint64_t dumpedSize = 0U;
     409            5 :     for (int32_t i = 0; i < dumpData.buffer_size(); ++i) {
     410            2 :         auto& buffer = dumpData.buffer(i);
     411            2 :         if (buffer.size() == 0U) {
     412            0 :             aicpusd_info("op name[%s], op buffer[%d] data size is zero", opName_.c_str(), i);
     413            0 :             continue;
     414              :         }
     415            2 :         const size_t opBufferAddrIndex = static_cast<size_t>(i);
     416            2 :         if (opBufferAddr_[opBufferAddrIndex] == 0U) {
     417            1 :             aicpusd_info("op name[%s], op buffer[%d] addr is null", opName_.c_str(), i);
     418            1 :             continue;
     419              :         }
     420            1 :         uint64_t innerOffset = 0U;
     421            1 :         while (innerOffset < buffer.size()) {
     422            1 :             const uint64_t emptyBufferSize = buffSize_ - offset_;
     423            1 :             const uint64_t actSize = std::min(emptyBufferSize, buffer.size() - innerOffset);
     424            1 :             const uint64_t srcAddr = opBufferAddr_[opBufferAddrIndex] + innerOffset;
     425            1 :             aicpusd_info(
     426              :                 "op name[%s], begin to copy data from HBM to DDR for op buffer[%d], size[%llu]", opName_.c_str(), i,
     427              :                 actSize);
     428            1 :             const errno_t eRet = memcpy_s(buff_.get() + offset_, emptyBufferSize, ValueToPtr(srcAddr), actSize);
     429            1 :             if (eRet != EOK) {
     430            1 :                 aicpusd_err(
     431              :                     "op name[%s], op buffer[%d] memcpy failed, desSize[%llu], srcSize[%llu]", opName_.c_str(), i,
     432              :                     emptyBufferSize, actSize);
     433            1 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     434              :             }
     435            0 :             aicpusd_info(
     436              :                 "op name[%s], end of copy data from HBM to DDR for op buffer[%d], size[%llu]", opName_.c_str(), i,
     437              :                 actSize);
     438            0 :             offset_ += actSize;
     439            0 :             innerOffset += actSize;
     440            0 :             dumpedSize += actSize;
     441            0 :             const bool isLastSilce =
     442            0 :                 (offset_ >= buffSize_) || ((dumpedSize == opBufferTotalSize_) && (opWorkspaceTotalSize_ == 0U));
     443            0 :             if (isLastSilce) {
     444            0 :                 const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
     445            0 :                 if (ret != AICPU_SCHEDULE_OK) {
     446            0 :                     aicpusd_err("op name[%s], dump op buffer failed", opName_.c_str());
     447            0 :                     return ret;
     448              :                 }
     449            0 :                 offset_ = 0U;
     450              :             }
     451              :         }
     452            0 :         aicpusd_info("op name[%s], process op buffer[%d] data success.", opName_.c_str(), i);
     453              :     }
     454            3 :     return AICPU_SCHEDULE_OK;
     455              : }
     456              : 
     457            8 : StatusCode OpDumpTask::ProcessOpWorkspaceDump(
     458              :     const ::toolkit::dumpdata::DumpData& dumpData, const std::string& path, const IDE_SESSION ideSession)
     459              : {
     460            8 :     uint64_t dumpedSize = 0U;
     461           12 :     for (int64_t i = 0; i < dumpData.space_size(); ++i) {
     462            6 :         auto& space = dumpData.space(i);
     463            6 :         if (space.size() == 0U) {
     464            1 :             aicpusd_err("op name[%s], op space[%d] data size is zero", opName_.c_str(), i);
     465            1 :             continue;
     466              :         }
     467            5 :         const size_t opWorkspaceAddrIndex = static_cast<size_t>(i);
     468            5 :         if (opWorkspaceAddr_[opWorkspaceAddrIndex] == 0U) {
     469            1 :             aicpusd_err("op name[%s], op space[%d] workspace is null", opName_.c_str(), i);
     470            1 :             continue;
     471              :         }
     472            4 :         uint64_t innerOffset = 0U;
     473            6 :         while (innerOffset < space.size()) {
     474            4 :             const uint64_t emptyWorkspaceSize = buffSize_ - offset_;
     475            4 :             const uint64_t actSize = std::min(emptyWorkspaceSize, space.size() - innerOffset);
     476            4 :             const uint64_t srcAddr = opWorkspaceAddr_[opWorkspaceAddrIndex] + innerOffset;
     477            4 :             aicpusd_info(
     478              :                 "op name[%s], begin to copy data from HBM to DDR for spaceIndex[%d],"
     479              :                 " srcSize[%llu], innerOffset[%llu], offset[%llu], dstSize[%llu]",
     480              :                 opName_.c_str(), i, actSize, innerOffset, offset_, emptyWorkspaceSize);
     481           12 :             const errno_t eRet = memcpy_s(
     482            4 :                 buff_.get() + offset_, emptyWorkspaceSize, PtrToPtr<void, char_t>(ValueToPtr(srcAddr)), actSize);
     483            4 :             if (eRet != EOK) {
     484            1 :                 aicpusd_err(
     485              :                     "op name[%s], op spaceIndex[%d] memcpy failed, dstSize[%llu], srcSize[%llu]", opName_.c_str(), i,
     486              :                     emptyWorkspaceSize, actSize);
     487            2 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     488              :             }
     489            3 :             aicpusd_info(
     490              :                 "op name[%s], op spaceIndex[%d] end copy, dstSize[%llu], srcSize[%llu]", opName_.c_str(), i,
     491              :                 emptyWorkspaceSize, actSize);
     492            3 :             offset_ += actSize;
     493            3 :             innerOffset += actSize;
     494            3 :             dumpedSize += actSize;
     495            3 :             const bool isLastSilce = (dumpedSize == opWorkspaceTotalSize_);
     496            3 :             if (!((offset_ >= buffSize_) || isLastSilce)) {
     497            0 :                 continue;
     498              :             }
     499            3 :             const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
     500            3 :             if (ret != AICPU_SCHEDULE_OK) {
     501            1 :                 aicpusd_err("op name[%s], dump op space failed", opName_.c_str());
     502            1 :                 return ret;
     503              :             }
     504            2 :             offset_ = 0U;
     505              :         }
     506            2 :         aicpusd_info("op name[%s], process op space[%d] data success.", opName_.c_str(), i);
     507              :     }
     508            6 :     return AICPU_SCHEDULE_OK;
     509              : }
     510              : 
     511            6 : StatusCode OpDumpTask::Dump(
     512              :     const std::string& path, char_t* const data, const uint64_t len, const IDE_SESSION ideSession,
     513              :     const bool isLastSlice) const
     514              : {
     515            6 :     if (ideSession != nullptr) {
     516            6 :         IdeDumpChunk ideDumpChunk = {};
     517            6 :         ideDumpChunk.fileName = const_cast<char_t*>(path.c_str());
     518            6 :         ideDumpChunk.dataBuf = reinterpret_cast<uint8_t*>(data);
     519            6 :         ideDumpChunk.bufLen = static_cast<uint32_t>(len);
     520            6 :         ideDumpChunk.isLastChunk = isLastSlice ? 1U : 0U;
     521            6 :         ideDumpChunk.offset = -1; // append
     522            6 :         ideDumpChunk.flag = IDE_DUMP_NONE_FLAG;
     523            6 :         aicpusd_info(
     524              :             "op name[%s], start to call IdeDumpData, size[%u], isLastChunk[%u]", opName_.c_str(), len,
     525              :             ideDumpChunk.isLastChunk);
     526            6 :         const IdeErrorT ideState = IdeDumpData(ideSession, &ideDumpChunk);
     527            6 :         if (ideState != IDE_DAEMON_NONE_ERROR) {
     528            2 :             aicpusd_err("op name[%s], call IdeDumpData failed, size[%u].", opName_.c_str(), len);
     529            2 :             return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     530              :         }
     531            4 :         aicpusd_info("op name[%s], end of call IdeDumpData, size[%u]", opName_.c_str(), len);
     532              :     } else {
     533            0 :         aicpusd_err("op name[%s], ide session is null, size[%u].", opName_.c_str(), len);
     534            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     535              :     }
     536            4 :     return AICPU_SCHEDULE_OK;
     537              : }
     538              : 
     539            3 : StatusCode OpDumpTask::DumpOpInfo(const uint32_t streamId, const uint32_t taskId, const std::string& dumpDebugInfo)
     540              : {
     541            3 :     const std::lock_guard<std::mutex> queLock(dumpMtx_);
     542            3 :     uint64_t dumpNumber = 0U;
     543            3 :     if (GetDumpNumber(dumpNumber) != AICPU_SCHEDULE_OK) {
     544            1 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     545              :     }
     546            2 :     if (!NeedDump(dumpNumber)) {
     547            0 :         return AICPU_SCHEDULE_OK;
     548              :     }
     549              : 
     550            2 :     const uint64_t nowTime = GetCurrentTime();
     551            2 :     baseDumpData_.set_dump_time(nowTime);
     552              : 
     553            2 :     if ((baseDumpData_.ByteSizeLong() > static_cast<uint64_t>(INT_MAX)) || (baseDumpData_.ByteSizeLong() == 0U)) {
     554            0 :         aicpusd_err(
     555              :             "op name[%s], dump data size[%zuB] should be in [1B, 2GB)].", opName_.c_str(),
     556              :             baseDumpData_.ByteSizeLong());
     557            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     558              :     }
     559            2 :     aicpusd_info("op name[%s], proto buffer total bytes[%llu]", opName_.c_str(), baseDumpData_.ByteSizeLong());
     560            2 :     buffSize_ = baseDumpData_.ByteSizeLong() + sizeof(uint64_t) + inputTotalSize_ + outputTotalSize_ +
     561            2 :                 opBufferTotalSize_ + opWorkspaceTotalSize_;
     562            2 :     buffSize_ = std::min(buffSize_, DUMP_SLICE_SIZE);
     563            2 :     buffSize_ = std::max(buffSize_, baseDumpData_.ByteSizeLong() + sizeof(uint64_t));
     564            2 :     buff_.reset(new (std::nothrow) char_t[buffSize_]);
     565            2 :     if (buff_ == nullptr) {
     566            0 :         aicpusd_err("op name[%s], malloc buffer for data dump failed, size[%llu]", opName_.c_str(), buffSize_);
     567            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     568              :     }
     569              :     // for memory statistic
     570            2 :     aicpusd_memory_log(
     571              :         "op name[%s], MallocMemory, func=new, size=%llu, purpose=data dump buffer", opName_.c_str(), buffSize_);
     572            2 :     uint64_t* const sizePtr = PtrToPtr<char_t, uint64_t>(buff_.get());
     573            2 :     *sizePtr = baseDumpData_.ByteSizeLong();
     574            2 :     offset_ = sizeof(uint64_t);
     575            2 :     if (!baseDumpData_.SerializeToArray(
     576            2 :             buff_.get() + sizeof(uint64_t), static_cast<int32_t>(baseDumpData_.ByteSizeLong()))) {
     577            0 :         aicpusd_err(
     578              :             "op name[%s], serialize dump data to string failed, data size[%zuB].", opName_.c_str(),
     579              :             baseDumpData_.ByteSizeLong());
     580            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     581              :     }
     582            2 :     offset_ += baseDumpData_.ByteSizeLong();
     583              :     // dump file path name
     584            2 :     const std::string dumpFilePath = DumpPath(nowTime, dumpNumber, streamId, taskId);
     585            2 :     std::string dumpDebugFilePath;
     586            2 :     if (!(dumpDebugInfo.empty())) {
     587            0 :         dumpDebugFilePath = DumpPath(nowTime, dumpNumber, streamId, taskId, true);
     588              :     }
     589            2 :     return DoDump(dumpFilePath, dumpDebugFilePath, dumpDebugInfo);
     590            3 : }
     591              : 
     592            2 : StatusCode OpDumpTask::DoDump(
     593              :     const std::string& dumpFilePath, const std::string& dumpDebugFilePath, const std::string& dumpDebugInfo)
     594              : {
     595            2 :     aicpusd_info("op name[%s], start to dump data, path[%s]", opName_.c_str(), dumpFilePath.c_str());
     596              :     // the port is not used in ide module, just for privateInfo format check
     597            2 :     const std::string privateInfo = "127.0.0.1:22118;" + std::to_string(deviceId_) + ";" + std::to_string(hostPid_);
     598            2 :     aicpusd_info("op name[%s], ide dump start private info[%s]", opName_.c_str(), privateInfo.c_str());
     599            2 :     const IDE_SESSION ideSession = IdeDumpStart(privateInfo.c_str());
     600            2 :     if (ideSession == nullptr) {
     601            0 :         aicpusd_err("op name[%s], call IdeDumpStart failed, path[%s].", opName_.c_str(), dumpFilePath.c_str());
     602            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     603              :     }
     604            4 :     const ScopeGuard ideSessGuard([&ideSession]() { IdeDumpEnd(ideSession); });
     605            2 :     StatusCode ret = AICPU_SCHEDULE_OK;
     606            2 :     if (offset_ == buffSize_) {
     607            0 :         ret = Dump(dumpFilePath, buff_.get(), buffSize_, ideSession, false);
     608            0 :         if (ret != AICPU_SCHEDULE_OK) {
     609            0 :             aicpusd_err("op name[%s], dump proto failed, path[%s].", opName_.c_str(), dumpFilePath.c_str());
     610            0 :             return ret;
     611              :         }
     612            0 :         offset_ = 0U;
     613              :     }
     614              : 
     615            2 :     ret = ProcessInputDump(baseDumpData_, dumpFilePath, ideSession);
     616            2 :     if (ret != AICPU_SCHEDULE_OK) {
     617            0 :         return ret;
     618              :     }
     619            2 :     ret = ProcessOutputDump(baseDumpData_, dumpFilePath, ideSession);
     620            2 :     if (ret != AICPU_SCHEDULE_OK) {
     621            0 :         return ret;
     622              :     }
     623            2 :     ret = ProcessOpBufferDump(baseDumpData_, dumpFilePath, ideSession);
     624            2 :     if (ret != AICPU_SCHEDULE_OK) {
     625            0 :         return ret;
     626              :     }
     627            2 :     ret = ProcessOpWorkspaceDump(baseDumpData_, dumpFilePath, ideSession);
     628            2 :     if (ret != AICPU_SCHEDULE_OK) {
     629            0 :         return ret;
     630              :     }
     631              :     // release buffer
     632            2 :     buff_.reset(nullptr);
     633              : 
     634            2 :     if (!(dumpDebugInfo.empty())) {
     635              :         ret =
     636            0 :             Dump(dumpDebugFilePath, const_cast<char_t*>(dumpDebugInfo.c_str()), dumpDebugInfo.size(), ideSession, true);
     637            0 :         if (ret != AICPU_SCHEDULE_OK) {
     638            0 :             aicpusd_err("op name[%s], dump debug info failed, path[%s].", opName_.c_str(), dumpDebugFilePath.c_str());
     639            0 :             return ret;
     640              :         }
     641              :     }
     642            2 :     aicpusd_info("op name[%s], dump data success, path[%s]", opName_.c_str(), dumpFilePath.c_str());
     643            2 :     return AICPU_SCHEDULE_OK;
     644            2 : }
     645              : 
     646            1 : void OpDumpTask::UpdateDumpNum()
     647              : {
     648            1 :     const std::lock_guard<std::mutex> queLock(dumpMtx_);
     649            1 :     taskDumpNum_++;
     650            1 :     aicpusd_info("op name[%s], dump number is updated, dump number[%llu].", opName_.c_str(), taskDumpNum_);
     651            1 : }
     652              : 
     653            1 : bool OpDumpTask::IsEndGraph() const { return endGraph_; }
     654              : 
     655            1 : bool OpDumpTask::GetModelId(uint32_t& modelId) const
     656              : {
     657            1 :     if (optionalParam_.hasModelId) {
     658            1 :         modelId = optionalParam_.modelId;
     659            1 :         return true;
     660              :     }
     661            0 :     return false;
     662              : }
     663              : 
     664            0 : std::string OpDumpTask::GetOpName() const { return opName_; }
     665              : 
     666            7 : bool OpDumpTask::NeedDump(const uint64_t step)
     667              : {
     668            7 :     if (endGraph_) {
     669            1 :         aicpusd_run_info("op name[%s], end graph dump task.", opName_.c_str());
     670            1 :         return false;
     671              :     }
     672              : 
     673            6 :     bool stepNeedDump = false;
     674            6 :     if (dumpStep_.singleStep.empty() && dumpStep_.intervalStep.empty()) {
     675            2 :         stepNeedDump = true;
     676              :     }
     677            6 :     if (dumpStep_.singleStep.find(step) != dumpStep_.singleStep.end()) {
     678            1 :         stepNeedDump = true;
     679              :     }
     680            6 :     for (const auto item : dumpStep_.intervalStep) {
     681            2 :         if ((step >= item.start) && (step <= item.end)) {
     682            2 :             stepNeedDump = true;
     683            2 :             break;
     684              :         }
     685              :     }
     686            6 :     if (!stepNeedDump) {
     687            1 :         aicpusd_run_info(
     688              :             "op name[%s], the step[%llu] is not in dump list %s.", opName_.c_str(), step,
     689              :             dumpStep_.DebugString().c_str());
     690            1 :         return false;
     691              :     }
     692              : 
     693            5 :     if ((inputTotalSize_ == 0U) && (outputTotalSize_ == 0U) && (opBufferTotalSize_ == 0U) &&
     694            1 :         (opWorkspaceTotalSize_ == 0U)) {
     695            1 :         aicpusd_run_info("op name[%s], no data need to dump.", opName_.c_str());
     696            1 :         return false;
     697              :     }
     698              : 
     699            4 :     return true;
     700              : }
     701              : 
     702            4 : std::string OpDumpTask::DumpPath(
     703              :     const uint64_t nowTime, const uint64_t dumpNumber, const uint32_t streamId, const uint32_t taskId,
     704              :     const bool debugFlag)
     705              : {
     706            4 :     std::ostringstream oss;
     707            4 :     oss << baseDumpPath_;
     708            4 :     if (optionalParam_.hasModelName) {
     709            3 :         oss << "/" << optionalParam_.modelName;
     710              :     }
     711            4 :     if (optionalParam_.hasModelId) {
     712            3 :         oss << "/" << optionalParam_.modelId;
     713              :     }
     714              :     // single op dump
     715            4 :     if (!((skipAddressConversion_) && (!optionalParam_.hasStepId))) {
     716            3 :         oss << "/" << dumpNumber;
     717              :     }
     718              : 
     719            4 :     std::string opName = opName_;
     720            4 :     std::string opType = opType_;
     721            4 :     ReplaceStringElem(opName);
     722            4 :     ReplaceStringElem(opType);
     723            4 :     if (debugFlag) {
     724            1 :         opName += "Debug";
     725              :     }
     726            4 :     if ((streamId != INVALID_VAL) && (taskId != INVALID_VAL)) {
     727            1 :         oss << "/" << opType << "." << opName << "." << taskId << "." << streamId << "." << nowTime;
     728              :     } else {
     729            3 :         oss << "/" << opType << "." << opName << "." << taskInfo_.taskId_ << "." << taskInfo_.streamId_ << "."
     730            3 :             << nowTime;
     731              :     }
     732            8 :     return oss.str();
     733            4 : }
     734              : 
     735            2 : void OpDumpTask::ClearBaseDumpData()
     736              : {
     737            2 :     baseDumpData_.Clear();
     738            2 :     return;
     739              : }
     740              : 
     741            1 : std::string DumpStep::DebugString()
     742              : {
     743            1 :     std::ostringstream oss;
     744            1 :     for (const auto step : singleStep) {
     745            0 :         oss << "[" << step << "] ";
     746              :     }
     747            1 :     for (const auto step : intervalStep) {
     748            0 :         oss << "[" << step.start << ", " << step.end << "] ";
     749              :     }
     750              : 
     751            2 :     return oss.str();
     752            1 : }
     753              : 
     754            7 : OpDumpTaskManager& OpDumpTaskManager::GetInstance()
     755              : {
     756            7 :     static OpDumpTaskManager instance;
     757            7 :     return instance;
     758              : }
     759              : 
     760            9 : void OpDumpTaskManager::GetOptionalParam(
     761              :     const aicpu::dump::OpMappingInfo& opMappingInfo, MappingInfoOptionalParam& optionalParam) const
     762              : {
     763            9 :     if (opMappingInfo.model_name_param_case() == aicpu::dump::OpMappingInfo::kModelName) {
     764            8 :         optionalParam.modelName = opMappingInfo.model_name();
     765            8 :         ReplaceStringElem(optionalParam.modelName);
     766            8 :         optionalParam.hasModelName = true;
     767              :     }
     768            9 :     if (opMappingInfo.model_id_param_case() == aicpu::dump::OpMappingInfo::kModelId) {
     769            8 :         optionalParam.modelId = opMappingInfo.model_id();
     770            8 :         optionalParam.hasModelId = true;
     771              :     }
     772            9 :     if (opMappingInfo.step_id_case() == aicpu::dump::OpMappingInfo::kStepIdAddr) {
     773            8 :         optionalParam.stepIdAddr = PtrToPtr<void, uint64_t>(ValueToPtr(opMappingInfo.step_id_addr()));
     774            8 :         optionalParam.hasStepId = true;
     775              :     }
     776            9 :     if (opMappingInfo.iterations_per_loop_case() == aicpu::dump::OpMappingInfo::kIterationsPerLoopAddr) {
     777            7 :         optionalParam.iterationsPerLoopAddr =
     778            7 :             PtrToPtr<void, uint64_t>(ValueToPtr(opMappingInfo.iterations_per_loop_addr()));
     779            7 :         optionalParam.hasIterationsPerLoop = true;
     780              :     }
     781            9 :     if (opMappingInfo.loop_cond_case() == aicpu::dump::OpMappingInfo::kLoopCondAddr) {
     782            7 :         optionalParam.loopCondAddr = PtrToPtr<void, uint64_t>(ValueToPtr(opMappingInfo.loop_cond_addr()));
     783            7 :         optionalParam.hasLoopCond = true;
     784              :     }
     785            9 : }
     786              : 
     787            6 : int32_t OpDumpTaskManager::Load(const aicpu::dump::OpMappingInfo& opMappingInfo)
     788              : {
     789            6 :     const std::string dumpPath = opMappingInfo.dump_path();
     790            6 :     MappingInfoOptionalParam optionalParam;
     791            6 :     GetOptionalParam(opMappingInfo, optionalParam);
     792            6 :     const std::string dumpStepStr = opMappingInfo.dump_step();
     793            6 :     DumpStep dumpStep;
     794            6 :     if (!GetDumpStepFromString(dumpStepStr, dumpStep)) {
     795            1 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     796              :     }
     797            5 :     const int32_t hostPid = static_cast<int32_t>(AicpuSchedule::AicpuDrvManager::GetInstance().GetHostPid());
     798            5 :     const uint32_t deviceId = AicpuSchedule::AicpuDrvManager::GetInstance().GetDeviceId();
     799            5 :     std::set<TaskInfo> tasksInfo;
     800              :     {
     801            5 :         const std::lock_guard<std::mutex> mapLock(dumpTaskMapMtx_);
     802           10 :         for (int32_t i = 0; i < opMappingInfo.task_size(); ++i) {
     803            5 :             const aicpu::dump::Task task = opMappingInfo.task(i);
     804            5 :             const uint32_t taskId = task.task_id() & 0xFFFF;
     805            5 :             const uint32_t streamId = task.stream_id();
     806            5 :             std::shared_ptr<OpDumpTask> opDumpTaskPtr = nullptr;
     807              :             try {
     808            5 :                 opDumpTaskPtr = std::make_shared<OpDumpTask>(hostPid, deviceId);
     809            0 :             } catch (...) {
     810            0 :                 aicpusd_err("make shared for OpDumpTask failed.");
     811            0 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     812            0 :             }
     813            5 :             aicpusd_memory_log("MallocMemory, func=new, size=%zu, purpose=data dumper", sizeof(OpDumpTask));
     814            5 :             if (opDumpTaskPtr == nullptr) {
     815            0 :                 aicpusd_err("malloc memory for OpDumpTask object failed");
     816            0 :                 return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     817              :             }
     818            5 :             const int32_t ret = opDumpTaskPtr->PreProcessOpMappingInfo(task, dumpPath, optionalParam, dumpStep);
     819            5 :             if (ret != AICPU_SCHEDULE_OK) {
     820              :                 // when error occur, ge call unload op mapping info
     821            0 :                 aicpusd_err("pre process op mapping info failed");
     822            0 :                 return ret;
     823              :             }
     824            5 :             TaskInfo taskInfo(streamId, taskId);
     825            5 :             (void)dumpTaskMap_.insert(std::make_pair(taskInfo, std::move(opDumpTaskPtr)));
     826            5 :             (void)tasksInfo.insert(taskInfo);
     827            5 :         }
     828            5 :         if (optionalParam.hasModelId) {
     829            5 :             const auto iter = modelIdToTask_.find(optionalParam.modelId);
     830            5 :             if (iter == modelIdToTask_.end()) {
     831            2 :                 (void)modelIdToTask_.insert(std::make_pair(optionalParam.modelId, std::move(tasksInfo)));
     832              :             } else {
     833            6 :                 for (const auto item : tasksInfo) {
     834            3 :                     (void)iter->second.insert(item);
     835              :                 }
     836              :             }
     837              :         }
     838            5 :     }
     839            5 :     return AICPU_SCHEDULE_OK;
     840            6 : }
     841              : 
     842            3 : void OpDumpTaskManager::UnloadClearTaskInfo(const TaskInfo& taskInfo)
     843              : {
     844            3 :     const auto range = dumpTaskMap_.equal_range(taskInfo);
     845            3 :     if (range.first != range.second) {
     846            3 :         for (auto item = range.first; item != range.second; ++item) {
     847            2 :             item->second->ClearBaseDumpData();
     848              :         }
     849              :     }
     850            3 :     (void)dumpTaskMap_.erase(taskInfo);
     851            6 :     return;
     852              : }
     853              : 
     854            2 : int32_t OpDumpTaskManager::Unload(const aicpu::dump::OpMappingInfo& opMappingInfo)
     855              : {
     856            2 :     const std::lock_guard<std::mutex> mapLock(dumpTaskMapMtx_);
     857            4 :     for (int32_t i = 0; i < opMappingInfo.task_size(); ++i) {
     858            2 :         const aicpu::dump::Task task = opMappingInfo.task(i);
     859            2 :         const uint32_t taskId = task.task_id();
     860            2 :         const uint32_t streamId = task.stream_id();
     861            2 :         const TaskInfo taskInfo(streamId, taskId);
     862            2 :         UnloadClearTaskInfo(taskInfo);
     863            2 :         aicpusd_info("Unload op mapping info, stream id[%u], task id[%u].", streamId, taskId);
     864            2 :     }
     865            2 :     MappingInfoOptionalParam optionalParam;
     866            2 :     GetOptionalParam(opMappingInfo, optionalParam);
     867            2 :     if (optionalParam.hasModelId) {
     868            2 :         const auto iter = modelIdToTask_.find(optionalParam.modelId);
     869            2 :         if (iter == modelIdToTask_.end()) {
     870            1 :             aicpusd_warn("no model id[%u], unload dump model failed", optionalParam.modelId);
     871            1 :             return AICPU_SCHEDULE_OK;
     872              :         }
     873            2 :         for (const auto taskInfo : iter->second) {
     874            1 :             UnloadClearTaskInfo(taskInfo);
     875            1 :             aicpusd_info(
     876              :                 "Check and clean data dump task resource, stream id[%u], task id[%u].", taskInfo.streamId_,
     877              :                 taskInfo.taskId_);
     878              :         }
     879            1 :         (void)modelIdToTask_.erase(iter);
     880            1 :         aicpusd_info("Unloaded model id[%u] successfully", optionalParam.modelId);
     881              :     }
     882            1 :     return AICPU_SCHEDULE_OK;
     883            2 : }
     884              : 
     885           10 : int32_t OpDumpTaskManager::LoadOpMappingInfo(const char_t* const infoAddr, const uint32_t len)
     886              : {
     887           10 :     aicpusd_info("Load op mapping info, size[%u].", len);
     888           10 :     if (infoAddr == nullptr) {
     889            1 :         aicpusd_err("op mapping info addr is null");
     890            1 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     891              :     }
     892            9 :     aicpu::dump::OpMappingInfo opMappingInfo;
     893            9 :     const std::string protoInfo(infoAddr, static_cast<unsigned long>(len));
     894            9 :     const bool parseRet = opMappingInfo.ParseFromString(protoInfo);
     895            9 :     if (!parseRet) {
     896            1 :         aicpusd_err("parse op mapping info failed");
     897            1 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     898              :     }
     899            8 :     if (opMappingInfo.flag() == 0x01U) {
     900            6 :         return Load(opMappingInfo);
     901            2 :     } else if (opMappingInfo.flag() == 0x00U) {
     902            2 :         return Unload(opMappingInfo);
     903              :     } else {
     904            0 :         aicpusd_info("Flag [%d] invalid, allow [0x00, 0x01]", opMappingInfo.flag());
     905            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     906              :     }
     907              :     return AICPU_SCHEDULE_OK;
     908            9 : }
     909              : 
     910            2 : int32_t OpDumpTaskManager::DumpOpInfo(
     911              :     const uint32_t streamId, const uint32_t taskId, const uint32_t streamId1, const uint32_t taskId1,
     912              :     const std::string& dumpDebugInfo)
     913              : {
     914            2 :     const TaskInfo taskInfo(streamId, taskId);
     915            2 :     dumpTaskMapMtx_.lock();
     916            2 :     const auto range = dumpTaskMap_.equal_range(taskInfo);
     917            2 :     if (range.first == range.second) {
     918            1 :         dumpTaskMapMtx_.unlock();
     919            1 :         aicpusd_run_info("task required to dump does not exist, stream id[%u], task id[%u].", streamId, taskId);
     920            1 :         return AICPU_SCHEDULE_OK;
     921              :     } else {
     922            1 :         std::vector<std::shared_ptr<OpDumpTask>> opDumptasks;
     923            3 :         for (auto item = range.first; item != range.second; ++item) {
     924            2 :             std::shared_ptr<OpDumpTask> opDumpTask = item->second;
     925            2 :             opDumptasks.push_back(std::move(opDumpTask));
     926            2 :         }
     927            1 :         int32_t ret = AICPU_SCHEDULE_OK;
     928            1 :         dumpTaskMapMtx_.unlock();
     929            1 :         aicpusd_run_info(
     930              :             "require to dump op info, stream id=%u, task id=%u, task number=%zu", streamId, taskId, opDumptasks.size());
     931            2 :         for (auto item : opDumptasks) {
     932            2 :             aicpusd_run_info(
     933              :                 "start to dump op info, stream id=%u, task id=%u, op name=%s", streamId, taskId,
     934              :                 item->GetOpName().c_str());
     935            2 :             ret = item->DumpOpInfo(streamId1, taskId1, dumpDebugInfo);
     936            2 :             aicpusd_run_info(
     937              :                 "end of dump op info, result=%d, stream id=%u, task id=%u, op name=%s", ret, streamId, taskId,
     938              :                 item->GetOpName().c_str());
     939            2 :             if (ret != AICPU_SCHEDULE_OK) {
     940            1 :                 return ret;
     941              :             }
     942            2 :         }
     943              :         // process if task is end graph
     944            0 :         ProcessEndGraph(opDumptasks);
     945            1 :     }
     946            0 :     return AICPU_SCHEDULE_OK;
     947              : }
     948              : 
     949            2 : int32_t OpDumpTaskManager::DumpOpInfoForUnknowShape(
     950              :     const uint64_t opMappingInfoAddr, const uint64_t opMappingInfoLen) const
     951              : {
     952            2 :     aicpusd_info("load op mapping info for single op or unknown shape op, size[%llu]", opMappingInfoLen);
     953            2 :     if (opMappingInfoAddr == 0U) {
     954            1 :         aicpusd_err("op mapping info addr is null");
     955            1 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     956              :     }
     957            1 :     aicpu::dump::OpMappingInfo opMappingInfo;
     958            1 :     const std::string protoInfo(PtrToPtr<const void, const char_t>(ValueToPtr(opMappingInfoAddr)), opMappingInfoLen);
     959            1 :     const bool parseRet = opMappingInfo.ParseFromString(protoInfo);
     960            1 :     if (!parseRet) {
     961            0 :         aicpusd_err("parse op mapping info failed, size[%u]", opMappingInfoLen);
     962            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     963              :     }
     964            1 :     const int32_t taskSize = opMappingInfo.task_size();
     965            1 :     if (taskSize != 1) {
     966            0 :         aicpusd_err(
     967              :             "task number[%d] should be only one, op mapping info: %s", opMappingInfo.task_size(),
     968              :             opMappingInfo.DebugString().c_str());
     969            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     970              :     }
     971            1 :     return DoDump(opMappingInfo);
     972            1 : }
     973              : 
     974            1 : int32_t OpDumpTaskManager::DoDump(const aicpu::dump::OpMappingInfo& opMappingInfo) const
     975              : {
     976            1 :     const std::string dumpPath = opMappingInfo.dump_path();
     977            1 :     MappingInfoOptionalParam optionalParam;
     978            1 :     GetOptionalParam(opMappingInfo, optionalParam);
     979            1 :     const std::string dumpStepStr = opMappingInfo.dump_step();
     980              : 
     981            1 :     DumpStep dumpStep;
     982            1 :     if (!GetDumpStepFromString(dumpStepStr, dumpStep)) {
     983            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     984              :     }
     985            1 :     const int32_t hostPid = static_cast<int32_t>(AicpuSchedule::AicpuDrvManager::GetInstance().GetHostPid());
     986            1 :     const uint32_t deviceId = AicpuSchedule::AicpuDrvManager::GetInstance().GetDeviceId();
     987            1 :     std::shared_ptr<OpDumpTask> opDumpTaskPtr = nullptr;
     988              :     try {
     989            1 :         opDumpTaskPtr = std::make_shared<OpDumpTask>(hostPid, deviceId);
     990            0 :     } catch (const std::bad_alloc& err) {
     991            0 :         aicpusd_err("malloc memory for OpDumpTask object failed, reason is [%s]", err.what());
     992            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     993            0 :     } catch (...) {
     994            0 :         aicpusd_err("malloc memory for OpDumpTask object failed");
     995            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
     996            0 :     }
     997            1 :     aicpusd_memory_log("MallocMemory, func=new, size=%zu, purpose=data dumper", sizeof(OpDumpTask));
     998            1 :     if (opDumpTaskPtr == nullptr) {
     999            0 :         aicpusd_err("malloc memory for OpDumpTask object failed");
    1000            0 :         return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
    1001              :     }
    1002            1 :     int32_t ret = AICPU_SCHEDULE_OK;
    1003            1 :     const aicpu::dump::Task task = opMappingInfo.task(0);
    1004            1 :     ret = opDumpTaskPtr->PreProcessOpMappingInfo(task, dumpPath, optionalParam, dumpStep, true);
    1005            1 :     if (ret != AICPU_SCHEDULE_OK) {
    1006            0 :         aicpusd_err("pre process op mapping info failed, op mapping info: %s", opMappingInfo.DebugString().c_str());
    1007            0 :         return ret;
    1008              :     }
    1009            1 :     auto startTime = std::chrono::steady_clock::now();
    1010            1 :     aicpusd_run_info("start to dump op info, op name=%s", opDumpTaskPtr->GetOpName().c_str());
    1011            2 :     ret = opDumpTaskPtr->DumpOpInfo();
    1012            1 :     auto endTime = std::chrono::steady_clock::now();
    1013            1 :     double drUs = std::chrono::duration<double, std::micro>(endTime - startTime).count();
    1014            1 :     aicpusd_run_info(
    1015              :         "end of dump op info, result=%d, op name=%s, cost time is [%.2lf]us", ret, opDumpTaskPtr->GetOpName().c_str(),
    1016              :         drUs);
    1017              :     UNUSED(drUs);
    1018            1 :     return ret;
    1019            1 : }
    1020              : 
    1021            1 : void OpDumpTaskManager::ProcessEndGraph(const std::vector<std::shared_ptr<OpDumpTask>>& opDumptasks)
    1022              : {
    1023            2 :     for (const auto& item : opDumptasks) {
    1024            1 :         if (item->IsEndGraph()) {
    1025              :             uint32_t modelId;
    1026            0 :             if (item->GetModelId(modelId)) {
    1027            0 :                 UpdateDumpNumByModelId(modelId);
    1028              :             } else {
    1029            0 :                 item->UpdateDumpNum();
    1030              :             }
    1031              :         }
    1032              :     }
    1033            1 : }
    1034              : 
    1035            1 : void OpDumpTaskManager::UpdateDumpNumByModelId(const uint32_t modelId)
    1036              : {
    1037            1 :     std::vector<std::shared_ptr<OpDumpTask>> opDumptasks;
    1038              :     {
    1039            1 :         const std::lock_guard<std::mutex> mapLock(dumpTaskMapMtx_);
    1040            1 :         const auto iter = modelIdToTask_.find(modelId);
    1041            1 :         if (iter != modelIdToTask_.end()) {
    1042            0 :             for (auto& taskInfo : iter->second) {
    1043            0 :                 const auto range = dumpTaskMap_.equal_range(taskInfo);
    1044            0 :                 for (auto item = range.first; item != range.second; ++item) {
    1045            0 :                     std::shared_ptr<OpDumpTask> opDumpTask = item->second;
    1046            0 :                     opDumptasks.push_back(std::move(opDumpTask));
    1047            0 :                 }
    1048              :             }
    1049              :         }
    1050            1 :     }
    1051              : 
    1052            1 :     for (auto& dumpTask : opDumptasks) {
    1053            0 :         dumpTask->UpdateDumpNum();
    1054              :     }
    1055            1 : }
    1056              : 
    1057            1 : static void DoSplit(const std::string& externStr, std::vector<std::string>& ret, const std::string& delim)
    1058              : {
    1059            1 :     size_t i = 0UL;
    1060            2 :     while (i < externStr.size()) {
    1061            1 :         const size_t pos = externStr.find(delim, i);
    1062            1 :         if (pos != std::string::npos) {
    1063            1 :             std::string s = externStr.substr(i, pos - i);
    1064            1 :             if (!s.empty()) {
    1065            1 :                 ret.push_back(std::move(s));
    1066              :             }
    1067            1 :             i = pos + delim.size() - 1UL;
    1068            1 :         }
    1069            1 :         ++i;
    1070              :     }
    1071            1 : }
    1072              : 
    1073            7 : static std::vector<std::string> Split(const std::string& str, const std::string& delim)
    1074              : {
    1075            7 :     std::vector<std::string> ret;
    1076            7 :     if (!str.empty()) {
    1077            1 :         const std::string externStr = str + delim;
    1078            1 :         DoSplit(externStr, ret, delim);
    1079            1 :     }
    1080            7 :     return ret;
    1081            0 : }
    1082              : 
    1083            1 : bool OpDumpTaskManager::MatchAndInsert(const std::string& step, DumpStep& tmpDumpStep) const
    1084              : {
    1085              :     // smatch result
    1086            1 :     const std::regex singleStepPatten("(\\s*)(\\d+)(\\s*)");
    1087            1 :     const std::regex intervalStepPatten("((\\s*)(\\d+)(\\s*)){1}(-(\\s*)(\\d+)(\\s*))");
    1088            1 :     if (std::regex_match(step, singleStepPatten)) {
    1089            1 :         (void)tmpDumpStep.singleStep.insert(static_cast<uint64_t>(std::stoull(step)));
    1090            0 :     } else if (std::regex_match(step, intervalStepPatten)) {
    1091            0 :         const std::vector<std::string> intervalStepStr = Split(step, "-");
    1092            0 :         if (intervalStepStr.size() == INTERNAL_STEP_SIZE) {
    1093              :             IntervalStep intervalStep;
    1094            0 :             intervalStep.start = static_cast<uint64_t>(std::stoull(intervalStepStr[0U]));
    1095            0 :             intervalStep.end = static_cast<uint64_t>(std::stoull(intervalStepStr[1U]));
    1096            0 :             if (intervalStep.start > intervalStep.end) {
    1097            0 :                 std::swap(intervalStep.start, intervalStep.end);
    1098              :             }
    1099            0 :             tmpDumpStep.intervalStep.push_back(std::move(intervalStep));
    1100              :         }
    1101            0 :     } else {
    1102            0 :         aicpusd_err("invalid step[%s], please check.", step.c_str());
    1103            0 :         return false;
    1104              :     }
    1105            0 :     return true;
    1106            2 : }
    1107              : 
    1108            7 : bool OpDumpTaskManager::GetDumpStepFromString(const std::string& str, DumpStep& dumpStep) const
    1109              : {
    1110              :     // split by |, such as "0|5-10"
    1111            7 :     aicpusd_info("Step need to dump[%s].", str.c_str());
    1112            7 :     const std::vector<std::string> steps = Split(str, "|");
    1113            7 :     DumpStep tmpDumpStep;
    1114            7 :     for (const auto& step : steps) {
    1115              :         try {
    1116            1 :             if (!MatchAndInsert(step, tmpDumpStep)) {
    1117            1 :                 return false;
    1118              :             }
    1119            1 :         } catch (std::out_of_range& e) {
    1120            1 :             aicpusd_err(
    1121              :                 "out of range of uint64_max[%llu], invalid step[%s], msg[%s], please check.", UINT64_MAX, step.c_str(),
    1122              :                 e.what());
    1123            1 :             return false;
    1124            1 :         } catch (...) {
    1125            0 :             aicpusd_err("invalid step[%s], please check.", step.c_str());
    1126            0 :             return false;
    1127            0 :         }
    1128              :     }
    1129            6 :     dumpStep = std::move(tmpDumpStep);
    1130            6 :     return true;
    1131            7 : }
    1132              : 
    1133            1 : void OpDumpTaskManager::ClearResource()
    1134              : {
    1135            1 :     const std::lock_guard<std::mutex> mapLock(dumpTaskMapMtx_);
    1136            1 :     aicpusd_run_info("clear all resource of data dump");
    1137            1 :     dumpTaskMap_.clear();
    1138            1 :     modelIdToTask_.clear();
    1139            1 : }
    1140              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1