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_manager.h"
11 : #include <thread>
12 : #include <cctype>
13 : #include <cinttypes>
14 : #include <map>
15 : #include <algorithm>
16 : #include <cerrno>
17 : #include "str_utils.h"
18 : #include "lib_path.h"
19 : #include "file_utils.h"
20 : #include "log/adx_log.h"
21 : #include "runtime/context.h"
22 : #include "adump_dsmi.h"
23 : #include "common_utils.h"
24 : #include "dump_config_converter.h"
25 : #include "adump_api.h"
26 :
27 : namespace Adx {
28 :
29 : // AdumpGetDFXInfoAddr chunk
30 : uint64_t* g_dynamicChunk = nullptr;
31 : uint64_t* g_staticChunk = nullptr;
32 :
33 1 : DumpManager::DumpManager() {}
34 :
35 21 : DumpManager& DumpManager::Instance()
36 : {
37 21 : static DumpManager instance;
38 21 : return instance;
39 : }
40 :
41 1 : void DumpManager::KFCResourceInit() { isKFCInit_ = true; }
42 :
43 0 : int32_t DumpManager::SetDumpConfig(DumpType dumpType, const DumpConfig& dumpConfig)
44 : {
45 : UNUSED(dumpType);
46 : UNUSED(dumpConfig);
47 0 : std::lock_guard<std::mutex> lk(resourceMtx_);
48 0 : return ADUMP_SUCCESS;
49 0 : }
50 :
51 4 : int32_t DumpManager::SetDumpConfig(const char* dumpConfigData, size_t dumpConfigSize, const char* dumpConfigPath)
52 : {
53 4 : std::lock_guard<std::mutex> lk(resourceMtx2_);
54 4 : if ((dumpConfigData == nullptr) || (dumpConfigSize == 0U) || (dumpConfigPath == nullptr)) {
55 3 : IDE_LOGE("Set dump config failed. Config data is null or empty.");
56 3 : return ADUMP_FAILED;
57 : }
58 1 : DumpConfig dumpConfig;
59 1 : DumpDfxConfig dumpDfxConfig;
60 : DumpType dumpType;
61 1 : bool needDump = true;
62 1 : DumpConfigConverter converter{dumpConfigData, dumpConfigSize, dumpConfigPath};
63 1 : int32_t ret = converter.Convert(dumpType, dumpConfig, needDump, dumpDfxConfig);
64 1 : if (ret != ADUMP_SUCCESS) {
65 0 : IDE_LOGE("Parse dump config from memory[%s] failed.", dumpConfigData);
66 0 : return ADUMP_INPUT_FAILED;
67 : }
68 1 : if (!needDump) {
69 1 : return ADUMP_SUCCESS;
70 : }
71 :
72 0 : (void)dumpConfigInfo_.assign(dumpConfigData, dumpConfigSize);
73 0 : IDE_LOGI("Dump config info set: addr=%p, size=%zu", dumpConfigInfo_.data(), dumpConfigInfo_.size());
74 0 : ret = SetDumpConfig(dumpType, dumpConfig);
75 0 : for (auto& item : enableCallbackFunc_) {
76 0 : IDE_LOGI("SetDumpConfig HandleDumpEvent start for module [%zu]", item.first);
77 0 : HandleDumpEvent(item.first, DumpEnableAction::ENABLE);
78 : }
79 0 : IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ret, "Set dump config failed.");
80 0 : (void)openedDump_.insert(dumpType);
81 0 : return ADUMP_SUCCESS;
82 4 : }
83 :
84 1 : int32_t DumpManager::UnSetDumpConfig()
85 : {
86 1 : std::lock_guard<std::mutex> lk(resourceMtx2_);
87 1 : DumpConfig config;
88 1 : config.dumpStatus = ADUMP_DUMP_STATUS_SWITCH_OFF;
89 1 : for (const auto dumpType : openedDump_) {
90 0 : if (IsEnableDump(dumpType)) {
91 0 : const auto ret = SetDumpConfig(dumpType, config);
92 0 : if (ret != ADUMP_SUCCESS) {
93 0 : IDE_LOGE(
94 : "[Set][Dump]set dump off failed, dumpType:[%d], errorCode = %d", static_cast<int32_t>(dumpType),
95 : ret);
96 0 : return ADUMP_FAILED;
97 : }
98 0 : IDE_LOGI("set dump off successfully, dumpType:[%d].", static_cast<int32_t>(dumpType));
99 : }
100 : }
101 1 : openedDump_.clear();
102 1 : for (auto& item : disableCallbackFunc_) {
103 0 : IDE_LOGI("UnSetDumpConfig start for module [%zu]", item.first);
104 0 : HandleDumpEvent(item.first, DumpEnableAction::DISABLE);
105 : }
106 1 : dumpConfigInfo_.clear();
107 1 : IDE_LOGI("Dump config info cleared.");
108 1 : return ADUMP_SUCCESS;
109 1 : }
110 :
111 0 : std::string DumpManager::GetBinName() const { return ""; }
112 :
113 0 : bool DumpManager::CheckBinValidation() { return false; }
114 :
115 2 : bool DumpManager::IsEnableDump(DumpType dumpType)
116 : {
117 2 : std::lock_guard<std::mutex> lk(resourceMtx_);
118 2 : if (dumpType == DumpType::OPERATOR) {
119 1 : return dumpSetting_.GetDumpStatus();
120 1 : } else if (dumpType == DumpType::OP_OVERFLOW) {
121 1 : return dumpSetting_.GetDumpDebugStatus();
122 : } else {
123 0 : IDE_LOGW("Dump type is not support.");
124 : }
125 0 : return false;
126 2 : }
127 :
128 1 : int32_t DumpManager::DumpOperator(
129 : const std::string& opType, const std::string& opName, const std::vector<TensorInfo>& tensors, rtStream_t stream)
130 : {
131 : UNUSED(opType);
132 : UNUSED(opName);
133 : UNUSED(tensors);
134 : UNUSED(stream);
135 1 : return ADUMP_SUCCESS;
136 : }
137 :
138 1 : int32_t DumpManager::DumpOperatorV2(
139 : const std::string& opType, const std::string& opName, const std::vector<TensorInfoV2>& tensors, rtStream_t stream)
140 : {
141 : UNUSED(opType);
142 : UNUSED(opName);
143 : UNUSED(tensors);
144 : UNUSED(stream);
145 1 : return ADUMP_SUCCESS;
146 : }
147 :
148 0 : int32_t DumpManager::DumpOperatorWithCfg(
149 : const std::string& opType, const std::string& opName, const std::vector<TensorInfo>& tensors, aclrtStream stream,
150 : const DumpCfg& dumpCfg)
151 : {
152 : UNUSED(opType);
153 : UNUSED(opName);
154 : UNUSED(tensors);
155 : UNUSED(stream);
156 : UNUSED(dumpCfg);
157 0 : return ADUMP_SUCCESS;
158 : }
159 :
160 2 : int32_t DumpManager::RegisterExceptionDumpCallback(ExceptionDumpCallback callback)
161 : {
162 : UNUSED(callback);
163 2 : return ADUMP_SUCCESS;
164 : }
165 :
166 3 : int32_t DumpManager::UnregisterExceptionDumpCallback(ExceptionDumpCallback callback)
167 : {
168 : UNUSED(callback);
169 3 : return ADUMP_SUCCESS;
170 : }
171 :
172 0 : void DumpManager::AddExceptionOp(const OperatorInfo& opInfo) { UNUSED(opInfo); }
173 :
174 0 : void DumpManager::AddExceptionOpV2(const OperatorInfoV2& opInfo) { UNUSED(opInfo); }
175 :
176 0 : int32_t DumpManager::DelExceptionOp(uint32_t deviceId, uint32_t streamId)
177 : {
178 : UNUSED(deviceId);
179 : UNUSED(streamId);
180 0 : return ADUMP_SUCCESS;
181 : }
182 :
183 0 : std::vector<TensorInfoV2> DumpManager::ConvertTensorInfoToDumpTensorV2(const std::vector<TensorInfo>& tensorInfos) const
184 : {
185 0 : std::vector<TensorInfoV2> tensors;
186 0 : tensors.reserve(tensorInfos.size());
187 0 : for (const auto& tensorInfo : tensorInfos) {
188 0 : TensorInfoV2 tensor = {};
189 0 : ConvertTensorInfo(tensorInfo, tensor);
190 0 : tensors.emplace_back(tensor);
191 0 : }
192 0 : return tensors;
193 0 : }
194 :
195 0 : void DumpManager::ConvertTensorInfo(const TensorInfo& tensorInfo, TensorInfoV2& tensor) const
196 : {
197 0 : tensor.dataType = tensorInfo.dataType;
198 0 : tensor.format = tensorInfo.format;
199 0 : tensor.placement = tensorInfo.placement;
200 0 : tensor.tensorAddr = tensorInfo.tensorAddr;
201 0 : tensor.tensorSize = tensorInfo.tensorSize;
202 0 : tensor.type = tensorInfo.type;
203 0 : tensor.addrType = tensorInfo.addrType;
204 0 : tensor.argsOffSet = tensorInfo.argsOffSet;
205 0 : std::vector<int64_t> shape = tensorInfo.shape;
206 0 : for (auto dim : shape) {
207 0 : tensor.shape.emplace_back(static_cast<uint64_t>(dim));
208 : }
209 0 : std::vector<int64_t> originShape = tensorInfo.originShape;
210 0 : for (auto dim : originShape) {
211 0 : tensor.originShape.emplace_back(static_cast<uint64_t>(dim));
212 : }
213 0 : }
214 :
215 0 : void DumpManager::ConvertOperatorInfo(const OperatorInfo& opInfo, OperatorInfoV2& operatorInfoV2) const
216 : {
217 0 : operatorInfoV2.agingFlag = opInfo.agingFlag;
218 0 : operatorInfoV2.taskId = opInfo.taskId;
219 0 : operatorInfoV2.streamId = opInfo.streamId;
220 0 : operatorInfoV2.deviceId = opInfo.deviceId;
221 0 : operatorInfoV2.contextId = opInfo.contextId;
222 0 : operatorInfoV2.opType = opInfo.opType;
223 0 : operatorInfoV2.opName = opInfo.opName;
224 0 : operatorInfoV2.tensorInfos = ConvertTensorInfoToDumpTensorV2(opInfo.tensorInfos);
225 0 : operatorInfoV2.deviceInfos = opInfo.deviceInfos;
226 0 : operatorInfoV2.additionalInfo = opInfo.additionalInfo;
227 0 : }
228 :
229 1 : uint64_t DumpManager::AdumpGetDumpSwitch()
230 : {
231 1 : std::lock_guard<std::mutex> lk(resourceMtx_);
232 2 : return dumpSetting_.GetDumpSwitch();
233 1 : }
234 :
235 1 : DumpSetting DumpManager::GetDumpSetting() const { return dumpSetting_; }
236 :
237 4 : int32_t DumpManager::RegisterCallback(uint32_t moduleId, AdumpCallback enableFunc, AdumpCallback disableFunc)
238 : {
239 4 : if (enableFunc == nullptr) {
240 2 : IDE_LOGE("Register callback failed: enableFunc is null for module %u", moduleId);
241 2 : return ADUMP_FAILED;
242 : }
243 :
244 2 : if (disableFunc == nullptr) {
245 0 : IDE_LOGE("Register callback failed: disableFunc is null for module %u", moduleId);
246 0 : return ADUMP_FAILED;
247 : }
248 2 : std::lock_guard<std::mutex> lk(resourceMtx2_);
249 2 : enableCallbackFunc_[moduleId] = enableFunc;
250 2 : disableCallbackFunc_[moduleId] = disableFunc;
251 2 : IDE_LOGI("Registered callback for module %u", moduleId);
252 2 : return HandleDumpEvent(moduleId, DumpEnableAction::AUTO);
253 2 : }
254 :
255 2 : int32_t DumpManager::HandleDumpEvent(uint32_t moduleId, DumpEnableAction action)
256 : {
257 2 : IDE_LOGI("RegisterCallback HandleDumpEvent start for module %u", moduleId);
258 2 : const uint64_t dumpSwitch = dumpSetting_.GetDumpSwitch();
259 2 : auto callbackFunc = disableCallbackFunc_[moduleId];
260 2 : if (action == DumpEnableAction::ENABLE) {
261 0 : callbackFunc = enableCallbackFunc_[moduleId];
262 : }
263 2 : if (action == DumpEnableAction::AUTO) {
264 2 : if (dumpConfigInfo_.data() == nullptr || dumpConfigInfo_.size() == 0U) {
265 2 : IDE_LOGW("Config data is null or empty. Not trigger HandleDumpEvent. ");
266 2 : return ADUMP_SUCCESS;
267 : }
268 0 : if (dumpSwitch > 0U) {
269 0 : callbackFunc = enableCallbackFunc_[moduleId];
270 : }
271 : }
272 :
273 0 : if (!callbackFunc) {
274 0 : IDE_LOGE("No registered callback for module %u", moduleId);
275 0 : return ADUMP_FAILED;
276 : }
277 :
278 0 : IDE_LOGI("HandleDumpEvent callbackFunc start for module [%zu]", moduleId);
279 0 : IDE_LOGI("HandleDumpEvent callbackFunc switch [%" PRIu64 "]", dumpSwitch);
280 0 : IDE_LOGI(
281 : "HandleDumpEvent callbackFunc Dump config info: addr=%p, size=%zu", dumpConfigInfo_.data(),
282 : dumpConfigInfo_.size());
283 0 : int32_t result = callbackFunc(dumpSwitch, dumpConfigInfo_.data(), dumpConfigInfo_.size());
284 0 : IDE_LOGI("callbackFunc returned: %d", result);
285 0 : return result;
286 : }
287 :
288 : } // namespace Adx
|