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.
base_printer.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/base_printer.hpp
27 * \brief Definition for various functions for base_printer in operations
28 */
29
30#pragma once
31
35
36namespace tim
37{
38namespace operation
39{
40//
41//--------------------------------------------------------------------------------------//
42//
43/// \struct tim::operation::base_printer
44/// \brief invoked from the base class to provide default printing behavior
45//
46//--------------------------------------------------------------------------------------//
47//
48template <typename Tp>
50{
51 using type = Tp;
52 using widths_t = std::vector<int64_t>;
53
54 base_printer(std::ostream& _os, const type& _obj) { (*this)(_os, _obj); }
55
56 std::ostream& operator()(std::ostream& _os, const type& _obj) const
57 {
58 (*this)(_os, _obj, 0);
59 return _os;
60 }
61
62private:
63 template <typename Up>
64 auto operator()(std::ostream& _os, const Up& _obj, int) const
65 -> decltype((void) _obj.get_display(), (void) _obj.get_display_unit(),
66 (void) _obj.get_label(), void())
67 {
68 auto _value = _obj.get_display();
69 auto _disp = _obj.get_display_unit();
70 auto _label = _obj.get_label();
71
72 sfinae(_os, 0, _value, _disp, _label);
73 }
74
75 template <typename Up>
76 void operator()(std::ostream&, const Up&, long) const
77 {}
78
79 //----------------------------------------------------------------------------------//
80 //
81 // Array of values + Array of labels + Array of display units
82 //
83 //----------------------------------------------------------------------------------//
84 //
85 template <typename ValueT, typename DispT, typename LabelT>
86 auto sfinae(std::ostream& _os, int, ValueT& _value, DispT& _disp, LabelT& _label,
87 enable_if_t<not_string<ValueT, LabelT, DispT>(), int> = 0) const
88 -> decltype((_value.size() + _disp.size() + _label.size()), void())
89 {
90 auto _prec = type::get_precision();
91 auto _width = type::get_width();
92 auto _flags = type::get_format_flags();
93
94 std::stringstream ss_value;
95 std::stringstream ss_extra;
96 ss_value.setf(_flags);
97
98 auto _vn = _value.size();
99 auto _dn = _disp.size();
100 auto _ln = _label.size();
101 auto _n = std::min<size_t>(_vn, std::min<size_t>(_dn, _ln));
102 std::stringstream _ss;
103 for(size_t i = 0; i < _n; ++i)
104 {
105 ss_value << std::setw(_width) << std::setprecision(_prec)
106 << _value.at(i % _vn);
107
108 // get display returned an empty string
109 if(ss_value.str().find_first_not_of(' ') == std::string::npos)
110 continue;
111
112 // check traits to see if we should print
113 constexpr bool units_print = !trait::custom_unit_printing<type>::value;
114 constexpr bool label_print = !trait::custom_label_printing<type>::value;
115
116 print_tag<units_print>(ss_extra, _disp.at(i % _dn));
117 print_tag<label_print>(ss_extra, _label.at(i % _ln));
118
119 _ss << ss_value.str() << ss_extra.str();
120 if(i + 1 < _n)
121 _ss << ", ";
122 }
123
124 _os << _ss.str();
125 }
126
127 //----------------------------------------------------------------------------------//
128 //
129 // Array of values + Array of labels + string display unit
130 //
131 //----------------------------------------------------------------------------------//
132 //
133 template <typename ValueT, typename DispT, typename LabelT>
134 auto sfinae(std::ostream& _os, int, ValueT& _value, DispT& _disp, LabelT& _label,
135 enable_if_t<not_string<ValueT, LabelT>() && is_string<DispT>(), long> =
136 0L) const -> decltype((_value.size() + _label.size()), void())
137 {
138 auto _prec = type::get_precision();
139 auto _width = type::get_width();
140 auto _flags = type::get_format_flags();
141
142 std::stringstream ss_value;
143 std::stringstream ss_extra;
144 ss_value.setf(_flags);
145
146 auto _vn = _value.size();
147 auto _ln = _label.size();
148 auto _n = std::min<size_t>(_vn, _ln);
149 std::stringstream _ss;
150 for(size_t i = 0; i < _n; ++i)
151 {
152 ss_value << std::setw(_width) << std::setprecision(_prec)
153 << _value.at(i % _vn);
154
155 // get display returned an empty string
156 if(ss_value.str().find_first_not_of(' ') == std::string::npos)
157 continue;
158
159 // check traits to see if we should print
160 constexpr bool units_print = !trait::custom_unit_printing<type>::value;
161 constexpr bool label_print = !trait::custom_label_printing<type>::value;
162
163 if(i + 1 < _n)
164 print_tag<units_print>(ss_extra, _disp);
165 print_tag<label_print>(ss_extra, _label.at(i % _ln));
166
167 _ss << ss_value.str() << ss_extra.str();
168 if(i + 1 < _n)
169 _ss << ", ";
170 }
171
172 _os << _ss.str();
173 }
174
175 //----------------------------------------------------------------------------------//
176 //
177 // Array of values + string label + string display unit
178 //
179 //----------------------------------------------------------------------------------//
180 //
181 template <typename ValueT, typename DispT, typename LabelT>
182 auto sfinae(std::ostream& _os, int, ValueT& _value, DispT& _disp, LabelT& _label,
183 enable_if_t<not_string<ValueT>() && is_string<LabelT, DispT>(), double> =
184 0.0) const -> decltype((_value.size() + _label.size()), void())
185 {
186 auto _prec = type::get_precision();
187 auto _width = type::get_width();
188 auto _flags = type::get_format_flags();
189
190 std::stringstream ss_value;
191 std::stringstream ss_extra;
192 ss_value.setf(_flags);
193
194 auto _vn = _value.size();
195 auto _ln = _label.size();
196 auto _n = std::min<size_t>(_vn, _ln);
197 std::stringstream _ss;
198 for(size_t i = 0; i < _n; ++i)
199 {
200 ss_value << std::setw(_width) << std::setprecision(_prec)
201 << _value.at(i % _vn);
202
203 // get display returned an empty string
204 if(ss_value.str().find_first_not_of(' ') == std::string::npos)
205 continue;
206
207 if(i + 1 < _n)
208 {
209 // check traits to see if we should print
210 constexpr bool units_print = !trait::custom_unit_printing<type>::value;
211 constexpr bool label_print = !trait::custom_label_printing<type>::value;
212
213 print_tag<units_print>(ss_extra, _disp);
214 print_tag<label_print>(ss_extra, _label);
215 }
216
217 _ss << ss_value.str() << ss_extra.str();
218 if(i + 1 < _n)
219 _ss << ", ";
220 }
221
222 _os << _ss.str();
223 }
224
225 //----------------------------------------------------------------------------------//
226 //
227 // Scalar value + string label + string display unit
228 //
229 //----------------------------------------------------------------------------------//
230 //
231 template <typename ValueT, typename DispT, typename LabelT>
232 auto sfinae(std::ostream& _os, long, ValueT& _value, DispT& _disp,
233 LabelT& _label) const
234 {
235 auto _prec = type::get_precision();
236 auto _width = type::get_width();
237 auto _flags = type::get_format_flags();
238
239 std::stringstream ss_value;
240 std::stringstream ss_extra;
241 ss_value.setf(_flags);
242 ss_value << std::setw(_width) << std::setprecision(_prec) << _value;
243
244 // get display returned an empty string
245 if(ss_value.str().find_first_not_of(' ') == std::string::npos)
246 return;
247
248 // check traits to see if we should print
249 constexpr bool units_print = !trait::custom_unit_printing<type>::value;
250 constexpr bool label_print = !trait::custom_label_printing<type>::value;
251
252 print_tag<units_print>(ss_extra, _disp);
253 print_tag<label_print>(ss_extra, _label);
254
255 _os << ss_value.str() << ss_extra.str();
256 }
257};
258//
259//--------------------------------------------------------------------------------------//
260//
261} // namespace operation
262} // 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
The declaration for the types for operations without definitions.
Include the macros for operations.
Declare the operations types.
invoked from the base class to provide default printing behavior
base_printer(std::ostream &_os, const type &_obj)
std::ostream & operator()(std::ostream &_os, const type &_obj) const
std::vector< int64_t > widths_t
common string manipulation utilities