7#include <guanaqo/export.h>
34 friend std::ostream &
operator<<(std::ostream &os, Log) {
return os; }
37 __itt_domain *domain = __itt_domain_create(
"guanaqo");
38 static constexpr int64_t max_instance_num = 255;
40 for (int64_t i = 0; i <= max_instance_num; ++i)
43 __itt_id_make(
nullptr,
static_cast<unsigned long long>(i)));
49 : domain{std::exchange(other.domain,
nullptr)} {}
54 for (int64_t i = 0; i <= max_instance_num; ++i)
57 __itt_id_make(
nullptr,
static_cast<unsigned long long>(i)));
62 ScopedLog(__itt_domain *domain, __itt_string_handle *name,
67 instance = std::clamp<int64_t>(instance, 0, max_instance_num);
68 auto id = __itt_id_make(
nullptr,
69 static_cast<unsigned long long>(instance));
70 __itt_task_begin(domain,
id, __itt_null, name);
75 : domain{std::exchange(other.domain,
nullptr)} {}
80 __itt_task_end(domain);
85 int64_t instance)
const {
89 void trace_instant(__itt_string_handle *name, int64_t instance)
const {
92 instance = std::clamp<int64_t>(instance, 0, max_instance_num);
94 __itt_id_make(
nullptr,
static_cast<unsigned long long>(instance));
95 __itt_marker(domain,
id, name, __itt_scope_task);
98 [[nodiscard]] std::span<const Log>
get_logs()
const {
return {}; }
105#if !GUANAQO_WITH_PERFETTO
106#define GUANAQO_TRACE_IMPL(var_name, name, instance) \
107 static auto GUANAQO_CAT(var_name, _name) = \
108 __itt_string_handle_create(name); \
109 const auto var_name = ::guanaqo::get_trace_logger().trace( \
110 GUANAQO_CAT(var_name, _name), instance)
111#define GUANAQO_TRACE_INSTANT_IMPL(var_name, name, instance) \
113 static auto GUANAQO_CAT(var_name, _name) = \
114 __itt_string_handle_create(name); \
115 ::guanaqo::get_trace_logger().trace_instant( \
116 GUANAQO_CAT(var_name, _name), instance); \
118#define GUANAQO_TRACE(name, instance, ...) \
119 GUANAQO_TRACE_IMPL(GUANAQO_CAT(trace_log_, __COUNTER__), name, instance)
120#define GUANAQO_TRACE_INSTANT(name, instance) \
121 GUANAQO_TRACE_INSTANT_IMPL(GUANAQO_CAT(trace_instant_, __COUNTER__), name, \
123#define GUANAQO_TRACE_LINALG(name, gflops) \
124 GUANAQO_TRACE(name, 0)
125#define GUANAQO_TRACE_REGION(name, instance) GUANAQO_TRACE(name, instance)
126#define GUANAQO_TRACE_STATIC_STR(s) s
143 return os << std::quoted(log.name) <<
',' << log.instance <<
','
144 << log.start_time.count() <<
',' << log.duration.count()
145 <<
',' << log.thread_id <<
',' << log.flop_count;
150 return os <<
"name" <<
',' <<
"instance" <<
',' <<
"start_time" <<
','
151 <<
"duration" <<
',' <<
"thread_id" <<
',' <<
"flop_count";
154 using clock = std::chrono::steady_clock;
156 clock::time_point
t0 = clock::now();
170 :
log{std::exchange(other.log,
nullptr)},
182 int64_t flop_count = -1) {
183 size_t index =
count.fetch_add(1, std::memory_order_relaxed);
184 if (index >=
logs.size())
186 static constexpr std::hash<std::thread::id> hasher;
187 auto &log =
logs[index];
188 auto t1 = clock::now();
190 log.instance = instance;
191 log.flop_count = flop_count;
192 log.start_time = t1 -
t0;
193 log.thread_id = hasher(std::this_thread::get_id());
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 auto n = std::min(
logs.size(),
count.load(std::memory_order_relaxed));
205 return std::span{
logs}.first(n);
211#if GUANAQO_WITH_TRACING
221#if !GUANAQO_WITH_PERFETTO && !GUANAQO_WITH_ITT
222#if GUANAQO_WITH_TRACING
223#define GUANAQO_TRACE(name, ...) \
224 const auto GUANAQO_CAT(trace_log_, __COUNTER__) = \
225 ::guanaqo::get_trace_logger().trace(name, __VA_ARGS__)
226#define GUANAQO_TRACE_INSTANT(name, instance) \
228 ::guanaqo::get_trace_logger().trace_instant(name, instance); \
230#define GUANAQO_TRACE_LINALG(name, gflops) GUANAQO_TRACE(name, 0, gflops)
231#define GUANAQO_TRACE_REGION(name, instance) GUANAQO_TRACE(name, instance)
232#define GUANAQO_TRACE_STATIC_STR(s) s
234#define GUANAQO_TRACE(name, ...) GUANAQO_NOOP()
235#define GUANAQO_TRACE_INSTANT(name, instance) GUANAQO_NOOP()
236#define GUANAQO_TRACE_LINALG(name, gflops) GUANAQO_NOOP()
237#define GUANAQO_TRACE_REGION(name, instance) GUANAQO_NOOP()
238#define GUANAQO_TRACE_STATIC_STR(s) s
243#define GUANAQO_IF_ITT(...) __VA_ARGS__
245#define GUANAQO_IF_ITT(...)
TraceLogger & get_trace_logger()
Get a reference to the global trace logger instance.
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)
TraceLogger(size_t capacity)
std::chrono::steady_clock clock
ScopedLog trace(const char *name, int64_t instance, int64_t flop_count=-1)
static std::ostream & write_column_headings(std::ostream &os)
std::span< const Log > get_logs() const