Caffe2 - C++ API
A deep learning, cross platform ML framework
logging.h
1 
17 #ifndef CAFFE2_CORE_LOGGING_H_
18 #define CAFFE2_CORE_LOGGING_H_
19 
20 #include <climits>
21 #include <exception>
22 #include <functional>
23 #include <limits>
24 #include <sstream>
25 
26 #include "caffe2/core/flags.h"
27 #include "caffe2/proto/caffe2.pb.h"
28 
29 // CAFFE2_LOG_THRESHOLD is a compile time flag that would allow us to turn off
30 // logging at compile time so no logging message below that level is produced
31 // at all. The value should be between INT_MIN and CAFFE_FATAL.
32 #ifndef CAFFE2_LOG_THRESHOLD
33 // If we have not defined the compile time log threshold, we keep all the
34 // log cases.
35 #define CAFFE2_LOG_THRESHOLD INT_MIN
36 #endif // CAFFE2_LOG_THRESHOLD
37 
38 // Below are different implementations for glog and non-glog cases.
39 #ifdef CAFFE2_USE_GOOGLE_GLOG
40 #include "caffe2/core/logging_is_google_glog.h"
41 #else // !CAFFE2_USE_GOOGLE_GLOG
42 #include "caffe2/core/logging_is_not_google_glog.h"
43 #endif // CAFFE2_USE_GOOGLE_GLOG
44 
45 CAFFE2_DECLARE_int(caffe2_log_level);
46 CAFFE2_DECLARE_bool(caffe2_use_fatal_for_enforce);
47 
48 namespace caffe2 {
49 // Functions that we use for initialization.
50 bool InitCaffeLogging(int* argc, char** argv);
51 
52 constexpr bool IsUsingGoogleLogging() {
53 #ifdef CAFFE2_USE_GOOGLE_GLOG
54  return true;
55 #else
56  return false;
57 #endif
58 }
59 
68 void ShowLogInfoToStderr();
69 
70 inline void MakeStringInternal(std::stringstream& /*ss*/) {}
71 
72 template <typename T>
73 inline void MakeStringInternal(std::stringstream& ss, const T& t) {
74  ss << t;
75 }
76 
77 template <typename T, typename... Args>
78 inline void
79 MakeStringInternal(std::stringstream& ss, const T& t, const Args&... args) {
80  MakeStringInternal(ss, t);
81  MakeStringInternal(ss, args...);
82 }
83 
84 template <typename... Args>
85 string MakeString(const Args&... args) {
86  std::stringstream ss;
87  MakeStringInternal(ss, args...);
88  return string(ss.str());
89 }
90 
91 // Specializations for already-a-string types.
92 template <>
93 inline string MakeString(const string& str) {
94  return str;
95 }
96 inline string MakeString(const char* c_str) {
97  return string(c_str);
98 }
99 
100 template <class Container>
101 inline string Join(const string& delimiter, const Container& v) {
102  std::stringstream s;
103  int cnt = static_cast<int64_t>(v.size()) - 1;
104  for (auto i = v.begin(); i != v.end(); ++i, --cnt) {
105  s << (*i) << (cnt ? delimiter : "");
106  }
107  return s.str();
108 }
109 
110 // Obtains the base name from a full path.
111 string StripBasename(const std::string& full_path);
112 
113 // Replace all occurrences of "from" substring to "to" string.
114 // Returns number of replacements
115 size_t ReplaceAll(string& s, const char* from, const char* to);
116 
117 void SetStackTraceFetcher(std::function<string(void)> fetcher);
118 
119 void SetOperatorLogger(std::function<void(const OperatorDef&)> tracer);
120 std::function<void(const OperatorDef&)> GetOperatorLogger();
121 
122 class EnforceNotMet : public std::exception {
123  public:
125  const char* file,
126  const int line,
127  const char* condition,
128  const string& msg,
129  const void* caller=nullptr);
130  void AppendMessage(const string& msg);
131  string msg() const;
132  inline const vector<string>& msg_stack() const {
133  return msg_stack_;
134  }
135 
136  const char* what() const noexcept override;
137 
138  const void* caller() const noexcept;
139 
140  private:
141  vector<string> msg_stack_;
142  string full_msg_;
143  string stack_trace_;
144  const void* caller_;
145 };
146 
147 #define CAFFE_ENFORCE(condition, ...) \
148  do { \
149  if (!(condition)) { \
150  throw ::caffe2::EnforceNotMet( \
151  __FILE__, __LINE__, #condition, ::caffe2::MakeString(__VA_ARGS__)); \
152  } \
153  } while (false)
154 
155 #define CAFFE_ENFORCE_WITH_CALLER(condition, ...) \
156  do { \
157  if (!(condition)) { \
158  throw ::caffe2::EnforceNotMet( \
159  __FILE__, __LINE__, #condition, ::caffe2::MakeString(__VA_ARGS__), this); \
160  } \
161  } while (false)
162 
163 #define CAFFE_THROW(...) \
164  throw ::caffe2::EnforceNotMet( \
165  __FILE__, __LINE__, "", ::caffe2::MakeString(__VA_ARGS__))
166 
194 namespace enforce_detail {
195 
196 struct EnforceOK {};
197 
199  public:
200 #ifdef _MSC_VER
201  // MSVC + NVCC ignores constexpr and will issue a warning if included.
202  /* implicit */ EnforceFailMessage(EnforceOK) : msg_(nullptr) {}
203 #else
204  constexpr /* implicit */ EnforceFailMessage(EnforceOK) : msg_(nullptr) {}
205 #endif
206  EnforceFailMessage(EnforceFailMessage&&) = default;
207  EnforceFailMessage(const EnforceFailMessage&) = delete;
208  EnforceFailMessage& operator=(EnforceFailMessage&&) = delete;
209  EnforceFailMessage& operator=(const EnforceFailMessage&) = delete;
210 
211  // Catch all wrong usages like CAFFE_ENFORCE_THAT(x < y)
212  template <class... Args>
213  /* implicit */ EnforceFailMessage(Args...) {
214  static_assert(
215  // This stands for an "impossible" condition. Plain `false` doesn't
216  // trick compiler enough.
217  sizeof...(Args) == std::numeric_limits<std::size_t>::max(),
218  "CAFFE_ENFORCE_THAT has to be used with one of special check functions "
219  "like `Equals`. Use CAFFE_ENFORCE for simple boolean checks.");
220  }
221 
222  /* implicit */ EnforceFailMessage(std::string&& msg) {
223  msg_ = new std::string(std::move(msg));
224  }
225  inline bool bad() const {
226  return msg_ != nullptr;
227  }
228  std::string get_message_and_free(std::string&& extra) const {
229  std::string r;
230  if (extra.empty()) {
231  r = std::move(*msg_);
232  } else {
233  r = ::caffe2::MakeString(std::move(*msg_), ". ", std::move(extra));
234  }
235  delete msg_;
236  return r;
237  }
238 
239  private:
240  std::string* msg_;
241 };
242 
243 #define BINARY_COMP_HELPER(name, op) \
244  template <typename T1, typename T2> \
245  inline EnforceFailMessage name(const T1& x, const T2& y) { \
246  if (x op y) { \
247  return EnforceOK(); \
248  } \
249  return MakeString(x, " vs ", y); \
250  }
251 BINARY_COMP_HELPER(Equals, ==)
252 BINARY_COMP_HELPER(NotEquals, !=)
253 BINARY_COMP_HELPER(Greater, >)
254 BINARY_COMP_HELPER(GreaterEquals, >=)
255 BINARY_COMP_HELPER(Less, <)
256 BINARY_COMP_HELPER(LessEquals, <=)
257 #undef BINARY_COMP_HELPER
258 
259 #define CAFFE_ENFORCE_THAT_IMPL(condition, expr, ...) \
260  do { \
261  using namespace ::caffe2::enforce_detail; \
262  const EnforceFailMessage& CAFFE_ENFORCE_THAT_IMPL_r_ = (condition); \
263  if (CAFFE_ENFORCE_THAT_IMPL_r_.bad()) { \
264  throw ::caffe2::EnforceNotMet( \
265  __FILE__, \
266  __LINE__, \
267  expr, \
268  CAFFE_ENFORCE_THAT_IMPL_r_.get_message_and_free( \
269  ::caffe2::MakeString(__VA_ARGS__))); \
270  } \
271  } while (false)
272 
273 #define CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(condition, expr, ...) \
274  do { \
275  using namespace ::caffe2::enforce_detail; \
276  const EnforceFailMessage& CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER_r_ = \
277  (condition); \
278  if (CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER_r_.bad()) { \
279  throw ::caffe2::EnforceNotMet( \
280  __FILE__, \
281  __LINE__, \
282  expr, \
283  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER_r_.get_message_and_free( \
284  ::caffe2::MakeString(__VA_ARGS__)), \
285  this); \
286  } \
287  } while (false)
288 }
289 
290 #define CAFFE_ENFORCE_THAT(condition, ...) \
291  CAFFE_ENFORCE_THAT_IMPL((condition), #condition, __VA_ARGS__)
292 
293 #define CAFFE_ENFORCE_EQ(x, y, ...) \
294  CAFFE_ENFORCE_THAT_IMPL(Equals((x), (y)), #x " == " #y, __VA_ARGS__)
295 #define CAFFE_ENFORCE_NE(x, y, ...) \
296  CAFFE_ENFORCE_THAT_IMPL(NotEquals((x), (y)), #x " != " #y, __VA_ARGS__)
297 #define CAFFE_ENFORCE_LE(x, y, ...) \
298  CAFFE_ENFORCE_THAT_IMPL(LessEquals((x), (y)), #x " <= " #y, __VA_ARGS__)
299 #define CAFFE_ENFORCE_LT(x, y, ...) \
300  CAFFE_ENFORCE_THAT_IMPL(Less((x), (y)), #x " < " #y, __VA_ARGS__)
301 #define CAFFE_ENFORCE_GE(x, y, ...) \
302  CAFFE_ENFORCE_THAT_IMPL(GreaterEquals((x), (y)), #x " >= " #y, __VA_ARGS__)
303 #define CAFFE_ENFORCE_GT(x, y, ...) \
304  CAFFE_ENFORCE_THAT_IMPL(Greater((x), (y)), #x " > " #y, __VA_ARGS__)
305 #define CAFFE_ENFORCE_EQ_WITH_CALLER(x, y, ...) \
306  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(Equals((x), (y)), #x " == " #y, __VA_ARGS__)
307 #define CAFFE_ENFORCE_NE_WITH_CALLER(x, y, ...) \
308  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(NotEquals((x), (y)), #x " != " #y, __VA_ARGS__)
309 #define CAFFE_ENFORCE_LE_WITH_CALLER(x, y, ...) \
310  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(LessEquals((x), (y)), #x " <= " #y, __VA_ARGS__)
311 #define CAFFE_ENFORCE_LT_WITH_CALLER(x, y, ...) \
312  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(Less((x), (y)), #x " < " #y, __VA_ARGS__)
313 #define CAFFE_ENFORCE_GE_WITH_CALLER(x, y, ...) \
314  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(GreaterEquals((x), (y)), #x " >= " #y, __VA_ARGS__)
315 #define CAFFE_ENFORCE_GT_WITH_CALLER(x, y, ...) \
316  CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(Greater((x), (y)), #x " > " #y, __VA_ARGS__)
317 } // namespace caffe2
318 
319 #endif // CAFFE2_CORE_LOGGING_H_
Copyright (c) 2016-present, Facebook, Inc.
void ShowLogInfoToStderr()
A utility to allow one to show log info to stderr after the program starts.
Definition: logging.cc:212
Copyright (c) 2016-present, Facebook, Inc.