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 deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
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 all
15// 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 FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25#pragma once
26
28
29#include <cassert>
30
31#if defined(TIMEMORY_CORE_SOURCE)
32# define TIMEMORY_SETTINGS_SOURCE
33#elif defined(TIMEMORY_USE_CORE_EXTERN)
34# define TIMEMORY_USE_SETTINGS_EXTERN
35#endif
36//
37#if defined(TIMEMORY_USE_EXTERN) && !defined(TIMEMORY_USE_SETTINGS_EXTERN)
38# define TIMEMORY_USE_SETTINGS_EXTERN
39#endif
40//
41#if defined(TIMEMORY_SETTINGS_SOURCE)
42# define TIMEMORY_SETTINGS_COMPILE_MODE
43# define TIMEMORY_SETTINGS_INLINE
44# define TIMEMORY_SETTINGS_LINKAGE(...) __VA_ARGS__
45#elif defined(TIMEMORY_USE_SETTINGS_EXTERN)
46# define TIMEMORY_SETTINGS_EXTERN_MODE
47# define TIMEMORY_SETTINGS_INLINE
48# define TIMEMORY_SETTINGS_LINKAGE(...) __VA_ARGS__
49#else
50# define TIMEMORY_SETTINGS_HEADER_MODE
51# define TIMEMORY_SETTINGS_INLINE inline
52# define TIMEMORY_SETTINGS_LINKAGE(...) inline __VA_ARGS__
53#endif
54//
55#if !defined(TIMEMORY_SETTINGS_PREFIX)
56# define TIMEMORY_SETTINGS_PREFIX "TIMEMORY_"
57#endif
58//
59#if !defined(TIMEMORY_SETTINGS_KEY)
60# define TIMEMORY_SETTINGS_KEY(...) TIMEMORY_SETTINGS_PREFIX __VA_ARGS__
61#endif
62//
63//--------------------------------------------------------------------------------------//
64//
65#if !defined(TIMEMORY_SETTINGS_MEMBER_DECL)
66// memory leak w/ _key is intentional due to potential calls during _cxa_finalize
67// which may have already deleted a non-heap allocation
68# define TIMEMORY_SETTINGS_MEMBER_DECL(TYPE, FUNC) \
69 public: \
70 TYPE& get_##FUNC() TIMEMORY_NEVER_INSTRUMENT TIMEMORY_VISIBILITY("default"); \
71 TYPE get_##FUNC() \
72 const TIMEMORY_NEVER_INSTRUMENT TIMEMORY_VISIBILITY("default"); \
73 static TYPE& FUNC() TIMEMORY_NEVER_INSTRUMENT TIMEMORY_VISIBILITY("default");
74#endif
75//
76//--------------------------------------------------------------------------------------//
77//
78#if !defined(TIMEMORY_SETTINGS_REFERENCE_DECL)
79// memory leak w/ _key is intentional due to potential calls during _cxa_finalize
80// which may have already deleted a non-heap allocation
81# define TIMEMORY_SETTINGS_REFERENCE_DECL(TYPE, FUNC) \
82 public: \
83 TYPE& get_##FUNC() TIMEMORY_NEVER_INSTRUMENT TIMEMORY_VISIBILITY("default"); \
84 TYPE get_##FUNC() \
85 const TIMEMORY_NEVER_INSTRUMENT TIMEMORY_VISIBILITY("default"); \
86 static TYPE& FUNC() TIMEMORY_NEVER_INSTRUMENT TIMEMORY_VISIBILITY("default");
87#endif
88//
89//--------------------------------------------------------------------------------------//
90//
91#if !defined(TIMEMORY_SETTINGS_MEMBER_DEF)
92// memory leak w/ _key is intentional due to potential calls during _cxa_finalize
93// which may have already deleted a non-heap allocation
94# define TIMEMORY_SETTINGS_MEMBER_DEF(TYPE, FUNC, ENV_VAR) \
95 TIMEMORY_SETTINGS_INLINE TYPE& settings::get_##FUNC() \
96 { \
97 return static_cast<tsettings<TYPE>*>(m_data.at(ENV_VAR).get())->get(); \
98 } \
99 \
100 TIMEMORY_SETTINGS_INLINE TYPE settings::get_##FUNC() const \
101 { \
102 auto ret = m_data.find(ENV_VAR); \
103 if(ret == m_data.end()) \
104 return TYPE{}; \
105 if(!ret->second) \
106 return TYPE{}; \
107 return static_cast<tsettings<TYPE>*>(ret->second.get())->get(); \
108 } \
109 \
110 TIMEMORY_SETTINGS_INLINE TYPE& settings::FUNC() \
111 { \
112 return shared_instance()->get_##FUNC(); \
113 }
114#endif
115//
116//--------------------------------------------------------------------------------------//
117//
118#if !defined(TIMEMORY_SETTINGS_REFERENCE_DEF)
119// memory leak w/ _key is intentional due to potential calls during _cxa_finalize
120// which may have already deleted a non-heap allocation
121# define TIMEMORY_SETTINGS_REFERENCE_DEF(TYPE, FUNC, ENV_VAR) \
122 TIMEMORY_SETTINGS_INLINE TYPE& settings::get_##FUNC() \
123 { \
124 return static_cast<tsettings<TYPE, TYPE&>*>(m_data.at(ENV_VAR).get()) \
125 ->get(); \
126 } \
127 \
128 TIMEMORY_SETTINGS_INLINE TYPE settings::get_##FUNC() const \
129 { \
130 auto ret = m_data.find(ENV_VAR); \
131 if(ret == m_data.end()) \
132 return TYPE{}; \
133 if(!ret->second) \
134 return TYPE{}; \
135 return static_cast<tsettings<TYPE, TYPE&>*>(ret->second.get())->get(); \
136 } \
137 \
138 TIMEMORY_SETTINGS_INLINE TYPE& settings::FUNC() \
139 { \
140 return shared_instance()->get_##FUNC(); \
141 }
142#endif
143//
144//--------------------------------------------------------------------------------------//
145//
146#if !defined(TIMEMORY_SETTINGS_MEMBER_IMPL)
147# define TIMEMORY_SETTINGS_MEMBER_IMPL(TYPE, FUNC, ENV_VAR, DESC, INIT) \
148 \
149 if(m_data \
150 .insert({ ENV_VAR, std::make_shared<tsettings<TYPE>>( \
151 INIT, std::string{ #FUNC }, \
152 std::string{ ENV_VAR }, std::string{ DESC }) }) \
153 .second) \
154 m_order.push_back(ENV_VAR);
155#endif
156//
157//--------------------------------------------------------------------------------------//
158//
159#if !defined(TIMEMORY_SETTINGS_HIDDEN_MEMBER_IMPL)
160# define TIMEMORY_SETTINGS_HIDDEN_MEMBER_IMPL(TYPE, ENV_VAR, DESC, INIT) \
161 \
162 if(m_data \
163 .insert({ ENV_VAR, std::make_shared<tsettings<TYPE>>( \
164 INIT, std::string{}, std::string{ ENV_VAR }, \
165 std::string{ DESC }) }) \
166 .second) \
167 m_order.push_back(ENV_VAR);
168#endif
169//
170//--------------------------------------------------------------------------------------//
171//
172#if !defined(TIMEMORY_SETTINGS_MEMBER_ARG_IMPL)
173# define TIMEMORY_SETTINGS_MEMBER_ARG_IMPL(TYPE, FUNC, ENV_VAR, DESC, INIT, ...) \
174 \
175 if(m_data \
176 .insert( \
177 { ENV_VAR, std::make_shared<tsettings<TYPE>>( \
178 INIT, std::string{ #FUNC }, std::string{ ENV_VAR }, \
179 std::string{ DESC }, __VA_ARGS__) }) \
180 .second) \
181 m_order.push_back(ENV_VAR);
182#endif
183//
184//--------------------------------------------------------------------------------------//
185//
186#if !defined(TIMEMORY_SETTINGS_HIDDEN_MEMBER_ARG_IMPL)
187# define TIMEMORY_SETTINGS_HIDDEN_MEMBER_ARG_IMPL(TYPE, ENV_VAR, DESC, INIT, ...) \
188 \
189 if(m_data \
190 .insert({ ENV_VAR, std::make_shared<tsettings<TYPE>>( \
191 INIT, std::string{}, std::string{ ENV_VAR }, \
192 std::string{ DESC }, __VA_ARGS__) }) \
193 .second) \
194 m_order.push_back(ENV_VAR);
195#endif
196//
197//--------------------------------------------------------------------------------------//
198//
199#if !defined(TIMEMORY_SETTINGS_REFERENCE_IMPL)
200# define TIMEMORY_SETTINGS_REFERENCE_IMPL(TYPE, FUNC, ENV_VAR, DESC, INIT) \
201 \
202 if(m_data \
203 .insert({ ENV_VAR, std::make_shared<tsettings<TYPE, TYPE&>>( \
204 INIT, std::string{ #FUNC }, \
205 std::string{ ENV_VAR }, std::string{ DESC }) }) \
206 .second) \
207 m_order.push_back(ENV_VAR);
208#endif
209//
210//--------------------------------------------------------------------------------------//
211//
212#if !defined(TIMEMORY_SETTINGS_REFERENCE_ARG_IMPL)
213# define TIMEMORY_SETTINGS_REFERENCE_ARG_IMPL(TYPE, FUNC, ENV_VAR, DESC, INIT, ...) \
214 if(m_data \
215 .insert( \
216 { ENV_VAR, std::make_shared<tsettings<TYPE, TYPE&>>( \
217 INIT, std::string{ #FUNC }, std::string{ ENV_VAR }, \
218 std::string{ DESC }, __VA_ARGS__) }) \
219 .second) \
220 m_order.push_back(ENV_VAR);
221#endif
222//
223//--------------------------------------------------------------------------------------//
224//
225#if !defined(TIMEMORY_ERROR_FUNCTION_MACRO)
226# if defined(__PRETTY_FUNCTION__)
227# define TIMEMORY_ERROR_FUNCTION_MACRO __PRETTY_FUNCTION__
228# else
229# define TIMEMORY_ERROR_FUNCTION_MACRO __FUNCTION__
230# endif
231#endif
232//
233//--------------------------------------------------------------------------------------//
234//
235#if !defined(TIMEMORY_SETTINGS_TRY_CATCH_NVP)
236# define TIMEMORY_SETTINGS_TRY_CATCH_NVP(ENV_VAR, FUNC) \
237 try \
238 { \
239 ar(cereal::make_nvp(ENV_VAR, FUNC())); \
240 } catch(...) \
241 {}
242#endif
243//
244//--------------------------------------------------------------------------------------//
245//
246#if !defined(TIMEMORY_SETTINGS_EXTERN_TEMPLATE)
247//
248# if defined(TIMEMORY_SETTINGS_SOURCE)
249//
250# define TIMEMORY_SETTINGS_EXTERN_TEMPLATE(API) \
251 namespace tim \
252 { \
253 template std::shared_ptr<settings> settings::shared_instance<API>(); \
254 template settings* settings::instance<API>(); \
255 template void settings::serialize_settings(cereal::JSONInputArchive&); \
256 template void settings::serialize_settings( \
257 cereal::PrettyJSONOutputArchive&); \
258 template void settings::serialize_settings( \
259 cereal::MinimalJSONOutputArchive&); \
260 template void settings::serialize_settings(cereal::JSONInputArchive&, \
261 settings&); \
262 template void settings::serialize_settings(cereal::PrettyJSONOutputArchive&, \
263 settings&); \
264 template void settings::serialize_settings( \
265 cereal::MinimalJSONOutputArchive&, settings&); \
266 template void settings::save(cereal::PrettyJSONOutputArchive&, \
267 const unsigned int) const; \
268 template void settings::save(cereal::MinimalJSONOutputArchive&, \
269 const unsigned int) const; \
270 template void settings::load(cereal::JSONInputArchive&, const unsigned int); \
271 }
272//
273# elif defined(TIMEMORY_USE_SETTINGS_EXTERN)
274//
275# define TIMEMORY_SETTINGS_EXTERN_TEMPLATE(API) \
276 namespace tim \
277 { \
278 extern template std::shared_ptr<settings> settings::shared_instance<API>(); \
279 extern template settings* settings::instance<API>(); \
280 extern template void settings::serialize_settings( \
281 cereal::JSONInputArchive&); \
282 extern template void settings::serialize_settings( \
283 cereal::PrettyJSONOutputArchive&); \
284 extern template void settings::serialize_settings( \
285 cereal::MinimalJSONOutputArchive&); \
286 extern template void settings::serialize_settings(cereal::JSONInputArchive&, \
287 settings&); \
288 extern template void settings::serialize_settings( \
289 cereal::PrettyJSONOutputArchive&, settings&); \
290 extern template void settings::serialize_settings( \
291 cereal::MinimalJSONOutputArchive&, settings&); \
292 extern template void settings::save(cereal::PrettyJSONOutputArchive&, \
293 const unsigned int) const; \
294 extern template void settings::save(cereal::MinimalJSONOutputArchive&, \
295 const unsigned int) const; \
296 extern template void settings::load(cereal::JSONInputArchive&, \
297 const unsigned int); \
298 }
299//
300# else
301//
302# define TIMEMORY_SETTINGS_EXTERN_TEMPLATE(...)
303//
304# endif
305#endif
306//
307//======================================================================================//
308//