* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "dump.h"
#include <mutex>
#include <sstream>
#include <set>
#include "mmpa/mmpa_api.h"
#include "adx_datadump_server.h"
#include "adump_pub.h"
#include "common/json_parser.h"
#include "common/error_codes_inner.h"
#include "common/log_inner.h"
#include "utils/string_utils.h"
#include "aclrt_impl/acl_rt_impl_base.h"
#include "acl_rt_impl.h"
namespace {
bool aclmdlInitDumpFlag = false;
std::mutex aclDumpMutex;
constexpr int32_t ADX_ERROR_NONE = 0;
}
namespace acl {
AclDump &AclDump::GetInstance()
{
static AclDump aclDumpProc;
return aclDumpProc;
}
aclError AclDump::HandleDumpCommand(const char *configStr, size_t size, const char *configPath)
{
ACL_LOG_INFO("start to execute HandleDumpCommand.");
int32_t adxRet = AdxDataDumpServerInit();
if (adxRet != ADX_ERROR_NONE) {
ACL_LOG_INNER_ERROR("[AdxDataDumpServer][Init]dump server run failed, adx errorCode = %d", adxRet);
return ACL_ERROR_INTERNAL_ERROR;
}
acl::AclDump::GetInstance().SetAdxInitFromAclInitFlag(true);
Adx::DumpConfigInfo configInfo;
configInfo.dumpConfigPath = configPath;
configInfo.dumpConfigData = configStr;
configInfo.dumpConfigSize = size;
adxRet = Adx::AdumpSetDumpConfig(configInfo);
if (adxRet != ADX_ERROR_NONE) {
auto ret =
(adxRet == Adx::ADUMP_INPUT_FAILED) ? ACL_ERROR_INVALID_DUMP_CONFIG : ACL_ERROR_INTERNAL_ERROR;
ACL_LOG_INNER_ERROR("[Set][Dump]set dump config failed, adx errorCode = %d", adxRet);
return ret;
}
return ACL_SUCCESS;
}
aclError AclDump::HandleDumpConfig(const char_t *const configPath)
{
ACL_LOG_INFO("start to execute HandleDumpConfig.");
std::string configStr;
aclError ret = acl::JsonParser::GetConfigStrFromFile(configPath, configStr);
if (ret != ACL_SUCCESS) {
ACL_LOG_INNER_ERROR("Get config string from file[%s] failed, errorCode = %d",
configPath, ret);
return ret;
}
try {
if (!configStr.empty()) {
return HandleDumpCommand(configStr.c_str(), configStr.size(), configPath);
}
} catch (const nlohmann::json::exception &e) {
ACL_LOG_INNER_ERROR("[Convert][DumpConfig]parse json for config failed, exception:%s.",
e.what());
return ACL_ERROR_INVALID_DUMP_CONFIG;
}
ACL_LOG_INFO("HandleDumpConfig end in HandleDumpConfig.");
return ACL_SUCCESS;
}
}
#ifdef __cplusplus
extern "C" {
#endif
aclError aclmdlInitDumpImpl()
{
ACL_LOG_INFO("start to execute aclmdlInitDump.");
if (!acl::GetAclInitFlag()) {
acl::AclErrorLogManager::ReportInputError(
"EP0008", std::vector<const char*>({"func", "reason"}),
std::vector<const char*>(
{"aclmdlInitDump", "aclInit must be executed before aclmdlInitDump is called"}));
ACL_LOG_ERROR("[Check][AclInitFlag]aclInit must be executed before aclmdlInitDump is called");
return ACL_ERROR_UNINITIALIZE;
}
const std::unique_lock<std::mutex> lk(aclDumpMutex);
if (aclmdlInitDumpFlag) {
acl::AclErrorLogManager::ReportInputError(
"EP0008", std::vector<const char*>({"func", "reason"}),
std::vector<const char*>({"aclmdlInitDump", "This API cannot be called repeatedly"}));
ACL_LOG_ERROR("[Check][InitDumpFlag]This API cannot be called repeatedly");
return ACL_ERROR_REPEAT_INITIALIZE;
}
const int32_t adxRet = AdxDataDumpServerInit();
if (adxRet != ADX_ERROR_NONE) {
ACL_LOG_CALL_ERROR("[AdxDataDumpServer][Init]dump server run failed, adx errorCode = %d", adxRet);
return ACL_ERROR_INTERNAL_ERROR;
}
aclmdlInitDumpFlag = true;
ACL_LOG_INFO("successfully initialized dump in aclmdlInitDump.");
return ACL_SUCCESS;
}
aclError aclmdlSetDumpImpl(const char *dumpCfgPath)
{
ACL_LOG_INFO("start to execute aclmdlSetDump.");
if (!acl::GetAclInitFlag()) {
acl::AclErrorLogManager::ReportInputError(
"EP0008", std::vector<const char*>({"func", "reason"}),
std::vector<const char*>(
{"aclmdlSetDump", "aclInit must be executed before aclmdlSetDumpImpl is called"}));
ACL_LOG_ERROR("[Check][AclInitFlag]aclInit must be executed before aclmdlSetDumpImpl is called");
return ACL_ERROR_UNINITIALIZE;
}
const std::unique_lock<std::mutex> lk(aclDumpMutex);
if (!aclmdlInitDumpFlag) {
acl::AclErrorLogManager::ReportInputError(
"EP0008", std::vector<const char*>({"func", "reason"}),
std::vector<const char*>(
{"aclmdlSetDump", "aclmdlInitDump must be executed before aclmdlSetDumpImpl is called"}));
ACL_LOG_ERROR("[Check][aclmdlInitDumpFlag]aclmdlInitDump must be executed before aclmdlSetDumpImpl is called");
return ACL_ERROR_DUMP_NOT_RUN;
}
ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dumpCfgPath);
std::string configStr;
aclError ret = acl::JsonParser::GetConfigStrFromFile(dumpCfgPath, configStr);
if (ret != ACL_SUCCESS) {
ACL_LOG_INNER_ERROR("Get config string from file[%s] failed, errorCode = %d",
dumpCfgPath, ret);
return ret;
}
if (!configStr.empty()) {
ACL_LOG_INFO("Start to set dump.");
Adx::DumpConfigInfo configInfo;
configInfo.dumpConfigPath = dumpCfgPath;
configInfo.dumpConfigData = configStr.c_str();
configInfo.dumpConfigSize = configStr.size();
const auto adxRet = Adx::AdumpSetDumpConfig(configInfo);
if (adxRet != ADX_ERROR_NONE) {
ret =
(adxRet == Adx::ADUMP_INPUT_FAILED) ? ACL_ERROR_INVALID_DUMP_CONFIG : ACL_ERROR_INTERNAL_ERROR;
ACL_LOG_INNER_ERROR("[Set][Dump]set dump config failed, adx errorCode = %d", adxRet);
return ret;
}
}
ACL_LOG_INFO("set dump config successfully.");
return ACL_SUCCESS;
}
aclError aclmdlFinalizeDumpImpl()
{
ACL_LOG_INFO("start to execute aclmdlFinalizeDump.");
if (!acl::GetAclInitFlag()) {
acl::AclErrorLogManager::ReportInputError(
"EP0008", std::vector<const char*>({"func", "reason"}),
std::vector<const char*>(
{"aclmdlFinalizeDump", "aclInit must be executed before aclmdlFinalizeDump is called"}));
ACL_LOG_ERROR("[Check][AclInitFlag]aclInit must be executed before aclmdlFinalizeDump is called");
return ACL_ERROR_UNINITIALIZE;
}
const std::unique_lock<std::mutex> lk(aclDumpMutex);
if (!aclmdlInitDumpFlag) {
acl::AclErrorLogManager::ReportInputError(
"EP0008", std::vector<const char*>({"func", "reason"}),
std::vector<const char*>(
{"aclmdlFinalizeDump", "aclmdlInitDump must be executed before aclmdlFinalizeDump is called"}));
ACL_LOG_ERROR("[Check][aclmdlInitDumpFlag]aclmdlInitDump must be executed before aclmdlFinalizeDump is called");
return ACL_ERROR_DUMP_NOT_RUN;
}
int32_t adxRet = Adx::AdumpUnSetDump();
if (adxRet != ADX_ERROR_NONE) {
ACL_LOG_INNER_ERROR("[Set][Dump]set dump off failed, adx errorCode = %d", adxRet);
return ACL_ERROR_INTERNAL_ERROR;
}
adxRet = AdxDataDumpServerUnInit();
if (adxRet != ADX_ERROR_NONE) {
ACL_LOG_CALL_ERROR("[AdxDataDumpServer][UnInit]generate dump file failed in disk, adx errorCode = %d", adxRet);
return ACL_ERROR_INTERNAL_ERROR;
}
aclmdlInitDumpFlag = false;
ACL_LOG_INFO("successfully execute aclmdlFinalizeDump, the dump task completed!");
return ACL_SUCCESS;
}
#ifdef __cplusplus
}
#endif