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.
concepts.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
27#include <cstddef>
28#include <cstdint>
29#include <string>
30#include <tuple>
31#include <type_traits>
32
33#if __cplusplus >= 201703L // C++17
34# include <string_view>
35#endif
36
37//--------------------------------------------------------------------------------------//
38
39#define TIMEMORY_IMPL_IS_CONCEPT(CONCEPT) \
40 struct CONCEPT \
41 {}; \
42 template <typename Tp> \
43 struct is_##CONCEPT \
44 { \
45 private: \
46 template <typename, typename = std::true_type> \
47 struct have : std::false_type \
48 {}; \
49 template <typename U> \
50 struct have<U, typename std::is_base_of<typename U::CONCEPT, U>::type> \
51 : std::true_type \
52 {}; \
53 template <typename U> \
54 struct have<U, typename std::is_base_of<typename U::CONCEPT##_type, U>::type> \
55 : std::true_type \
56 {}; \
57 \
58 public: \
59 using type = typename is_##CONCEPT::template have< \
60 typename std::remove_cv<Tp>::type>::type; \
61 static constexpr bool value = \
62 is_##CONCEPT::template have<typename std::remove_cv<Tp>::type>::value; \
63 };
64// constexpr operator bool() const noexcept { return value; }
65
66//--------------------------------------------------------------------------------------//
67namespace tim
68{
69namespace cereal
70{
71namespace detail
72{
73//
74class OutputArchiveBase;
75class InputArchiveBase;
76//
77} // namespace detail
78} // namespace cereal
79} // namespace tim
80//
81namespace tim
82{
83//
84using true_type = std::true_type;
85using false_type = std::false_type;
86//
87struct null_type;
88//
89struct quirk_type;
90//
91template <typename Tp>
92struct statistics;
93//
94namespace audit
95{
96struct incoming;
97struct outgoing;
98} // namespace audit
99//
100namespace trait
101{
102template <typename Tp>
103struct is_available;
104//
105template <typename Tp>
106struct is_component;
107} // namespace trait
108//
109namespace
110{
111template <typename Tp>
112struct anonymous
113{
114 using type = Tp;
115};
116//
117template <typename Tp>
118using anonymous_t = typename anonymous<Tp>::type;
119} // namespace
120//
121namespace component
122{
123template <size_t Idx, typename Tag>
124struct user_bundle;
125//
126template <size_t Nt, typename ComponentsT, typename DifferentiatorT = anonymous_t<void>>
127struct gotcha;
128//
129template <typename... Types>
130struct placeholder;
131//
132struct nothing;
133//
134} // namespace component
135//
136template <typename... Types>
137class lightweight_tuple;
138//
139namespace concepts
140{
141//
142using input_archive_base = cereal::detail::InputArchiveBase;
143using output_archive_base = cereal::detail::OutputArchiveBase;
144//
145//--------------------------------------------------------------------------------------//
146/// \struct tim::concepts::is_empty
147/// \brief concept that specifies that a variadic type is empty
148///
150
151template <template <typename...> class Tuple>
152struct is_empty<Tuple<>> : true_type
153{};
154
155//--------------------------------------------------------------------------------------//
156/// \struct tim::concepts::is_null_type
157/// \brief concept that specifies that a type is not a useful type
158///
160
161template <template <typename...> class Tuple>
162struct is_null_type<Tuple<>> : true_type
163{};
164
165template <>
166struct is_null_type<void> : true_type
167{};
168
169template <>
170struct is_null_type<false_type> : true_type
171{};
172
173template <>
174struct is_null_type<::tim::null_type> : true_type
175{};
176
177template <template <typename...> class Tuple>
178struct is_null_type<statistics<Tuple<>>> : true_type
179{};
180
181template <>
182struct is_null_type<statistics<void>> : true_type
183{};
184
185template <>
186struct is_null_type<statistics<false_type>> : true_type
187{};
188
189template <>
191{};
192
193//--------------------------------------------------------------------------------------//
194/// \struct tim::concepts::is_placeholder
195/// \brief concept that specifies that a type is not necessarily marked as not available
196/// but is still a dummy type
197///
199
200template <typename... Types>
201struct is_placeholder<component::placeholder<Types...>> : true_type
202{};
203
204template <>
205struct is_placeholder<component::placeholder<component::nothing>> : true_type
206{};
207
208template <>
209struct is_placeholder<component::nothing> : true_type
210{};
211
212//--------------------------------------------------------------------------------------//
213/// \struct tim::concepts::is_component
214/// \brief concept that specifies that a type is a component. Components are used to
215/// perform some measurement, capability, or logging implementation. Adding this
216/// concept can be performs through inheriting from \ref tim::component::base,
217/// inheriting from tim::concepts::component, or specializing either \ref
218/// tim::concepts::is_component or \ref tim::trait::is_component (with the latter
219/// being deprecated).
220///
222{};
223//
224template <typename Tp>
226{
227private:
228 /// did not inherit
229 template <typename, typename = std::true_type>
230 struct have : std::false_type
231 {};
232
233 /// did inherit
234 template <typename U>
235 struct have<U, typename std::is_base_of<typename U::component, U>::type>
236 : std::true_type
237 {};
238
239 /// this uses sfinae to see if U::is_component is provided within the type
240 template <typename U>
241 static constexpr decltype(U::is_component, bool{}) test(int)
242 {
243 return U::is_component;
244 }
245
246 /// this checks for the (deprecated) `tim::trait::is_component` specialization
247 /// and checks for inheritance
248 template <typename Up>
249 static constexpr bool test(long)
250 {
252 is_component::template have<std::remove_cv_t<Tp>>::value;
253 }
254
255public:
256 static constexpr bool value = test<Tp>(int{});
257 using type = std::conditional_t<value, true_type, false_type>;
258};
259
260//--------------------------------------------------------------------------------------//
261/// \struct tim::concepts::is_quirk_type
262/// \brief concept that specifies that a type is a quirk. Quirks are used to modify
263/// the traditional behavior of component bundles slightly. E.g. disable calling
264/// start in the constructor of an auto_tuple.
265///
267
268//--------------------------------------------------------------------------------------//
269/// \struct tim::concepts::is_api
270/// \brief concept that specifies that a type is an API. APIs are used to designate
271/// different project implementations, different external library tools, etc.
272///
274
275//--------------------------------------------------------------------------------------//
276/// \struct tim::concepts::is_variadic
277/// \brief concept that specifies that a type is a generic variadic wrapper
278///
280
281//--------------------------------------------------------------------------------------//
282/// \struct tim::concepts::is_wrapper
283/// \brief concept that specifies that a type is a timemory variadic wrapper
284///
286
287//--------------------------------------------------------------------------------------//
288/// \struct tim::concepts::is_stack_wrapper
289/// \brief concept that specifies that a type is a timemory variadic wrapper
290/// and components are stack-allocated
291///
293
294//--------------------------------------------------------------------------------------//
295/// \struct tim::concepts::is_heap_wrapper
296/// \brief concept that specifies that a type is a timemory variadic wrapper
297/// and components are heap-allocated
298///
300
301//--------------------------------------------------------------------------------------//
302/// \struct tim::concepts::is_mixed_wrapper
303/// \brief concept that specifies that a type is a timemory variadic wrapper
304/// and variadic types are mix of stack- and heap- allocated
305///
307
308//--------------------------------------------------------------------------------------//
309/// \struct tim::concepts::is_tagged
310/// \brief concept that specifies that a type's template parameters include
311/// a API specific tag as one of the template parameters (usually first)
312///
314
315//--------------------------------------------------------------------------------------//
316/// \struct tim::concepts::is_comp_wrapper
317/// \brief concept that specifies that a type is a timemory variadic wrapper
318/// that does not perform auto start/stop, e.g. component_{tuple,list,hybrid}
319///
321
322//--------------------------------------------------------------------------------------//
323/// \struct tim::concepts::is_auto_wrapper
324/// \brief concept that specifies that a type is a timemory variadic wrapper
325/// that performs auto start/stop, e.g. auto_{tuple,list,hybrid}
326///
328
329//--------------------------------------------------------------------------------------//
330/// \struct tim::concepts::is_runtime_configurable
331/// \brief concept that specifies that a type is used to modify behavior at runtime.
332/// For example, the \ref tim::component::user_bundle component is runtime configurable bc
333/// it allows you insert components at runtime. The timing category
334/// (`tim::category::timing`) is another example of a type that is runtime configurable --
335/// setting `tim::trait::runtime_enabled<tim::category::timing>::set(false);` will disable
336/// (at runtime) all the types which are part of the timing API. It should be noted that
337/// types which satisfy `is_runtime_configurable<Tp>::value == true` (e.g. \ref
338/// tim::component::user_bundle) are not eligible to be inserted into other runtime
339/// configurable components; i.e. you cannot insert/add \ref
340/// tim::component::user_trace_bundle into \ref tim::component::user_global_bundle, etc.
341/// This restriction is primarily due to the significant increase in compile-time that
342/// arises from allowing this behavior.
343///
345
346//--------------------------------------------------------------------------------------//
347/// \struct tim::concepts::is_external_function_wrapper
348/// \brief concept that specifies that a component type wraps external functions
349///
351
352//--------------------------------------------------------------------------------------//
353/// \struct tim::concepts::is_phase_id
354/// \brief concept that specifies that a type is used for identifying a phase in some
355/// measurement. For example, `tim::audit::incoming` and `tim::audit::outgoing`
356/// can be added to overloads to distinguish whether the `double` type in `double
357/// exp(double val)` is `val` or whether it is the return value.
358///
359/// \code{.cpp}
360/// struct exp_wrapper_A
361/// {
362/// // unable to distingush whether "val" is input or output
363/// void audit(double val) { ... }
364/// };
365///
366/// struct exp_wrapper_B
367/// {
368/// // able to distingush whether "val" is input or output
369/// void audit(audit::incoming, double val) { ... }
370/// void audit(audit::outgoing, double val) { ... }
371/// };
372/// \endcode
374
375//--------------------------------------------------------------------------------------//
376/// \struct tim::concepts::is_string_type
377/// \brief concept that specifies that a component type wraps external functions
378///
380
381template <>
382struct is_string_type<std::string> : true_type
383{};
384
385template <>
386struct is_string_type<char*> : true_type
387{};
388
389template <>
390struct is_string_type<const char*> : true_type
391{};
392
393#if __cplusplus >= 201703L // C++17
394template <>
395struct is_string_type<std::string_view> : true_type
396{};
397#endif
398
399//--------------------------------------------------------------------------------------//
400/// \struct tim::concepts::has_gotcha
401/// \brief determines if a variadic wrapper contains a gotcha component
402///
403template <typename T>
404struct has_gotcha : std::false_type
405{};
406
407//--------------------------------------------------------------------------------------//
408/// \struct tim::concepts::has_user_bundle
409/// \brief concept that specifies that a type is a user_bundle type
410///
411template <typename T>
412struct has_user_bundle : false_type
413{};
414
415//--------------------------------------------------------------------------------------//
416/// \struct tim::concepts::is_output_archive
417/// \brief concept that specifies that a type is an output serialization archive
418///
419template <typename Tp>
421{
422private:
423 /// did not inherit
424 template <typename, typename = std::true_type>
425 struct have : std::false_type
426 {};
427
428 /// did inherit
429 template <typename U>
430 struct have<U, typename std::is_base_of<output_archive_base, U>::type>
431 : std::true_type
432 {};
433
434public:
435 static constexpr bool value =
436 is_output_archive::template have<std::remove_cv_t<Tp>>::value;
437 using type = std::conditional_t<value, true_type, false_type>;
438};
439
440//--------------------------------------------------------------------------------------//
441/// \struct tim::concepts::is_input_archive
442/// \brief concept that specifies that a type is an input serialization archive
443///
444template <typename Tp>
446{
447private:
448 /// did not inherit
449 template <typename, typename = std::true_type>
450 struct have : std::false_type
451 {};
452
453 /// did inherit
454 template <typename U>
455 struct have<U, typename std::is_base_of<input_archive_base, U>::type> : std::true_type
456 {};
457
458public:
459 static constexpr bool value =
460 is_input_archive::template have<std::remove_cv_t<Tp>>::value;
461 using type = std::conditional_t<value, true_type, false_type>;
462};
463
464//--------------------------------------------------------------------------------------//
465/// \struct tim::concepts::is_archive
466/// \brief concept that specifies that a type is a serialization archive (input or output)
467///
468template <typename Tp>
470{
471 static constexpr bool value =
473 using type = std::conditional_t<value, true_type, false_type>;
474};
475
476//--------------------------------------------------------------------------------------//
477/// \struct tim::concepts::is_acceptable_conversion
478/// \tparam Lhs the provided type
479/// \tparam Rhs the target type
480///
481/// \brief This concept designates that is safe to perform a `static_cast<Lhs>(rhs)`
482/// where needed. This is primarily used in the \ref tim::component::data_tracker
483/// where `data_tracker<unsigned int, ...>` might be provided another integral type,
484/// such as `int`.
485///
486template <typename Lhs, typename Rhs>
488{
489 static constexpr bool value =
490 (std::is_same<Lhs, Rhs>::value ||
491 (std::is_integral<Lhs>::value && std::is_integral<Rhs>::value) ||
492 (std::is_floating_point<Lhs>::value && std::is_floating_point<Rhs>::value));
493};
494
495//--------------------------------------------------------------------------------------//
496/// \struct tim::concepts::tuple_type
497/// \brief This concept is used to express how to convert a given type into a
498/// `std::tuple`, e.g. `tim::component_tuple<T...>` to `std::tuple<T...>`. It
499/// is necessary for types like \ref tim::component_bundle where certain template
500/// parameters are tags.
501///
502template <typename T>
504{
505 using type = typename T::tuple_type;
506};
507
508/// \struct tim::concepts::auto_type
509/// \brief This concept is used to express how to convert a component bundler into
510/// another component bundler which performs automatic starting upon construction.
511///
512template <typename T>
514{
515 using type = typename T::auto_type;
516};
517
518/// \struct tim::concepts::component_type
519/// \brief This concept is used to express how to convert a component bundler which
520/// automatically starts upon construction into a type that requires an explicit
521/// call to start.
522///
523template <typename T>
525{
526 using type = typename T::component_type;
527};
528
529template <>
530struct component_type<std::tuple<>>
531{
533};
534
535//--------------------------------------------------------------------------------------//
536
537} // namespace concepts
538
539template <typename T>
541
542template <typename T>
544
545template <typename T>
547
548template <typename T>
550
551template <typename T>
553
554//--------------------------------------------------------------------------------------//
555
556} // namespace tim
557
558//======================================================================================//
559
560#if !defined(TIMEMORY_CONCEPT_ALIAS)
561# define TIMEMORY_CONCEPT_ALIAS(ALIAS, TYPE) \
562 namespace tim \
563 { \
564 namespace concepts \
565 { \
566 template <typename T> \
567 using ALIAS = typename TYPE<T>::type; \
568 } \
569 }
570#endif
571
572//--------------------------------------------------------------------------------------//
573
579
583
584//--------------------------------------------------------------------------------------//
585
586#define TIMEMORY_DEFINE_CONCRETE_CONCEPT(CONCEPT, SPECIALIZED_TYPE, VALUE) \
587 namespace tim \
588 { \
589 namespace concepts \
590 { \
591 template <> \
592 struct CONCEPT<SPECIALIZED_TYPE> : VALUE \
593 {}; \
594 } \
595 }
596
597//--------------------------------------------------------------------------------------//
598
599#define TIMEMORY_DEFINE_TEMPLATE_CONCEPT(CONCEPT, SPECIALIZED_TYPE, VALUE, TYPE) \
600 namespace tim \
601 { \
602 namespace concepts \
603 { \
604 template <TYPE T> \
605 struct CONCEPT<SPECIALIZED_TYPE<T>> : VALUE \
606 {}; \
607 } \
608 }
609
610//--------------------------------------------------------------------------------------//
611
612#define TIMEMORY_DEFINE_VARIADIC_CONCEPT(CONCEPT, SPECIALIZED_TYPE, VALUE, TYPE) \
613 namespace tim \
614 { \
615 namespace concepts \
616 { \
617 template <TYPE... T> \
618 struct CONCEPT<SPECIALIZED_TYPE<T...>> : VALUE \
619 {}; \
620 } \
621 }
622
623//--------------------------------------------------------------------------------------//
624
625#define TIMEMORY_DEFINE_CONCRETE_CONCEPT_TYPE(CONCEPT, SPECIALIZED_TYPE, ...) \
626 namespace tim \
627 { \
628 namespace concepts \
629 { \
630 template <> \
631 struct CONCEPT<SPECIALIZED_TYPE> \
632 { \
633 using type = __VA_ARGS__; \
634 }; \
635 } \
636 }
637
638//--------------------------------------------------------------------------------------//
639
640#define TIMEMORY_DEFINE_TEMPLATE_CONCEPT_TYPE(CONCEPT, SPECIALIZED_TYPE, TYPE, ...) \
641 namespace tim \
642 { \
643 namespace concepts \
644 { \
645 template <TYPE T> \
646 struct CONCEPT<SPECIALIZED_TYPE<T>> \
647 { \
648 using type = __VA_ARGS__; \
649 }; \
650 } \
651 }
652
653//--------------------------------------------------------------------------------------//
654
655#define TIMEMORY_DEFINE_VARIADIC_CONCEPT_TYPE(CONCEPT, SPECIALIZED_TYPE, TYPE, ...) \
656 namespace tim \
657 { \
658 namespace concepts \
659 { \
660 template <TYPE... T> \
661 struct CONCEPT<SPECIALIZED_TYPE<T...>> \
662 { \
663 using type = __VA_ARGS__; \
664 }; \
665 } \
666 }
This is a variadic component wrapper which provides the least amount of runtime and compilation overh...
#define TIMEMORY_CONCEPT_ALIAS(ALIAS, TYPE)
Definition: concepts.hpp:561
#define TIMEMORY_IMPL_IS_CONCEPT(CONCEPT)
Definition: concepts.hpp:39
STL namespace.
typename is_stack_wrapper< T >::type is_stack_wrapper_t
Definition: concepts.hpp:577
typename is_variadic< T >::type is_variadic_t
Definition: concepts.hpp:575
typename T::tuple_type type
Definition: concepts.hpp:505
typename auto_type< T >::type auto_type_t
Definition: concepts.hpp:581
cereal::detail::InputArchiveBase input_archive_base
Definition: concepts.hpp:142
typename tuple_type< T >::type tuple_type_t
Definition: concepts.hpp:580
cereal::detail::OutputArchiveBase output_archive_base
Definition: concepts.hpp:143
typename is_heap_wrapper< T >::type is_heap_wrapper_t
Definition: concepts.hpp:578
typename is_empty< T >::type is_empty_t
Definition: concepts.hpp:574
typename T::component_type type
Definition: concepts.hpp:526
typename is_wrapper< T >::type is_wrapper_t
Definition: concepts.hpp:576
typename T::auto_type type
Definition: concepts.hpp:515
typename component_type< T >::type component_type_t
Definition: concepts.hpp:582
This concept is used to express how to convert a component bundler into another component bundler whi...
Definition: concepts.hpp:514
This concept is used to express how to convert a given type into a std::tuple, e.g....
Definition: concepts.hpp:504
This concept is used to express how to convert a component bundler which automatically starts upon co...
Definition: concepts.hpp:525
void audit(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:939
Definition: kokkosp.cpp:39
typename concepts::is_heap_wrapper< T >::type is_heap_wrapper_t
Definition: concepts.hpp:552
typename concepts::is_empty< T >::type is_empty_t
Definition: concepts.hpp:540
typename concepts::is_stack_wrapper< T >::type is_stack_wrapper_t
Definition: concepts.hpp:549
typename concepts::is_wrapper< T >::type is_wrapper_t
Definition: concepts.hpp:546
typename concepts::is_variadic< T >::type is_variadic_t
Definition: concepts.hpp:543
Used by component audit member function to designate the parameters being passed are incoming (e....
Definition: types.hpp:780
Used by component audit member function to designate the parameters being passed are outgoing (e....
Definition: types.hpp:790
determines if a variadic wrapper contains a gotcha component
Definition: concepts.hpp:405
concept that specifies that a type is a user_bundle type
Definition: concepts.hpp:413
This concept designates that is safe to perform a static_cast<Lhs>(rhs) where needed....
Definition: concepts.hpp:488
concept that specifies that a type is a serialization archive (input or output)
Definition: concepts.hpp:470
std::conditional_t< value, true_type, false_type > type
Definition: concepts.hpp:473
static constexpr bool value
Definition: concepts.hpp:471
concept that specifies that a type is a component. Components are used to perform some measurement,...
Definition: concepts.hpp:226
std::conditional_t< value, true_type, false_type > type
Definition: concepts.hpp:257
static constexpr bool value
Definition: concepts.hpp:256
concept that specifies that a variadic type is empty
Definition: concepts.hpp:149
typename is_empty ::template have< typename std::remove_cv< Tp >::type >::type type
Definition: concepts.hpp:149
concept that specifies that a type is a timemory variadic wrapper and components are heap-allocated
Definition: concepts.hpp:299
typename is_heap_wrapper ::template have< typename std::remove_cv< Tp >::type >::type type
Definition: concepts.hpp:299
concept that specifies that a type is an input serialization archive
Definition: concepts.hpp:446
std::conditional_t< value, true_type, false_type > type
Definition: concepts.hpp:461
static constexpr bool value
Definition: concepts.hpp:459
concept that specifies that a type is not a useful type
Definition: concepts.hpp:159
concept that specifies that a type is an output serialization archive
Definition: concepts.hpp:421
std::conditional_t< value, true_type, false_type > type
Definition: concepts.hpp:437
static constexpr bool value
Definition: concepts.hpp:435
concept that specifies that a type is not necessarily marked as not available but is still a dummy ty...
Definition: concepts.hpp:198
concept that specifies that a type is a timemory variadic wrapper and components are stack-allocated
Definition: concepts.hpp:292
typename is_stack_wrapper ::template have< typename std::remove_cv< Tp >::type >::type type
Definition: concepts.hpp:292
concept that specifies that a component type wraps external functions
Definition: concepts.hpp:379
concept that specifies that a type is a generic variadic wrapper
Definition: concepts.hpp:279
typename is_variadic ::template have< typename std::remove_cv< Tp >::type >::type type
Definition: concepts.hpp:279
concept that specifies that a type is a timemory variadic wrapper
Definition: concepts.hpp:285
typename is_wrapper ::template have< typename std::remove_cv< Tp >::type >::type type
Definition: concepts.hpp:285
this is a placeholder type for optional type-traits. It is used as the default type for the type-trai...
Definition: types.hpp:225
A generic class for statistical accumulation. It uses the timemory math overloads to enable statistic...
Definition: statistics.hpp:83
trait that designates the type is a timemory component
typename typename typename
Definition: types.hpp:226