LCOV - code coverage report
Current view: top level - adump/manage - adump_api_platform.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.5 % 171 165
Test Date: 2026-08-31 10:09:28 Functions: 100.0 % 15 15

            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 <atomic>
      11              : #include "acl_dump.h"
      12              : #include "adump_pub.h"
      13              : #include "adump_api.h"
      14              : #include "dump_manager.h"
      15              : #include "dump_printf.h"
      16              : #include "adump_error_manager.h"
      17              : #include "str_utils.h"
      18              : #include "common/path.h"
      19              : 
      20              : namespace Adx {
      21              : uint64_t g_chunk[RING_CHUNK_SIZE + MAX_TENSOR_NUM] = {0};
      22              : bool g_setAssert = false;
      23              : static std::mutex g_setAssertMtx;
      24              : namespace {
      25              : uint32_t g_atomicIndex = 0x2000;
      26              : std::atomic<uint64_t> g_writeIdx{0};
      27              : 
      28           24 : void ConvertAclDumpTensorInner(const acldumpTensorInfo& src, size_t index, TensorInfo& dst)
      29              : {
      30           24 :     dst.type = static_cast<TensorType>(src.type);
      31           24 :     dst.tensorSize = src.tensorSize;
      32           24 :     dst.format = src.format;
      33           24 :     dst.dataType = src.dataType;
      34           24 :     dst.tensorAddr = src.tensorAddr;
      35           24 :     dst.addrType = static_cast<AddressType>(src.addrType);
      36           24 :     dst.placement = static_cast<int32_t>(src.placement);
      37           24 :     dst.argsOffSet = static_cast<uint32_t>(index);
      38              : 
      39           72 :     for (uint32_t i = 0; i < src.shapeNum; ++i) {
      40           48 :         dst.shape.emplace_back(static_cast<int64_t>(src.shape[i]));
      41              :     }
      42           72 :     for (uint32_t i = 0; i < src.originShapeNum; ++i) {
      43           48 :         dst.originShape.emplace_back(static_cast<int64_t>(src.originShape[i]));
      44              :     }
      45           24 : }
      46              : 
      47           27 : bool ReportInvalidTensorField(size_t index, const char* field, const std::string& reason)
      48              : {
      49           27 :     std::string param = StrUtils::Format("tensors[%zu].%s", index, field);
      50          594 :     REPORT_EP0006_INVALID_ARGUMENT(
      51              :         FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, param, FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_TENSORS, reason);
      52           27 :     return false;
      53           81 : }
      54              : 
      55           18 : bool ReportUnsupportedTensorField(size_t index, const char* field, int32_t value, const char* expected)
      56              : {
      57           18 :     return ReportInvalidTensorField(
      58              :         index, field,
      59           36 :         StrUtils::Format(ADUMP_REASON_PARAM_VALUE_NOT_SUPPORTED, std::to_string(value).c_str(), expected));
      60              : }
      61              : 
      62           57 : bool CheckAclDumpTensorShape(const acldumpTensorInfo& src, size_t index)
      63              : {
      64           57 :     const std::string maxShapeNum = std::to_string(ACL_DUMP_MAX_SHAPE_NUM);
      65           57 :     if (src.shapeNum > ACL_DUMP_MAX_SHAPE_NUM) {
      66            3 :         return ReportInvalidTensorField(
      67              :             index, "shapeNum",
      68            9 :             StrUtils::Format(
      69            9 :                 ADUMP_REASON_PARAM_VALUE_EXCEED_LIMIT, std::to_string(src.shapeNum).c_str(), maxShapeNum.c_str()));
      70              :     }
      71           54 :     if (src.originShapeNum > ACL_DUMP_MAX_SHAPE_NUM) {
      72            3 :         return ReportInvalidTensorField(
      73              :             index, "originShapeNum",
      74            9 :             StrUtils::Format(
      75            6 :                 ADUMP_REASON_PARAM_VALUE_EXCEED_LIMIT, std::to_string(src.originShapeNum).c_str(),
      76            3 :                 maxShapeNum.c_str()));
      77              :     }
      78           51 :     return true;
      79           57 : }
      80              : 
      81           51 : bool CheckAclDumpTensorEnum(const acldumpTensorInfo& src, size_t index)
      82              : {
      83           51 :     if (src.type != ACL_DUMP_TENSOR_INPUT && src.type != ACL_DUMP_TENSOR_OUTPUT &&
      84            6 :         src.type != ACL_DUMP_TENSOR_WORKSPACE) {
      85            6 :         return ReportUnsupportedTensorField(
      86            3 :             index, "type", static_cast<int32_t>(src.type),
      87            3 :             "ACL_DUMP_TENSOR_INPUT/ACL_DUMP_TENSOR_OUTPUT/ACL_DUMP_TENSOR_WORKSPACE");
      88              :     }
      89           48 :     if (src.addrType != ACL_DUMP_ADDR_RAW) {
      90            9 :         return ReportUnsupportedTensorField(index, "addrType", static_cast<int32_t>(src.addrType), "ACL_DUMP_ADDR_RAW");
      91              :     }
      92           39 :     if (src.placement != ACL_DUMP_PLACEMENT_DEVICE) {
      93           12 :         return ReportUnsupportedTensorField(
      94            6 :             index, "placement", static_cast<int32_t>(src.placement), "ACL_DUMP_PLACEMENT_DEVICE");
      95              :     }
      96           33 :     return true;
      97              : }
      98              : 
      99           33 : bool CheckAclDumpTensorData(const acldumpTensorInfo& src, size_t index)
     100              : {
     101           33 :     if (src.tensorAddr == nullptr) {
     102            6 :         std::string param = StrUtils::Format("tensors[%zu].tensorAddr", index);
     103           84 :         REPORT_EP0007_NULL_POINTER(FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, param);
     104            6 :         return false;
     105            6 :     }
     106           27 :     if (src.tensorSize == 0) {
     107            3 :         return ReportInvalidTensorField(
     108            6 :             index, "tensorSize", StrUtils::Format(ADUMP_REASON_PARAM_MUST_BE_GREATER_THAN, "0"));
     109              :     }
     110           24 :     return true;
     111           12 : }
     112              : 
     113           57 : bool ConvertAclDumpTensor(const acldumpTensorInfo& src, size_t index, TensorInfo& dst)
     114              : {
     115           90 :     if (!CheckAclDumpTensorShape(src, index) || !CheckAclDumpTensorEnum(src, index) ||
     116           33 :         !CheckAclDumpTensorData(src, index)) {
     117           33 :         return false;
     118              :     }
     119              : 
     120           24 :     ConvertAclDumpTensorInner(src, index, dst);
     121           24 :     return true;
     122              : }
     123              : } // namespace
     124              : 
     125        45022 : void* AdumpGetSizeInfoAddr(uint32_t space, uint32_t& atomicIndex)
     126              : {
     127        45022 :     if (!g_setAssert) {
     128            3 :         const std::lock_guard<std::mutex> lock(g_setAssertMtx);
     129            3 :         if (!g_setAssert) {
     130            3 :             (void)rtSetTaskFailCallback(AdxAssertCallBack);
     131            3 :             g_setAssert = true;
     132              :         }
     133            3 :     }
     134        45022 :     if (space > MAX_TENSOR_NUM) {
     135            3 :         return nullptr;
     136              :     }
     137              : 
     138        45019 :     atomicIndex = g_atomicIndex++;
     139        45019 :     auto nextWriteCursor = g_writeIdx.fetch_add(space);
     140        45019 :     return g_chunk + (nextWriteCursor % RING_CHUNK_SIZE);
     141              : }
     142              : 
     143           18 : int32_t AdumpRegisterCallback(uint32_t moduleId, AdumpCallback enableFunc, AdumpCallback disableFunc)
     144              : {
     145           18 :     return DumpManager::Instance().RegisterCallback(moduleId, enableFunc, disableFunc);
     146              : }
     147              : 
     148           24 : int32_t AdumpSaveToFile(const char* data, size_t dataLen, const char* filename, SaveType type)
     149              : {
     150           24 :     return DumpManager::Instance().SaveFile(data, dataLen, filename, type);
     151              : }
     152              : } // namespace Adx
     153              : 
     154              : /**
     155              :  * @ingroup AscendCL
     156              :  * @brief Enable the dump function of the corresponding dump type.
     157              :  *
     158              :  * @param dumpType [IN]  type of dump
     159              :  * @param path     [IN]  dump path
     160              :  *
     161              :  * @retval ACL_SUCCESS The function is successfully executed.
     162              :  * @retval OtherValues Failure
     163              :  */
     164           30 : aclError aclopStartDumpArgs(uint32_t dumpType, const char* path)
     165              : {
     166           30 :     if (path == nullptr) {
     167           48 :         REPORT_EP0007_NULL_POINTER(Adx::FUNC_NAME_ACL_OP_START_DUMP_ARGS, Adx::FUNC_ACL_OP_START_DUMP_ARGS_PARAM_PATH);
     168            3 :         return ACL_ERROR_FAILURE;
     169              :     }
     170              : 
     171           27 :     if ((dumpType & ACL_OP_DUMP_OP_AICORE_ARGS) != ACL_OP_DUMP_OP_AICORE_ARGS) {
     172            6 :         std::string dumpTypeStr = std::to_string(dumpType);
     173            6 :         std::string expTypeStr = std::to_string(ACL_OP_DUMP_OP_AICORE_ARGS);
     174            6 :         std::string reason = Adx::StrUtils::Format(Adx::ADUMP_REASON_RESERVED_PARAM_MUST_EQUAL, expTypeStr.c_str());
     175          132 :         REPORT_EP0006_INVALID_ARGUMENT(
     176              :             Adx::FUNC_NAME_ACL_OP_START_DUMP_ARGS, dumpTypeStr, Adx::FUNC_ACL_OP_START_DUMP_ARGS_PARAM_DUMPTYPE,
     177              :             reason);
     178            6 :         return ACL_ERROR_FAILURE;
     179            6 :     }
     180              : 
     181           21 :     std::string dumpPath(path);
     182           21 :     int32_t ret = Adx::DumpManager::Instance().StartDumpArgs(dumpPath);
     183           21 :     if (ret != 0) {
     184           15 :         return ACL_ERROR_FAILURE;
     185              :     }
     186              : 
     187            6 :     return ACL_SUCCESS;
     188           33 : }
     189              : 
     190              : /**
     191              :  * @ingroup AscendCL
     192              :  * @brief Disable the dump function of the corresponding dump type.
     193              :  *
     194              :  * @param dumpType [IN]  type of dump
     195              :  *
     196              :  * @retval ACL_SUCCESS The function is successfully executed.
     197              :  * @retval OtherValues Failure
     198              :  */
     199           15 : aclError aclopStopDumpArgs(uint32_t dumpType)
     200              : {
     201           15 :     if ((dumpType & ACL_OP_DUMP_OP_AICORE_ARGS) == ACL_OP_DUMP_OP_AICORE_ARGS) {
     202           15 :         if (Adx::DumpManager::Instance().StopDumpArgs() != 0) {
     203            3 :             return ACL_ERROR_FAILURE;
     204              :         }
     205              :     }
     206           12 :     return ACL_SUCCESS;
     207              : }
     208              : 
     209              : /**
     210              :  * @ingroup AscendCL
     211              :  * @brief Get Exception Dump path.
     212              :  *
     213              :  * @retval path for success
     214              :  * @retval NULL for failed
     215              :  */
     216           12 : const char* acldumpGetPath(acldumpType dumpType)
     217              : {
     218           12 :     switch (dumpType) {
     219            6 :         case acldumpType::AIC_ERR_BRIEF_DUMP:
     220              :         case acldumpType::AIC_ERR_NORM_DUMP:
     221              :         case acldumpType::AIC_ERR_DETAIL_DUMP:
     222            6 :             return Adx::DumpManager::Instance().GetExtraExceptionDumpPath();
     223            3 :         case acldumpType::DATA_DUMP:
     224              :         case acldumpType::OVERFLOW_DUMP:
     225            3 :             return Adx::DumpManager::Instance().GetDataDumpPath();
     226            3 :         default:
     227            3 :             return nullptr;
     228              :     }
     229              : }
     230              : 
     231              : /**
     232              :  * @ingroup AscendCL
     233              :  * @brief Save custom exception info (tensors) to the Exception Dump path.
     234              :  * @retval ACL_SUCCESS The function is successfully executed.
     235              :  * @retval OtherValues Failure
     236              :  */
     237           66 : aclError acldumpSaveExceptionInfo(
     238              :     const char* fileName, const char* userTag, const acldumpTensorInfo* tensors, size_t tensorCount)
     239              : {
     240           66 :     if (fileName == nullptr) {
     241           48 :         REPORT_EP0007_NULL_POINTER(
     242              :             Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_FILENAME);
     243            3 :         return ACL_ERROR_INVALID_PARAM;
     244              :     }
     245              : 
     246           63 :     if (fileName[0] == '\0') {
     247           75 :         REPORT_EP0006_INVALID_ARGUMENT(
     248              :             Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, "", Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_FILENAME,
     249              :             Adx::ADUMP_REASON_PARAM_PATH_EMPTY);
     250            3 :         return ACL_ERROR_INVALID_PARAM;
     251              :     }
     252              : 
     253          120 :     if (Adx::Path::HasParentDirSegment(fileName)) {
     254          150 :         REPORT_EP0006_INVALID_ARGUMENT(
     255              :             Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, fileName,
     256              :             Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_FILENAME, Adx::ADUMP_REASON_PARAM_PATH_HAS_PARENT_DIR);
     257            6 :         return ACL_ERROR_INVALID_PARAM;
     258              :     }
     259              : 
     260           54 :     if (tensors == nullptr) {
     261           48 :         REPORT_EP0007_NULL_POINTER(
     262              :             Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_TENSORS);
     263            3 :         return ACL_ERROR_INVALID_PARAM;
     264              :     }
     265              : 
     266           51 :     if (tensorCount == 0) {
     267            3 :         const std::string reason = Adx::StrUtils::Format(Adx::ADUMP_REASON_PARAM_MUST_BE_GREATER_THAN, "0");
     268           66 :         REPORT_EP0006_INVALID_ARGUMENT(
     269              :             Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, std::to_string(tensorCount),
     270              :             Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_TENSORCOUNT, reason);
     271            3 :         return ACL_ERROR_INVALID_PARAM;
     272            3 :     }
     273              : 
     274           48 :     if (!Adx::DumpManager::Instance().IsEnabledExceptionDump()) {
     275              :         const std::string reason = Adx::StrUtils::Format(
     276            0 :             Adx::ADUMP_REASON_EXCEPTION_DUMP_NOT_ENABLED, Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO);
     277            0 :         REPORT_EP0008_API_CALL_SEQUENCE(Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, reason);
     278            0 :         return ACL_ERROR_FAILURE;
     279            0 :     }
     280              : 
     281           48 :     std::vector<Adx::TensorInfo> tensorInfos(tensorCount);
     282           72 :     for (size_t i = 0; i < tensorCount; ++i) {
     283           57 :         if (!Adx::ConvertAclDumpTensor(tensors[i], i, tensorInfos[i])) {
     284           33 :             return ACL_ERROR_INVALID_PARAM;
     285              :         }
     286              :     }
     287              : 
     288           15 :     const std::string userTagStr = (userTag == nullptr) ? "" : userTag;
     289           30 :     const int32_t ret = Adx::DumpManager::Instance().SaveExceptionInfo(fileName, userTagStr, tensorInfos);
     290           15 :     return ret == 0 ? ACL_SUCCESS : ACL_ERROR_FAILURE;
     291           72 : }
     292              : 
     293              : /**
     294              :  * @ingroup AscendCL
     295              :  * @brief Get the Exception Dump root path({dump_path}/extra-info/data-dump/{deviceId}/).
     296              :  * @retval ACL_SUCCESS The function is successfully executed.
     297              :  * @retval OtherValues Failure
     298              :  */
     299           21 : aclError acldumpGetExceptionInfoPath(char* path, size_t maxLen)
     300              : {
     301           21 :     if (path == nullptr) {
     302           48 :         REPORT_EP0007_NULL_POINTER(
     303              :             Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, Adx::FUNC_ACL_DUMP_GET_EXCEPTION_INFO_PATH_PARAM_PATH);
     304            3 :         return ACL_ERROR_INVALID_PARAM;
     305              :     }
     306           18 :     if (maxLen <= 1) {
     307            6 :         std::string reason = Adx::StrUtils::Format(Adx::ADUMP_REASON_PARAM_MUST_BE_GREATER_THAN, "1");
     308          132 :         REPORT_EP0006_INVALID_ARGUMENT(
     309              :             Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, std::to_string(maxLen),
     310              :             Adx::FUNC_ACL_DUMP_GET_EXCEPTION_INFO_PATH_PARAM_MAXLEN, reason);
     311            6 :         return ACL_ERROR_INVALID_PARAM;
     312            6 :     }
     313              : 
     314           12 :     if (!Adx::DumpManager::Instance().IsEnabledExceptionDump()) {
     315              :         const std::string reason = Adx::StrUtils::Format(
     316            3 :             Adx::ADUMP_REASON_EXCEPTION_DUMP_NOT_ENABLED, Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH);
     317           42 :         REPORT_EP0008_API_CALL_SEQUENCE(Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, reason);
     318            3 :         return ACL_ERROR_FAILURE;
     319            3 :     }
     320              : 
     321            9 :     std::string dumpPath;
     322            9 :     int32_t ret = Adx::DumpManager::Instance().GetExceptionDumpPath(dumpPath);
     323            9 :     if (ret != 0 || dumpPath.empty()) {
     324            3 :         IDE_LOGE("Get the exception dump path failed, path size=%zu, maxLen=%zu.", dumpPath.size(), maxLen);
     325            3 :         return ACL_ERROR_FAILURE;
     326              :     }
     327              : 
     328            6 :     if (dumpPath.size() + 1 > maxLen) {
     329              :         std::string reason = Adx::StrUtils::Format(
     330            6 :             Adx::ADUMP_REASON_BUFFER_SIZE_NOT_ENOUGH, std::to_string(maxLen).c_str(),
     331            9 :             std::to_string(dumpPath.size() + 1).c_str());
     332           66 :         REPORT_EP0006_INVALID_ARGUMENT(
     333              :             Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, std::to_string(maxLen),
     334              :             Adx::FUNC_ACL_DUMP_GET_EXCEPTION_INFO_PATH_PARAM_MAXLEN, reason);
     335            3 :         return ACL_ERROR_INVALID_PARAM;
     336            3 :     }
     337            3 :     if (strcpy_s(path, maxLen, dumpPath.c_str()) != EOK) {
     338            0 :         IDE_LOGE(
     339              :             "Copy the path to buffer failed when get the exception dump path, path size=%zu, maxLen=%zu.",
     340              :             dumpPath.size(), maxLen);
     341            0 :         return ACL_ERROR_FAILURE;
     342              :     }
     343            3 :     return ACL_SUCCESS;
     344           33 : }
        

Generated by: LCOV version 2.0-1