1 /**
2 * Copyright 2019-2023 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef MINDSPORE_CORE_UTILS_LOG_ADAPTER_H_
18 #define MINDSPORE_CORE_UTILS_LOG_ADAPTER_H_
19
20 #include <cstdarg>
21 #include <cstdint>
22 #include <string>
23 #include <sstream>
24 #include <memory>
25 #include <map>
26 #include <vector>
27 #include <thread>
28 #include <functional>
29 #include "mindapi/base/macros.h"
30 #include "utils/os.h"
31 #include "utils/overload.h"
32 #include "securec.h"
33 #ifdef USE_GLOG
34 #define GLOG_NO_ABBREVIATED_SEVERITIES
35 #define google mindspore_private
36 #include "glog/logging.h"
37 #undef google
38 #endif
39
40 #undef SM_DEBUG
41
42 // NOTICE: when relative path of 'log_adapter.h' changed, macro 'LOG_HDR_FILE_REL_PATH' must be changed
43 #ifndef LOG_HDR_FILE_REL_PATH
44 #define LOG_HDR_FILE_REL_PATH "mindspore/core/utils/log_adapter.h"
45 #endif
46 // Get start index of file relative path in __FILE__
GetRelPathPos()47 static constexpr size_t GetRelPathPos() noexcept {
48 return sizeof(__FILE__) > sizeof(LOG_HDR_FILE_REL_PATH) ? sizeof(__FILE__) - sizeof(LOG_HDR_FILE_REL_PATH) : 0;
49 }
50 namespace mindspore {
51 /// \brief The handler map for ACL.
52 #define FILE_NAME \
53 (sizeof(__FILE__) > GetRelPathPos() ? static_cast<const char *>(__FILE__) + GetRelPathPos() \
54 : static_cast<const char *>(__FILE__))
55 enum ExceptionType {
56 NoExceptionType = 0,
57 UnknownError,
58 ArgumentError,
59 NotSupportError,
60 NotExistsError,
61 DeviceProcessError,
62 AbortedError,
63 IndexError,
64 ValueError,
65 TypeError,
66 ShapeError,
67 KeyError,
68 AttributeError,
69 NameError,
70 AssertionError,
71 BaseException,
72 KeyboardInterrupt,
73 Exception,
74 StopIteration,
75 OverflowError,
76 ZeroDivisionError,
77 EnvironmentError,
78 IOError,
79 OSError,
80 ImportError,
81 MemoryError,
82 UnboundLocalError,
83 RuntimeError,
84 NotImplementedError,
85 IndentationError,
86 RuntimeWarning,
87 };
88
89 static const inline std::map<std::string, ExceptionType> exception_types_map = {
90 {"IndexError", IndexError},
91 {"ValueError", ValueError},
92 {"TypeError", TypeError},
93 {"KeyError", KeyError},
94 {"AttributeError", AttributeError},
95 {"NameError", NameError},
96 {"AssertionError", AssertionError},
97 {"BaseException", BaseException},
98 {"KeyboardInterrupt", KeyboardInterrupt},
99 {"Exception", Exception},
100 {"StopIteration", StopIteration},
101 {"OverflowError", OverflowError},
102 {"ZeroDivisionError", ZeroDivisionError},
103 {"EnvironmentError", EnvironmentError},
104 {"IOError", IOError},
105 {"OSError", OSError},
106 {"MemoryError", MemoryError},
107 {"UnboundLocalError", UnboundLocalError},
108 {"RuntimeError", RuntimeError},
109 {"NotImplementedError", NotImplementedError},
110 {"IndentationError", IndentationError},
111 {"RuntimeWarning", RuntimeWarning}};
112
SupportedExceptionsToString()113 static inline std::string SupportedExceptionsToString() {
114 std::ostringstream oss;
115 size_t index = 0;
116 for (auto iter = exception_types_map.cbegin(); iter != exception_types_map.cend(); ++iter) {
117 oss << iter->first;
118 if (index != exception_types_map.size() - 1) {
119 oss << ", ";
120 }
121 ++index;
122 }
123 oss << ". ";
124 return oss.str();
125 }
126
127 struct LocationInfo {
LocationInfoLocationInfo128 LocationInfo(const char *file, int line, const char *func) : file_(file), line_(line), func_(func) {}
129 ~LocationInfo() = default;
130
131 const char *file_;
132 int line_;
133 const char *func_;
134 };
135
136 template <class T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
137 constexpr std::ostream &operator<<(std::ostream &stream, const T &value) {
138 return stream << static_cast<typename std::underlying_type<T>::type>(value);
139 }
140
141 class LogStream {
142 public:
LogStream()143 LogStream() { sstream_ = std::make_shared<std::stringstream>(); }
144 ~LogStream() = default;
145
146 template <typename T>
147 LogStream &operator<<(const T &val) noexcept {
148 (*sstream_) << val;
149 return *this;
150 }
151
152 LogStream &operator<<(std::ostream &func(std::ostream &os)) noexcept {
153 (*sstream_) << func;
154 return *this;
155 }
156
157 friend class LogWriter;
158
159 private:
160 std::shared_ptr<std::stringstream> sstream_;
161 };
162
163 enum MsLogLevel : int { kDebug = 0, kInfo, kWarning, kError, kException };
164
165 enum SubModuleId : int {
166 SM_UNKNOWN = 0, // unknown submodule
167 SM_CORE, // core
168 SM_ANALYZER, // static analyzer
169 SM_COMMON, // common
170 SM_DEBUG, // debug
171 SM_OFFLINE_DEBUG, // offline debug
172 SM_DEVICE, // device
173 SM_GE_ADPT, // ge adapter
174 SM_IR, // IR
175 SM_KERNEL, // kernel
176 SM_MD, // MindData
177 SM_ME, // MindExpression
178 SM_EXPRESS, // EXPRESS_IR
179 SM_OPTIMIZER, // optimzer
180 SM_PARALLEL, // parallel
181 SM_PARSER, // parser
182 SM_PIPELINE, // ME pipeline
183 SM_PRE_ACT, // pre-activate
184 SM_PYNATIVE, // PyNative
185 SM_SESSION, // session
186 SM_UTILS, // utils
187 SM_VM, // VM
188 SM_PROFILER, // profiler
189 SM_PS, // Parameter Server
190 SM_PI, // PIJIT
191 SM_FL, // Federated Learning
192 SM_DISTRIBUTED, // Distributed
193 SM_LITE, // LITE
194 SM_ARMOUR, // ARMOUR
195 SM_HCCL_ADPT, // Hccl Adapter
196 SM_RUNTIME_FRAMEWORK, // Runtime framework
197 SM_GE, // GraphEngine
198 SM_API, // MindAPI
199 SM_SYMBOLIC_SHAPE, // symbolic shape
200 SM_GRAPH_KERNEL, // graph kernel fusion
201 SM_MINDIO, // mindio tpp
202 NUM_SUBMODUES, // number of submodules
203 };
204
205 #ifndef SUBMODULE_ID
206 #define SUBMODULE_ID mindspore::SubModuleId::SM_ME
207 #endif
208
209 constexpr int COMPONENT_START = 10000; // vlog start level for component
210 constexpr int COMPONENT_RANGE = 100; // number for levels allocated for each component
211 #define NUM_ALIGN(val, base) (((val) + (base)-1) / (base) * (base))
212
213 // VLOG level definition and group
214 enum VLogLevel : int {
215 VL_INVALID = 0, // invalid vlog level
216 VL_FLOW = 1, // start of end to end flow related log level
217
218 VL_CORE = COMPONENT_START + (SM_CORE - 1) * COMPONENT_RANGE, // 0. core
219 VL_ANALYZER = COMPONENT_START + (SM_ANALYZER - 1) * COMPONENT_RANGE, // 1. static analyzer
220 VL_COMMON = COMPONENT_START + (SM_COMMON - 1) * COMPONENT_RANGE, // 2. common
221 VL_DEBUG = COMPONENT_START + (SM_DEBUG - 1) * COMPONENT_RANGE, // 3. debug
222 VL_OFFLINE_DEBUG = COMPONENT_START + (SM_OFFLINE_DEBUG - 1) * COMPONENT_RANGE, // 4. offline debug
223 VL_DEVICE = COMPONENT_START + (SM_DEVICE - 1) * COMPONENT_RANGE, // 5. device
224 VL_GE_ADPT = COMPONENT_START + (SM_GE_ADPT - 1) * COMPONENT_RANGE, // 6. ge adapter
225 VL_IR = COMPONENT_START + (SM_IR - 1) * COMPONENT_RANGE, // 7. IR
226 VL_KERNEL = COMPONENT_START + (SM_KERNEL - 1) * COMPONENT_RANGE, // 8. kernel
227 VL_MD = COMPONENT_START + (SM_MD - 1) * COMPONENT_RANGE, // 9. MindData
228 VL_ME = COMPONENT_START + (SM_ME - 1) * COMPONENT_RANGE, // 10. MindExpression
229 VL_EXPRESS = COMPONENT_START + (SM_EXPRESS - 1) * COMPONENT_RANGE, // 11. EXPRESS_IR
230 VL_OPTIMIZER = COMPONENT_START + (SM_OPTIMIZER - 1) * COMPONENT_RANGE, // 12. optimzer
231 VL_PARALLEL = COMPONENT_START + (SM_PARALLEL - 1) * COMPONENT_RANGE, // 13. parallel
232 VL_PARSER = COMPONENT_START + (SM_PARSER - 1) * COMPONENT_RANGE, // 14. parser
233 VL_PIPELINE = COMPONENT_START + (SM_PIPELINE - 1) * COMPONENT_RANGE, // 15. ME pipeline
234 VL_PRE_ACT = COMPONENT_START + (SM_PRE_ACT - 1) * COMPONENT_RANGE, // 16. pre-activate
235 VL_PYNATIVE = COMPONENT_START + (SM_PYNATIVE - 1) * COMPONENT_RANGE, // 17. PyNative
236 VL_SESSION = COMPONENT_START + (SM_SESSION - 1) * COMPONENT_RANGE, // 18. session
237 VL_UTILS = COMPONENT_START + (SM_UTILS - 1) * COMPONENT_RANGE, // 19. utils
238 VL_VM = COMPONENT_START + (SM_VM - 1) * COMPONENT_RANGE, // 20. VM
239 VL_PROFILER = COMPONENT_START + (SM_PROFILER - 1) * COMPONENT_RANGE, // 21. profiler
240 VL_PS = COMPONENT_START + (SM_PS - 1) * COMPONENT_RANGE, // 22. Parameter Server
241 VL_PI = COMPONENT_START + (SM_PI - 1) * COMPONENT_RANGE, // 23. PIJIT
242 VL_FL = COMPONENT_START + (SM_FL - 1) * COMPONENT_RANGE, // 24. Federated Learning
243 VL_DISTRIBUTED = COMPONENT_START + (SM_DISTRIBUTED - 1) * COMPONENT_RANGE, // 25. Distributed
244 VL_LITE = COMPONENT_START + (SM_LITE - 1) * COMPONENT_RANGE, // 26. LITE
245 VL_ARMOUR = COMPONENT_START + (SM_ARMOUR - 1) * COMPONENT_RANGE, // 27. ARMOUR
246 VL_HCCL_ADPT = COMPONENT_START + (SM_HCCL_ADPT - 1) * COMPONENT_RANGE, // 28. Hccl Adapter
247 VL_RUNTIME_FRAMEWORK = COMPONENT_START + (SM_RUNTIME_FRAMEWORK - 1) * COMPONENT_RANGE, // 29. Runtime framework
248
249 VL_GE = COMPONENT_START + (SM_GE - 1) * COMPONENT_RANGE, // 30. GraphEngine
250 VL_ASCEND_KERNEL_SELECT = VL_GE, // print ascend kernel select
251
252 VL_API = COMPONENT_START + (SM_API - 1) * COMPONENT_RANGE, // 31. MindAPI
253 VL_SYMBOLIC_SHAPE = COMPONENT_START + (SM_SYMBOLIC_SHAPE - 1) * COMPONENT_RANGE, // 32. symbolic shape
254 VL_GRAPH_KERNEL = COMPONENT_START + (SM_GRAPH_KERNEL - 1) * COMPONENT_RANGE, // 33. graph kernel fusion
255
256 VL_USER_CUSTOM = NUM_ALIGN(COMPONENT_START + (NUM_SUBMODUES - 1) * COMPONENT_RANGE,
257 COMPONENT_START), // start of user defined vlog level
258 VL_DISP_VLOG_TAGS = VL_USER_CUSTOM // print already used vlog tags
259 };
260
261 /// \brief Get sub-module name by the module id.
262 ///
263 /// \param[in] module_id The module id.
264 ///
265 /// \return The sub-module name.
266 MS_EXPORT const std::string GetSubModuleName(SubModuleId module_id);
267
268 MS_CORE_API void InitSubModulesLogLevel();
269
270 /// \brief Get current time as a string.
271 ///
272 /// \return The string presents current time.
273 MS_EXPORT std::string GetTimeString();
274
275 /// \brief The log levels of mindspore sub-module.
276 MS_EXPORT extern int g_ms_submodule_log_levels[];
277
278 /// \brief The variables for controlling output of vlog.
279 MS_EXPORT extern int g_ms_vlog_level_from;
280 MS_EXPORT extern int g_ms_vlog_level_to;
281
282 #if defined(_WIN32) || defined(_WIN64)
283 /// \brief The max log level of current thread.
284 MS_EXPORT extern enum MsLogLevel this_thread_max_log_level;
285 #else
286 /// \brief The max log level of current thread.
287 MS_EXPORT extern thread_local enum MsLogLevel this_thread_max_log_level;
288 #endif
289
290 class TryCatchGuard {
291 public:
TryCatchGuard()292 TryCatchGuard() : origin_log_level_(this_thread_max_log_level) { this_thread_max_log_level = MsLogLevel::kWarning; }
~TryCatchGuard()293 ~TryCatchGuard() { this_thread_max_log_level = origin_log_level_; }
294
295 private:
296 enum MsLogLevel origin_log_level_;
297 };
298 #define MS_LOG_TRY_CATCH_SCOPE mindspore::TryCatchGuard mindspore_log_try_catch_guard
299
300 class AnfNode;
301 using AnfNodePtr = std::shared_ptr<AnfNode>;
302 /// \brief LogWriter defines interface to write log.
303 class MS_CORE_API LogWriter {
304 public:
305 using ExceptionHandler = void (*)(ExceptionType, const std::string &);
306 using MessageHandler = void (*)(std::ostringstream *oss);
307 using TraceProvider = std::function<void(std::ostringstream &, bool)>;
308 using GetTraceStrProvider = std::string (*)(const AnfNodePtr &, bool);
309
310 LogWriter(const LocationInfo &location, MsLogLevel log_level, SubModuleId submodule,
311 ExceptionType excp_type = NoExceptionType, bool is_internal_exception = false,
312 const AnfNodePtr &node = nullptr)
location_(location)313 : location_(location),
314 log_level_(log_level),
315 vlog_level_(-1),
316 submodule_(submodule),
317 exception_type_(excp_type),
318 is_internal_exception_(is_internal_exception),
319 node_(node) {}
LogWriter(const LocationInfo & location,int vlog_level,SubModuleId submodule)320 LogWriter(const LocationInfo &location, int vlog_level, SubModuleId submodule)
321 : location_(location),
322 log_level_(mindspore::kInfo),
323 vlog_level_(vlog_level),
324 submodule_(submodule),
325 exception_type_(NoExceptionType),
326 is_internal_exception_(false) {}
327 ~LogWriter() = default;
328
329 /// \brief Output log message from the input log stream.
330 ///
331 /// \param[in] stream The input log stream.
332 void operator<(const LogStream &stream) const noexcept;
333
334 /// \brief Output log message from the input log stream and then throw exception.
335 ///
336 /// \param[in] stream The input log stream.
337 void operator^(const LogStream &stream) const NO_RETURN;
338
339 /// \brief Get the function pointer of converting exception types in c++.
340 ///
341 /// \return A pointer of the function.
342 static const ExceptionHandler &GetExceptionHandler();
343
344 /// \brief Set the function pointer of converting exception types in c++.
345 ///
346 /// \param[in] A function pointer of converting exception types in c++.
347 static void SetExceptionHandler(const ExceptionHandler &new_exception_handler);
348
349 /// \brief Get the function pointer of handling message for different device.
350 ///
351 /// \return A pointer of the function.
352 static const MessageHandler &GetMessageHandler();
353
354 /// \brief Set the function pointer of handling message for different device.
355 ///
356 /// \param[in] A function pointer of handling message for different device.
357 static void SetMessageHandler(const MessageHandler &new_message_handler);
358
359 /// \brief Get the function pointer of printing trace stacks.
360 ///
361 /// \return A pointer of the function.
362 static const TraceProvider &GetTraceProvider();
363
364 /// \brief Set the function pointer of printing trace stacks.
365 ///
366 /// \param[in] A function pointer of printing trace stacks.
367 static void SetTraceProvider(const TraceProvider &new_trace_provider);
368
369 /// \brief Set the function pointer of getting node trace string.
370 ///
371 /// \param[in] A function pointer of getting trace string.
372 static void SetGetTraceStrProvider(const LogWriter::GetTraceStrProvider &provider);
373
374 private:
375 const std::string GetNodeDebugInfoStr() const;
376 void OutputLog(const std::ostringstream &msg) const;
377 void RemoveLabelBeforeOutputLog(const std::ostringstream &msg) const;
378 static ExceptionHandler &exception_handler();
379 static MessageHandler &message_handler();
380 static TraceProvider &trace_provider();
381 static GetTraceStrProvider &get_trace_str_provider();
382
383 LocationInfo location_;
384 MsLogLevel log_level_;
385 int vlog_level_ = -1;
386 SubModuleId submodule_;
387 ExceptionType exception_type_;
388 bool is_internal_exception_;
389 AnfNodePtr node_;
390 };
391
392 #define MSLOG_IF(level, condition, excp_type, node) \
393 !(condition) ? void(0) \
394 : mindspore::LogWriter(mindspore::LocationInfo(FILE_NAME, __LINE__, __FUNCTION__), level, SUBMODULE_ID, \
395 excp_type, false, node) < mindspore::LogStream()
396
397 #define MSLOG_THROW(excp_type, is_internal_exception, node) \
398 mindspore::LogWriter(mindspore::LocationInfo(FILE_NAME, __LINE__, __FUNCTION__), mindspore::kException, \
399 SUBMODULE_ID, excp_type, is_internal_exception, node) ^ \
400 mindspore::LogStream()
401
402 #define MATCH_LEVEL(level) \
403 static_cast<int>(level) >= mindspore::g_ms_submodule_log_levels[SUBMODULE_ID] && \
404 static_cast<int>(level) <= static_cast<int>(mindspore::this_thread_max_log_level)
405
406 #define IS_OUTPUT_ON(level) (MATCH_LEVEL(level))
407 #define IS_VLOG_ON(level) (((level) >= g_ms_vlog_level_from) && ((level) <= g_ms_vlog_level_to))
408
409 #define __MS_LOG_DEBUG(node) \
410 MSLOG_IF(mindspore::kDebug, IS_OUTPUT_ON(mindspore::kDebug), mindspore::NoExceptionType, node)
411 #define __MS_LOG_INFO(node) MSLOG_IF(mindspore::kInfo, IS_OUTPUT_ON(mindspore::kInfo), mindspore::NoExceptionType, node)
412 #define __MS_LOG_WARNING(node) \
413 MSLOG_IF(mindspore::kWarning, IS_OUTPUT_ON(mindspore::kWarning), mindspore::NoExceptionType, node)
414 #define __MS_LOG_ERROR(node) \
415 MSLOG_IF(mindspore::kError, IS_OUTPUT_ON(mindspore::kError), mindspore::NoExceptionType, node)
416 #define MS_VLOG(level) \
417 !(IS_VLOG_ON(level)) ? void(0) \
418 : mindspore::LogWriter(mindspore::LocationInfo(FILE_NAME, __LINE__, __FUNCTION__), level, \
419 SUBMODULE_ID) < mindspore::LogStream()
420 #define __MS_LOG_EXCEPTION(node) MSLOG_THROW(mindspore::NoExceptionType, false, node)
421 #define __MS_LOG_INTERNAL_EXCEPTION(node) MSLOG_THROW(mindspore::NoExceptionType, true, node)
422
423 #define MS_LOG(level) __MS_LOG_##level(nullptr)
424 #define MS_LOG_WITH_NODE(level, node) __MS_LOG_##level(node)
425
426 #define MS_LOG_EXCEPTION __MS_LOG_EXCEPTION(nullptr)
427 #define MS_INTERNAL_EXCEPTION(type) MSLOG_THROW(type, true, nullptr)
428 #define MS_EXCEPTION(type) MSLOG_THROW(type, false, nullptr)
429 #define MS_EXCEPTION_WITH_NODE(type, node) MSLOG_THROW(type, false, node)
430 } // namespace mindspore
431
432 #define MS_EXCEPTION_IF_NULL(ptr) \
433 do { \
434 if ((ptr) == nullptr) { \
435 MS_LOG(INTERNAL_EXCEPTION) << "The pointer[" << #ptr << "] is null."; \
436 } \
437 } while (0)
438
439 #define MS_EXCEPTION_IF_CHECK_FAIL(condition, error_info) \
440 do { \
441 if (!(condition)) { \
442 MS_LOG(INTERNAL_EXCEPTION) << "Failure info [" << (error_info) << "]."; \
443 } \
444 } while (0)
445
446 #define MS_EXCEPTION_IF_ZERO(name, value) \
447 do { \
448 if ((value) == 0) { \
449 MS_LOG(INTERNAL_EXCEPTION) << "The " << (name) << " is zero."; \
450 } \
451 } while (0)
452
453 #define MS_ERROR_IF_NULL(ptr) \
454 do { \
455 if ((ptr) == nullptr) { \
456 MS_LOG(ERROR) << ": The pointer[" << #ptr << "] is null."; \
457 return false; \
458 } \
459 } while (0)
460
461 #define MS_ERROR_IF_NULL_W_RET_VAL(ptr, val) \
462 do { \
463 if ((ptr) == nullptr) { \
464 MS_LOG(ERROR) << ": The pointer[" << #ptr << "] is null."; \
465 return val; \
466 } \
467 } while (0)
468
469 #define MS_ERROR_IF_NULL_WO_RET_VAL(ptr) \
470 do { \
471 if ((ptr) == nullptr) { \
472 MS_LOG(ERROR) << ": The pointer[" << #ptr << "] is null."; \
473 return; \
474 } \
475 } while (0)
476
477 #define RETURN_IF_FALSE(condition) \
478 do { \
479 if (!(condition)) { \
480 return false; \
481 } \
482 } while (0)
483
484 #define RETURN_IF_FALSE_WITH_LOG(condition, message) \
485 do { \
486 if (!(condition)) { \
487 MS_LOG(ERROR) << message; \
488 return false; \
489 } \
490 } while (0)
491
492 #ifdef DEBUG
493 #include <cassert>
494 #define MS_ASSERT(f) assert(f)
495 #else
496 #define MS_ASSERT(f) ((void)0)
497 #endif
498
499 #endif // MINDSPORE_CORE_UTILS_LOG_ADAPTER_H_
500