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.
get.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/**
26 * \file timemory/operations/types/get.hpp
27 * \brief Definition for various functions for get in operations
28 */
29
30#pragma once
31
35
36namespace tim
37{
38namespace operation
39{
40//
41//--------------------------------------------------------------------------------------//
42//
43///
44/// \struct tim::operation::get
45///
46/// \brief The purpose of this operation class is to provide a non-template hook to get
47/// the object itself
48///
49//
50//--------------------------------------------------------------------------------------//
51//
52template <typename Tp>
53struct get
54{
55 using type = Tp;
56
58
59 //----------------------------------------------------------------------------------//
60 //
61 get(const type& obj, void*& ptr, size_t nhash) { get_sfinae(obj, 0, 0, ptr, nhash); }
62
63private:
64 template <typename U = type>
65 auto get_sfinae(const U& obj, int, int, void*& ptr, size_t nhash)
66 -> decltype((void) obj.get(ptr, nhash), void())
67 {
68 if(!ptr)
69 obj.get(ptr, nhash);
70 }
71
72 template <typename U = type, typename base_type = typename U::base_type>
73 auto get_sfinae(const U& obj, int, long, void*& ptr, size_t nhash)
74 -> decltype((void) static_cast<const base_type&>(obj).get(ptr, nhash), void())
75 {
76 if(!ptr)
77 static_cast<const base_type&>(obj).get(ptr, nhash);
78 }
79
80 template <typename U = type>
81 void get_sfinae(const U&, long, long, void*&, size_t)
82 {}
83};
84//
85//--------------------------------------------------------------------------------------//
86//
87///
88/// \struct tim::operation::get_data
89/// \brief The purpose of this operation class is to combine the output types from the
90/// "get()" member function for multiple components -- this is specifically used in the
91/// Python interface to provide direct access to the results
92///
93//
94//--------------------------------------------------------------------------------------//
95//
96template <typename Tp>
98{
99 using type = Tp;
100 using data_type = decltype(std::declval<type>().get());
101
102 TIMEMORY_DEFAULT_OBJECT(get_data)
103
104 //----------------------------------------------------------------------------------//
105 // SFINAE
106 //
107 get_data(const type& obj, data_type& dst) { sfinae(obj, 0, 0, dst); }
108
109 template <typename Dp, typename... Args>
110 get_data(const type& obj, Dp& dst, Args&&... args)
111 {
112 static_assert(std::is_same<Dp, data_type>::value, "Error! Dp != type::get()");
113 sfinae(obj, 0, 0, dst, std::forward<Args>(args)...);
114 }
115
117 {
118 data_type _data{};
119 sfinae(_obj, 0, 0, _data);
120 return _data;
121 }
122
123private:
124 //----------------------------------------------------------------------------------//
125 // only if components are available
126 //
127 template <typename Up, typename Dp, typename... Args,
129 auto sfinae(const Up& obj, int, int, Dp& dst, Args&&... args)
130 -> decltype((void) obj.get(std::forward<Args>(args)...), void())
131 {
132 dst = obj.get(std::forward<Args>(args)...);
133 }
134
135 //----------------------------------------------------------------------------------//
136 // only if components are available
137 //
138 template <typename Up, typename Dp, typename... Args,
140 auto sfinae(const Up& obj, int, long, Dp& dst, Args&&...)
141 -> decltype((void) obj.get(), void())
142 {
143 dst = obj.get();
144 }
145
146 //----------------------------------------------------------------------------------//
147 // component is available but no "get" function
148 //
149 template <typename Up, typename Dp, typename... Args,
150 enable_if_t<has_data<Up>::value, char> = 0>
151 void sfinae(const Up&, long, long, Dp&, Args&&...)
152 {}
153
154 //----------------------------------------------------------------------------------//
155 // nothing if component is not available
156 //
157 template <typename Up, typename Dp, typename... Args,
158 enable_if_t<!has_data<Up>::value, char> = 0>
159 void sfinae(const Up&, long, long, Dp&, Args&&...)
160 {}
161};
162//
163//--------------------------------------------------------------------------------------//
164//
165///
166/// \struct tim::operation::get_data
167/// \brief The purpose of this operation class is to combine the output types from the
168/// "get()" member function for multiple components -- this is specifically used in the
169/// Python interface to provide direct access to the results
170///
171//
172//--------------------------------------------------------------------------------------//
173//
174template <typename Tp>
176{
177 using type = Tp;
178 using data_type = std::tuple<std::string, decltype(std::declval<type>().get())>;
179
180 TIMEMORY_DEFAULT_OBJECT(get_labeled_data)
181
182 //----------------------------------------------------------------------------------//
183 // SFINAE
184 //
185 get_labeled_data(const type& obj, data_type& dst) { sfinae(obj, 0, 0, dst); }
186
187 template <typename Dp, typename... Args>
188 get_labeled_data(const type& obj, Dp& dst, Args&&... args)
189 {
190 static_assert(std::is_same<Dp, data_type>::value,
191 "Error! Dp != tuple<string, type::get()>");
192 sfinae(obj, 0, 0, dst, std::forward<Args>(args)...);
193 }
194
196 {
197 data_type _data{};
198 sfinae(_obj, 0, 0, _data);
199 return _data;
200 }
201
202private:
203 //----------------------------------------------------------------------------------//
204 // only if components are available
205 //
206 template <typename Up, typename Dp, typename... Args,
208 auto sfinae(const Up& obj, int, int, Dp& dst, Args&&... args)
209 -> decltype((void) obj.get(std::forward<Args>(args)...), void())
210 {
211 dst = data_type(type::get_label(), obj.get(std::forward<Args>(args)...));
212 }
213
214 //----------------------------------------------------------------------------------//
215 // only if components are available
216 //
217 template <typename Up, typename Dp, typename... Args,
219 auto sfinae(const Up& obj, int, long, Dp& dst, Args&&...)
220 -> decltype((void) obj.get(), void())
221 {
222 dst = data_type(type::get_label(), obj.get());
223 }
224
225 //----------------------------------------------------------------------------------//
226 // component is available but no "get" function
227 //
228 template <typename Up, typename Dp, typename... Args,
229 enable_if_t<has_data<Up>::value, char> = 0>
230 void sfinae(const Up&, long, long, Dp&, Args&&...)
231 {}
232
233 //----------------------------------------------------------------------------------//
234 // nothing if component is not available
235 //
236 template <typename Up, typename Dp, typename... Args,
237 enable_if_t<!has_data<Up>::value, char> = 0>
238 void sfinae(const Up&, long, long, Dp&, Args&&...)
239 {}
240};
241//
242//--------------------------------------------------------------------------------------//
243//
244} // namespace operation
245} // 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
auto get(const auto_bundle< Tag, Types... > &_obj)
The declaration for the types for operations without definitions.
Include the macros for operations.
Declare the operations types.
The purpose of this operation class is to combine the output types from the "get()" member function f...
Definition: get.hpp:98
decltype(std::declval< type >().get()) data_type
Definition: get.hpp:100
data_type operator()(const type &_obj)
Definition: get.hpp:116
get_data(const type &obj, Dp &dst, Args &&... args)
Definition: get.hpp:110
std::tuple< std::string, decltype(std::declval< type >().get())> data_type
Definition: get.hpp:178
data_type operator()(const type &_obj)
Definition: get.hpp:195
get_labeled_data(const type &obj, Dp &dst, Args &&... args)
Definition: get.hpp:188
The purpose of this operation class is to provide a non-template hook to get the object itself.
Definition: get.hpp:54
void *& ptr
Definition: get.hpp:61
void size_t nhash
Definition: get.hpp:61
TIMEMORY_DELETED_OBJECT(get) get(const type &obj