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-12 11:04:53 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          621 :     REPORT_EP0006_INVALID_ARGUMENT(FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, param,
      51              :         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(index, field,
      58           36 :         StrUtils::Format(ADUMP_REASON_PARAM_VALUE_NOT_SUPPORTED, std::to_string(value).c_str(), expected));
      59              : }
      60              : 
      61           57 : bool CheckAclDumpTensorShape(const acldumpTensorInfo &src, size_t index)
      62              : {
      63           57 :     const std::string maxShapeNum = std::to_string(ACL_DUMP_MAX_SHAPE_NUM);
      64           57 :     if (src.shapeNum > ACL_DUMP_MAX_SHAPE_NUM) {
      65            3 :         return ReportInvalidTensorField(index, "shapeNum",
      66            9 :             StrUtils::Format(ADUMP_REASON_PARAM_VALUE_EXCEED_LIMIT, 
      67            9 :                 std::to_string(src.shapeNum).c_str(), maxShapeNum.c_str()));
      68              :     }
      69           54 :     if (src.originShapeNum > ACL_DUMP_MAX_SHAPE_NUM) {
      70            3 :         return ReportInvalidTensorField(index, "originShapeNum",
      71            9 :             StrUtils::Format(ADUMP_REASON_PARAM_VALUE_EXCEED_LIMIT, 
      72            9 :                 std::to_string(src.originShapeNum).c_str(), maxShapeNum.c_str()));
      73              :     }
      74           51 :     return true;
      75           57 : }
      76              : 
      77           51 : bool CheckAclDumpTensorEnum(const acldumpTensorInfo &src, size_t index)
      78              : {
      79           51 :     if (src.type != ACL_DUMP_TENSOR_INPUT
      80           12 :         && src.type != ACL_DUMP_TENSOR_OUTPUT
      81            6 :         && src.type != ACL_DUMP_TENSOR_WORKSPACE) {
      82            3 :         return ReportUnsupportedTensorField(index, "type", static_cast<int32_t>(src.type),
      83            3 :             "ACL_DUMP_TENSOR_INPUT/ACL_DUMP_TENSOR_OUTPUT/ACL_DUMP_TENSOR_WORKSPACE");
      84              :     }
      85           48 :     if (src.addrType != ACL_DUMP_ADDR_RAW) {
      86           18 :         return ReportUnsupportedTensorField(
      87            9 :             index, "addrType", static_cast<int32_t>(src.addrType), "ACL_DUMP_ADDR_RAW");
      88              :     }
      89           39 :     if (src.placement != ACL_DUMP_PLACEMENT_DEVICE) {
      90           12 :         return ReportUnsupportedTensorField(
      91            6 :             index, "placement", static_cast<int32_t>(src.placement), "ACL_DUMP_PLACEMENT_DEVICE");
      92              :     }
      93           33 :     return true;
      94              : }
      95              : 
      96           33 : bool CheckAclDumpTensorData(const acldumpTensorInfo &src, size_t index)
      97              : {
      98           33 :     if (src.tensorAddr == nullptr) {
      99            6 :         std::string param = StrUtils::Format("tensors[%zu].tensorAddr", index);
     100           90 :         REPORT_EP0007_NULL_POINTER(FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, param);
     101            6 :         return false;
     102            6 :     }
     103           27 :     if (src.tensorSize == 0) {
     104            3 :         return ReportInvalidTensorField(
     105            6 :             index, "tensorSize", StrUtils::Format(ADUMP_REASON_PARAM_MUST_BE_GREATER_THAN, "0"));
     106              :     }
     107           24 :     return true;
     108           12 : }
     109              : 
     110           57 : bool ConvertAclDumpTensor(const acldumpTensorInfo &src, size_t index, TensorInfo &dst)
     111              : {
     112           57 :     if (!CheckAclDumpTensorShape(src, index)
     113           51 :         || !CheckAclDumpTensorEnum(src, index)
     114          108 :         || !CheckAclDumpTensorData(src, index)) {
     115           33 :         return false;
     116              :     }
     117              : 
     118           24 :     ConvertAclDumpTensorInner(src, index, dst);
     119           24 :     return true;
     120              : }
     121              : }  // namespace
     122              : 
     123        45022 : void *AdumpGetSizeInfoAddr(uint32_t space, uint32_t &atomicIndex)
     124              : {
     125        45022 :     if (!g_setAssert) {
     126            3 :         const std::lock_guard<std::mutex> lock(g_setAssertMtx);
     127            3 :         if (!g_setAssert) {
     128            3 :             (void)rtSetTaskFailCallback(AdxAssertCallBack);
     129            3 :             g_setAssert = true;
     130              :         }
     131            3 :     }
     132        45022 :     if (space > MAX_TENSOR_NUM) {
     133            3 :         return nullptr;
     134              :     }
     135              : 
     136        45019 :     atomicIndex = g_atomicIndex++;
     137        45019 :     auto nextWriteCursor = g_writeIdx.fetch_add(space);
     138        45019 :     return g_chunk + (nextWriteCursor % RING_CHUNK_SIZE);
     139              : }
     140              : 
     141           18 : int32_t AdumpRegisterCallback(uint32_t moduleId, AdumpCallback enableFunc, AdumpCallback disableFunc)
     142              : {
     143           18 :     return DumpManager::Instance().RegisterCallback(moduleId, enableFunc, disableFunc);
     144              : }
     145              : 
     146           24 : int32_t AdumpSaveToFile(const char *data, size_t dataLen, const char *filename, SaveType type)
     147              : {
     148           24 :     return DumpManager::Instance().SaveFile(data, dataLen, filename, type);
     149              : }
     150              : }  // namespace Adx
     151              : 
     152              : /**
     153              :  * @ingroup AscendCL
     154              :  * @brief Enable the dump function of the corresponding dump type.
     155              :  *
     156              :  * @param dumpType [IN]  type of dump
     157              :  * @param path     [IN]  dump path
     158              :  *
     159              :  * @retval ACL_SUCCESS The function is successfully executed.
     160              :  * @retval OtherValues Failure
     161              :  */
     162           30 : aclError aclopStartDumpArgs(uint32_t dumpType, const char *path)
     163              : {
     164           30 :     if (path == nullptr) {
     165           54 :         REPORT_EP0007_NULL_POINTER(
     166              :             Adx::FUNC_NAME_ACL_OP_START_DUMP_ARGS, Adx::FUNC_ACL_OP_START_DUMP_ARGS_PARAM_PATH);
     167            3 :         return ACL_ERROR_FAILURE;
     168              :     }
     169              : 
     170           27 :     if ((dumpType & ACL_OP_DUMP_OP_AICORE_ARGS) != ACL_OP_DUMP_OP_AICORE_ARGS) {
     171            6 :         std::string dumpTypeStr = std::to_string(dumpType);
     172            6 :         std::string expTypeStr = std::to_string(ACL_OP_DUMP_OP_AICORE_ARGS);
     173              :         std::string reason = Adx::StrUtils::Format(
     174            6 :             Adx::ADUMP_REASON_RESERVED_PARAM_MUST_EQUAL, expTypeStr.c_str());
     175          138 :         REPORT_EP0006_INVALID_ARGUMENT(
     176              :             Adx::FUNC_NAME_ACL_OP_START_DUMP_ARGS, dumpTypeStr,
     177              :             Adx::FUNC_ACL_OP_START_DUMP_ARGS_PARAM_DUMPTYPE, 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(const char *fileName, const char *userTag,
     238              :     const acldumpTensorInfo *tensors, size_t tensorCount)
     239              : {
     240           66 :     if (fileName == nullptr) {
     241           54 :         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           78 :         REPORT_EP0006_INVALID_ARGUMENT(Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, "",
     248              :             Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_FILENAME, Adx::ADUMP_REASON_PARAM_PATH_EMPTY);
     249            3 :         return ACL_ERROR_INVALID_PARAM;
     250              :     }
     251              : 
     252          120 :     if (Adx::Path::HasParentDirSegment(fileName)) {
     253          156 :         REPORT_EP0006_INVALID_ARGUMENT(Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, fileName,
     254              :             Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_FILENAME, Adx::ADUMP_REASON_PARAM_PATH_HAS_PARENT_DIR);
     255            6 :         return ACL_ERROR_INVALID_PARAM;
     256              :     }
     257              : 
     258           54 :     if (tensors == nullptr) {
     259           54 :         REPORT_EP0007_NULL_POINTER(
     260              :             Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_TENSORS);
     261            3 :         return ACL_ERROR_INVALID_PARAM;
     262              :     }
     263              : 
     264           51 :     if (tensorCount == 0) {
     265            3 :         const std::string reason = Adx::StrUtils::Format(Adx::ADUMP_REASON_PARAM_MUST_BE_GREATER_THAN, "0");
     266           69 :         REPORT_EP0006_INVALID_ARGUMENT(Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, std::to_string(tensorCount),
     267              :             Adx::FUNC_ACL_DUMP_SAVE_EXCEPTION_INFO_PARAM_TENSORCOUNT, reason);
     268            3 :         return ACL_ERROR_INVALID_PARAM;
     269            3 :     }
     270              : 
     271           48 :     if (!Adx::DumpManager::Instance().IsEnabledExceptionDump()) {
     272              :         const std::string reason = Adx::StrUtils::Format(
     273            0 :             Adx::ADUMP_REASON_EXCEPTION_DUMP_NOT_ENABLED, Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO);
     274            0 :         REPORT_EP0008_API_CALL_SEQUENCE(Adx::FUNC_NAME_ACL_DUMP_SAVE_EXCEPTION_INFO, reason);
     275            0 :         return ACL_ERROR_FAILURE;
     276            0 :     }
     277              : 
     278           48 :     std::vector<Adx::TensorInfo> tensorInfos(tensorCount);
     279           72 :     for (size_t i = 0; i < tensorCount; ++i) {
     280           57 :         if (!Adx::ConvertAclDumpTensor(tensors[i], i, tensorInfos[i])) {
     281           33 :             return ACL_ERROR_INVALID_PARAM;
     282              :         }
     283              :     }
     284              : 
     285           15 :     const std::string userTagStr = (userTag == nullptr) ? "" : userTag;
     286           30 :     const int32_t ret = Adx::DumpManager::Instance().SaveExceptionInfo(fileName, userTagStr, tensorInfos);
     287           15 :     return ret == 0 ? ACL_SUCCESS : ACL_ERROR_FAILURE;
     288           72 : }
     289              : 
     290              : /**
     291              :  * @ingroup AscendCL
     292              :  * @brief Get the Exception Dump root path({dump_path}/extra-info/data-dump/{deviceId}/).
     293              :  * @retval ACL_SUCCESS The function is successfully executed.
     294              :  * @retval OtherValues Failure
     295              :  */
     296           21 : aclError acldumpGetExceptionInfoPath(char *path, size_t maxLen)
     297              : {
     298           21 :     if (path == nullptr) {
     299           54 :         REPORT_EP0007_NULL_POINTER(
     300              :             Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, Adx::FUNC_ACL_DUMP_GET_EXCEPTION_INFO_PATH_PARAM_PATH);
     301            3 :         return ACL_ERROR_INVALID_PARAM;
     302              :     }
     303           18 :     if (maxLen <= 1) {
     304            6 :         std::string reason = Adx::StrUtils::Format(Adx::ADUMP_REASON_PARAM_MUST_BE_GREATER_THAN, "1");
     305          138 :         REPORT_EP0006_INVALID_ARGUMENT(Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, std::to_string(maxLen),
     306              :             Adx::FUNC_ACL_DUMP_GET_EXCEPTION_INFO_PATH_PARAM_MAXLEN, reason);
     307            6 :         return ACL_ERROR_INVALID_PARAM;
     308            6 :     }
     309              : 
     310           12 :     if (!Adx::DumpManager::Instance().IsEnabledExceptionDump()) {
     311              :         const std::string reason = Adx::StrUtils::Format(
     312            3 :             Adx::ADUMP_REASON_EXCEPTION_DUMP_NOT_ENABLED, Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH);
     313           45 :         REPORT_EP0008_API_CALL_SEQUENCE(Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, reason);
     314            3 :         return ACL_ERROR_FAILURE;
     315            3 :     }
     316              : 
     317            9 :     std::string dumpPath;
     318            9 :     int32_t ret = Adx::DumpManager::Instance().GetExceptionDumpPath(dumpPath);
     319            9 :     if (ret != 0 || dumpPath.empty()) {
     320            3 :         IDE_LOGE("Get the exception dump path failed, path size=%zu, maxLen=%zu.", dumpPath.size(), maxLen);
     321            3 :         return ACL_ERROR_FAILURE;
     322              :     }
     323              : 
     324            6 :     if (dumpPath.size() + 1 > maxLen) {
     325              :         std::string reason = Adx::StrUtils::Format(Adx::ADUMP_REASON_BUFFER_SIZE_NOT_ENOUGH,
     326            3 :             std::to_string(maxLen).c_str(), std::to_string(dumpPath.size() + 1).c_str());
     327           69 :         REPORT_EP0006_INVALID_ARGUMENT(Adx::FUNC_NAME_ACL_DUMP_GET_EXCEPTION_INFO_PATH, std::to_string(maxLen),
     328              :             Adx::FUNC_ACL_DUMP_GET_EXCEPTION_INFO_PATH_PARAM_MAXLEN, reason);
     329            3 :         return ACL_ERROR_INVALID_PARAM;
     330            3 :     }
     331            3 :     if (strcpy_s(path, maxLen, dumpPath.c_str()) != EOK) {
     332            0 :         IDE_LOGE("Copy the path to buffer failed when get the exception dump path, path size=%zu, maxLen=%zu.",
     333              :             dumpPath.size(), maxLen);
     334            0 :         return ACL_ERROR_FAILURE;
     335              :     }
     336            3 :     return ACL_SUCCESS;
     337           33 : }
        

Generated by: LCOV version 2.0-1