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.
tim::operation::finalize::get< Type, true > Struct Template Reference

#include "timemory/operations/types/finalize/get.hpp"

+ Collaboration diagram for tim::operation::finalize::get< Type, true >:

Public Types

using storage_type = impl::storage< Type, value >
 
using result_type = typename storage_type::result_array_t
 
using distrib_type = typename storage_type::dmp_result_t
 
using result_node = typename storage_type::result_node
 
using graph_type = typename storage_type::graph_t
 
using graph_node = typename storage_type::graph_node
 
using hierarchy_type = typename storage_type::uintvector_t
 
using basic_tree_type = basic_tree< node::tree< Type > >
 
using basic_tree_vector_type = std::vector< basic_tree_type >
 
using metadata = typename serialization< Type >::metadata
 

Public Member Functions

 get (storage_type &_storage)
 
 get (storage_type *_storage)
 
result_typeoperator() (result_type &)
 
basic_tree_vector_typeoperator() (basic_tree_vector_type &)
 
std::vector< basic_tree_vector_type > & operator() (std::vector< basic_tree_vector_type > &_data)
 
template<typename Archive >
enable_if_t< concepts::is_output_archive< Archive >::value, Archive & > operator() (Archive &)
 
template<typename Archive >
enable_if_t< concepts::is_output_archive< Archive >::value, Archive & > operator() (Archive &, metadata)
 

Static Public Member Functions

static auto get_identifier (const Type &_obj=Type{})
 
static auto get_label (const Type &_obj=Type{})
 
static auto get_description (const Type &_obj=Type{})
 
static auto get_unit (const Type &_obj=Type{})
 
static auto get_display_unit (const Type &_obj=Type{})
 

Static Public Attributes

static constexpr bool value = true
 

Detailed Description

template<typename Type>
struct tim::operation::finalize::get< Type, true >

Definition at line 57 of file get.hpp.

Member Typedef Documentation

◆ basic_tree_type

Definition at line 67 of file get.hpp.

◆ basic_tree_vector_type

template<typename Type >
using tim::operation::finalize::get< Type, true >::basic_tree_vector_type = std::vector<basic_tree_type>

Definition at line 68 of file get.hpp.

◆ distrib_type

template<typename Type >
using tim::operation::finalize::get< Type, true >::distrib_type = typename storage_type::dmp_result_t

Definition at line 62 of file get.hpp.

◆ graph_node

template<typename Type >
using tim::operation::finalize::get< Type, true >::graph_node = typename storage_type::graph_node

Definition at line 65 of file get.hpp.

◆ graph_type

template<typename Type >
using tim::operation::finalize::get< Type, true >::graph_type = typename storage_type::graph_t

Definition at line 64 of file get.hpp.

◆ hierarchy_type

template<typename Type >
using tim::operation::finalize::get< Type, true >::hierarchy_type = typename storage_type::uintvector_t

Definition at line 66 of file get.hpp.

◆ metadata

Definition at line 69 of file get.hpp.

◆ result_node

template<typename Type >
using tim::operation::finalize::get< Type, true >::result_node = typename storage_type::result_node

Definition at line 63 of file get.hpp.

◆ result_type

template<typename Type >
using tim::operation::finalize::get< Type, true >::result_type = typename storage_type::result_array_t

Definition at line 61 of file get.hpp.

◆ storage_type

template<typename Type >
using tim::operation::finalize::get< Type, true >::storage_type = impl::storage<Type, value>

Definition at line 60 of file get.hpp.

Constructor & Destructor Documentation

◆ get() [1/2]

template<typename Type >
tim::operation::finalize::get< Type, true >::get ( storage_type _storage)
inlineexplicit

Definition at line 73 of file get.hpp.

74 : m_storage(&_storage)
75 {}

◆ get() [2/2]

template<typename Type >
tim::operation::finalize::get< Type, true >::get ( storage_type _storage)
inlineexplicit

Definition at line 77 of file get.hpp.

78 : m_storage(_storage)
79 {}

Member Function Documentation

◆ get_description()

template<typename Type >
static auto tim::operation::finalize::get< Type, true >::get_description ( const Type &  _obj = Type{})
inlinestatic

Definition at line 109 of file get.hpp.

109 {})
110 {
111 return serialization<Type>::get_description(_obj);
112 }

