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.
start.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
31
32#include <type_traits>
33
34namespace tim
35{
36//
37namespace operation
38{
39//
40//--------------------------------------------------------------------------------------//
41//
42//
43//
44//--------------------------------------------------------------------------------------//
45//
46template <typename Tp>
47struct start
48{
49 using type = Tp;
50
51 template <typename U>
52 using base_t = typename U::base_type;
53
54 TIMEMORY_DEFAULT_OBJECT(start)
55
56 TIMEMORY_HOT explicit start(type& obj) { impl(obj); }
57 TIMEMORY_HOT explicit start(type& obj, quirk::unsafe&&)
58 {
59 impl(obj, quirk::unsafe{});
60 }
61
62 template <typename Arg, typename... Args>
63 TIMEMORY_HOT start(type& obj, Arg&& arg, Args&&... args)
64 {
65 impl(obj, std::forward<Arg>(arg), std::forward<Args>(args)...);
66 }
67
68 template <typename... Args>
69 TIMEMORY_HOT auto operator()(type& obj, Args&&... args) const
70 {
71 using RetT = decltype(do_sfinae(obj, 0, 0, std::forward<Args>(args)...));
72 if(!is_running<Tp, false>{}(obj))
73 {
74 return do_sfinae(obj, 0, 0, std::forward<Args>(args)...);
75 }
76 return get_return<RetT>();
77 }
78
79 template <typename... Args>
80 TIMEMORY_HOT auto operator()(type& obj, quirk::unsafe&&, Args&&... args) const
81 {
82 return do_sfinae(obj, 0, 0, std::forward<Args>(args)...);
83 }
84
85private:
86 template <typename T>
87 auto get_return(enable_if_t<std::is_void<T>::value, int> = 0) const
88 {}
89
90 template <typename T>
91 auto get_return(enable_if_t<!std::is_void<T>::value, long> = 0) const
92 {
93 static_assert(std::is_default_constructible<T>::value,
94 "Error! start() returns a type that is not default constructible! "
95 "You must specialize operation::start<T> struct");
96 return T{};
97 }
98
99 template <typename... Args>
100 TIMEMORY_HOT void impl(type& obj, Args&&... args) const;
101
102 template <typename... Args>
103 TIMEMORY_HOT auto impl(type& obj, quirk::unsafe&&, Args&&... args) const
104 {
105 return do_sfinae(obj, 0, 0, std::forward<Args>(args)...);
106 }
107
108 // resolution #1 (best)
109 template <typename Up, typename... Args>
110 TIMEMORY_HOT auto do_sfinae(Up& obj, int, int, Args&&... args) const
111 -> decltype(obj.start(std::forward<Args>(args)...))
112 {
113 set_started<Tp>{}(obj);
114 return obj.start(std::forward<Args>(args)...);
115 }
116
117 // resolution #2
118 template <typename Up, typename... Args>
119 TIMEMORY_HOT auto do_sfinae(Up& obj, int, long, Args&&...) const
120 -> decltype(obj.start())
121 {
122 set_started<Tp>{}(obj);
123 return obj.start();
124 }
125
126 // resolution #3 (worst) - no member function
127 template <typename Up, typename... Args>
128 void do_sfinae(Up&, long, long, Args&&...) const
129 {
131 DEBUG_PRINT_HERE("No support for arguments: start(%s)",
132 tim::mpl::apply<std::string>::join(", ", try_demangle<Up>(),
133 demangle<Args>()...)
134 .c_str());
135 }
136};
137//
138//--------------------------------------------------------------------------------------//
139//
140//
141//
142//--------------------------------------------------------------------------------------//
143//
144template <typename Tp>
146{
147 using type = Tp;
148
150
151 template <typename... Args>
152 TIMEMORY_HOT explicit priority_start(type& obj, Args&&... args);
153
154private:
155 // satisfies mpl condition
156 template <typename Up, typename... Args>
157 TIMEMORY_HOT auto sfinae(Up& obj, true_type&&, Args&&... args)
158 {
159 start<Tp>{ obj, std::forward<Args>(args)... };
160 }
161
162 // does not satisfy mpl condition
163 template <typename Up, typename... Args>
164 TIMEMORY_INLINE void sfinae(Up&, false_type&&, Args&&...)
165 {}
166};
167//
168//--------------------------------------------------------------------------------------//
169//
170//
171//
172//--------------------------------------------------------------------------------------//
173//
174template <typename Tp>
176{
177 using type = Tp;
178
180
181 template <typename... Args>
182 TIMEMORY_HOT explicit standard_start(type& obj, Args&&... args);
183
184private:
185 // satisfies mpl condition
186 template <typename Up, typename... Args>
187 TIMEMORY_HOT auto sfinae(Up& obj, true_type&&, Args&&... args)
188 {
189 start<Tp>{ obj, std::forward<Args>(args)... };
190 }
191
192 // does not satisfy mpl condition
193 template <typename Up, typename... Args>
194 TIMEMORY_INLINE void sfinae(Up&, false_type&&, Args&&...)
195 {}
196};
197//
198//--------------------------------------------------------------------------------------//
199//
200//
201//
202//--------------------------------------------------------------------------------------//
203//
204template <typename Tp>
206{
207 using type = Tp;
208
210
211 template <typename... Args>
212 TIMEMORY_HOT explicit delayed_start(type& obj, Args&&... args);
213
214private:
215 // satisfies mpl condition
216 template <typename Up, typename... Args>
217 TIMEMORY_HOT auto sfinae(Up& obj, true_type&&, Args&&... args)
218 {
219 start<Tp>{ obj, std::forward<Args>(args)... };
220 }
221
222 // does not satisfy mpl condition
223 template <typename Up, typename... Args>
224 TIMEMORY_INLINE void sfinae(Up&, false_type&&, Args&&...)
225 {}
226};
227//
228//--------------------------------------------------------------------------------------//
229//
230template <typename Tp>
231template <typename... Args>
232void
233start<Tp>::impl(type& obj, Args&&... args) const
234{
235 if(!is_running<Tp, false>{}(obj))
236 {
237 set_started<Tp>{}(obj);
238 do_sfinae(obj, 0, 0, std::forward<Args>(args)...);
239 }
240}
241//
242//--------------------------------------------------------------------------------------//
243//
244template <typename Tp>
245template <typename... Args>
246priority_start<Tp>::priority_start(type& obj, Args&&... args)
247{
248 using sfinae_type =
249 conditional_t<(trait::start_priority<Tp>::value < 0), true_type, false_type>;
250 sfinae(obj, sfinae_type{}, std::forward<Args>(args)...);
251}
252//
253//--------------------------------------------------------------------------------------//
254//
255template <typename Tp>
256template <typename... Args>
257standard_start<Tp>::standard_start(type& obj, Args&&... args)
258{
259 using sfinae_type =
260 conditional_t<(trait::start_priority<Tp>::value == 0), true_type, false_type>;
261 sfinae(obj, sfinae_type{}, std::forward<Args>(args)...);
262}
263//
264//--------------------------------------------------------------------------------------//
265//
266template <typename Tp>
267template <typename... Args>
268delayed_start<Tp>::delayed_start(type& obj, Args&&... args)
269{
270 using sfinae_type =
271 conditional_t<(trait::start_priority<Tp>::value > 0), true_type, false_type>;
272 sfinae(obj, sfinae_type{}, std::forward<Args>(args)...);
273}
274//
275//--------------------------------------------------------------------------------------//
276//
277} // namespace operation
278} // namespace tim
Definition: kokkosp.cpp:39
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
typename std::conditional< B, Lhs, Rhs >::type conditional_t
Definition: types.hpp:197
The declaration for the types for operations without definitions.
#define SFINAE_WARNING(...)
Definition: declaration.hpp:70
Include the macros for operations.
Declare the operations types.
TIMEMORY_DELETED_OBJECT(delayed_start) template< typename... Args > explicit delayed_start(type &obj
This operation attempts to call a member function which provides whether or not the component current...
Definition: types.hpp:597
TIMEMORY_DELETED_OBJECT(priority_start) template< typename... Args > explicit priority_start(type &obj
TIMEMORY_DELETED_OBJECT(standard_start) template< typename... Args > explicit standard_start(type &obj
auto operator()(type &obj, quirk::unsafe &&, Args &&... args) const
Definition: start.hpp:80
start(type &obj, quirk::unsafe &&)
Definition: start.hpp:57
start(type &obj, Arg &&arg, Args &&... args)
Definition: start.hpp:63
typename U::base_type base_t
Definition: start.hpp:52
auto operator()(type &obj, Args &&... args) const
Definition: start.hpp:69
start(type &obj)
Definition: start.hpp:56
When present, this argument instructs to skip any safety checks. Example checks include: checking whe...
Definition: quirks.hpp:270
#define DEBUG_PRINT_HERE(...)
Definition: macros.hpp:168