timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
macros.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to
9// deal in the Software without restriction, including without limitation the
10// rights to use, copy, modify, merge, publish, distribute, sublicense, and
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23// IN THE SOFTWARE.
24//
25
26#pragma once
27
29
30#include <cstdint>
31#include <cstdio>
32#include <iosfwd>
33#include <string>
34#include <utility>
35
36#if defined(TIMEMORY_CORE_SOURCE)
37# define TIMEMORY_UTILITY_SOURCE
38# define TIMEMORY_UTILITY_INLINE
39#elif defined(TIMEMORY_USE_CORE_EXTERN)
40# define TIMEMORY_USE_UTILITY_EXTERN
41# define TIMEMORY_UTILITY_INLINE
42#else
43# define TIMEMORY_UTILITY_INLINE inline
44# define TIMEMORY_UTILITY_HEADER_ONLY 1
45#endif
46//
47#if defined(TIMEMORY_USE_EXTERN) && !defined(TIMEMORY_USE_UTILITY_EXTERN)
48# define TIMEMORY_USE_UTILITY_EXTERN
49#endif
50
51//======================================================================================//
52//
53// Quick way to create a globally accessible setting
54//
55//======================================================================================//
56
57#if !defined(CREATE_STATIC_VARIABLE_ACCESSOR)
58# define CREATE_STATIC_VARIABLE_ACCESSOR(TYPE, FUNC_NAME, VARIABLE) \
59 static TYPE& FUNC_NAME() \
60 { \
61 static TYPE _instance = Type::VARIABLE; \
62 return _instance; \
63 }
64#endif
65
66//--------------------------------------------------------------------------------------//
67
68#if !defined(CREATE_STATIC_FUNCTION_ACCESSOR)
69# define CREATE_STATIC_FUNCTION_ACCESSOR(TYPE, FUNC_NAME, VARIABLE) \
70 static TYPE& FUNC_NAME() \
71 { \
72 static TYPE _instance = Type::VARIABLE(); \
73 return _instance; \
74 }
75#endif
76
77//======================================================================================//
78//
79// DEBUG
80//
81//======================================================================================//
82
83// stringify some macro -- uses TIMEMORY_STRINGIZE2 which does the actual
84// "stringify-ing" after the macro has been substituted by it's result
85#if !defined(TIMEMORY_STRINGIZE)
86# define TIMEMORY_STRINGIZE(X) TIMEMORY_STRINGIZE2(X)
87#endif
88
89// actual stringifying
90#if !defined(TIMEMORY_STRINGIZE2)
91# define TIMEMORY_STRINGIZE2(X) # X
92#endif
93
94#if !defined(TIMEMORY_TRUNCATED_FILE_STRING)
95# define TIMEMORY_TRUNCATED_FILE_STRING(FILE) \
96 []() { \
97 std::string _f{ FILE }; \
98 auto _pos = _f.find("/timemory/"); \
99 if(_pos != std::string::npos) \
100 { \
101 return _f.substr(_pos + 1); \
102 } \
103 return _f; \
104 }()
105#endif
106
107#if !defined(TIMEMORY_FILE_LINE_FUNC_STRING)
108# define TIMEMORY_FILE_LINE_FUNC_STRING \
109 std::string \
110 { \
111 std::string{ "[" } + TIMEMORY_TRUNCATED_FILE_STRING(__FILE__) + ":" + \
112 std::to_string(__LINE__) + "@'" + __FUNCTION__ + "']" \
113 }
114#endif
115
116#if !defined(TIMEMORY_PID_TID_STRING)
117# define TIMEMORY_PID_TID_STRING \
118 std::string \
119 { \
120 std::string{ "[pid=" } + std::to_string(::tim::process::get_id()) + \
121 std::string{ "][tid=" } + std::to_string(::tim::threading::get_id()) + \
122 "]" \
123 }
124#endif
125
126template <typename Arg>
127TIMEMORY_NOINLINE auto
128timemory_proxy_value(Arg&& arg, int) -> decltype(arg.proxy_value())
129{
130 return arg.proxy_value();
131}
132
133template <typename Arg>
134TIMEMORY_NOINLINE auto
135timemory_proxy_value(Arg&& arg, long)
136{
137 return std::forward<Arg>(arg);
138}
139
140template <typename... Args>
141TIMEMORY_NOINLINE void
142timemory_print_here(const char* _pid_tid, const char* _file, int _line, const char* _func,
143 Args&&... args)
144{
145 fprintf(stderr, "%s[%s:%i@'%s']> ", _pid_tid, _file, _line, _func);
146 fprintf(stderr, timemory_proxy_value(std::forward<Args>(args), 0)...);
147 fprintf(stderr, "...\n");
148 fflush(stderr);
149}
150
151#if !defined(PRINT_HERE)
152# define PRINT_HERE(...) \
153 timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
154 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), __LINE__, \
155 __FUNCTION__, __VA_ARGS__)
156#endif
157
158#if !defined(DEBUG_PRINT_HERE)
159# if defined(DEBUG)
160# define DEBUG_PRINT_HERE(...) \
161 if(::tim::settings::debug()) \
162 { \
163 timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
164 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
165 __LINE__, __FUNCTION__, __VA_ARGS__); \
166 }
167# else
168# define DEBUG_PRINT_HERE(...)
169# endif
170#endif
171
172#if !defined(VERBOSE_PRINT_HERE)
173# define VERBOSE_PRINT_HERE(VERBOSE_LEVEL, ...) \
174 if(::tim::settings::verbose() >= VERBOSE_LEVEL) \
175 { \
176 timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
177 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
178 __LINE__, __FUNCTION__, __VA_ARGS__); \
179 }
180#endif
181
182#if !defined(CONDITIONAL_PRINT_HERE)
183# define CONDITIONAL_PRINT_HERE(CONDITION, ...) \
184 if(CONDITION) \
185 { \
186 timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
187 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
188 __LINE__, __FUNCTION__, __VA_ARGS__); \
189 }
190#endif
191
192#if !defined(TIMEMORY_CONDITIONAL_BACKTRACE)
193# define TIMEMORY_CONDITIONAL_BACKTRACE(CONDITION, DEPTH) \
194 if(CONDITION) \
195 { \
196 ::tim::print_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING, \
197 TIMEMORY_FILE_LINE_FUNC_STRING); \
198 }
199#endif
200
201#if !defined(TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE)
202# define TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE(CONDITION, DEPTH) \
203 if(CONDITION) \
204 { \
205 ::tim::print_demangled_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING, \
206 TIMEMORY_FILE_LINE_FUNC_STRING); \
207 }
208#endif
209
210#if !defined(PRETTY_PRINT_HERE)
211# if defined(TIMEMORY_GNU_COMPILER) || defined(TIMEMORY_CLANG_COMPILER)
212# define PRETTY_PRINT_HERE(...) \
213 timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
214 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
215 __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__)
216# else
217# define PRETTY_PRINT_HERE(...) \
218 timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
219 TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
220 __LINE__, __FUNCTION__, __VA_ARGS__)
221# endif
222#endif
223
224#if !defined(TIMEMORY_CONDITIONAL_BACKTRACE)
225# define TIMEMORY_CONDITIONAL_BACKTRACE(CONDITION, DEPTH) \
226 if(CONDITION) \
227 { \
228 ::tim::print_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING); \
229 }
230#endif
231
232#if !defined(TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE)
233# define TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE(CONDITION, DEPTH) \
234 if(CONDITION) \
235 { \
236 ::tim::print_demangled_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING); \
237 }
238#endif
239
240#if defined(DEBUG)
241
242template <typename... Args>
243inline void
244__LOG(std::string file, int line, const char* msg, Args&&... args)
245{
246 auto _pos = file.find("/timemory/");
247 if(_pos == std::string::npos)
248 _pos = file.find_last_of('/');
249 if(_pos != std::string::npos)
250 file = file.substr(_pos);
251 fprintf(stderr, "[Log @ %s:%i]> ", file.c_str(), line);
252 fprintf(stderr, msg, std::forward<Args>(args)...);
253 fprintf(stderr, "\n");
254}
255
256//--------------------------------------------------------------------------------------//
257
258inline void
259__LOG(std::string file, int line, const char* msg)
260{
261 if(file.find('/') != std::string::npos)
262 file = file.substr(file.find_last_of('/'));
263 fprintf(stderr, "[Log @ %s:%i]> %s\n", file.c_str(), line, msg);
264}
265
266//--------------------------------------------------------------------------------------//
267// auto insert the file and line
268# define _LOG(...) __LOG(__FILE__, __LINE__, __VA_ARGS__)
269
270//--------------------------------------------------------------------------------------//
271
272template <typename... Args>
273inline void
274_DBG(const char* msg, Args&&... args)
275{
276 fprintf(stderr, msg, std::forward<Args>(args)...);
277}
278
279//--------------------------------------------------------------------------------------//
280
281inline void
282_DBG(const char* msg)
283{
284 fprintf(stderr, "%s", msg);
285}
286
287#else
288# define _LOG(...) \
289 {}
290# define _DBG(...) \
291 {}
292#endif
293
294//======================================================================================//
295//
296// Define macros for utility
297//
298//======================================================================================//
299//
300#if defined(TIMEMORY_UTILITY_SOURCE)
301# define TIMEMORY_UTILITY_LINKAGE(...) __VA_ARGS__
302# define TIMEMORY_UTILITY_INLINE
303#elif defined(TIMEMORY_USE_EXTERN) || defined(TIMEMORY_USE_UTILITY_EXTERN)
304# define TIMEMORY_UTILITY_LINKAGE(...) __VA_ARGS__
305# define TIMEMORY_UTILITY_INLINE
306#else
307# define TIMEMORY_UTILITY_LINKAGE(...) inline __VA_ARGS__
308# define TIMEMORY_UTILITY_INLINE inline
309# define TIMEMORY_UTILITY_HEADER_MODE
310#endif
const auto & _file
Definition: definition.hpp:72
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
auto timemory_proxy_value(Arg &&arg, int) -> decltype(arg.proxy_value())
Definition: macros.hpp:128
#define _DBG(...)
Definition: macros.hpp:290
void timemory_print_here(const char *_pid_tid, const char *_file, int _line, const char *_func, Args &&... args)
Definition: macros.hpp:142