◆ get_display_unit()

template<typename Type >
static auto tim::operation::finalize::get< Type, true >::get_display_unit ( const Type &  _obj = Type{})
inlinestatic

Definition at line 117 of file get.hpp.

117 {})
118 {
119 return serialization<Type>::get_display_unit(_obj);
120 }

◆ get_identifier()

template<typename Type >
static auto tim::operation::finalize::get< Type, true >::get_identifier ( const Type &  _obj = Type{})
inlinestatic

Definition at line 101 of file get.hpp.

101 {})
102 {
103 return serialization<Type>::get_identifier(_obj);
104 }

◆ get_label()

template<typename Type >
static auto tim::operation::finalize::get< Type, true >::get_label ( const Type &  _obj = Type{})
inlinestatic

Definition at line 105 of file get.hpp.

105 {})
106 {
107 return serialization<Type>::get_label(_obj);
108 }

◆ get_unit()

template<typename Type >
static auto tim::operation::finalize::get< Type, true >::get_unit ( const Type &  _obj = Type{})
inlinestatic

Definition at line 113 of file get.hpp.

113 {})
114 {
115 return serialization<Type>::get_unit(_obj);
116 }

◆ operator()() [1/5]

template<typename Type >
template<typename Archive >
enable_if_t< concepts::is_output_archive< Archive >::value, Archive & > tim::operation::finalize::get< Type, true >::operator() ( Archive &  ar)

Definition at line 397 of file get.hpp.

398{
399 if(!m_storage)
400 return ar;
401
402 m_storage->m_node_init = dmp::is_initialized();
403 m_storage->m_node_rank = dmp::rank();
404 m_storage->m_node_size = dmp::size();
405 m_storage->merge();
406
407 auto bt = basic_tree_vector_type{};
408 serialization<Type>{}(ar, bt);
409 return ar;
410}
std::vector< basic_tree_type > basic_tree_vector_type
Definition: get.hpp:68

◆ operator()() [2/5]

template<typename Type >
template<typename Archive >
enable_if_t< concepts::is_output_archive< Archive >::value, Archive & > tim::operation::finalize::get< Type, true >::operator() ( Archive &  ar,
metadata   
)

Definition at line 386 of file get.hpp.

387{
388 serialization<Type>{}(ar, metadata{});
389 return ar;
390}
typename serialization< Type >::metadata metadata
Definition: get.hpp:69

◆ operator()() [3/5]

template<typename Type >
get< Type, true >::basic_tree_vector_type & tim::operation::finalize::get< Type, true >::operator() ( basic_tree_vector_type bt)

Definition at line 362 of file get.hpp.

363{
364 using sibling_iterator = typename graph_type::sibling_iterator;
365
366 if(!m_storage)
367 return bt;
368
369 auto& data = *m_storage;
370 auto& t = data.graph();
371 for(sibling_iterator itr = t.begin(); itr != t.end(); ++itr)
372 bt.push_back(basic_tree_type{}(t, itr));
373
374 bt = merge<Type, true>{}(bt);
375 return bt;
376 // return (trait::thread_scope_only<Type>::value || !settings::collapse_threads())
377 // ? bt
378 // : merge<Type, true>{}(bt);
379}
basic_tree< node::tree< Type > > basic_tree_type
Definition: get.hpp:67

◆ operator()() [4/5]

template<typename Type >
get< Type, true >::result_type & tim::operation::finalize::get< Type, true >::operator() ( result_type ret)

Definition at line 145 of file get.hpp.

