7#include <guanaqo/export.h>
35 friend std::ostream &
operator<<(std::ostream &os, Log) {
return os; }
38 __itt_domain *domain = __itt_domain_create(
"guanaqo");
39 static constexpr int64_t max_instance_num = 255;
41 for (int64_t i = 0; i <= max_instance_num; ++i)
44 __itt_id_make(
nullptr,
static_cast<unsigned long long>(i)));
50 : domain{std::exchange(other.domain,
nullptr)} {}
55 for (int64_t i = 0; i <= max_instance_num; ++i)
58 __itt_id_make(
nullptr,
static_cast<unsigned long long>(i)));
63 ScopedLog(__itt_domain *domain, __itt_string_handle *name,
68 instance = std::clamp<int64_t>(instance, 0, max_instance_num);
69 auto id = __itt_id_make(
nullptr,
70 static_cast<unsigned long long>(instance));
71 __itt_task_begin(domain,
id, __itt_null, name);
76 : domain{std::exchange(other.domain,
nullptr)} {}
81 __itt_task_end(domain);
86 int64_t instance)
const {
90 void trace_instant(__itt_string_handle *name, int64_t instance)
const {
93 instance = std::clamp<int64_t>(instance, 0, max_instance_num);
95 __itt_id_make(
nullptr,
static_cast<unsigned long long>(instance));
96 __itt_marker(domain,
id, name, __itt_scope_task);
99 [[nodiscard]] std::span<const Log>
get_logs()
const {
return {}; }
106#if !GUANAQO_WITH_PERFETTO
107#define GUANAQO_TRACE_IMPL(var_name, name, instance) \
108 static auto GUANAQO_CAT(var_name, _name) = \
109 __itt_string_handle_create(name); \
110 const auto var_name = ::guanaqo::get_trace_logger().trace( \
111 GUANAQO_CAT(var_name, _name), instance)
112#define GUANAQO_TRACE_INSTANT_IMPL(var_name, name, instance) \
114 static auto GUANAQO_CAT(var_name, _name) = \
115 __itt_string_handle_create(name); \
116 ::guanaqo::get_trace_logger().trace_instant( \
117 GUANAQO_CAT(var_name, _name), instance); \
119#define GUANAQO_TRACE(name, instance, ...) \
120 GUANAQO_TRACE_IMPL(GUANAQO_CAT(trace_log_, __COUNTER__), name, instance)
121#define GUANAQO_TRACE_INSTANT(name, instance) \
122 GUANAQO_TRACE_INSTANT_IMPL(GUANAQO_CAT(trace_instant_, __COUNTER__), name, \
124#define GUANAQO_TRACE_LINALG(name, gflops) \
125 GUANAQO_TRACE(name, 0)
126#define GUANAQO_TRACE_REGION(name, instance) GUANAQO_TRACE(name, instance)
127#define GUANAQO_TRACE_STATIC_STR(s) s
146 return os << std::quoted(log.name) <<
',' << log.instance <<
','
147 << log.start_time.count() <<
',' << log.duration.count()
148 <<
',' << log.thread_id <<
',' << log.flop_count;
153 return os <<
"name" <<
',' <<
"instance" <<
',' <<
"start_time" <<
','
154 <<
"duration" <<
',' <<
"thread_id" <<
',' <<
"flop_count";
157 using clock = std::chrono::steady_clock;
159 static clock::time_point
t0;
172 :
log{std::exchange(other.log,
nullptr)},
184 int64_t flop_count = -1) {
187 auto &log =
logs.emplace_back();
188 auto t1 = clock::now();
190 log.instance = instance;
191 log.flop_count = flop_count;
192 log.start_time = t1 -
t0;
198 int64_t flop_count = -1) {
199 auto instant_log =
trace(name, instance, flop_count);
200 instant_log.log =
nullptr;
203 [[nodiscard]] std::span<const Log>
get_logs()
const {
204 return std::span{
logs};
215#if GUANAQO_WITH_TRACING
232 const std::function<
void(std::shared_ptr<TraceLogger>)> &callback =
238#if !GUANAQO_WITH_PERFETTO && !GUANAQO_WITH_ITT
239#if GUANAQO_WITH_TRACING
240#define GUANAQO_TRACE(name, ...) \
241 const auto GUANAQO_CAT(trace_log_, __COUNTER__) = \
242 ::guanaqo::get_trace_logger().trace(name, __VA_ARGS__)
243#define GUANAQO_TRACE_INSTANT(name, instance) \
245 ::guanaqo::get_trace_logger().trace_instant(name, instance); \
247#define GUANAQO_TRACE_LINALG(name, gflops) GUANAQO_TRACE(name, 0, gflops)
248#define GUANAQO_TRACE_REGION(name, instance) GUANAQO_TRACE(name, instance)
249#define GUANAQO_TRACE_STATIC_STR(s) s
251#define GUANAQO_TRACE(name, ...) GUANAQO_NOOP()
252#define GUANAQO_TRACE_INSTANT(name, instance) GUANAQO_NOOP()
253#define GUANAQO_TRACE_LINALG(name, gflops) GUANAQO_NOOP()
254#define GUANAQO_TRACE_REGION(name, instance) GUANAQO_NOOP()
255#define GUANAQO_TRACE_STATIC_STR(s) s
260#define GUANAQO_IF_ITT(...) __VA_ARGS__
262#define GUANAQO_IF_ITT(...)
TraceLogger & get_trace_logger()
Get a reference to the global (but thread-local) trace logger instance.
size_t trace_logger_set_default_size(size_t size)
Set the default capacity for trace loggers created by get_trace_logger().
void drop_trace_loggers(const std::function< void(std::shared_ptr< TraceLogger >)> &callback=nullptr)
Like for_each_trace_logger, but also forgets about all loggers.
void for_each_trace_logger(const std::function< void(TraceLogger &)> &callback)
Call callback for each trace logger instance.
std::size_t get_thread_id()
Perfetto tracing macros and session helpers.
Token concatenation and argument-counting helpers.
Stringify and token concatenation helpers.
std::chrono::nanoseconds start_time
std::chrono::nanoseconds duration
friend std::ostream & operator<<(std::ostream &os, const Log &log)
ScopedLog(Log *log, clock::time_point start_time_point)
ScopedLog(const ScopedLog &)=delete
ScopedLog & operator=(ScopedLog &&)=delete
ScopedLog(ScopedLog &&other) noexcept
clock::time_point start_time_point
ScopedLog & operator=(const ScopedLog &)=delete
Class for recording trace logs, used when ITT or Perfetto tracing is not enabled.
void trace_instant(const char *name, int64_t instance, int64_t flop_count=-1)
static clock::time_point t0
TraceLogger(size_t capacity)
std::chrono::steady_clock clock
ScopedLog trace(const char *name, int64_t instance, int64_t flop_count=-1)
void clear()
Clear all recorded logs and set capacity to 0 (essentially disabling the logger).
static std::ostream & write_column_headings(std::ostream &os)
void reserve(size_t capacity)
Set the maximum number of logs that can be recorded. Additional logs are discarded.
void reset()
Clear all recorded logs, but keep the reserved capacity.
std::span< const Log > get_logs() const