• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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