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
33
34//======================================================================================//
35//
36// PROTECTS COMMAS FROM BEING DELIMITED
37//
38// TIMEMORY_STATISTICS_TYPE(foo, std::array<size_t, 10>)
39//
40// should be
41//
42// TIMEMORY_STATISTICS_TYPE(foo, TIMEMORY_ESC(std::array<size_t, 10>))
43//
44//======================================================================================//
45
46#if !defined(TIMEMORY_ESC)
47# define TIMEMORY_ESC(...) __VA_ARGS__
48#endif
49
50// stringify some macro -- uses TIMEMORY_STRINGIZE2 which does the actual
51// "stringify-ing" after the macro has been substituted by it's result
52#if !defined(TIMEMORY_STRINGIZE)
53# define TIMEMORY_STRINGIZE(X) TIMEMORY_STRINGIZE2(X)
54#endif
55
56// actual stringifying
57#if !defined(TIMEMORY_STRINGIZE2)
58# define TIMEMORY_STRINGIZE2(X) # X
59#endif
60
61//======================================================================================//
62//
63/// Simple way to define a static variable which avoids the static initialization fiasco
64#if !defined(TIMEMORY_STATIC_ACCESSOR)
65# define TIMEMORY_STATIC_ACCESSOR(RETURN_TYPE, FUNC_NAME, ...) \
66 static RETURN_TYPE& FUNC_NAME() \
67 { \
68 static RETURN_TYPE _v = __VA_ARGS__; \
69 return _v; \
70 }
71#endif
72
73/// Simple way to define a static thread-local variable which avoids the static
74/// initialization fiasco
75#if !defined(TIMEMORY_STATIC_THREAD_LOCAL_ACCESSOR)
76# define TIMEMORY_STATIC_THREAD_LOCAL_ACCESSOR(RETURN_TYPE, FUNC_NAME, ...) \
77 static RETURN_TYPE& FUNC_NAME() \
78 { \
79 static thread_local RETURN_TYPE _v = __VA_ARGS__; \
80 return _v; \
81 }
82#endif
83
84//======================================================================================//
85//
86// COMPONENTS
87//
88//======================================================================================//
89
90#if !defined(TIMEMORY_FORWARD_DECLARE_COMPONENT)
91/// use this macro for forward declarations. Using \ref TIMEMORY_DECLARE_COMPONENT
92/// on a pre-existing type will fail because of is_component specialization
93# define TIMEMORY_FORWARD_DECLARE_COMPONENT(NAME) \
94 namespace tim \
95 { \
96 namespace component \
97 { \
98 struct NAME; \
99 } \
100 }
101#endif
102
103//======================================================================================//
104//
105// GENERIC TYPE-TRAIT SPECIALIZATION (for true_type/false_type traits)
106//
107//======================================================================================//
108
109#if !defined(TIMEMORY_DEFINE_CONCRETE_TRAIT)
110# define TIMEMORY_DEFINE_CONCRETE_TRAIT(TRAIT, COMPONENT, VALUE) \
111 namespace tim \
112 { \
113 namespace trait \
114 { \
115 template <> \
116 struct TRAIT<COMPONENT> : VALUE \
117 {}; \
118 } \
119 }
120#endif
121
122//--------------------------------------------------------------------------------------//
123
124#if !defined(TIMEMORY_DEFINE_TEMPLATE_TRAIT)
125# define TIMEMORY_DEFINE_TEMPLATE_TRAIT(TRAIT, COMPONENT, VALUE, TYPE) \
126 namespace tim \
127 { \
128 namespace trait \
129 { \
130 template <TYPE T> \
131 struct TRAIT<COMPONENT<T>> : VALUE \
132 {}; \
133 } \
134 }
135#endif
136
137//--------------------------------------------------------------------------------------//
138
139#if !defined(TIMEMORY_DEFINE_VARIADIC_TRAIT)
140# define TIMEMORY_DEFINE_VARIADIC_TRAIT(TRAIT, COMPONENT, VALUE, TYPE) \
141 namespace tim \
142 { \
143 namespace trait \
144 { \
145 template <TYPE... T> \
146 struct TRAIT<COMPONENT<T...>> : VALUE \
147 {}; \
148 } \
149 }
150#endif
151
152//======================================================================================//
153//
154// GENERIC TYPE-TRAIT SPECIALIZATION (for defining ::type traits)
155//
156//======================================================================================//
157
158#if !defined(TIMEMORY_TRAIT_TYPE)
159# define TIMEMORY_TRAIT_TYPE(TRAIT, COMPONENT, ...) \
160 namespace tim \
161 { \
162 namespace trait \
163 { \
164 template <> \
165 struct TRAIT<COMPONENT> \
166 { \
167 using type = __VA_ARGS__; \
168 }; \
169 } \
170 }
171#endif
172//
173//--------------------------------------------------------------------------------------//
174//
175#if !defined(TIMEMORY_TEMPLATE_TRAIT_TYPE)
176# define TIMEMORY_TEMPLATE_TRAIT_TYPE(TRAIT, COMPONENT, TEMPLATE_PARAM, TEMPLATE_ARG, \
177 ...) \
178 namespace tim \
179 { \
180 namespace trait \
181 { \
182 template <TEMPLATE_PARAM> \
183 struct TRAIT<COMPONENT<TEMPLATE_ARG>> \
184 { \
185 using type = __VA_ARGS__; \
186 }; \
187 } \
188 }
189#endif
190//
191//--------------------------------------------------------------------------------------//
192//
193#if !defined(TIMEMORY_VARIADIC_TRAIT_TYPE)
194# define TIMEMORY_VARIADIC_TRAIT_TYPE(TRAIT, COMPONENT, TEMPLATE_PARAM, TEMPLATE_ARG, \
195 ...) \
196 TIMEMORY_TEMPLATE_TRAIT_TYPE(TRAIT, COMPONENT, TIMEMORY_ESC(TEMPLATE_PARAM), \
197 TIMEMORY_ESC(TEMPLATE_ARG), __VA_ARGS__)
198#endif
199
200//======================================================================================//
201//
202// STATISTICS TYPE-TRAIT SPECIALIZATION
203//
204//======================================================================================//
205
206#if !defined(TIMEMORY_STATISTICS_TYPE)
207# define TIMEMORY_STATISTICS_TYPE(COMPONENT, TYPE) \
208 TIMEMORY_TRAIT_TYPE(statistics, TIMEMORY_ESC(COMPONENT), TIMEMORY_ESC(TYPE))
209#endif
210//
211//--------------------------------------------------------------------------------------//
212//
213#if !defined(TIMEMORY_TEMPLATE_STATISTICS_TYPE)
214# define TIMEMORY_TEMPLATE_STATISTICS_TYPE(COMPONENT, TYPE, TEMPLATE_TYPE) \
215 TIMEMORY_TEMPLATE_TRAIT_TYPE(statistics, TIMEMORY_ESC(COMPONENT), \
216 TIMEMORY_ESC(TEMPLATE_TYPE T), TIMEMORY_ESC(T), \
217 TIMEMORY_ESC(TYPE))
218#endif
219//
220//--------------------------------------------------------------------------------------//
221//
222#if !defined(TIMEMORY_VARIADIC_STATISTICS_TYPE)
223# define TIMEMORY_VARIADIC_STATISTICS_TYPE(COMPONENT, TYPE, TEMPLATE_TYPE) \
224 TIMEMORY_VARIADIC_TRAIT_TYPE(statistics, TIMEMORY_ESC(COMPONENT), \
225 TIMEMORY_ESC(TEMPLATE_TYPE... T), \
226 TIMEMORY_ESC(T...), TIMEMORY_ESC(TYPE))
227#endif
228
229//======================================================================================//
230//
231// GOTCHA
232//
233//======================================================================================//
234//
235#if defined(TIMEMORY_USE_GOTCHA)
236//
237//--------------------------------------------------------------------------------------//
238//
239/// \macro TIMEMORY_C_GOTCHA
240/// \brief attempt to generate a GOTCHA wrapper for a C function (unmangled)
241///
242# if !defined(TIMEMORY_C_GOTCHA)
243# define TIMEMORY_C_GOTCHA(type, idx, func) \
244 type::template instrument< \
245 idx, typename ::tim::mpl::function_traits<decltype(func)>::result_type, \
246 typename ::tim::mpl::function_traits<decltype(func)>::call_type>:: \
247 generate(TIMEMORY_STRINGIZE(func))
248# endif
249//
250//--------------------------------------------------------------------------------------//
251//
252/// \macro
253/// \brief TIMEMORY_C_GOTCHA + ability to pass priority and tool name
254///
255# if !defined(TIMEMORY_C_GOTCHA_TOOL)
256# define TIMEMORY_C_GOTCHA_TOOL(type, idx, func, ...) \
257 type::template instrument< \
258 idx, typename ::tim::mpl::function_traits<decltype(func)>::result_type, \
259 typename ::tim::mpl::function_traits<decltype(func)>::call_type>:: \
260 generate(TIMEMORY_STRINGIZE(func), __VA_ARGS__)
261# endif
262//
263//--------------------------------------------------------------------------------------//
264//
265/// \macro TIMEMORY_CXX_GOTCHA
266/// \brief attempt to generate a GOTCHA wrapper for a C++ function by mangling the
267/// function name in general, mangling template function is not supported
268///
269# if !defined(TIMEMORY_CXX_GOTCHA)
270# define TIMEMORY_CXX_GOTCHA(type, idx, func) \
271 type::template instrument< \
272 idx, typename ::tim::mpl::function_traits<decltype(func)>::result_type, \
273 typename ::tim::mpl::function_traits<decltype(func)>::call_type>:: \
274 generate(::tim::mangle<decltype(func)>(TIMEMORY_STRINGIZE(func)))
275# endif
276//
277//--------------------------------------------------------------------------------------//
278//
279/// \macro TIMEMORY_CXX_GOTCHA_TOOL
280/// \brief TIMEMORY_CXX_GOTCHA + ability to pass priority and tool name
281///
282# if !defined(TIMEMORY_CXX_GOTCHA_TOOL)
283# define TIMEMORY_CXX_GOTCHA_TOOL(type, idx, func, ...) \
284 type::template instrument< \
285 idx, typename ::tim::mpl::function_traits<decltype(func)>::result_type, \
286 typename ::tim::mpl::function_traits<decltype(func)>::call_type>:: \
287 generate(::tim::mangle<decltype(func)>(TIMEMORY_STRINGIZE(func)), \
288 __VA_ARGS__)
289# endif
290//
291//--------------------------------------------------------------------------------------//
292//
293/// \macro TIMEMORY_CXX_GOTCHA_MEMFUN
294/// \brief attempt to generate a GOTCHA wrapper for a C++ function by mangling the
295/// function name in general, mangling template function is not supported
296///
297# if !defined(TIMEMORY_CXX_GOTCHA_MEMFUN)
298# define TIMEMORY_CXX_GOTCHA_MEMFUN(type, idx, func) \
299 type::template instrument< \
300 idx, typename ::tim::mpl::function_traits<decltype(&func)>::result_type, \
301 typename ::tim::mpl::function_traits<decltype(&func)>::call_type>:: \
302 generate(::tim::mangle<decltype(&func)>(TIMEMORY_STRINGIZE(func)))
303# endif
304//
305//--------------------------------------------------------------------------------------//
306//
307/// \macro TIMEMORY_DERIVED_GOTCHA
308/// \brief generate a GOTCHA wrapper for function with identical args but different name
309/// -- useful for C++ template function where the mangled name is determined
310/// via `nm --dynamic <EXE>`
311///
312# if !defined(TIMEMORY_DERIVED_GOTCHA)
313# define TIMEMORY_DERIVED_GOTCHA(type, idx, func, ...) \
314 type::template instrument< \
315 idx, typename ::tim::mpl::function_traits<decltype(func)>::result_type, \
316 typename ::tim::mpl::function_traits<decltype(func)>::call_type>:: \
317 generate(__VA_ARGS__)
318# endif
319//
320#else
321//
322# if !defined(TIMEMORY_C_GOTCHA)
323# define TIMEMORY_C_GOTCHA(...)
324# endif
325# if !defined(TIMEMORY_C_GOTCHA_TOOL)
326# define TIMEMORY_C_GOTCHA_TOOL(...)
327# endif
328# if !defined(TIMEMORY_CXX_GOTCHA)
329# define TIMEMORY_CXX_GOTCHA(...)
330# endif
331# if !defined(TIMEMORY_CXX_GOTCHA_TOOL)
332# define TIMEMORY_CXX_GOTCHA_TOOL(...)
333# endif
334# if !defined(TIMEMORY_CXX_GOTCHA_MEMFUN)
335# define TIMEMORY_CXX_GOTCHA_MEMFUN(...)
336# endif
337# if !defined(TIMEMORY_DERIVED_GOTCHA)
338# define TIMEMORY_DERIVED_GOTCHA(...)
339# endif
340//
341#endif
342//
343// backwards compatibility
344//
345#if !defined(TIMEMORY_CXX_MEMFUN_GOTCHA)
346# define TIMEMORY_CXX_MEMFUN_GOTCHA(...) TIMEMORY_CXX_GOTCHA_MEMFUN(__VA_ARGS__)
347#endif
348
349//======================================================================================//
350//
351// CUPTI
352//
353//======================================================================================//
354//
355#if defined(TIMEMORY_USE_CUPTI)
356
357//--------------------------------------------------------------------------------------//
358
359# if !defined(TIMEMORY_CUDA_DRIVER_API_CALL)
360# define TIMEMORY_CUDA_DRIVER_API_CALL(apiFuncCall) \
361 { \
362 CUresult _status = apiFuncCall; \
363 if(_status != CUDA_SUCCESS) \
364 { \
365 fprintf(stderr, \
366 "%s:%d: error: function '%s' failed with error: %d.\n", \
367 __FILE__, __LINE__, #apiFuncCall, _status); \
368 } \
369 }
370# endif
371
372//--------------------------------------------------------------------------------------//
373
374# if !defined(TIMEMORY_CUPTI_CALL)
375# define TIMEMORY_CUPTI_CALL(call) \
376 { \
377 CUptiResult _status = call; \
378 if(_status != CUPTI_SUCCESS) \
379 { \
380 const char* errstr; \
381 cuptiGetResultString(_status, &errstr); \
382 fprintf(stderr, \
383 "%s:%d: error: function '%s' failed with error: %s.\n", \
384 __FILE__, __LINE__, #call, errstr); \
385 } \
386 }
387# endif
388
389//--------------------------------------------------------------------------------------//
390
391#else // !defined(TIMEMORY_USE_CUPTI)
392//
393# if !defined(TIMEMORY_CUDA_DRIVER_API_CALL)
394# define TIMEMORY_CUDA_DRIVER_API_CALL(...)
395# endif
396//
397# if !defined(TIMEMORY_CUPTI_CALL)
398# define TIMEMORY_CUPTI_CALL(...)
399# endif
400//
401#endif // !defined(TIMEMORY_USE_CUPTI)
402
403//--------------------------------------------------------------------------------------//
404//
405#if !defined(TIMEMORY_CUPTI_BUFFER_SIZE)
406# define TIMEMORY_CUPTI_BUFFER_SIZE (32 * 1024)
407#endif
408//
409//--------------------------------------------------------------------------------------//
410//
411#if !defined(TIMEMORY_CUPTI_ALIGN_SIZE)
412# define TIMEMORY_CUPTI_ALIGN_SIZE (8)
413#endif
414//
415//--------------------------------------------------------------------------------------//
416//
417#if !defined(TIMEMORY_CUPTI_ALIGN_BUFFER)
418# define TIMEMORY_CUPTI_ALIGN_BUFFER(buffer, align) \
419 (((uintptr_t)(buffer) & ((align) -1)) \
420 ? ((buffer) + (align) - ((uintptr_t)(buffer) & ((align) -1))) \
421 : (buffer))
422#endif
423//
424//--------------------------------------------------------------------------------------//
425//
426#if !defined(TIMEMORY_CUPTI_PROFILER_NAME_SHORT)
427# define TIMEMORY_CUPTI_PROFILER_NAME_SHORT 128
428#endif
429//
430//--------------------------------------------------------------------------------------//
431//
432#if !defined(TIMEMORY_CUPTI_PROFILER_NAME_LONG)
433# define TIMEMORY_CUPTI_PROFILER_NAME_LONG 512
434#endif
435
436//======================================================================================//
437//
438// CUDA
439//
440//======================================================================================//
441//
442#if defined(TIMEMORY_USE_CUDA)
443//
444//--------------------------------------------------------------------------------------//
445//
446# if !defined(TIMEMORY_CUDA_RUNTIME_API_CALL)
447# define TIMEMORY_CUDA_RUNTIME_API_CALL(apiFuncCall) \
448 { \
449 ::tim::cuda::error_t err = apiFuncCall; \
450 if(err != ::tim::cuda::success_v && (int) err != 0) \
451 { \
452 fprintf(stderr, \
453 "%s:%d: error: function '%s' failed with error: %s.\n", \
454 __FILE__, __LINE__, #apiFuncCall, \
455 ::tim::cuda::get_error_string(err)); \
456 } \
457 }
458# endif
459//
460//--------------------------------------------------------------------------------------//
461//
462# if !defined(TIMEMORY_CUDA_RUNTIME_API_CALL_THROW)
463# define TIMEMORY_CUDA_RUNTIME_API_CALL_THROW(apiFuncCall) \
464 { \
465 ::tim::cuda::error_t err = apiFuncCall; \
466 if(err != ::tim::cuda::success_v && (int) err != 0) \
467 { \
468 char errmsg[std::numeric_limits<uint16_t>::max()]; \
469 sprintf(errmsg, \
470 "%s:%d: error: function '%s' failed with error: %s.\n", \
471 __FILE__, __LINE__, #apiFuncCall, \
472 ::tim::cuda::get_error_string(err)); \
473 throw std::runtime_error(errmsg); \
474 } \
475 }
476# endif
477//
478//--------------------------------------------------------------------------------------//
479//
480# if !defined(TIMEMORY_CUDA_RUNTIME_CHECK_ERROR)
481# define TIMEMORY_CUDA_RUNTIME_CHECK_ERROR(err) \
482 { \
483 if(err != ::tim::cuda::success_v && (int) err != 0) \
484 { \
485 fprintf(stderr, "%s:%d: error check failed with: code %i -- %s.\n", \
486 __FILE__, __LINE__, (int) err, \
487 ::tim::cuda::get_error_string(err)); \
488 } \
489 }
490# endif
491//
492//--------------------------------------------------------------------------------------//
493//
494#else
495//
496//--------------------------------------------------------------------------------------//
497//
498# if !defined(TIMEMORY_CUDA_RUNTIME_API_CALL)
499# define TIMEMORY_CUDA_RUNTIME_API_CALL(...)
500# endif
501//
502//--------------------------------------------------------------------------------------//
503//
504# if !defined(TIMEMORY_CUDA_RUNTIME_API_CALL_THROW)
505# define TIMEMORY_CUDA_RUNTIME_API_CALL_THROW(...)
506# endif
507//
508//--------------------------------------------------------------------------------------//
509//
510# if !defined(TIMEMORY_CUDA_RUNTIME_CHECK_ERROR)
511# define TIMEMORY_CUDA_RUNTIME_CHECK_ERROR(...)
512# endif
513//
514//--------------------------------------------------------------------------------------//
515//
516#endif
517
518#if defined(TIMEMORY_USE_NVML)
519# if !defined(TIMEMORY_NVML_RUNTIME_CHECK_ERROR)
520# define TIMEMORY_NVML_RUNTIME_CHECK_ERROR(apiFuncCall, ...) \
521 { \
522 auto err = apiFuncCall; \
523 if(err != NVML_SUCCESS && (int) err != 0) \
524 { \
525 fprintf(stderr, \
526 "%s:%d: error check failed with: code %i -- %s.\nFunction " \
527 "call: %s\n", \
528 __FILE__, __LINE__, (int) err, nvmlErrorString(err), \
529 #apiFuncCall); \
530 __VA_ARGS__; \
531 } \
532 }
533# endif
534#else
535# if !defined(TIMEMORY_NVML_RUNTIME_CHECK_ERROR)
536# define TIMEMORY_NVML_RUNTIME_CHECK_ERROR(...)
537# endif
538#endif
539
540//======================================================================================//
541//
542// HIP
543//
544//======================================================================================//
545//
546#if defined(TIMEMORY_USE_HIP)
547//
548//--------------------------------------------------------------------------------------//
549//
550# if !defined(TIMEMORY_HIP_RUNTIME_API_CALL)
551# define TIMEMORY_HIP_RUNTIME_API_CALL(apiFuncCall) \
552 { \
553 ::tim::hip::error_t err = apiFuncCall; \
554 if(err != ::tim::hip::success_v && (int) err != 0) \
555 { \
556 fprintf(stderr, \
557 "%s:%d: error: function '%s' failed with error: %s.\n", \
558 __FILE__, __LINE__, #apiFuncCall, \
559 ::tim::hip::get_error_string(err)); \
560 } \
561 }
562# endif
563//
564//--------------------------------------------------------------------------------------//
565//
566# if !defined(TIMEMORY_HIP_RUNTIME_API_CALL_THROW)
567# define TIMEMORY_HIP_RUNTIME_API_CALL_THROW(apiFuncCall) \
568 { \
569 ::tim::hip::error_t err = apiFuncCall; \
570 if(err != ::tim::hip::success_v && (int) err != 0) \
571 { \
572 char errmsg[std::numeric_limits<uint16_t>::max()]; \
573 sprintf(errmsg, \
574 "%s:%d: error: function '%s' failed with error: %s.\n", \
575 __FILE__, __LINE__, #apiFuncCall, \
576 ::tim::hip::get_error_string(err)); \
577 throw std::runtime_error(errmsg); \
578 } \
579 }
580# endif
581//
582//--------------------------------------------------------------------------------------//
583//
584# if !defined(TIMEMORY_HIP_RUNTIME_CHECK_ERROR)
585# define TIMEMORY_HIP_RUNTIME_CHECK_ERROR(err) \
586 { \
587 if(err != ::tim::hip::success_v && (int) err != 0) \
588 { \
589 fprintf(stderr, "%s:%d: error check failed with: code %i -- %s.\n", \
590 __FILE__, __LINE__, (int) err, \
591 ::tim::hip::get_error_string(err)); \
592 } \
593 }
594# endif
595//
596//--------------------------------------------------------------------------------------//
597//
598#else
599//
600//--------------------------------------------------------------------------------------//
601//
602# if !defined(TIMEMORY_HIP_RUNTIME_API_CALL)
603# define TIMEMORY_HIP_RUNTIME_API_CALL(...)
604# endif
605//
606//--------------------------------------------------------------------------------------//
607//
608# if !defined(TIMEMORY_HIP_RUNTIME_API_CALL_THROW)
609# define TIMEMORY_HIP_RUNTIME_API_CALL_THROW(...)
610# endif
611//
612//--------------------------------------------------------------------------------------//
613//
614# if !defined(TIMEMORY_HIP_RUNTIME_CHECK_ERROR)
615# define TIMEMORY_HIP_RUNTIME_CHECK_ERROR(...)
616# endif
617//
618//--------------------------------------------------------------------------------------//
619//
620#endif
621
622//======================================================================================//
623//
624// GPU
625//
626//======================================================================================//
627//
628#if !defined(TIMEMORY_GPU_RUNTIME_API_CALL)
629# if defined(TIMEMORY_USE_CUDA)
630# define TIMEMORY_GPU_RUNTIME_API_CALL(...) \
631 TIMEMORY_CUDA_RUNTIME_API_CALL(__VA_ARGS__)
632# elif defined(TIMEMORY_USE_HIP)
633# define TIMEMORY_GPU_RUNTIME_API_CALL(...) \
634 TIMEMORY_HIP_RUNTIME_API_CALL(__VA_ARGS__)
635# else
636# define TIMEMORY_GPU_RUNTIME_API_CALL(...)
637# endif
638#endif
639//
640//--------------------------------------------------------------------------------------//
641//
642#if !defined(TIMEMORY_GPU_RUNTIME_API_CALL_THROW)
643# if defined(TIMEMORY_USE_CUDA)
644# define TIMEMORY_GPU_RUNTIME_API_CALL_THROW(...) \
645 TIMEMORY_CUDA_RUNTIME_API_CALL_THROW(__VA_ARGS__)
646# elif defined(TIMEMORY_USE_HIP)
647# define TIMEMORY_GPU_RUNTIME_API_CALL_THROW(...) \
648 TIMEMORY_HIP_RUNTIME_API_CALL_THROW(__VA_ARGS__)
649# else
650# define TIMEMORY_GPU_RUNTIME_API_CALL_THROW(...)
651# endif
652#endif
653//
654//--------------------------------------------------------------------------------------//
655//
656#if !defined(TIMEMORY_GPU_RUNTIME_CHECK_ERROR)
657# if defined(TIMEMORY_USE_CUDA)
658# define TIMEMORY_GPU_RUNTIME_CHECK_ERROR(...) \
659 TIMEMORY_CUDA_RUNTIME_CHECK_ERROR(__VA_ARGS__)
660# elif defined(TIMEMORY_USE_HIP)
661# define TIMEMORY_GPU_RUNTIME_CHECK_ERROR(...) \
662 TIMEMORY_HIP_RUNTIME_CHECK_ERROR(__VA_ARGS__)
663# else
664# define TIMEMORY_GPU_RUNTIME_CHECK_ERROR(...)
665# endif
666#endif
667//
668//--------------------------------------------------------------------------------------//
669//
670
671//======================================================================================//
672//
673// LIKWID
674//
675//======================================================================================//
676//
677#if !defined(TIMEMORY_USE_LIKWID)
678//
679//--------------------------------------------------------------------------------------//
680//
681# if !defined(LIKWID_MARKER_INIT)
682# define LIKWID_MARKER_INIT
683# endif
684//
685//--------------------------------------------------------------------------------------//
686//
687# if !defined(LIKWID_MARKER_THREADINIT)
688# define LIKWID_MARKER_THREADINIT
689# endif
690//
691//--------------------------------------------------------------------------------------//
692//
693# if !defined(LIKWID_MARKER_SWITCH)
694# define LIKWID_MARKER_SWITCH
695# endif
696//
697//--------------------------------------------------------------------------------------//
698//
699# if !defined(LIKWID_MARKER_REGISTER)
700# define LIKWID_MARKER_REGISTER(...)
701# endif
702//
703//--------------------------------------------------------------------------------------//
704//
705# if !defined(LIKWID_MARKER_CLOSE)
706# define LIKWID_MARKER_CLOSE
707# endif
708//
709//--------------------------------------------------------------------------------------//
710//
711# if !defined(LIKWID_MARKER_GET)
712# define LIKWID_MARKER_GET(...)
713# endif
714//
715//--------------------------------------------------------------------------------------//
716//
717# if !defined(LIKWID_MARKER_RESET)
718# define LIKWID_MARKER_RESET(...)
719# endif
720//
721//--------------------------------------------------------------------------------------//
722//
723# if !defined(LIKWID_WITH_NVMON)
724# define LIKWID_NVMARKER_INIT
725# endif
726//
727//--------------------------------------------------------------------------------------//
728//
729# if !defined(LIKWID_WITH_NVMON)
730# define LIKWID_NVMARKER_THREADINIT
731# endif
732//
733//--------------------------------------------------------------------------------------//
734//
735# if !defined(LIKWID_WITH_NVMON)
736# define LIKWID_NVMARKER_SWITCH
737# endif
738//
739//--------------------------------------------------------------------------------------//
740//
741# if !defined(LIKWID_WITH_NVMON)
742# define LIKWID_NVMARKER_REGISTER(...)
743# endif
744//
745//--------------------------------------------------------------------------------------//
746//
747# if !defined(LIKWID_WITH_NVMON)
748# define LIKWID_NVMARKER_CLOSE
749# endif
750//
751//--------------------------------------------------------------------------------------//
752//
753# if !defined(LIKWID_WITH_NVMON)
754# define LIKWID_NVMARKER_GET(...)
755# endif
756//
757//--------------------------------------------------------------------------------------//
758//
759# if !defined(LIKWID_WITH_NVMON)
760# define LIKWID_NVMARKER_RESET(...)
761# endif
762//
763//--------------------------------------------------------------------------------------//
764//
765#endif
766
767//======================================================================================//
768//
769// OPENMP TOOLS (OMPT)
770//
771//======================================================================================//
772//
773#if !defined(TIMEMORY_OMPT_API_TAG)
774# define TIMEMORY_OMPT_API_TAG TIMEMORY_API
775#endif
776
777// for callback declarations
778#if !defined(TIMEMORY_OMPT_CBDECL)
779# if defined(TIMEMORY_USE_OMPT)
780# define TIMEMORY_OMPT_CBDECL(NAME) (ompt_callback_t) & NAME
781# else
782# define TIMEMORY_OMPT_CBDECL(...)
783# endif
784#endif
785
786//======================================================================================//
787//
788// OTHERS
789//
790//======================================================================================//
791//