LCOV - code coverage report
Current view: top level - adump/operator - operator_dumper.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.7 % 271 262
Test Date: 2026-08-31 10:09:28 Functions: 100.0 % 23 23

            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 "operator_dumper.h"
      11              : #include "runtime/rt.h"
      12              : #include "rts/rts_device.h"
      13              : #include "rts/rts_stream.h"
      14              : #include "rts/rts_kernel.h"
      15              : #include "aicpu_sched/common/aicpu_task_struct.h"
      16              : #include "dump_datatype.h"
      17              : #include "dump_memory.h"
      18              : #include "log/adx_log.h"
      19              : 
      20              : namespace Adx {
      21              : namespace {
      22              : constexpr uint32_t AI_CPU_LOAD_FLAG = 1U;
      23              : constexpr uint32_t TASK_ID_BITS_MASK = 0x0000FFFFU; // 16 bits, 1111,1111,1111,1111
      24              : constexpr int32_t TASK_ID_LEN_16 = 16;
      25              : constexpr char DUMP_KERNAL_OP_NAME[] = "DumpDataInfo";
      26              : // Dump开关的device内存
      27              : void* g_devMemDumpSwitch{nullptr};
      28              : // 静态图下发Dump算子proto的device内存
      29              : std::vector<void*> g_devMemProtoInfo;
      30              : constexpr uint32_t DUMP_SWITCH_DUMP_TENSOR = 0x1U;
      31              : constexpr uint32_t DUMP_SWITCH_DUMP_STATS = 0x2U;
      32              : constexpr uint32_t DUMP_SWITCH_DUMP_OVERFLOW = 0x4U;
      33              : } // namespace
      34              : 
      35           54 : OperatorDumper::OperatorDumper(const std::string& opType, const std::string& opName)
      36           54 :     : opType_(opType), opName_(opName), stream_(nullptr)
      37           54 : {}
      38              : 
      39          318 : OperatorDumper::OperatorDumper(const DumpSetting& setting) : setting_(setting) {}
      40              : 
      41           54 : OperatorDumper& OperatorDumper::SetDumpSetting(const DumpSetting& setting)
      42              : {
      43           54 :     setting_ = setting;
      44           54 :     return *this;
      45              : }
      46              : 
      47           54 : OperatorDumper& OperatorDumper::InputDumpTensor(const std::vector<DumpTensor>& inputTensors)
      48              : {
      49           54 :     inputTensors_ = inputTensors;
      50           54 :     return *this;
      51              : }
      52           54 : OperatorDumper& OperatorDumper::OutputDumpTensor(const std::vector<DumpTensor>& outputTensors)
      53              : {
      54           54 :     outputTensors_ = outputTensors;
      55           54 :     return *this;
      56              : }
      57              : 
      58           18 : int32_t OperatorDumper::InitDevMemDumpSwitch()
      59              : {
      60           18 :     if (g_devMemDumpSwitch == nullptr) {
      61           18 :         uint64_t dumpSwitchSize = static_cast<uint64_t>(sizeof(uint64_t));
      62           18 :         uint16_t moduleId = static_cast<uint16_t>(IDEDD);
      63           18 :         rtError_t rtRet = rtMalloc(&g_devMemDumpSwitch, dumpSwitchSize, RT_MEMORY_HBM, moduleId);
      64           18 :         IDE_CTRL_VALUE_FAILED(
      65              :             rtRet == RT_ERROR_NONE, return ADUMP_FAILED, "rtMalloc for dump switch on device failed! ret: 0x%X", rtRet);
      66           15 :         IDE_LOGI("rtMalloc for dump switch on device success. addr: %p, size: %lu", g_devMemDumpSwitch, dumpSwitchSize);
      67              : 
      68           15 :         if (SetDevMemDumpSwitch() != ADUMP_SUCCESS) {
      69            3 :             IDE_LOGE("Init to set dump switch on device failed!");
      70            3 :             DumpMemory::FreeDevice(g_devMemDumpSwitch);
      71            3 :             return ADUMP_FAILED;
      72              :         }
      73              :     }
      74           12 :     return ADUMP_SUCCESS;
      75              : }
      76              : 
      77          333 : int32_t OperatorDumper::SetDevMemDumpSwitch()
      78              : {
      79          333 :     if (g_devMemDumpSwitch != nullptr) {
      80           15 :         uint64_t dumpSwitch = GetDevMemDumpSwitch();
      81           15 :         uint64_t dumpSwitchSize = static_cast<uint64_t>(sizeof(uint64_t));
      82              :         rtError_t rtRet =
      83           15 :             rtMemcpy(g_devMemDumpSwitch, dumpSwitchSize, &dumpSwitch, dumpSwitchSize, RT_MEMCPY_HOST_TO_DEVICE);
      84           15 :         IDE_CTRL_VALUE_FAILED(
      85              :             rtRet == RT_ERROR_NONE, return ADUMP_FAILED, "rtMemcpy for dump switch on device failed! ret: 0x%X", rtRet);
      86           12 :         IDE_LOGI("Set dump switch on device success. addr: %p, dump switch: %lu", g_devMemDumpSwitch, dumpSwitch);
      87              :     }
      88          330 :     return ADUMP_SUCCESS;
      89              : }
      90              : 
      91           15 : uint64_t OperatorDumper::GetDevMemDumpSwitch()
      92              : {
      93           15 :     uint64_t dumpSwitch = 0;
      94           15 :     if (setting_.GetDumpStatusEx()) {
      95           12 :         dumpSwitch |= (setting_.IsDumpDataStats()) ? DUMP_SWITCH_DUMP_STATS : DUMP_SWITCH_DUMP_TENSOR;
      96              :     }
      97           15 :     if (setting_.GetDumpDebugStatus()) {
      98            3 :         dumpSwitch |= DUMP_SWITCH_DUMP_OVERFLOW;
      99            3 :         if (!setting_.GetDumpStatusEx()) {
     100              :             // 默认tensor的溢出检测
     101            3 :             dumpSwitch |= DUMP_SWITCH_DUMP_TENSOR;
     102              :         }
     103              :     }
     104           15 :     return dumpSwitch;
     105              : }
     106              : 
     107          366 : void OperatorDumper::FreeDevMemProtoCache()
     108              : {
     109          750 :     for (void* devMemPtr : g_devMemProtoInfo) {
     110           18 :         DumpMemory::FreeDevice(devMemPtr);
     111              :     }
     112          366 :     g_devMemProtoInfo.clear();
     113          366 :     IDE_LOGI("Free all proto messages on device success.");
     114          366 : }
     115              : 
     116          318 : int32_t OperatorDumper::UpdateDevMemCache()
     117              : {
     118          318 :     FreeDevMemProtoCache();
     119          318 :     return SetDevMemDumpSwitch();
     120              : }
     121              : 
     122           48 : void OperatorDumper::FreeDevMemCache()
     123              : {
     124           48 :     if (g_devMemDumpSwitch != nullptr) {
     125           12 :         DumpMemory::FreeDevice(g_devMemDumpSwitch);
     126           12 :         IDE_LOGI("Free the dump switch on device success.");
     127              :     }
     128           48 :     FreeDevMemProtoCache();
     129           48 : }
     130              : 
     131           54 : OperatorDumper& OperatorDumper::RuntimeStream(aclrtStream stream)
     132              : {
     133           54 :     stream_ = stream;
     134           54 :     return *this;
     135              : }
     136              : 
     137           30 : int32_t OperatorDumper::Launch()
     138              : {
     139           30 :     IDE_LOGI(
     140              :         "Start to launch dump with cfg for op %s[%s], inputSize(%zu), outputSize(%zu).", opName_.c_str(),
     141              :         opType_.c_str(), inputTensors_.size(), outputTensors_.size());
     142              : 
     143           30 :     IDE_CTRL_VALUE_FAILED(FillOpMappingInfo() == ADUMP_SUCCESS, return ADUMP_FAILED, "Fill op mapping info failed!");
     144              : 
     145           18 :     IDE_CTRL_VALUE_FAILED(LaunchDumpKernel() == ADUMP_SUCCESS, return ADUMP_FAILED, "Launch dump kernel failed!");
     146            9 :     return ADUMP_SUCCESS;
     147              : }
     148              : 
     149           18 : int32_t OperatorDumper::LaunchWithCfg(const DumpCfg& dumpCfg)
     150              : {
     151           18 :     IDE_LOGI(
     152              :         "Start to launch dump with cfg for op %s[%s], inputSize(%zu), outputSize(%zu).", opName_.c_str(),
     153              :         opType_.c_str(), inputTensors_.size(), outputTensors_.size());
     154              : 
     155           18 :     IDE_CTRL_VALUE_FAILED(
     156              :         InitDevMemDumpSwitch() == ADUMP_SUCCESS, return ADUMP_FAILED, "Init dump switch on device failed!");
     157              : 
     158           12 :     IDE_CTRL_VALUE_FAILED(FillOpMappingInfo() == ADUMP_SUCCESS, return ADUMP_FAILED, "Fill op mapping info failed!");
     159              : 
     160              :     // 默认按静态图处理,下发算子后不执行同步流操作
     161           12 :     bool synchronize = false;
     162           12 :     FillOpMappingInfoWithCfg(dumpCfg, synchronize);
     163              : 
     164           12 :     IDE_CTRL_VALUE_FAILED(
     165              :         LaunchDumpKernel(synchronize) == ADUMP_SUCCESS, return ADUMP_FAILED, "Launch dump kernel with cfg failed!");
     166           12 :     return ADUMP_SUCCESS;
     167              : }
     168              : 
     169           12 : void OperatorDumper::FillOpMappingInfoWithCfg(const DumpCfg& dumpCfg, bool& synchronize)
     170              : {
     171           42 :     for (size_t i = 0; i < dumpCfg.numAttrs; ++i) {
     172           30 :         DumpAttr* attr = &(dumpCfg.attrs[i]);
     173           30 :         switch (attr->id) {
     174            3 :             case DUMP_ATTR_MODEL_NAME:
     175            3 :                 if (attr->value.modelName != nullptr) {
     176            9 :                     opMappingInfo_.set_model_name(std::string(attr->value.modelName));
     177            3 :                     IDE_LOGD("Fill opMapping model_name: %s", attr->value.modelName);
     178              :                 }
     179            3 :                 break;
     180            3 :             case DUMP_ATTR_MODEL_ID:
     181            3 :                 opMappingInfo_.set_model_id(attr->value.modelId);
     182            3 :                 IDE_LOGD("Fill opMapping model_id: %u", attr->value.modelId);
     183            3 :                 break;
     184            3 :             case DUMP_ATTR_STEP_ID_ADDR:
     185            3 :                 if (attr->value.stepIdAddr != 0U) {
     186            3 :                     opMappingInfo_.set_step_id_addr(attr->value.stepIdAddr);
     187            3 :                     IDE_LOGD("Fill opMapping step_id_add: 0x%llx", attr->value.stepIdAddr);
     188              :                 }
     189            3 :                 break;
     190            3 :             case DUMP_ATTR_ITER_PER_LOOP_ADDR:
     191            3 :                 if (attr->value.iterPerLoopAddr != 0U) {
     192            3 :                     opMappingInfo_.set_iterations_per_loop_addr(attr->value.iterPerLoopAddr);
     193            3 :                     IDE_LOGD("Fill opMapping iterations_per_loop_addr: 0x%llx", attr->value.iterPerLoopAddr);
     194              :                 }
     195            3 :                 break;
     196            3 :             case DUMP_ATTR_LOOP_COND_ADDR:
     197            3 :                 if (attr->value.loopCondAddr != 0U) {
     198            3 :                     opMappingInfo_.set_loop_cond_addr(attr->value.loopCondAddr);
     199            3 :                     IDE_LOGD("Fill opMapping loop_cond_addr: 0x%llx", attr->value.loopCondAddr);
     200              :                 }
     201            3 :                 break;
     202            3 :             case DUMP_ATTR_DUMP_STEP:
     203            3 :                 if (attr->value.dumpStep != nullptr) {
     204            9 :                     opMappingInfo_.set_dump_step(std::string(attr->value.dumpStep));
     205            3 :                     IDE_LOGD("Fill opMapping dump_step: %s", attr->value.dumpStep);
     206              :                 }
     207            3 :                 break;
     208            6 :             case DUMP_ATTR_STREAM_MODEL:
     209              :                 // 0:静态图,不执行同步流
     210            6 :                 synchronize = attr->value.streamModel == 0U ? false : true;
     211            6 :                 IDE_LOGD("to synchronize stream: %d", synchronize);
     212            6 :                 break;
     213            6 :             default:
     214            6 :                 IDE_LOGD("not support attr id: %d", attr->id);
     215            6 :                 break;
     216              :         }
     217              :     }
     218           12 :     IDE_LOGD("dump_switch_addr: 0x%llx", static_cast<uint64_t>(reinterpret_cast<uintptr_t>(g_devMemDumpSwitch)));
     219           12 :     opMappingInfo_.set_dump_switch_addr(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(g_devMemDumpSwitch)));
     220           12 : }
     221              : 
     222           42 : int32_t OperatorDumper::FillOpMappingInfo()
     223              : {
     224              :     // Set default
     225           42 :     opMappingInfo_.clear_task();
     226           42 :     opMappingInfo_.set_flag(AI_CPU_LOAD_FLAG);
     227           42 :     if (setting_.IsDumpDataStats()) {
     228            9 :         opMappingInfo_.set_dump_data(toolkitV2::aicpu::dump::DumpData::STATS_DUMP_DATA);
     229              :     } else {
     230           33 :         opMappingInfo_.set_dump_data(toolkitV2::aicpu::dump::DumpData::TENSOR_DUMP_DATA);
     231              :     }
     232              : 
     233           42 :     int32_t deviceId = 0;
     234           42 :     rtError_t rtRet = rtGetDevice(&deviceId);
     235           42 :     if (rtRet != RT_ERROR_NONE || deviceId < 0) {
     236            3 :         IDE_LOGE("rtGetDevice failed, ret 0x%X, devId: %d", rtRet, deviceId);
     237            3 :         return ADUMP_FAILED;
     238              :     }
     239              : 
     240           39 :     IDE_CTRL_VALUE_FAILED(FillDumpPath(deviceId) == ADUMP_SUCCESS, return ADUMP_FAILED, "Fill dump path failed!");
     241              : 
     242           39 :     IDE_CTRL_VALUE_FAILED(FillDumpTask(deviceId) == ADUMP_SUCCESS, return ADUMP_FAILED, "Fill dump task failed!");
     243           30 :     return ADUMP_SUCCESS;
     244              : }
     245              : 
     246           39 : int32_t OperatorDumper::FillDumpPath(int32_t deviceId)
     247              : {
     248           39 :     Path dumpPathWithDevId(setting_.GetDumpPath());
     249           39 :     dumpPathWithDevId.Append(std::to_string(deviceId));
     250           78 :     opMappingInfo_.set_dump_path(dumpPathWithDevId.GetString());
     251           39 :     IDE_LOGI("Dump op to path %s.", dumpPathWithDevId.GetCString());
     252           39 :     return ADUMP_SUCCESS;
     253           39 : }
     254              : 
     255           39 : int32_t OperatorDumper::FillDumpTask(int32_t deviceId)
     256              : {
     257           39 :     toolkitV2::aicpu::dump::Task task;
     258           39 :     task.mutable_op()->set_op_name(opName_);
     259           39 :     task.mutable_op()->set_op_type(opType_);
     260              : 
     261           39 :     uint32_t taskId = 0U;
     262           39 :     rtError_t rtRet = rtsGetThreadLastTaskId(&taskId);
     263           39 :     if (rtRet != RT_ERROR_NONE) {
     264            3 :         IDE_LOGE("Call rtsGetThreadLastTaskId failed, ret 0x%X", rtRet);
     265            3 :         return ADUMP_FAILED;
     266              :     }
     267              : 
     268           36 :     int32_t streamId = 0U;
     269           36 :     rtRet = rtsStreamGetId(stream_, &streamId);
     270           36 :     if (rtRet != RT_ERROR_NONE) {
     271            3 :         IDE_LOGE("Call rtsStreamGetId failed, ret 0x%X", rtRet);
     272            3 :         return ADUMP_FAILED;
     273              :     }
     274              : 
     275           33 :     int32_t taskIdLen = 0;
     276           33 :     rtRet = rtsDeviceGetCapability(deviceId, RT_FEATURE_SYSTEM_TASKID_BIT_WIDTH, &taskIdLen);
     277           33 :     if (rtRet != RT_ERROR_NONE) {
     278            3 :         IDE_LOGE("Call rtsDeviceGetCapability failed, ret 0x%X", rtRet);
     279            3 :         return ADUMP_FAILED;
     280              :     }
     281           30 :     if (taskIdLen == TASK_ID_LEN_16) {
     282           30 :         taskId = taskId & TASK_ID_BITS_MASK;
     283              :     }
     284              : 
     285           30 :     task.set_task_id(taskId);
     286           30 :     task.set_stream_id(static_cast<uint32_t>(streamId));
     287           30 :     IDE_LOGI("Task id is %u, stream id is %d", taskId, streamId);
     288              : 
     289           30 :     uint32_t dumpMode = setting_.GetDumpMode();
     290           30 :     if ((dumpMode & DUMP_MODE_OUTPUT) != 0) {
     291           30 :         DumpOutput(task);
     292              :     }
     293              : 
     294           30 :     if ((dumpMode & DUMP_MODE_INPUT) != 0) {
     295           30 :         DumpInput(task);
     296              :     }
     297              : 
     298           60 :     opMappingInfo_.mutable_task()->Add(std::move(task));
     299           30 :     return ADUMP_SUCCESS;
     300           39 : }
     301              : 
     302           45 : toolkitV2::aicpu::dump::AddressType OperatorDumper::ConvertAddressType(const DumpTensor& dumpTensor)
     303              : {
     304           45 :     AddressType addressType = dumpTensor.GetAddressType();
     305           45 :     if (addressType == AddressType::NOTILING) {
     306            3 :         return toolkitV2::aicpu::dump::AddressType::NOTILING_ADDR;
     307           42 :     } else if (addressType == AddressType::RAW) {
     308           15 :         return toolkitV2::aicpu::dump::AddressType::RAW_ADDR;
     309              :     } else {
     310           27 :         return toolkitV2::aicpu::dump::AddressType::TRADITIONAL_ADDR;
     311              :     }
     312              : }
     313              : 
     314           30 : void OperatorDumper::DumpInput(toolkitV2::aicpu::dump::Task& task)
     315              : {
     316           84 :     for (const auto& dumpTensor : inputTensors_) {
     317           24 :         toolkitV2::aicpu::dump::Input input;
     318           24 :         auto ir_data_type = DumpDataType::GetIrDataType(static_cast<GeDataType>(dumpTensor.GetDataType()));
     319           24 :         input.set_data_type(static_cast<int32_t>(ir_data_type));
     320           24 :         input.set_format(static_cast<int32_t>(dumpTensor.GetFormat()));
     321              : 
     322           24 :         std::vector<int64_t> shape = dumpTensor.GetShape();
     323           69 :         for (auto dim : shape) {
     324           21 :             input.mutable_shape()->add_dim(static_cast<uint64_t>(dim));
     325              :         }
     326           24 :         std::vector<int64_t> originShape = dumpTensor.GetOriginShape();
     327           69 :         for (auto dim : originShape) {
     328           21 :             input.mutable_origin_shape()->add_dim(static_cast<uint64_t>(dim));
     329              :         }
     330              : 
     331           24 :         size_t dumpSize = dumpTensor.GetSize();
     332           24 :         const void* dumpAddr = dumpTensor.GetAddress();
     333           24 :         input.set_size(static_cast<uint64_t>(dumpSize));
     334           24 :         input.set_address(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dumpAddr)));
     335           24 :         IDE_LOGI("Dump op(%s) input addr(%p), size(%zu).", opName_.c_str(), dumpAddr, dumpSize);
     336           24 :         input.set_addr_type(ConvertAddressType(dumpTensor));
     337           48 :         task.mutable_input()->Add(std::move(input));
     338           24 :     }
     339           30 : }
     340              : 
     341           30 : void OperatorDumper::DumpOutput(toolkitV2::aicpu::dump::Task& task)
     342              : {
     343           81 :     for (const auto& dumpTensor : outputTensors_) {
     344           21 :         toolkitV2::aicpu::dump::Output output;
     345           21 :         auto ir_data_type = DumpDataType::GetIrDataType(static_cast<GeDataType>(dumpTensor.GetDataType()));
     346           21 :         output.set_data_type(static_cast<int32_t>(ir_data_type));
     347           21 :         output.set_format(static_cast<int32_t>(dumpTensor.GetFormat()));
     348           21 :         std::vector<int64_t> shape = dumpTensor.GetShape();
     349           63 :         for (auto dim : shape) {
     350           21 :             output.mutable_shape()->add_dim(static_cast<uint64_t>(dim));
     351              :         }
     352           21 :         std::vector<int64_t> originShape = dumpTensor.GetOriginShape();
     353           63 :         for (auto dim : originShape) {
     354           21 :             output.mutable_origin_shape()->add_dim(static_cast<uint64_t>(dim));
     355              :         }
     356              : 
     357           21 :         size_t dumpSize = dumpTensor.GetSize();
     358           21 :         const void* dumpAddr = dumpTensor.GetAddress();
     359           21 :         output.set_size(static_cast<uint64_t>(dumpSize));
     360           21 :         output.set_address(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dumpAddr)));
     361           21 :         IDE_LOGI("Dump op(%s) output addr(%p), size(%zu).", opName_.c_str(), dumpAddr, dumpSize);
     362           21 :         output.set_addr_type(ConvertAddressType(dumpTensor));
     363           42 :         task.mutable_output()->Add(std::move(output));
     364           21 :     }
     365           30 : }
     366              : 
     367           30 : int32_t OperatorDumper::LaunchDumpKernel(bool synchronize) const
     368              : {
     369           30 :     std::string protoMsg;
     370           30 :     const size_t protoSize = opMappingInfo_.ByteSizeLong();
     371           30 :     const bool bRet = opMappingInfo_.SerializeToString(&protoMsg);
     372           30 :     if ((!bRet) || (protoSize == 0U)) {
     373            0 :         IDE_LOGE("Serialize proto msg failed, size is %zu", protoSize);
     374            0 :         return ADUMP_FAILED;
     375              :     }
     376              : 
     377           30 :     void* protoMsgDevMem = DumpMemory::CopyHostToDevice(protoMsg.c_str(), static_cast<uint64_t>(protoSize));
     378           30 :     IDE_CTRL_VALUE_FAILED(
     379              :         protoMsgDevMem != nullptr, return ADUMP_FAILED, "Copy proto msg to device failed! size: %zu", protoSize);
     380              : 
     381           24 :     void* protoMsgSizeDevMem = DumpMemory::CopyHostToDevice(&protoSize, static_cast<uint64_t>(sizeof(size_t)));
     382           24 :     if (protoMsgSizeDevMem == nullptr) {
     383            0 :         DumpMemory::FreeDevice(protoMsgDevMem);
     384            0 :         IDE_LOGE("Copy proto msg size to device failed! size: %zu", protoSize);
     385            0 :         return ADUMP_FAILED;
     386              :     }
     387           24 :     int32_t ret = LaunchDumpKernel(protoMsgDevMem, protoMsgSizeDevMem, synchronize);
     388           24 :     if (synchronize) {
     389           15 :         DumpMemory::FreeDevice(protoMsgDevMem);
     390           15 :         DumpMemory::FreeDevice(protoMsgSizeDevMem);
     391              :     } else {
     392            9 :         g_devMemProtoInfo.push_back(protoMsgDevMem);
     393            9 :         g_devMemProtoInfo.push_back(protoMsgSizeDevMem);
     394              :     }
     395           24 :     return ret;
     396           30 : }
     397              : 
     398           24 : int32_t OperatorDumper::LaunchDumpKernel(
     399              :     const void* const protoMsgDevMem, const void* const protoMsgSizeDevMem, bool synchronize) const
     400              : {
     401           24 :     constexpr uint32_t ioAddrNum = 2U;
     402           24 :     constexpr uint32_t argSize = sizeof(aicpu::AicpuParamHead) + (ioAddrNum * sizeof(uint64_t));
     403           24 :     uint8_t args[argSize] = {};
     404              : 
     405              :     // fill head
     406           24 :     aicpu::AicpuParamHead* paramHead = reinterpret_cast<aicpu::AicpuParamHead*>(args);
     407           24 :     paramHead->length = argSize;
     408           24 :     paramHead->ioAddrNum = ioAddrNum;
     409              : 
     410              :     // fill body
     411           24 :     constexpr size_t protoMsgOffset = sizeof(aicpu::AicpuParamHead);
     412           24 :     constexpr size_t protoMsgSizeOffset = sizeof(aicpu::AicpuParamHead) + sizeof(uint64_t);
     413           24 :     uint64_t protoMsgDevAddr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(protoMsgDevMem));
     414           24 :     uint64_t protoMsgSizeDevAddr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(protoMsgSizeDevMem));
     415              : 
     416              :     // use memcpy to avoid 'uint64_t type 8 byte alignment requires'
     417           24 :     const auto cpyMsg = memcpy_s(&args[protoMsgOffset], sizeof(uint64_t), &protoMsgDevAddr, sizeof(uint64_t));
     418           24 :     if (cpyMsg != EOK) {
     419            0 :         IDE_LOGE("Copy addr to args failed");
     420            0 :         return ADUMP_FAILED;
     421              :     }
     422           24 :     const auto cpySize = memcpy_s(&args[protoMsgSizeOffset], sizeof(uint64_t), &protoMsgSizeDevAddr, sizeof(uint64_t));
     423           24 :     if (cpySize != EOK) {
     424            0 :         IDE_LOGE("Copy addr to args failed");
     425            0 :         return ADUMP_FAILED;
     426              :     }
     427              : 
     428           24 :     rtArgsEx_t argsInfo = {};
     429           24 :     argsInfo.args = reinterpret_cast<void*>(args);
     430           24 :     argsInfo.argsSize = argSize;
     431              :     // launch dump op
     432           24 :     rtError_t rtRet = rtCpuKernelLaunchWithFlag(nullptr, DUMP_KERNAL_OP_NAME, 1U, &argsInfo, nullptr, stream_, 0U);
     433           24 :     if (rtRet != RT_ERROR_NONE) {
     434            3 :         IDE_LOGE("rtCpuKernelLaunchWithFlag failed, ret: 0x%X", rtRet);
     435            3 :         return ADUMP_FAILED;
     436              :     }
     437              : 
     438           21 :     if (synchronize) {
     439           12 :         rtRet = rtStreamSynchronize(stream_);
     440           12 :         IDE_CTRL_VALUE_FAILED(
     441              :             rtRet == RT_ERROR_NONE, return ADUMP_FAILED, "rtStreamSynchronize failed, ret: 0x%X", rtRet);
     442              :     }
     443              : 
     444           21 :     IDE_LOGI("Kernel launch dump op %s success", opName_.c_str());
     445           21 :     return ADUMP_SUCCESS;
     446              : }
     447              : } // namespace Adx
        

Generated by: LCOV version 2.0-1