Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
Classes | Namespaces | Macros
trace.hpp File Reference
#include <uni20/config.hpp>
#include "demangle.hpp"
#include "diagnostic_error.hpp"
#include "floating_eq.hpp"
#include "namedenum.hpp"
#include "presentation.hpp"
#include "presentation_mdspan.hpp"
#include "presentation_stacktrace.hpp"
#include "terminal.hpp"
#include <algorithm>
#include <atomic>
#include <cctype>
#include <chrono>
#include <complex>
#include <concepts>
#include <coroutine>
#include <cstdio>
#include <exception>
#include <fmt/chrono.h>
#include <fmt/core.h>
#include <functional>
#include <map>
#include <source_location>
#include <string>
#include <string_view>
#include <thread>
#include <type_traits>
#include <utility>
#include <vector>
#include "trace_impl.hpp"
Include dependency graph for trace.hpp:

Go to the source code of this file.

Classes

struct  trace::BaseName< N >
 Compile-time string wrapper for use as a non-type template parameter. More...
 
struct  trace::TracingBaseClass< Derived >
 CRTP tracing base class that emits messages with demangled type name. More...
 

Namespaces

namespace  trace
 

Macros

#define CHECK(cond, ...)
 
#define CHECK_EQUAL(a, b, ...)
 
#define CHECK_FLOATING_EQ(a, b, ...)
 
#define COMPILER_NOTE(msg)   _Pragma(TRACE_STRINGIZE(message msg))
 
#define COMPILER_WARNING_NOTE(msg)
 
#define DEBUG_CHECK(cond, ...)
 
#define DEBUG_CHECK_EQUAL(a, b, ...)
 
#define DEBUG_CHECK_FLOATING_EQ(a, b, ...)
 
#define DEBUG_PRECONDITION(cond, ...)
 
#define DEBUG_PRECONDITION_EQUAL(a, b, ...)
 
#define DEBUG_PRECONDITION_FLOATING_EQ(a, b, ...)
 
#define DEBUG_TRACE(...)
 
#define DEBUG_TRACE_IF(cond, ...)
 
#define DEBUG_TRACE_IF_STACK(cond, ...)
 
#define DEBUG_TRACE_MODULE(m, ...)
 
#define DEBUG_TRACE_MODULE_IF(m, cond, ...)
 
#define DEBUG_TRACE_MODULE_IF_STACK(m, cond, ...)
 
#define DEBUG_TRACE_MODULE_STACK(m, ...)
 
#define DEBUG_TRACE_ONCE(...)
 
#define DEBUG_TRACE_ONCE_STACK(...)
 
#define DEBUG_TRACE_STACK(...)
 
#define ERROR(...)   trace::ErrorCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__));
 
#define ERROR_IF(cond, ...)
 
#define PANIC(...)   trace::PanicCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__));
 
#define PRECONDITION(cond, ...)
 
#define PRECONDITION_EQUAL(a, b, ...)
 
#define PRECONDITION_FLOATING_EQ(a, b, ...)
 
#define TRACE(...)
 
#define TRACE_BASE_CLASS(Name)   trace::TracingBaseClass<trace::BaseName(TRACE_STRINGIZE(Name)), Name>
 
#define TRACE_DISABLE   0
 
#define TRACE_HAS_STACKTRACE   0
 
#define TRACE_IF(cond, ...)
 
#define TRACE_IF_STACK(cond, ...)
 
#define TRACE_MODULE(m, ...)
 
#define TRACE_MODULE_IF(m, cond, ...)
 
#define TRACE_MODULE_IF_STACK(m, cond, ...)
 
#define TRACE_MODULE_STACK(m, ...)
 
#define TRACE_ONCE(...)
 
#define TRACE_ONCE_STACK(...)
 
#define TRACE_STACK(...)
 
#define TRACE_STRINGIZE(x)   TRACE_STRINGIZE_IMPL(x)
 
