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