VTK-m  2.0
Logging.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_Logging_h
11 #define vtk_m_cont_Logging_h
12 
13 #include <vtkm/internal/Configure.h>
15 
16 #include <vtkm/Types.h>
17 
18 #include <vtkm/cont/vtkm_cont_export.h>
19 
20 #include <iostream>
21 #include <memory>
22 #include <sstream>
23 #include <string>
24 #include <typeindex>
25 #include <typeinfo>
26 
101 
113 
126 
129 
132 
145 
148 
152 
157 
162 
170 
178 
190 
191 #define VTKM_CONCAT_IMPL(s1, s2) s1##s2
192 #define VTKM_CONCAT(s1, s2) VTKM_CONCAT_IMPL(s1, s2)
193 
194 #ifdef __COUNTER__
195 #define VTKM_ANONYMOUS_VARIABLE VTKM_CONCAT(vtk_m_anonymous_, __COUNTER__)
196 #else
197 #define VTKM_ANONYMOUS_VARIABLE VTKM_CONCAT(vtk_m_anonymous_, __LINE__)
198 #endif
199 
200 #if defined(VTKM_ENABLE_LOGGING)
201 
202 #define VTKM_LOG_IF_S(level, cond, ...) \
203  vtkm::cont::LogCondStream(level, cond, __FILE__, __LINE__) << __VA_ARGS__
204 
205 #define VTKM_LOG_IF_F(level, cond, ...) \
206  vtkm::cont::LogCond(level, cond, __FILE__, __LINE__, __VA_ARGS__)
207 
208 #define VTKM_LOG_S(level, ...) VTKM_LOG_IF_S(level, true, __VA_ARGS__)
209 #define VTKM_LOG_F(level, ...) VTKM_LOG_IF_F(level, true, __VA_ARGS__)
210 
211 #define VTKM_LOG_SCOPE(level, ...) \
212  vtkm::cont::detail::LogScope VTKM_ANONYMOUS_VARIABLE { level, __FILE__, __LINE__, __VA_ARGS__ }
213 
214 #define VTKM_LOG_SCOPE_FUNCTION(level) VTKM_LOG_SCOPE(level, __func__)
215 #define VTKM_LOG_ALWAYS_S(level, ...) VTKM_LOG_S(level, __VA_ARGS__)
216 
217 
218 // Convenience macros:
219 
220 // Cast success:
221 #define VTKM_LOG_CAST_SUCC(inObj, outObj) \
222  VTKM_LOG_F(vtkm::cont::LogLevel::Cast, \
223  "Cast succeeded: %s (%p) --> %s (%p)", \
224  vtkm::cont::TypeToString(inObj).c_str(), \
225  &inObj, \
226  vtkm::cont::TypeToString(outObj).c_str(), \
227  &outObj)
228 
229 // Cast failure:
230 #define VTKM_LOG_CAST_FAIL(inObj, outType) \
231  VTKM_LOG_F(vtkm::cont::LogLevel::Cast, \
232  "Cast failed: %s (%p) --> %s", \
233  vtkm::cont::TypeToString(inObj).c_str(), \
234  &inObj, \
235  vtkm::cont::TypeToString<outType>().c_str())
236 
237 // TryExecute failure
238 #define VTKM_LOG_TRYEXECUTE_FAIL(errorMessage, functorName, deviceId) \
239  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "TryExecute encountered an error: " << errorMessage); \
240  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Failing functor: " << functorName); \
241  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Failing device: " << deviceId.GetName())
242 
243 // Same, but disabling device:
244 #define VTKM_LOG_TRYEXECUTE_DISABLE(errorMessage, functorName, deviceId) \
245  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "TryExecute encountered an error: " << errorMessage); \
246  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Failing functor: " << functorName); \
247  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Failing device: " << deviceId.GetName()); \
248  VTKM_LOG_S(vtkm::cont::LogLevel::Error, "The failing device has been disabled.")
249 
250 // Custom log level
251 #define VTKM_DEFINE_USER_LOG_LEVEL(name, offset) \
252  static constexpr vtkm::cont::LogLevel name = static_cast<vtkm::cont::LogLevel>( \
253  static_cast<typename std::underlying_type<vtkm::cont::LogLevel>::type>( \
254  vtkm::cont::LogLevel::UserFirst) + \
255  offset % \
256  static_cast<typename std::underlying_type<vtkm::cont::LogLevel>::type>( \
257  vtkm::cont::LogLevel::UserLast))
258 
259 #else // VTKM_ENABLE_LOGGING
260 
261 #define VTKM_LOG_S(level, ...)
262 #define VTKM_LOG_F(level, ...)
263 #define VTKM_LOG_IF_S(level, cond, ...)
264 #define VTKM_LOG_IF_F(level, cond, ...)
265 #define VTKM_LOG_SCOPE(level, ...)
266 #define VTKM_LOG_SCOPE_FUNCTION(level)
267 #define VTKM_LOG_ERROR_CONTEXT(desc, data)
268 #define VTKM_LOG_CAST_SUCC(inObj, outObj)
269 #define VTKM_LOG_CAST_FAIL(inObj, outType)
270 #define VTKM_DEFINE_USER_LOG_LEVEL(name, offset)
271 
272 // Always emitted. When logging is disabled, std::cerr is used.
273 
274 #define VTKM_LOG_ALWAYS_S(level, ...) \
275  (static_cast<int>(level) < 0 ? std::cerr : std::cout) \
276  << vtkm::cont::GetLogLevelName(level) << ": " << __VA_ARGS__ << "\n"
277 
278 // TryExecute failures are still important enough to log, but we just write to
279 // std::cerr when logging is disabled.
280 #define VTKM_LOG_TRYEXECUTE_FAIL(errorMessage, functorName, deviceId) \
281  std::cerr << "Error: TryExecute encountered an error: " << errorMessage << "\n" \
282  << "\t- Failing functor: " << functorName << "\n" \
283  << "\t- Failing device: " << deviceId.GetName() << "\n\n"
284 #define VTKM_LOG_TRYEXECUTE_DISABLE(errorMessage, functorName, deviceId) \
285  std::cerr << "Error: TryExecute encountered an error: " << errorMessage << "\n" \
286  << "\t- Failing functor: " << functorName << "\n" \
287  << "\t- Failing device: " << deviceId.GetName() << "\n" \
288  << "The failing device has been disabled.\n\n"
289 
290 #endif // VTKM_ENABLE_LOGGING
291 
292 namespace vtkm
293 {
294 namespace cont
295 {
296 
298 enum class LogLevel
299 {
302  Off = -9, //loguru::Verbosity_OFF,
303 
305  Fatal = -3, // loguru::Verbosity_FATAL,
306 
308  Error = -2, // loguru::Verbosity_ERROR,
309 
311  Warn = -1, // loguru::Verbosity_WARNING,
312 
315  Info = 0, //loguru::Verbosity_INFO,
316 
318  UserFirst = 1,
320  UserLast = 255,
321 
324 
327  Perf,
328 
330  MemCont,
331 
333  MemExec,
334 
336  MemTransfer,
337 
340 
342  Cast,
343 
345  UserVerboseFirst = 1024,
347  UserVerboseLast = 2047
348 };
349 
350 
367 VTKM_CONT_EXPORT
368 VTKM_CONT
369 void InitLogging(int& argc, char* argv[], const std::string& loggingFlag = "--vtkm-log-level");
370 VTKM_CONT_EXPORT
371 VTKM_CONT
372 void InitLogging();
380 VTKM_CONT_EXPORT
381 VTKM_CONT
382 void SetStderrLogLevel(const char* verbosity);
383 
384 VTKM_CONT_EXPORT
385 VTKM_CONT
392 VTKM_CONT_EXPORT
393 VTKM_CONT
395 
405 VTKM_CONT_EXPORT
406 VTKM_CONT
407 void SetLogLevelName(vtkm::cont::LogLevel level, const std::string& name);
408 
414 VTKM_CONT_EXPORT
415 VTKM_CONT
416 std::string GetLogLevelName(vtkm::cont::LogLevel level);
417 
422 VTKM_CONT_EXPORT
423 VTKM_CONT
424 void SetLogThreadName(const std::string& name);
425 VTKM_CONT_EXPORT
426 VTKM_CONT
427 std::string GetLogThreadName();
430 // Per-thread error context, not currently used, undocumented....
431 VTKM_CONT_EXPORT
432 VTKM_CONT
433 std::string GetLogErrorContext();
434 
440 VTKM_CONT_EXPORT
441 VTKM_CONT
442 std::string GetStackTrace(vtkm::Int32 skip = 0);
443 
445 VTKM_CONT_EXPORT
449 VTKM_CONT
450 std::string GetHumanReadableSize(vtkm::UInt64 bytes, int prec = 2);
451 
452 template <typename T>
453 VTKM_CONT inline std::string GetHumanReadableSize(T&& bytes, int prec = 2)
454 {
455  return GetHumanReadableSize(static_cast<vtkm::UInt64>(std::forward<T>(bytes)), prec);
456 }
458 
460 VTKM_CONT_EXPORT
463 VTKM_CONT
464 std::string GetSizeString(vtkm::UInt64 bytes, int prec = 2);
465 
466 template <typename T>
467 VTKM_CONT inline std::string GetSizeString(T&& bytes, int prec = 2)
468 {
469  return GetSizeString(static_cast<vtkm::UInt64>(std::forward<T>(bytes)), prec);
470 }
472 
478 VTKM_CONT_EXPORT VTKM_CONT std::string TypeToString(const std::type_info& t);
479 VTKM_CONT_EXPORT VTKM_CONT std::string TypeToString(const std::type_index& t);
480 template <typename T>
481 inline VTKM_CONT std::string TypeToString()
482 {
483  return TypeToString(typeid(T));
484 }
485 template <typename T>
486 inline VTKM_CONT std::string TypeToString(const T&)
487 {
488  return TypeToString(typeid(T));
489 }
492 #ifdef VTKM_ENABLE_LOGGING
493 
501 VTKM_CONT_EXPORT
502 VTKM_CONT
503 void LogCond(LogLevel level, bool cond, const char* file, unsigned line, const char* format...);
504 
505 namespace detail
506 {
507 
515 class VTKM_CONT_EXPORT LogScope
516 {
517  struct InternalStruct;
518  std::unique_ptr<InternalStruct> Internals;
519 
520 public:
521  /*
522  * \param level Desired LogLevel value for the log message.
523  * \param cond When false this function is no-op.
524  * \param format Printf like format string.
525  */
526  VTKM_CONT
527  LogScope(LogLevel level, const char* file, unsigned line, const char* format...);
528 
529  VTKM_CONT ~LogScope();
530 };
531 
532 
533 } // namespace detail
534 
540 struct VTKM_CONT_EXPORT LogCondStream
541 {
542  VTKM_CONT
543  LogCondStream(LogLevel level, bool cond, const char* file, int line)
544  : Level(level)
545  , Condition(cond)
546  , File(file)
547  , Line(line)
548  {
549  }
550 
551  VTKM_CONT
552  ~LogCondStream() noexcept(false);
553 
554  template <typename T>
555  VTKM_CONT LogCondStream& operator<<(const T& in)
556  {
557  SStream << in;
558  return *this;
559  }
560 
561  VTKM_CONT
562  LogCondStream& operator<<(std::ostream& (*f)(std::ostream&))
563  {
564  f(SStream);
565  return *this;
566  }
567 
568 private:
569  LogLevel Level;
570  bool Condition;
571  const char* File;
572  int Line;
573  std::ostringstream SStream;
574 };
575 #endif // VTKM_ENABLE_LOGGING
576 
577 }
578 } // end namespace vtkm::cont
579 
580 #endif // vtk_m_cont_Logging_h
vtkm::cont::InitLogging
VTKM_CONT_EXPORT VTKM_CONT void InitLogging(int &argc, char *argv[], const std::string &loggingFlag="--vtkm-log-level")
This shouldn't be called directly – prefer calling vtkm::cont::Initialize, which takes care of loggin...
vtkm::cont::LogLevel::UserVerboseFirst
@ UserVerboseFirst
1024-2047 are reserved for application usage.
vtkm::cont::GetLogThreadName
VTKM_CONT_EXPORT VTKM_CONT std::string GetLogThreadName()
The name to identify the current thread in the log output.
vtkm::cont::GetSizeString
VTKM_CONT_EXPORT VTKM_CONT std::string GetSizeString(vtkm::UInt64 bytes, int prec=2)
Returns "%1 (%2 bytes)" where %1 is the result from GetHumanReadableSize and two is the exact number ...
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
Types.h
vtkm::cont::SetStderrLogLevel
VTKM_CONT_EXPORT VTKM_CONT void SetStderrLogLevel(const char *verbosity)
Set the range of log levels that will be printed to stderr.
vtkm::cont::LogLevel::DevicesEnabled
@ DevicesEnabled
Information about which devices are enabled/disabled.
vtkm::cont::LogLevel::MemTransfer
@ MemTransfer
Host->device / device->host data copies.
vtkm::cont::GetStackTrace
VTKM_CONT_EXPORT VTKM_CONT std::string GetStackTrace(vtkm::Int32 skip=0)
Returns a stacktrace on supported platforms.
vtkm::cont::LogLevel::UserLast
@ UserLast
The range 1-255 are reserved to application use.
vtkm::cont::LogLevel
LogLevel
Log levels for use with the logging macros.
Definition: Logging.h:298
vtkm::cont::Error
The superclass of all exceptions thrown by any VTKm function or method.
Definition: Error.h:33
vtkm::cont::LogLevel::UserVerboseLast
@ UserVerboseLast
1024-2047 are reserved for application usage.
vtkm::cont::LogLevel::Cast
@ Cast
When a dynamic object is (or isn't) resolved via CastAndCall, etc.
vtkm::cont::GetStderrLogLevel
VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::LogLevel GetStderrLogLevel()
Get the active highest log level that will be printed to stderr.
vtkm::Line
Ray< CoordType, Dim, true > Line
Lines are two-sided rays:
Definition: Geometry.h:330
ExportMacros.h
vtkm::cont::SetLogThreadName
VTKM_CONT_EXPORT VTKM_CONT void SetLogThreadName(const std::string &name)
The name to identify the current thread in the log output.
vtkm::cont::LogLevel::Info
@ Info
Information messages (detected hardware, etc) and temporary debugging output.
vtkm::cont::SetLogLevelName
VTKM_CONT_EXPORT VTKM_CONT void SetLogLevelName(vtkm::cont::LogLevel level, const std::string &name)
Register a custom name to identify a log level.
vtkm::cont::LogLevel::KernelLaunches
@ KernelLaunches
Details on Device-side Kernel Launches.
vtkm::cont::GetHumanReadableSize
VTKM_CONT_EXPORT VTKM_CONT std::string GetHumanReadableSize(vtkm::UInt64 bytes, int prec=2)
Convert a size in bytes to a human readable string (e.g.
vtkm::operator<<
VTKM_CONT std::ostream & operator<<(std::ostream &stream, const vtkm::Bounds &bounds)
Helper function for printing bounds during testing.
Definition: Bounds.h:237
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::LogLevel::MemCont
@ MemCont
Host-side resource allocations/frees (e.g. ArrayHandle control buffers)
vtkm::filter::mesh_info::CellMetric::Condition
@ Condition
vtkm::cont::LogLevel::Fatal
@ Fatal
Fatal errors that should abort execution.
vtkm::cont::LogLevel::Off
@ Off
Used with SetStderrLogLevel to silence the log.
vtkm::cont::LogLevel::MemExec
@ MemExec
Device-side resource allocations/frees (e.g ArrayHandle device buffers)
vtkm::Int32
int32_t Int32
Definition: Types.h:160
vtkm::cont::GetLogLevelName
VTKM_CONT_EXPORT VTKM_CONT std::string GetLogLevelName(vtkm::cont::LogLevel level)
Get a human readable name for the log level.
vtkm::cont::GetLogErrorContext
VTKM_CONT_EXPORT VTKM_CONT std::string GetLogErrorContext()
vtkm::cont::TypeToString
VTKM_CONT_EXPORT VTKM_CONT std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.
vtkm::cont::LogLevel::UserFirst
@ UserFirst
The range 1-255 are reserved to application use.
vtkm::cont::LogLevel::Perf
@ Perf
General timing data and algorithm flow information, such as filter execution, worklet dispatches,...