#define TRACE_STRINGIZE_IMPL(x)   #x
 

Macro Definition Documentation

◆ CHECK

#define CHECK (   cond,
  ... 
)
Value:
do \
{ \
if (!(cond)) \
{ \
::trace::CheckCall(#cond, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ CHECK_EQUAL

#define CHECK_EQUAL (   a,
  b,
  ... 
)
Value:
do \
{ \
if (!((a) == (b))) \
{ \
::trace::CheckEqualCall(#a, #b, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), __FILE__, __LINE__, a, \
b __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ CHECK_FLOATING_EQ

#define CHECK_FLOATING_EQ (   a,
  b,
  ... 
)
Value:
do \
{ \
auto va = (a); \
auto vb = (b); \
using T = std::decay_t<decltype(va)>; \
static_assert(::uni20::check::UlpComparable<T>, "CHECK_FLOATING_EQ requires a ULP-comparable scalar"); \
[&](auto const&... extra) \
{ \
auto const ulps = ::trace::detail::get_ulps(va, vb, extra...); \
if (!::uni20::check::FloatingULP<T>::eq(va, vb, ulps)) \
{ \
::trace::CheckFloatingEqCall(#a, #b, ulps, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), \
__FILE__, __LINE__, va, vb, extra...); \
} \
}(__VA_ARGS__); \
} \
while (0)
Compare floating point or complex values within a given ULP tolerance.
Definition floating_eq.hpp:154

◆ COMPILER_NOTE

#define COMPILER_NOTE (   msg)    _Pragma(TRACE_STRINGIZE(message msg))

◆ COMPILER_WARNING_NOTE

#define COMPILER_WARNING_NOTE (   msg)
Value:
do \
{} \
while (0)

◆ DEBUG_CHECK

#define DEBUG_CHECK (   cond,
  ... 
)
Value:
do \
{ \
if (!(cond)) \
{ \
::trace::DebugCheckCall(#cond, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_CHECK_EQUAL

#define DEBUG_CHECK_EQUAL (   a,
  b,
  ... 
)
Value:
do \
{ \
if (!((a) == (b))) \
{ \
::trace::DebugCheckEqualCall(#a, #b, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), __FILE__, __LINE__, a, \
b __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_CHECK_FLOATING_EQ

#define DEBUG_CHECK_FLOATING_EQ (   a,
  b,
  ... 
)
Value:
do \
{ \
auto va = (a); \
auto vb = (b); \
using T = std::decay_t<decltype(va)>; \
static_assert(::uni20::check::UlpComparable<T>, "DEBUG_CHECK_FLOATING_EQ requires a ULP-comparable scalar"); \
[&](auto const&... extra) \
{ \
auto const ulps = ::trace::detail::get_ulps(va, vb, extra...); \
if (!::uni20::check::FloatingULP<T>::eq(va, vb, ulps)) \
{ \
::trace::DebugCheckFloatingEqCall(#a, #b, ulps, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), \
__FILE__, __LINE__, va, vb, extra...); \
} \
}(__VA_ARGS__); \
} \
while (0)

◆ DEBUG_PRECONDITION

#define DEBUG_PRECONDITION (   cond,
  ... 
)
Value:
do \
{ \
if (!(cond)) \
{ \
::trace::DebugPreconditionCall(#cond, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_PRECONDITION_EQUAL

#define DEBUG_PRECONDITION_EQUAL (   a,
  b,
  ... 
)
Value:
do \
{ \
if (!((a) == (b))) \
{ \
::trace::DebugPreconditionEqualCall(#a, #b, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), __FILE__, __LINE__, a, \
b __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_PRECONDITION_FLOATING_EQ

#define DEBUG_PRECONDITION_FLOATING_EQ (   a,
  b,
  ... 
)
Value:
do \
{ \
auto va = (a); \
auto vb = (b); \
using T = std::decay_t<decltype(va)>; \
static_assert(::uni20::check::UlpComparable<T>, "DEBUG_PRECONDITION_FLOATING_EQ requires a ULP-comparable scalar"); \
[&](auto const&... extra) \
{ \
auto const ulps = ::trace::detail::get_ulps(va, vb, extra...); \
if (!::uni20::check::FloatingULP<T>::eq(va, vb, ulps)) \
{ \
::trace::DebugPreconditionFloatingEqCall(#a, #b, ulps, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), \
__FILE__, __LINE__, va, vb, extra...); \
} \
}(__VA_ARGS__); \
} \
while (0)

◆ DEBUG_TRACE

#define DEBUG_TRACE (   ...)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
::trace::DebugTraceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
while (0)
#define TRACE_DISABLE
Definition trace.hpp:44

◆ DEBUG_TRACE_IF

#define DEBUG_TRACE_IF (   cond,
  ... 
)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if (cond) \
{ \
::trace::DebugTraceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_TRACE_IF_STACK

#define DEBUG_TRACE_IF_STACK (   cond,
  ... 
)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if (cond) \
{ \
::trace::DebugTraceStackCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_TRACE_MODULE

#define DEBUG_TRACE_MODULE (   m,
  ... 
)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if constexpr (ENABLE_TRACE_##m) \
{ \
::trace::DebugTraceModuleCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_TRACE_MODULE_IF

#define DEBUG_TRACE_MODULE_IF (   m,
  cond,
  ... 
)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if constexpr (ENABLE_TRACE_##m) \
{ \
if (cond) \
{ \
::trace::DebugTraceModuleCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
while (0)

◆ DEBUG_TRACE_MODULE_IF_STACK

#define DEBUG_TRACE_MODULE_IF_STACK (   m,
  cond,
  ... 
)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if constexpr (ENABLE_TRACE_##m) \
{ \
if (cond) \
{ \
::trace::DebugTraceModuleStackCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
while (0)

◆ DEBUG_TRACE_MODULE_STACK

#define DEBUG_TRACE_MODULE_STACK (   m,
  ... 
)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if constexpr (ENABLE_TRACE_##m) \
{ \
::trace::DebugTraceModuleStackCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ DEBUG_TRACE_ONCE

#define DEBUG_TRACE_ONCE (   ...)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
static std::atomic_flag _trace_once_flag = ATOMIC_FLAG_INIT; \
if (!_trace_once_flag.test_and_set(std::memory_order_relaxed)) \
{ \
::trace::DebugTraceOnceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ DEBUG_TRACE_ONCE_STACK

#define DEBUG_TRACE_ONCE_STACK (   ...)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
static std::atomic_flag _debug_trace_once_stack_flag = ATOMIC_FLAG_INIT; \
if (!_debug_trace_once_stack_flag.test_and_set(std::memory_order_relaxed)) \
{ \
::trace::DebugTraceStackOnceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ DEBUG_TRACE_STACK

#define DEBUG_TRACE_STACK (   ...)
Value:
do \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
::trace::DebugTraceStackCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
while (0)

◆ ERROR

#define ERROR (   ...)    trace::ErrorCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__));

◆ ERROR_IF

#define ERROR_IF (   cond,
  ... 
)
Value:
do \
{ \
if (cond) \
{ \
::trace::ErrorIfCall(#cond, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ PANIC

#define PANIC (   ...)    trace::PanicCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__));

◆ PRECONDITION

#define PRECONDITION (   cond,
  ... 
)
Value:
do \
{ \
if (!(cond)) \
{ \
::trace::PreconditionCall(#cond, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ PRECONDITION_EQUAL

#define PRECONDITION_EQUAL (   a,
  b,
  ... 
)
Value:
do \
{ \
if (!((a) == (b))) \
{ \
::trace::PreconditionEqualCall(#a, #b, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), __FILE__, __LINE__, a, \
b __VA_OPT__(, __VA_ARGS__)); \
} \
} \
while (0)

◆ PRECONDITION_FLOATING_EQ

#define PRECONDITION_FLOATING_EQ (   a,
  b,
  ... 
)
Value:
do \
{ \
auto va = (a); \
auto vb = (b); \
using T = std::decay_t<decltype(va)>; \
static_assert(::uni20::check::UlpComparable<T>, "PRECONDITION_FLOATING_EQ requires a ULP-comparable scalar"); \
[&](auto const&... extra) \
{ \
auto const ulps = ::trace::detail::get_ulps(va, vb, extra...); \
if (!::uni20::check::FloatingULP<T>::eq(va, vb, ulps)) \
{ \
::trace::PreconditionFloatingEqCall(#a, #b, ulps, (#a "," #b __VA_OPT__("," #__VA_ARGS__)), \
__FILE__, __LINE__, va, vb, extra...); \
} \
}(__VA_ARGS__); \
} \
while (0)

◆ TRACE

#define TRACE (   ...)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
::trace::TraceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
while (0)

◆ TRACE_BASE_CLASS

#define TRACE_BASE_CLASS (   Name)    trace::TracingBaseClass<trace::BaseName(TRACE_STRINGIZE(Name)), Name>

◆ TRACE_DISABLE

#define TRACE_DISABLE   0

◆ TRACE_HAS_STACKTRACE

#define TRACE_HAS_STACKTRACE   0

◆ TRACE_IF

#define TRACE_IF (   cond,
  ... 
)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if (cond) \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
::trace::TraceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ TRACE_IF_STACK

#define TRACE_IF_STACK (   cond,
  ... 
)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else if (cond) \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
::trace::TraceStackCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ TRACE_MODULE

#define TRACE_MODULE (   m,
  ... 
)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (ENABLE_TRACE_##m) \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
::trace::TraceModuleCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ TRACE_MODULE_IF

#define TRACE_MODULE_IF (   m,
  cond,
  ... 
)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (ENABLE_TRACE_##m) \
{ \
if (cond) \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
::trace::TraceModuleCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
} \
while (0)

◆ TRACE_MODULE_IF_STACK

#define TRACE_MODULE_IF_STACK (   m,
  cond,
  ... 
)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (ENABLE_TRACE_##m) \
{ \
if (cond) \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
::trace::TraceModuleStackCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
} \
while (0)

◆ TRACE_MODULE_STACK

#define TRACE_MODULE_STACK (   m,
  ... 
)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (ENABLE_TRACE_##m) \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
::trace::TraceModuleStackCall(#m, #__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ TRACE_ONCE

#define TRACE_ONCE (   ...)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
static std::atomic_flag _trace_once_flag = ATOMIC_FLAG_INIT; \
if (!_trace_once_flag.test_and_set(std::memory_order_relaxed)) \
{ \
::trace::TraceOnceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ TRACE_ONCE_STACK

#define TRACE_ONCE_STACK (   ...)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
static std::atomic_flag _trace_once_stack_flag = ATOMIC_FLAG_INIT; \
if (!_trace_once_stack_flag.test_and_set(std::memory_order_relaxed)) \
{ \
::trace::TraceStackOnceCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
} \
while (0)

◆ TRACE_STACK

#define TRACE_STACK (   ...)
Value:
do \
{ \
if (::trace::detail::is_constant_evaluation()) \
{} \
else \
{ \
if constexpr (TRACE_DISABLE) \
{} \
else \
{ \
::trace::TraceStackCall(#__VA_ARGS__, __FILE__, __LINE__ __VA_OPT__(, __VA_ARGS__)); \
} \
} \
} \
while (0)

◆ TRACE_STRINGIZE

#define TRACE_STRINGIZE (   x)    TRACE_STRINGIZE_IMPL(x)

◆ TRACE_STRINGIZE_IMPL

#define TRACE_STRINGIZE_IMPL (   x)    #x