ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
logging_streams.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Empty log output, to be removed by the compiler
12#define DETRAY_EMPTY_LOG() \
13 do { \
14 } while (0)
15
16#if DETRAY_LOG_LVL >= 0
17
18// Project include(s)
19#include "detray/definitions/detail/qualifiers.hpp"
20#include "detray/utils/type_list.hpp"
21
22// System include(s)
23#include <cstring>
24#include <iomanip>
25#include <iostream>
26#include <regex>
27#include <source_location>
28#include <string>
29
30namespace detray::log::detail {
31
35constexpr const char *source_file_name(const char *path) {
36 const char *file = path;
37 while (*path != 0) {
38 if (*path++ == '/') {
39 file = path;
40 }
41 }
42 return file;
43}
44
46template <typename T>
47inline std::string_view process_typename() {
48 static const std::string type_name = [] {
49 std::string s{""};
50 try {
51 s = detray::types::demangle_type_name<T>();
52 } catch (...) {
53 return std::string{"unknown"};
54 }
55
56 if (s.empty()) {
57 return std::string{"unknown"};
58 }
59
60 std::regex re{"detray::"};
61 s = std::regex_replace(s, re, "");
62
63 // Special case type-list for readability
64 // Only attempt if the full type is a list
65 std::regex re_list{R"(^types::list<(.*)>$)"};
66
67 if (std::smatch match; std::regex_match(s, match, re_list)) {
68 s = "[" + std::string{match[1]} + "]";
69 }
70
71 return s;
72 }();
73
74 return type_name;
75}
76
77} // namespace detray::log::detail
78
79// Enable device-side logging
80#if defined(__CUDACC__) || defined(__HIP__) || \
81 defined(CL_SYCL_LANGUAGE_VERSION) || defined(SYCL_LANGUAGE_VERSION)
82#define __DEVICE_LOGGING__
83#endif
84
85// String that represents the backend that emitted the log message
86#if defined(__CUDACC__)
87#define __BACKEND__ "CUDA"
88#elif defined(__HIP__)
89#define __BACKEND__ "HIP"
90#elif defined(CL_SYCL_LANGUAGE_VERSION) || defined(SYCL_LANGUAGE_VERSION)
91#define __BACKEND__ "SYCL"
92#else
93#define __BACKEND__ "HOST"
94#endif
95
96// Convert type to string
97#ifdef __DEVICE_LOGGING__
98#define DETRAY_TYPENAME(type) "unknown type"
99#else // ifdef __DEVICE_LOGGING__
100#define DETRAY_TYPENAME(type) detray::log::detail::process_typename<type>()
101#endif // ifdef __DEVICE_LOGGING__
102
103// Get the file name
104#ifdef __DEVICE_LOGGING__
105#define __FILENAME__ detray::log::detail::source_file_name(__FILE__)
106#else // ifdef __DEVICE_LOGGING__
107#define __FILENAME__ \
108 (std::strrchr(__FILE__, '/') ? std::strrchr(__FILE__, '/') + 1 : __FILE__)
109#endif // ifdef __DEVICE_LOGGING__
110
111// Convert a vector to string
112#ifdef __DEVICE_LOGGING__
113#define DETRAY_LOG_VECTOR(x) ""
114#else // ifdef __DEVICE_LOGGING__
115#define DETRAY_LOG_VECTOR(x) \
116 [&]() { \
117 std::stringstream _vec_os; \
118 std::size_t _vec_i = 0; \
119 for (const auto &_vec_elem : x) { \
120 if (_vec_i > 0) { \
121 _vec_os << ", "; \
122 } \
123 _vec_os << _vec_elem; \
124 _vec_i++; \
125 } \
126 return _vec_os.str(); \
127 }()
128#endif // ifdef __DEVICE_LOGGING__
129
130// Print 'x' in the host logs only
131#ifndef __DEVICE_LOGGING__
132
133#define DETRAY_LOG_STREAM(stream, lib, lvl, x) \
134 std::stream << lib << " " << std::left << std::setw(7) << lvl << std::left \
135 << std::setw(9) << " (HOST):" << std::left << std::setw(29) \
136 << __FILENAME__ << "l." << std::left << std::setw(5) \
137 << std::source_location::current().line() << x << std::endl
138
139// Log output to stdout
140#define DETRAY_LOG_STREAM_STDOUT(lib, lvl, x) \
141 DETRAY_LOG_STREAM(cout, lib, lvl, x)
142
143// Log output to stderr
144#define DETRAY_LOG_STREAM_STDERR(lib, lvl, x) \
145 DETRAY_LOG_STREAM(clog, lib, lvl, x)
146
147#else // ifndef __DEVICE_LOGGING__
148#define DETRAY_LOG_STREAM_STDOUT(lib, lvl, x) DETRAY_EMPTY_LOG()
149#define DETRAY_LOG_STREAM_STDERR(lib, lvl, x) DETRAY_EMPTY_LOG()
150#endif // ifndef __DEVICE_LOGGING__
151
152// Print 'x' in printf
153// @note 'x' is the format string and the variadic arguments the corresponding
154// values
155// @note logging is currently disabled for SYCL builds
156#if !defined(CL_SYCL_LANGUAGE_VERSION) && !defined(SYCL_LANGUAGE_VERSION)
157// TODO: Move to device specific header for e.g. rate limiting by thread idx
158#ifdef __DEVICE_LOGGING__
159
160#define DETRAY_LOG_PRINTF(lib, lvl, x, ...) \
161 printf("%s %-7s (%s): %-29sl.%-5d" x "\n", lib, lvl, __BACKEND__, \
162 __FILENAME__, __LINE__ __VA_OPT__(, ) __VA_ARGS__)
163
164#define DETRAY_LOG_PRINTF_STDOUT(lib, lvl, x, ...) \
165 DETRAY_LOG_PRINTF(lib, lvl, x, __VA_ARGS__)
166
167#define DETRAY_LOG_PRINTF_STDERR(lib, lvl, x, ...) \
168 DETRAY_LOG_PRINTF(lib, lvl, x, __VA_ARGS__)
169
170#else // ifdef __DEVICE_LOGGING__
171
172#define DETRAY_LOG_PRINTF(stream, lib, lvl, x, ...) \
173 fprintf(stream, "%s %-7s (%s): %-29sl.%-5d" x "\n", lib, lvl, __BACKEND__, \
174 __FILENAME__, __LINE__ __VA_OPT__(, ) __VA_ARGS__)
175
176#define DETRAY_LOG_PRINTF_STDOUT(lib, lvl, x, ...) \
177 DETRAY_LOG_PRINTF(stdout, lib, lvl, x, __VA_ARGS__)
178
179#define DETRAY_LOG_PRINTF_STDERR(lib, lvl, x, ...) \
180 DETRAY_LOG_PRINTF(stderr, lib, lvl, x, __VA_ARGS__)
181
182#endif // ifdef __DEVICE_LOGGING__
183
184#else // ifndef SYCL
185#define DETRAY_LOG_PRINTF_STDOUT(lib, lvl, x, ...) DETRAY_EMPTY_LOG()
186#define DETRAY_LOG_PRINTF_STDERR(lib, lvl, x, ...) DETRAY_EMPTY_LOG()
187#endif // ifndef SYCL
188
189#else // DETRAY_LOG_LVL < 0
190#define DETRAY_LOG_STREAM_STDOUT(lib, lvl, x) DETRAY_EMPTY_LOG()
191#define DETRAY_LOG_STREAM_STDERR(lib, lvl, x) DETRAY_EMPTY_LOG()
192#define DETRAY_LOG_PRINTF_STDOUT(lib, lvl, x, ...) DETRAY_EMPTY_LOG()
193#define DETRAY_LOG_PRINTF_STDERR(lib, lvl, x, ...) DETRAY_EMPTY_LOG()
194#define DETRAY_TYPENAME(type) DETRAY_EMPTY_LOG()
195#endif // if DETRAY_LOG_LVL >= 0
196
197//
198// Define log levels
199//
200
201// Errors and warnings
202#define DETRAY_FATAL_STREAM(lib, x) DETRAY_LOG_STREAM_STDERR(lib, "FATAL", x)
203#define DETRAY_ERROR_STREAM(lib, x) DETRAY_LOG_STREAM_STDERR(lib, "ERROR", x)
204#define DETRAY_WARN_STREAM(lib, x) DETRAY_LOG_STREAM_STDERR(lib, "WARNING", x)
205
206#define DETRAY_FATAL_PRINTF(lib, x, ...) \
207 DETRAY_LOG_PRINTF_STDERR(lib, "FATAL", x, __VA_ARGS__)
208#define DETRAY_ERROR_PRINTF(lib, x, ...) \
209 DETRAY_LOG_PRINTF_STDERR(lib, "ERROR", x, __VA_ARGS__)
210#define DETRAY_WARN_PRINTF(lib, x, ...) \
211 DETRAY_LOG_PRINTF_STDERR(lib, "WARNING", x, __VA_ARGS__)
212
213// Info
214#if DETRAY_LOG_LVL > 0
215#define DETRAY_INFO_STREAM(lib, x) DETRAY_LOG_STREAM_STDOUT(lib, "INFO", x)
216#define DETRAY_INFO_PRINTF(lib, x, ...) \
217 DETRAY_LOG_PRINTF_STDOUT(lib, "INFO", x, __VA_ARGS__)
218#else // DETRAY_LOG_LVL > 0
219#define DETRAY_INFO_STREAM(lib, x) DETRAY_EMPTY_LOG()
220#define DETRAY_INFO_PRINTF(lib, x, ...) DETRAY_EMPTY_LOG()
221#endif // DETRAY_LOG_LVL > 0
222
223// Verbose
224#if DETRAY_LOG_LVL > 1
225#define DETRAY_VERBOSE_STREAM(lib, x) \
226 DETRAY_LOG_STREAM_STDERR(lib, "VERBOSE", x)
227#define DETRAY_VERBOSE_PRINTF(lib, x, ...) \
228 DETRAY_LOG_PRINTF_STDERR(lib, "VERBOSE", x, __VA_ARGS__)
229#else // DETRAY_LOG_LVL > 1
230#define DETRAY_VERBOSE_STREAM(lib, x) DETRAY_EMPTY_LOG()
231#define DETRAY_VERBOSE_PRINTF(lib, x, ...) DETRAY_EMPTY_LOG()
232#endif // DETRAY_LOG_LVL > 1
233
234// Debug
235#if DETRAY_LOG_LVL > 2
236#define DETRAY_DEBUG_STREAM(lib, x) DETRAY_LOG_STREAM_STDERR(lib, "DEBUG", x)
237#define DETRAY_DEBUG_PRINTF(lib, x, ...) \
238 DETRAY_LOG_PRINTF_STDERR(lib, "DEBUG", x, __VA_ARGS__)
239#else // DETRAY_LOG_LVL > 2
240#define DETRAY_DEBUG_STREAM(lib, x) DETRAY_EMPTY_LOG()
241#define DETRAY_DEBUG_PRINTF(lib, x, ...) DETRAY_EMPTY_LOG()
242#endif // DETRAY_LOG_LVL > 2
constexpr double s
Definition Units.hpp:120