timemory  3.2.1
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 
27 #include "timemory/mpl/quirks.hpp"
31 
32 #include <type_traits>
33 
34 namespace tim
35 {
36 //
37 namespace operation
38 {
39 //
40 //--------------------------------------------------------------------------------------//
41 //
42 //
43 //
44 //--------------------------------------------------------------------------------------//
45 //
46 template <typename Tp>
47 struct 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 
85 private:
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 //
144 template <typename Tp>
146 {
147  using type = Tp;
148 
150 
151  template <typename... Args>
152  TIMEMORY_HOT explicit priority_start(type& obj, Args&&... args);
153 
154 private:
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 //
174 template <typename Tp>
176 {
177  using type = Tp;
178 
180 
181  template <typename... Args>
182  TIMEMORY_HOT explicit standard_start(type& obj, Args&&... args);
183 
184 private:
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 //
204 template <typename Tp>
206 {
207  using type = Tp;
208 
210 
211  template <typename... Args>
212  TIMEMORY_HOT explicit delayed_start(type& obj, Args&&... args);
213 
214 private:
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 //
230 template <typename Tp>
231 template <typename... Args>
232 void
233 start<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 //
244 template <typename Tp>
245 template <typename... Args>
246 priority_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 //
255 template <typename Tp>
256 template <typename... Args>
257 standard_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 //
266 template <typename Tp>
267 template <typename... Args>
268 delayed_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:38
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:65
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:600
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:163