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 :
11 : /* WARNING: This is an internal header file. Any external reference to or inclusion of this file is prohibited.
12 : * It will be deprecated once the compatibility periods expires.
13 : * -------------------------------------------------------------------------------------------------------*/
14 : #ifndef ERROR_MANAGER_H_
15 : #define ERROR_MANAGER_H_
16 :
17 : #include <cinttypes>
18 : #include <map>
19 : #include <set>
20 : #include <string>
21 : #include <vector>
22 : #include <mutex>
23 : #include <atomic>
24 : #include <cstring>
25 : #include <cstdlib>
26 :
27 : namespace error_message {
28 : using char_t = char;
29 : std::string TrimPath(const std::string& str);
30 : #ifdef __GNUC__
31 : int32_t FormatErrorMessage(char_t* str_dst, size_t dst_max, const char_t* format, ...)
32 : __attribute__((format(printf, 3, 4)));
33 :
34 : void ReportInnerError(
35 : const char_t* file_name, const char_t* func, uint32_t line, const std::string error_code, const char_t* format, ...)
36 : __attribute__((format(printf, 5, 6)));
37 : #else
38 : int32_t FormatErrorMessage(char_t* str_dst, size_t dst_max, const char_t* format, ...);
39 : void ReportInnerError(
40 : const char_t* file_name, const char_t* func, uint32_t line, const std::string error_code, const char_t* format,
41 : ...);
42 : #endif
43 : } // namespace error_message
44 :
45 : constexpr size_t const LIMIT_PER_MESSAGE = 1024U;
46 :
47 : ///
48 : /// @brief Report error message
49 : /// @param [in] key: vector parameter key
50 : /// @param [in] value: vector parameter value
51 : ///
52 : #define REPORT_INPUT_ERROR(error_code, key, value) \
53 : ErrorManager::GetInstance().ATCReportErrMessage(error_code, key, value)
54 :
55 : ///
56 : /// @brief Report error message
57 : /// @param [in] key: vector parameter key
58 : /// @param [in] value: vector parameter value
59 : ///
60 : #define REPORT_ENV_ERROR(error_code, key, value) ErrorManager::GetInstance().ATCReportErrMessage(error_code, key, value)
61 :
62 : #define REPORT_INNER_ERROR(error_code, fmt, ...) \
63 : error_message::ReportInnerError(__FILE__, &__FUNCTION__[0], __LINE__, (error_code), (fmt), ##__VA_ARGS__)
64 :
65 : #define REPORT_CALL_ERROR REPORT_INNER_ERROR
66 :
67 : namespace error_message {
68 : // first stage
69 : extern const std::string kInitialize;
70 : extern const std::string kModelCompile;
71 : extern const std::string kModelLoad;
72 : extern const std::string kModelExecute;
73 : extern const std::string kFinalize;
74 :
75 : // SecondStage
76 : // INITIALIZE
77 : extern const std::string kParser;
78 : extern const std::string kOpsProtoInit;
79 : extern const std::string kSystemInit;
80 : extern const std::string kEngineInit;
81 : extern const std::string kOpsKernelInit;
82 : extern const std::string kOpsKernelBuilderInit;
83 : // MODEL_COMPILE
84 : extern const std::string kPrepareOptimize;
85 : extern const std::string kOriginOptimize;
86 : extern const std::string kSubGraphOptimize;
87 : extern const std::string kMergeGraphOptimize;
88 : extern const std::string kPreBuild;
89 : extern const std::string kStreamAlloc;
90 : extern const std::string kMemoryAlloc;
91 : extern const std::string kTaskGenerate;
92 : // COMMON
93 : extern const std::string kOther;
94 :
95 : struct Context {
96 : uint64_t work_stream_id;
97 : std::string first_stage;
98 : std::string second_stage;
99 : std::string log_header;
100 : };
101 :
102 : enum class ErrorMsgMode : uint32_t {
103 : // 0:内置模式,推理采用线程粒度,训练采用session粒度,1:以进程为粒度
104 : INTERNAL_MODE = 0U,
105 : PROCESS_MODE = 1U,
106 : ERR_MSG_MODE_MAX = 2U
107 : };
108 :
109 : struct ErrorItem {
110 : std::string error_id;
111 : std::string error_title;
112 : std::string error_message;
113 : std::string possible_cause;
114 : std::string solution;
115 : // args_map作用于有error_id对应的json文件配置时,填充error_message对象
116 : std::map<std::string, std::string> args_map;
117 : std::string report_time;
118 :
119 354 : friend bool operator==(const ErrorItem& lhs, const ErrorItem& rhs) noexcept
120 : {
121 979 : return (lhs.error_id == rhs.error_id) && (lhs.error_message == rhs.error_message) &&
122 979 : (lhs.possible_cause == rhs.possible_cause) && (lhs.solution == rhs.solution);
123 : }
124 : };
125 : } // namespace error_message
126 :
127 : class ErrorManager {
128 : public:
129 : using ErrorItem = error_message::ErrorItem;
130 : /// @brief Obtain ErrorManager instance
131 : /// @return ErrorManager instance
132 : static ErrorManager& GetInstance();
133 :
134 : /// @brief init
135 : /// @return int 0(success) -1(fail)
136 : int32_t Init();
137 :
138 : int32_t Init(error_message::ErrorMsgMode error_mode);
139 :
140 : /// @brief init
141 : /// @param [in] path: current so path
142 : /// @return int 0(success) -1(fail)
143 : int32_t Init(const std::string path);
144 :
145 : int32_t ReportInterErrMessage(const std::string error_code, const std::string& error_msg);
146 :
147 : /// @brief Report error message
148 : /// @param [in] error_code: error code
149 : /// @param [in] args_map: parameter map
150 : /// @return int 0(success) -1(fail)
151 : int32_t ReportErrMessage(const std::string error_code, const std::map<std::string, std::string>& args_map);
152 :
153 : /// @brief Report user defined error message
154 : /// @param [in] error_code: user defined error code
155 : /// @param [in] errmsg: error message
156 : /// @return int 0(success) -1(fail)
157 : int32_t ReportErrMsgWithoutTpl(const std::string& error_code, const std::string& errmsg);
158 :
159 : /// @brief output error message
160 : /// @param [in] handle: print handle
161 : /// @return int 0(success) -1(fail)
162 : int32_t OutputErrMessage(int32_t handle);
163 :
164 : /// @brief output message
165 : /// @param [in] handle: print handle
166 : /// @return int 0(success) -1(fail)
167 : int32_t OutputMessage(int32_t handle);
168 : // 调用成功后会进行已有的错误信息的清理
169 : std::string GetErrorMessage();
170 :
171 : // 传递原始错误码信息
172 : int32_t SetRawErrorMessages(const std::vector<ErrorItem>& items);
173 :
174 : // 获取当前线程下原始上报的内部,外部错误信息,顺序为上报的原始顺序
175 : // 便于调用方进行自定制的加工,调用成功后会进行已有的错误信息的清理
176 : std::vector<ErrorItem> GetRawErrorMessages();
177 :
178 : std::string GetWarningMessage();
179 :
180 : /// @brief Report error message
181 : /// @param [in] key: vector parameter key
182 : /// @param [in] value: vector parameter value
183 : void ATCReportErrMessage(
184 : const std::string error_code, const std::vector<std::string>& key = {},
185 : const std::vector<std::string>& value = {});
186 :
187 : /// @brief report graph compile failed message such as error code and op_name in mstune case
188 : /// @param [in] graph_name: root graph name
189 : /// @param [in] msg: failed message map, key is error code, value is op_name
190 : /// @return int 0(success) -1(fail)
191 : int32_t ReportMstuneCompileFailedMsg(
192 : const std::string& root_graph_name, const std::map<std::string, std::string>& msg);
193 :
194 : /// @brief get graph compile failed message in mstune case
195 : /// @param [in] graph_name: graph name
196 : /// @param [out] msg_map: failed message map, key is error code, value is op_name list
197 : /// @return int 0(success) -1(fail)
198 : int32_t GetMstuneCompileFailedMsg(
199 : const std::string& graph_name, std::map<std::string, std::vector<std::string>>& msg_map);
200 :
201 : // @brief generate work_stream_id by current pid and tid, clear error_message stored by same work_stream_id
202 : // used in external api entrance, all sync api can use
203 : void GenWorkStreamIdDefault();
204 :
205 : // @brief generate work_stream_id by args sessionid and graphid, clear error_message stored by same work_stream_id
206 : // used in external api entrance
207 : void GenWorkStreamIdBySessionGraph(const uint64_t session_id, const uint64_t graph_id);
208 :
209 : void GenWorkStreamIdWithSessionIdGraphId(const uint64_t session_id, const uint64_t graph_id);
210 :
211 : const std::string& GetLogHeader();
212 :
213 : error_message::Context& GetErrorManagerContext();
214 :
215 : void SetErrorContext(error_message::Context error_context);
216 :
217 : void SetStage(const std::string& first_stage, const std::string& second_stage);
218 :
219 : // The default priority is 0 and a higher value indicates a higher priority
220 : int32_t ParseJsonFormatString(const void* const handle, uint32_t priority = 0);
221 :
222 : private:
223 : struct ErrorInfoConfig {
224 : std::string error_id;
225 : std::string error_title;
226 : std::string error_message;
227 : std::string possible_cause;
228 : std::string solution;
229 : std::vector<std::string> arg_list;
230 : uint32_t priority{0};
231 : };
232 1 : ErrorManager() = default;
233 1 : ~ErrorManager() = default;
234 :
235 : ErrorManager(const ErrorManager&) = delete;
236 : ErrorManager(ErrorManager&&) = delete;
237 : ErrorManager& operator=(const ErrorManager&) & = delete;
238 : ErrorManager& operator=(ErrorManager&&) & = delete;
239 :
240 : int32_t ParseJsonFile(const std::string path);
241 :
242 : // 供各上报接口做懒初始化, 保证并发调用下ParseJsonFile只会被真正执行一次
243 : int32_t EnsureInitialized();
244 :
245 : static int32_t ReadJsonFile(const std::string& file_path, void* const handle);
246 :
247 : void ClassifyCompileFailedMsg(
248 : const std::map<std::string, std::string>& msg, std::map<std::string, std::vector<std::string>>& classified_msg);
249 :
250 : bool IsInnerErrorCode(const std::string& error_code) const;
251 :
252 : bool IsUserDefinedErrorCode(const std::string& error_code);
253 :
254 : bool IsParamCheckErrorId(const std::string& error_code) const;
255 :
256 96 : inline bool IsValidErrorCode(const std::string& error_codes) const
257 : {
258 96 : constexpr uint32_t kErrorCodeValidLength = 6U;
259 96 : return error_codes.size() == kErrorCodeValidLength;
260 : }
261 :
262 : std::vector<ErrorItem>& GetErrorMsgContainerByWorkId(uint64_t work_id);
263 : std::vector<ErrorItem>& GetWarningMsgContainerByWorkId(uint64_t work_id);
264 :
265 : std::vector<ErrorItem>& GetErrorMsgContainer(uint64_t work_stream_id);
266 : std::vector<ErrorItem>& GetWarningMsgContainer(uint64_t work_stream_id);
267 :
268 : void AssembleInnerErrorMessage(
269 : const std::vector<ErrorItem>& error_messages, const std::string& first_code,
270 : std::stringstream& err_stream) const;
271 :
272 : void ClearErrorMsgContainerByWorkId(const uint64_t work_stream_id);
273 : void ClearWarningMsgContainerByWorkId(const uint64_t work_stream_id);
274 :
275 : void ClearErrorMsgContainer(const uint64_t work_stream_id);
276 : void ClearWarningMsgContainer(const uint64_t work_stream_id);
277 :
278 : std::atomic<bool> is_init_{false};
279 : std::mutex mutex_;
280 : // 仅用于保护懒初始化的check-then-act, 与mutex_的加锁顺序固定为 init_mutex_ -> mutex_
281 : std::mutex init_mutex_;
282 : std::map<std::string, ErrorInfoConfig> error_map_;
283 : std::map<std::string, std::map<std::string, std::vector<std::string>>> compile_failed_msg_map_;
284 :
285 : std::map<uint64_t, std::vector<ErrorItem>> error_message_per_work_id_;
286 : std::map<uint64_t, std::vector<ErrorItem>> warning_messages_per_work_id_;
287 :
288 : thread_local static error_message::Context error_context_;
289 :
290 : std::atomic<error_message::ErrorMsgMode> error_mode_{error_message::ErrorMsgMode::INTERNAL_MODE};
291 : std::vector<ErrorItem> error_message_process_; // 进程粒度,所有的errmsg存到同一个vector
292 : std::vector<ErrorItem> warning_messages_process_; // 进程粒度,所有的warning msg存到同一个vector
293 : };
294 :
295 : #ifdef __cplusplus
296 : extern "C" {
297 : #endif
298 :
299 : #if defined(__GNUC__)
300 : #ifndef GE_FUNC_HOST_VISIBILITY
301 : #if defined(HOST_VISIBILITY)
302 : #define GE_FUNC_HOST_VISIBILITY __attribute__((visibility("default")))
303 : #else
304 : #define GE_FUNC_HOST_VISIBILITY
305 : #endif
306 : #endif // GE_FUNC_HOST_VISIBILITY
307 :
308 : #ifndef GE_FUNC_DEV_VISIBILITY
309 : #if defined(DEV_VISIBILITY)
310 : #define GE_FUNC_DEV_VISIBILITY __attribute__((visibility("default")))
311 : #else
312 : #define GE_FUNC_DEV_VISIBILITY
313 : #endif
314 : #endif // GE_FUNC_DEV_VISIBILITY
315 :
316 : #ifndef FORMAT_PRINTF
317 : #define FORMAT_PRINTF(format_idx, first_arg) __attribute__((format(printf, (format_idx), (first_arg))))
318 : #endif
319 :
320 : #else
321 : #ifndef GE_FUNC_HOST_VISIBILITY
322 : #define GE_FUNC_HOST_VISIBILITY
323 : #endif
324 :
325 : #ifndef GE_FUNC_DEV_VISIBILITY
326 : #define GE_FUNC_DEV_VISIBILITY
327 : #endif
328 :
329 : #ifndef FORMAT_PRINTF
330 : #define FORMAT_PRINTF(format_idx, first_arg)
331 : #endif
332 : #endif
333 :
334 : GE_FUNC_HOST_VISIBILITY GE_FUNC_DEV_VISIBILITY int32_t
335 : RegisterFormatErrorMessageForC(const char* error_msg, unsigned long error_msg_len);
336 :
337 : GE_FUNC_HOST_VISIBILITY GE_FUNC_DEV_VISIBILITY int32_t
338 : ReportPredefinedErrMsgForC(const char* error_code, const char** key, const char** value, unsigned long arg_num);
339 :
340 : #ifdef __GNUC__
341 : GE_FUNC_HOST_VISIBILITY GE_FUNC_DEV_VISIBILITY int32_t ReportInnerErrMsgForC(
342 : const char* file_name, const char* func, uint32_t line, const char* error_code, const char* format, ...)
343 : FORMAT_PRINTF(5, 6);
344 : #else
345 : GE_FUNC_HOST_VISIBILITY GE_FUNC_DEV_VISIBILITY int32_t ReportInnerErrMsgForC(
346 : const char* file_name, const char* func, uint32_t line, const char* error_code, const char* format, ...);
347 : #endif
348 :
349 : #ifdef __cplusplus
350 : }
351 : #endif
352 :
353 : #endif // ERROR_MANAGER_H_
|