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.
echo_measurement.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/echo_measurement.hpp
27 * \brief Definition for various functions for echo_measurement in operations
28 */
29
30#pragma once
31
36
37namespace tim
38{
39namespace operation
40{
41//
42//--------------------------------------------------------------------------------------//
43//
44///
45/// \struct tim::operation::echo_measurement
46/// \brief This operation class echoes DartMeasurements for a CDash dashboard
47///
48//
49//--------------------------------------------------------------------------------------//
50//
51template <typename Tp>
53{
54 template <typename... Args>
56 {}
57};
58//
59//--------------------------------------------------------------------------------------//
60//
61template <typename Tp>
63{
64 using type = Tp;
65 using attributes_t = std::map<std::string, std::string>;
66
67 //----------------------------------------------------------------------------------//
68 /// generate a name attribute
69 ///
70 template <typename... Args>
71 static TIMEMORY_COLD string_t generate_name(const string_t& _prefix, string_t _unit,
72 Args&&... _args)
73 {
75 {
76 return (_unit.length() > 0 && _unit != "%")
77 ? join("//", type::get_label(), _unit)
78 : type::get_label();
79 }
80
81 auto _extra = join('/', std::forward<Args>(_args)...);
82 auto _label = uppercase(type::get_label());
83 _unit = replace(_unit, "", { " " });
84 string_t _name =
85 (_extra.length() > 0) ? join("//", _extra, _prefix) : join("//", _prefix);
86
87 auto _ret = join("//", _label, _name);
88
89 if(_ret.length() > 0 && _ret.at(_ret.length() - 1) == '/')
90 _ret.erase(_ret.length() - 1);
91
92 if(_unit.length() > 0 && _unit != "%")
93 _ret += "//" + _unit;
94
95 return _ret;
96 }
97
98 //------------------------------------------------------------------------------//
99 //
100 struct impl
101 {
102 template <typename Tuple, typename... Args, size_t... Nt,
103 enable_if_t<sizeof...(Nt) == 0, char> = 0>
104 static TIMEMORY_COLD std::string name_generator(const string_t&, Tuple, Args&&...,
106 {
107 return "";
108 }
109
110 template <typename Tuple, typename... Args, size_t Idx, size_t... Nt,
111 enable_if_t<sizeof...(Nt) == 0, char> = 0>
112 static TIMEMORY_COLD std::string name_generator(const string_t& _prefix,
113 Tuple _units, Args&&... _args,
115 {
116 return generate_name(_prefix, std::get<Idx>(_units),
117 std::forward<Args>(_args)...);
118 }
119
120 template <typename Tuple, typename... Args, size_t Idx, size_t... Nt,
121 enable_if_t<(sizeof...(Nt) > 0), char> = 0>
122 static TIMEMORY_COLD std::string name_generator(const string_t& _prefix,
123 Tuple _units, Args&&... _args,
124 index_sequence<Idx, Nt...>)
125 {
126 return join(
127 ",",
128 name_generator<Tuple>(_prefix, _units, std::forward<Args>(_args)...,
129 index_sequence<Idx>{}),
130 name_generator<Tuple>(_prefix, _units, std::forward<Args>(_args)...,
131 index_sequence<Nt...>{}));
132 }
133 };
134
135 //----------------------------------------------------------------------------------//
136 /// generate a name attribute
137 ///
138 template <typename Tuple, typename... Args>
139 static TIMEMORY_COLD string_t generate_name(const string_t& _prefix, Tuple _unit,
140 Args&&... _args)
141 {
142 constexpr size_t N = std::tuple_size<Tuple>::value;
143 return impl::template name_generator<Tuple>(
144 _prefix, _unit, std::forward<Args>(_args)..., make_index_sequence<N>{});
145 }
146
147 //----------------------------------------------------------------------------------//
148 /// generate a name attribute
149 ///
150 template <typename T, typename... Alloc, typename... Args>
151 static TIMEMORY_COLD string_t generate_name(const string_t& _prefix,
152 std::vector<T, Alloc...> _unit,
153 Args&&... _args)
154 {
155 string_t ret;
156 for(auto& itr : _unit)
157 {
158 return join(",", ret,
159 generate_name(_prefix, itr, std::forward<Args>(_args)...));
160 }
161 return ret;
162 }
163
164 //----------------------------------------------------------------------------------//
165 /// generate a name attribute
166 ///
167 template <typename T, size_t N, typename... Args>
168 static TIMEMORY_COLD string_t generate_name(const string_t& _prefix,
169 std::array<T, N> _unit, Args&&... _args)
170 {
171 string_t ret;
172 for(auto& itr : _unit)
173 {
174 return join(",", ret,
175 generate_name(_prefix, itr, std::forward<Args>(_args)...));
176 }
177 return ret;
178 }
179
180 //----------------------------------------------------------------------------------//
181 /// generate a measurement tag
182 ///
183 template <typename Vt>
184 static TIMEMORY_COLD void generate_measurement(std::ostream& os,
185 const attributes_t& attributes,
186 const Vt& value)
187 {
188 os << "<DartMeasurement";
189 os << " " << attribute_string("type", "numeric/double");
190 for(const auto& itr : attributes)
191 os << " " << attribute_string(itr.first, itr.second);
192 os << ">" << std::setprecision(type::get_precision()) << value
193 << "</DartMeasurement>\n";
194 }
195
196 //----------------------------------------------------------------------------------//
197 /// generate a measurement tag
198 ///
199 template <typename Vt, typename... ExtraT>
200 static TIMEMORY_COLD void generate_measurement(
201 std::ostream& os, attributes_t attributes,
202 const std::vector<Vt, ExtraT...>& value)
203 {
204 auto _default_name = attributes["name"];
205 int i = 0;
206 for(const auto& itr : value)
207 {
208 std::stringstream ss;
209 ss << "INDEX_" << i++ << " ";
210 attributes["name"] = ss.str() + _default_name;
211 generate_measurement(os, attributes, itr);
212 }
213 }
214
215 //----------------------------------------------------------------------------------//
216 /// generate a measurement tag
217 ///
218 template <typename Lhs, typename Rhs, typename... ExtraT>
219 static TIMEMORY_COLD void generate_measurement(std::ostream& os,
220 attributes_t attributes,
221 const std::pair<Lhs, Rhs>& value)
222 {
223 auto default_name = attributes["name"];
224 auto set_name = [&](int i) {
225 std::stringstream ss;
226 ss << "INDEX_" << i << " ";
227 attributes["name"] = ss.str() + default_name;
228 };
229
230 set_name(0);
231 generate_measurement(os, attributes, value.first);
232 set_name(1);
233 generate_measurement(os, attributes, value.second);
234 }
235
236 //----------------------------------------------------------------------------------//
237 /// generate the prefix
238 ///
239 static TIMEMORY_COLD string_t generate_prefix(const strvec_t& hierarchy)
240 {
242 return string_t("");
243
244 string_t ret_prefix{};
245 string_t add_prefix{};
246 static const strset_t repl_chars = { "\t", "\n", "<", ">" };
247 for(const auto& itr : hierarchy)
248 {
249 auto prefix = itr;
250 prefix = replace(prefix, "", { ">>>" });
251 prefix = replace(prefix, "", { "|_" });
252 prefix = replace(prefix, "_", repl_chars);
253 prefix = replace(prefix, "_", { "__" });
254 if(prefix.length() > 0 && prefix.at(prefix.length() - 1) == '_')
255 prefix.erase(prefix.length() - 1);
256 ret_prefix += add_prefix + prefix;
257 }
258 return ret_prefix;
259 }
260
261 //----------------------------------------------------------------------------------//
262 /// assumes type is not a iterable
263 ///
264 template <typename Up = Tp, typename Vt = typename Up::value_type,
268 int> = 0>
269 TIMEMORY_COLD echo_measurement(Up& obj, const strvec_t& hierarchy)
270 {
271 auto prefix = generate_prefix(hierarchy);
272 auto _unit = type::get_display_unit();
273 auto name = generate_name(prefix, _unit);
274 auto _data = obj.get();
275
276 attributes_t attributes = { { "name", name } };
278 generate_measurement(ss, attributes, _data);
279 std::cout << ss.str() << std::flush;
280 }
281
282 //----------------------------------------------------------------------------------//
283 /// assumes type is iterable
284 ///
285 template <typename Up = Tp, typename Vt = typename Up::value_type,
289 int> = 0>
290 TIMEMORY_COLD echo_measurement(Up& obj, const strvec_t& hierarchy)
291 {
292 auto prefix = generate_prefix(hierarchy);
293 auto _data = obj.get();
294
295 attributes_t attributes = {};
297
298 uint64_t idx = 0;
299 auto _labels = obj.label_array();
300 auto _dunits = obj.display_unit_array();
301 for(auto& itr : _data)
302 {
303 string_t _extra = (idx < _labels.size()) ? _labels.at(idx) : "";
304 string_t _dunit = (idx < _labels.size()) ? _dunits.at(idx) : "";
305 ++idx;
306 attributes["name"] = generate_name(prefix, _dunit, _extra);
307 generate_measurement(ss, attributes, itr);
308 }
309 std::cout << ss.str() << std::flush;
310 }
311
312 template <typename... Args, typename Up = Tp, typename Vt = typename Up::value_type,
314 echo_measurement(Up&, Args&&...)
315 {}
316};
317//
318//--------------------------------------------------------------------------------------//
319//
320} // namespace operation
321} // namespace tim
std::string string_t
Definition: library.cpp:57
std::string & replace(std::string &_path, char _c, const char *_v)
Definition: filepath.hpp:66
return false
Definition: definition.hpp:326
const hash_alias_ptr_t hash_value_t std::string *& _ret
Definition: definition.hpp:300
This operation class echoes DartMeasurements for a CDash dashboard.
Definition: types.hpp:985
auto join(const char *sep, Arg &&arg, Args &&... args)
Definition: declaration.hpp:74
Definition: kokkosp.cpp:39
std::make_integer_sequence< size_t, Num > make_index_sequence
Alias template make_index_sequence.
Definition: types.hpp:182
std::array< char *, 4 > _args
char const std::string & _prefix
Definition: config.cpp:55
std::string string_t
Definition: utility.hpp:98
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
dart_label
Definition: settings.cpp:1671
const std::string std::ostream * os
std::integer_sequence< size_t, Idx... > index_sequence
Alias template index_sequence.
Definition: types.hpp:178
The declaration for the types for operations without definitions.
Include the macros for operations.
Declare the operations types.
common string manipulation utilities
std::vector< string_t > strvec_t
std::set< string_t > strset_t
std::stringstream stringstream_t
std::map< string_t, string_t > attributes_t
static void generate_measurement(std::ostream &os, const attributes_t &attributes, const Vt &value)
generate a measurement tag
echo_measurement(Up &obj, const strvec_t &hierarchy)
assumes type is not a iterable
static string_t generate_name(const string_t &_prefix, std::array< T, N > _unit, Args &&... _args)
generate a name attribute
static void generate_measurement(std::ostream &os, attributes_t attributes, const std::pair< Lhs, Rhs > &value)
generate a measurement tag
static string_t generate_prefix(const strvec_t &hierarchy)
generate the prefix
static void generate_measurement(std::ostream &os, attributes_t attributes, const std::vector< Vt, ExtraT... > &value)
generate a measurement tag
static string_t generate_name(const string_t &_prefix, Tuple _unit, Args &&... _args)
generate a name attribute
static string_t generate_name(const string_t &_prefix, std::vector< T, Alloc... > _unit, Args &&... _args)
generate a name attribute
static string_t generate_name(const string_t &_prefix, string_t _unit, Args &&... _args)
generate a name attribute
trait that signifies that data is an array type
trait that signifies that get() returns an iterable type