1 /**
2 * Copyright 2019-2021 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 <stdarg.h>
21 #include <stdint.h>
22 #include <string>
23 #include <sstream>
24 #include <memory>
25 #include <map>
26 #include <thread>
27 #include <functional>
28 #include "utils/visible.h"
29 #include "utils/overload.h"
30 #include "./securec.h"
31 #ifdef USE_GLOG
32 #define GLOG_NO_ABBREVIATED_SEVERITIES
33 #define google mindspore_private
34 #include "glog/logging.h"
35 #undef google
36 #else
37 #include "toolchain/slog.h"
38 #endif
39 // NOTICE: when relative path of 'log_adapter.h' changed, macro 'LOG_HDR_FILE_REL_PATH' must be changed
40 #define LOG_HDR_FILE_REL_PATH "mindspore/core/utils/log_adapter.h"
41
42 // Get start index of file relative path in __FILE__
GetRelPathPos()43 static constexpr size_t GetRelPathPos() noexcept {
44 return sizeof(__FILE__) > sizeof(LOG_HDR_FILE_REL_PATH) ? sizeof(__FILE__) - sizeof(LOG_HDR_FILE_REL_PATH) : 0;
45 }
46
47 namespace mindspore {
48 MS_CORE_API extern std::map<void **, std::thread *> acl_handle_map;
49 #define FILE_NAME \
50 (sizeof(__FILE__) > GetRelPathPos() ? static_cast<const char *>(__FILE__) + GetRelPathPos() \
51 : static_cast<const char *>(__FILE__))
52 enum ExceptionType {
53 NoExceptionType = 0,
54 UnknownError,
55 ArgumentError,
56 NotSupportError,
57 NotExistsError,
58 AlreadyExistsError,
59 UnavailableError,
60 DeviceProcessError,
61 AbortedError,
62 TimeOutError,
63 ResourceUnavailable,
64 NoPermissionError,
65 IndexError,
66 ValueError,
67 TypeError,
68 KeyError,
69 AttributeError,
70 NameError
71 };
72
73 struct LocationInfo {
LocationInfoLocationInfo74 LocationInfo(const char *file, int line, const char *func) : file_(file), line_(line), func_(func) {}
75 ~LocationInfo() = default;
76
77 const char *file_;
78 int line_;
79 const char *func_;
80 };
81
82 class LogStream {
83 public:
LogStream()84 LogStream() { sstream_ = std::make_shared<std::stringstream>(); }
85 ~LogStream() = default;
86
87 template <typename T>
88 LogStream &operator<<(const T &val) noexcept {
89 (*sstream_) << val;
90 return *this;
91 }
92
93 LogStream &operator<<(std::ostream &func(std::ostream &os)) noexcept {
94 (*sstream_) << func;
95 return *this;
96 }
97
98 friend class LogWriter;
99
100 private:
101 std::shared_ptr<std::stringstream> sstream_;
102 };
103
104 template <class T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
105 constexpr std::ostream &operator<<(std::ostream &stream, const T &value) {
106 return stream << static_cast<typename std::underlying_type<T>::type>(value);
107 }
108
109 enum MsLogLevel : int { DEBUG = 0, INFO, WARNING, ERROR, EXCEPTION };
110
111 enum SubModuleId : int {
112 SM_UNKNOWN = 0, // unknown submodule
113 SM_CORE, // core
114 SM_ANALYZER, // static analyzer
115 SM_COMMON, // common
116 SM_DEBUG, // debug
117 SM_OFFLINE_DEBUG, // offline debug
118 SM_DEVICE, // device
119 SM_GE_ADPT, // ge adapter
120 SM_IR, // IR
121 SM_KERNEL, // kernel
122 SM_MD, // MindData
123 SM_ME, // MindExpression
124 SM_EXPRESS, // EXPRESS_IR
125 SM_OPTIMIZER, // optimzer
126 SM_PARALLEL, // parallel
127 SM_PARSER, // parser
128 SM_PIPELINE, // ME pipeline
129 SM_PRE_ACT, // pre-activate
130 SM_PYNATIVE, // PyNative
131 SM_SESSION, // session
132 SM_UTILS, // utils
133 SM_VM, // VM
134 SM_PROFILER, // profiler
135 SM_PS, // Parameter Server
136 SM_FL, // Federated Learning
137 SM_LITE, // LITE
138 SM_ARMOUR, // ARMOUR
139 SM_HCCL_ADPT, // Hccl Adapter
140 SM_RUNTIME_FRAMEWORK, // Runtime framework
141 SM_GE, // GraphEngine
142 NUM_SUBMODUES // number of submodules
143 };
144
145 #ifndef SUBMODULE_ID
146 #define SUBMODULE_ID mindspore::SubModuleId::SM_ME
147 #endif
148
149 MS_EXPORT const std::string GetSubModuleName(SubModuleId module_id);
150
151 MS_EXPORT std::string GetTimeString();
152
153 MS_EXPORT extern int g_ms_submodule_log_levels[];
154
155 #if defined(_WIN32) || defined(_WIN64)
156 MS_EXPORT extern enum MsLogLevel this_thread_max_log_level;
157 #define MS_LOG_TRY_CATCH_SCOPE
158 #else
159 MS_EXPORT extern thread_local enum MsLogLevel this_thread_max_log_level;
160 class TryCatchGuard {
161 public:
TryCatchGuard()162 TryCatchGuard() {
163 origin_log_level_ = this_thread_max_log_level;
164 this_thread_max_log_level = MsLogLevel::WARNING;
165 }
166
~TryCatchGuard()167 ~TryCatchGuard() { this_thread_max_log_level = origin_log_level_; }
168
169 private:
170 enum MsLogLevel origin_log_level_;
171 };
172 #define MS_LOG_TRY_CATCH_SCOPE mindspore::TryCatchGuard mindspore_log_try_catch_guard
173 #endif
174
175 class LogWriter {
176 public:
177 using ExceptionHandler = std::function<void(ExceptionType, const std::string &msg)>;
178 using TraceProvider = std::function<void(std::ostringstream &oss)>;
179
180 LogWriter(const LocationInfo &location, MsLogLevel log_level, SubModuleId submodule,
181 ExceptionType excp_type = NoExceptionType)
location_(location)182 : location_(location), log_level_(log_level), submodule_(submodule), exception_type_(excp_type) {}
183 ~LogWriter() = default;
184
185 MS_CORE_API void operator<(const LogStream &stream) const noexcept;
186 MS_CORE_API void operator^(const LogStream &stream) const __attribute__((noreturn));
187
set_exception_handler(ExceptionHandler exception_handler)188 static void set_exception_handler(ExceptionHandler exception_handler) { exception_handler_ = exception_handler; }
set_trace_provider(TraceProvider trace_provider)189 static void set_trace_provider(TraceProvider trace_provider) { trace_provider_ = trace_provider; }
trace_provider()190 static TraceProvider trace_provider() { return trace_provider_; }
191
192 private:
193 void OutputLog(const std::ostringstream &msg) const;
194
195 LocationInfo location_;
196 MsLogLevel log_level_;
197 SubModuleId submodule_;
198 ExceptionType exception_type_;
199
200 inline static ExceptionHandler exception_handler_ = nullptr;
201 inline static TraceProvider trace_provider_ = nullptr;
202 };
203
204 #define MSLOG_IF(level, condition, excp_type) \
205 static_cast<void>(0), !(condition) \
206 ? void(0) \
207 : mindspore::LogWriter(mindspore::LocationInfo(FILE_NAME, __LINE__, __FUNCTION__), level, \
208 SUBMODULE_ID, excp_type) < mindspore::LogStream()
209 #define MSLOG_THROW(excp_type) \
210 mindspore::LogWriter(mindspore::LocationInfo(FILE_NAME, __LINE__, __FUNCTION__), mindspore::EXCEPTION, SUBMODULE_ID, \
211 excp_type) ^ \
212 mindspore::LogStream()
213
214 #define IS_OUTPUT_ON(level) \
215 ((level) >= mindspore::g_ms_submodule_log_levels[SUBMODULE_ID] && (level) <= mindspore::this_thread_max_log_level)
216
217 #define MS_LOG(level) MS_LOG_##level
218
219 #define MS_LOG_DEBUG MSLOG_IF(mindspore::DEBUG, IS_OUTPUT_ON(mindspore::DEBUG), mindspore::NoExceptionType)
220 #define MS_LOG_INFO MSLOG_IF(mindspore::INFO, IS_OUTPUT_ON(mindspore::INFO), mindspore::NoExceptionType)
221 #define MS_LOG_WARNING MSLOG_IF(mindspore::WARNING, IS_OUTPUT_ON(mindspore::WARNING), mindspore::NoExceptionType)
222 #define MS_LOG_ERROR MSLOG_IF(mindspore::ERROR, IS_OUTPUT_ON(mindspore::ERROR), mindspore::NoExceptionType)
223
224 #define MS_LOG_EXCEPTION MSLOG_THROW(mindspore::NoExceptionType)
225 #define MS_EXCEPTION(type) MSLOG_THROW(type)
226 } // namespace mindspore
227
228 #define MS_EXCEPTION_IF_NULL(ptr) \
229 do { \
230 if ((ptr) == nullptr) { \
231 MS_LOG(EXCEPTION) << ": The pointer[" << #ptr << "] is null."; \
232 } \
233 } while (0)
234
235 #define MS_EXCEPTION_IF_ZERO(name, value) \
236 do { \
237 if (value == 0) { \
238 MS_LOG(EXCEPTION) << ": The " << name << " is zero."; \
239 } \
240 } while (0)
241
242 #define MS_ERROR_IF_NULL(ptr) \
243 do { \
244 if ((ptr) == nullptr) { \
245 MS_LOG(ERROR) << ": The pointer[" << #ptr << "] is null."; \
246 return false; \
247 } \
248 } while (0)
249
250 #define MS_ERROR_IF_NULL_W_RET_VAL(ptr, val) \
251 do { \
252 if ((ptr) == nullptr) { \
253 MS_LOG(ERROR) << ": The pointer[" << #ptr << "] is null."; \
254 return val; \
255 } \
256 } while (0)
257
258 #define MS_ERROR_IF_NULL_WO_RET_VAL(ptr) \
259 do { \
260 if ((ptr) == nullptr) { \
261 MS_LOG(ERROR) << ": The pointer[" << #ptr << "] is null."; \
262 return; \
263 } \
264 } while (0)
265
266 #ifdef DEBUG
267 #include <cassert>
268 #define MS_ASSERT(f) assert(f)
269 #else
270 #define MS_ASSERT(f) ((void)0)
271 #endif
272
273 #endif // MINDSPORE_CORE_UTILS_LOG_ADAPTER_H_
274