146{
147 if(!m_storage)
148 return ret;
149
150 auto& data = *m_storage;
151 bool _thread_scope_only = trait::thread_scope_only<Type>::value;
152 bool _use_tid_prefix = (!settings::collapse_threads() || _thread_scope_only);
153 bool _use_pid_prefix = (!settings::collapse_processes());
154 auto _num_thr_count = manager::get_thread_count();
155 auto _num_pid_count = dmp::size();
156
157 data.m_node_init = dmp::is_initialized();
158 data.m_node_rank = dmp::rank();
159 data.m_node_size = dmp::size();
160
161 //------------------------------------------------------------------------------//
162 //
163 // Compute the thread prefix
164 //
165 //------------------------------------------------------------------------------//
166 auto _get_thread_prefix = [&](const graph_node& itr) {
167 if(!_use_tid_prefix || itr.tid() == std::numeric_limits<uint16_t>::max())
168 return std::string(">>> ");
169
170 // prefix spacing
171 static uint16_t width = 1;
172 if(_num_thr_count > 9)
173 width = std::max(width, (uint16_t)(log10(_num_thr_count) + 1));
174 std::stringstream ss;
175 ss.fill('0');
176 ss << "|" << std::setw(width) << itr.tid() << ">>> ";
177 return ss.str();
178 };
179
180 //------------------------------------------------------------------------------//
181 //
182 // Compute the node prefix
183 //
184 //------------------------------------------------------------------------------//
185 auto _get_node_prefix = [&](const graph_node& itr) {
186 if(!data.m_node_init || !_use_pid_prefix)
187 return _get_thread_prefix(itr);
188
189 auto _nc = settings::node_count(); // node-count
190 auto _idx = data.m_node_rank;
191 auto _range = std::make_pair(-1, -1);
192
193 if(_nc > 0 && _nc < data.m_node_size)
194 {
195 // calculate some size parameters and generate map of the pids to node ids
196 int32_t nmod = _num_pid_count % _nc;
197 int32_t bins = _num_pid_count / _nc + ((nmod == 0) ? 0 : 1);
198 int32_t bsize = _num_pid_count / bins;
199 int32_t ncnt = 0; // current count
200 int32_t midx = 0; // current bin map index
201 std::map<int32_t, std::set<int32_t>> binmap;
202 for(int32_t i = 0; i < _num_pid_count; ++i)
203 {
204 binmap[midx].insert(i);
205 // check to see if we reached the bin size
206 if(++ncnt == bsize)
207 {
208 // set counter to zero and advance the node
209 ncnt = 0;
210 ++midx;
211 }
212 }
213
214 // loop over the bins
215 for(const auto& bitr : binmap)
216 {
217 // if rank is found in a bin, assing range to first and last entry
218 if(bitr.second.find(_idx) != bitr.second.end())
219 {
220 auto vitr = bitr.second.begin();
221 _range.first = *vitr;
222 vitr = bitr.second.end();
223 --vitr;
224 _range.second = *vitr;
225 }
226 }
227
228 if(settings::debug())
229 {
230 std::stringstream ss;
231 for(const auto& bitr : binmap)
232 {
233 ss << ", [" << bitr.first << "] ";
234 std::stringstream bss;
235 for(const auto& nitr : bitr.second)
236 bss << ", " << nitr;
237 ss << bss.str().substr(2);
238 }
239 std::string _msg = "Intervals: ";
240 _msg += ss.str().substr(2);
241 PRINT_HERE("[%s][pid=%i][tid=%i]> %s. range = { %i, %i }",
242 demangle<get<Type, true>>().c_str(), (int) process::get_id(),
243 (int) threading::get_id(), _msg.c_str(), (int) _range.first,
244 (int) _range.second);
245 }
246 }
247
248 // prefix spacing
249 static uint16_t width = 1;
250 if(_num_pid_count > 9)
251 width = std::max(width, (uint16_t)(log10(_num_pid_count) + 1));
252 std::stringstream ss;
253 ss.fill('0');
254 if(_range.first >= 0 && _range.second >= 0)
255 {
256 ss << "|" << std::setw(width) << _range.first << ":" << std::setw(width)
257 << _range.second << _get_thread_prefix(itr);
258 }
259 else
260 {
261 ss << "|" << std::setw(width) << _idx << _get_thread_prefix(itr);
262 }
263 return ss.str();
264 };
265
266 //------------------------------------------------------------------------------//
267 //
268 // Compute the indentation
269 //
270 //------------------------------------------------------------------------------//
271 // fix up the prefix based on the actual depth
272 auto _compute_modified_prefix = [&](const graph_node& itr) {
273 std::string _prefix = data.get_prefix(itr);
274 std::string _indent = {};
275 std::string _node_prefix = _get_node_prefix(itr);
276
277 int64_t _depth = itr.depth() - 1;
278 if(_depth > 0)
279 {
280 for(int64_t ii = 0; ii < _depth - 1; ++ii)
281 _indent += " ";
282 _indent += "|_";
283 }
284
285 return _node_prefix + _indent + _prefix;
286 };
287
288 // convert graph to a vector
289 auto convert_graph = [&]() {
290 result_type _list{};
291 {
292 // the head node should always be ignored
293 int64_t _min = std::numeric_limits<int64_t>::max();
294 auto& _graph = data.graph();
295 for(auto itr = _graph.begin(); itr != _graph.end(); ++itr)
296 {
297 if(!itr)
298 {
299 PRINT_HERE("[%s] Warning! Invalid iterator!",
300 demangle<Type>().c_str());
301 continue;
302 }
303 _min = std::min<int64_t>(_min, itr->depth());
304 }
305
306 for(auto itr = _graph.begin(); itr != _graph.end(); ++itr)
307 {
308 if(!itr)
309 {
310 PRINT_HERE("[%s] Warning! Invalid iterator!",
311 demangle<Type>().c_str());
312 continue;
313 }
314 // skip if invalid
315 if(operation::get_is_invalid<Type, false>{}(itr->data()))
316 continue;
317 if(itr->depth() > _min)
318 {
319 auto _depth = itr->depth() - (_min + 1);
320 auto _prefix = _compute_modified_prefix(*itr);
321 auto _rolling = itr->id();
322 auto _stats = itr->stats();
323 auto _parent = graph_type::parent(itr);
324 auto _hierarchy = hierarchy_type{};
325 auto _tid = itr->tid();
326 auto _pid = itr->pid();
327 while(_parent && _parent->depth() > _min)
328 {
329 if(operation::get_is_invalid<Type, false>{}(_parent->data()))
330 break;
331 _hierarchy.push_back(_parent->id());
332 _rolling += _parent->id();
333 _parent = graph_type::parent(_parent);
334 }
335 if(_hierarchy.size() > 1)
336 std::reverse(_hierarchy.begin(), _hierarchy.end());
337 _hierarchy.push_back(itr->id());
338 auto _entry = result_node(itr->id(), itr->obj(), _prefix, _depth,
339 _rolling, _hierarchy, _stats, _tid, _pid);
340 _list.push_back(std::move(_entry));
341 }
342 }
343 }
344
345 // if collapse is disabled or thread-scope only, there is nothing to merge
346 if(!settings::collapse_threads() || _thread_scope_only)
347 return _list;
348
349 result_type _combined{};
350 operation::finalize::merge<Type, true>(_combined, _list);
351 return _combined;
352 };
353
354 ret = convert_graph();
355 return ret;
356}
static int32_t get_thread_count()
This effectively provides the total number of threads which collected data. It is only "decremented" ...
Definition: manager.hpp:182
::tim::statistics< Tp > max(::tim::statistics< Tp > lhs, const Tp &rhs)
Definition: statistics.hpp:320
char const std::string & _prefix
Definition: config.cpp:55
node_count
Definition: settings.cpp:1780
collapse_threads
Definition: settings.cpp:1637
std::string demangle(const char *_mangled_name, int *_status=nullptr)
Definition: demangle.hpp:47
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
collapse_processes
Definition: settings.cpp:1639
typename storage_type::result_array_t result_type
Definition: get.hpp:61
typename storage_type::graph_node graph_node
Definition: get.hpp:65
typename storage_type::result_node result_node
Definition: get.hpp:63
typename storage_type::uintvector_t hierarchy_type
Definition: get.hpp:66
#define PRINT_HERE(...)
Definition: macros.hpp:152

References tim::_prefix, tim::collapse_processes, tim::collapse_threads, tim::debug, tim::demangle(), tim::manager::get_thread_count(), std::max(), tim::node_count, PRINT_HERE, and tim::width.

◆ operator()() [5/5]

template<typename Type >
std::vector< basic_tree_vector_type > & tim::operation::finalize::get< Type, true >::operator() ( std::vector< basic_tree_vector_type > &  _data)
inline

Definition at line 83 of file get.hpp.

85 {
87 (*this)(_obj);
88 _data.emplace_back(_obj);
89 return _data;
90 }

Member Data Documentation

◆ value

template<typename Type >
constexpr bool tim::operation::finalize::get< Type, true >::value = true
staticconstexpr

Definition at line 59 of file get.hpp.


The documentation for this struct was generated from the following file: