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::data::stream Struct Reference

#include "timemory/data/stream.hpp"

+ Collaboration diagram for tim::data::stream:

Public Types

template<typename T >
using set_t = std::set< T >
 
template<typename K , typename M >
using map_t = std::map< K, M >
 
template<typename K , typename M >
using pair_t = std::pair< K, M >
 
template<typename T >
using vector_t = std::vector< T >
 
using string_t = std::string
 
using stringstream_t = std::stringstream
 
using format_flags = std::ios_base::fmtflags
 
using order_map_t = vector_t< string_t >
 
using header_col_t = vector_t< header >
 
using entry_col_t = vector_t< entry >
 
using header_pair_t = pair_t< string_t, header_col_t >
 
using entry_pair_t = pair_t< string_t, entry_col_t >
 
using header_map_t = vector_t< header_pair_t >
 
using entry_map_t = vector_t< entry_pair_t >
 
using break_set_t = set_t< int >
 

Public Member Functions

 stream (char _delim='|', char _fill='-', format_flags _fmt={}, int _width=0, int _prec=0, bool _center=false)
 
bool center () const
 
int precision () const
 
int width () const
 
char delim () const
 
format_flags flags () const
 
int64_t freq () const
 
void center (bool v)
 
void precision (int v)
 
void width (int v)
 
void delim (char v)
 
void setf (format_flags v)
 
void setfreq (int64_t v)
 
void set_name (string_t v)
 
void set_banner (string_t v)
 
void set_prefix_begin (int val=-1)
 
void set_prefix_end (int val=-1)
 
void insert_break (int val=-1)
 
void operator() (header _hdr)
 
void operator() (entry _obj)
 
template<typename StreamT >
void write_separator (StreamT &os, char _delim) const
 
template<typename StreamT >
void write_banner (StreamT &os) const
 
void clear ()
 
headerget_header (const string_t &_key, int64_t _n)
 
int add_row ()
 indicate that a row of data has been finished More...
 
void sort (const std::function< bool(const std::string &, const std::string &)> &sorter, std::vector< std::string > keys={}, const std::set< std::string > &exclude={})
 Provide a. More...
 

Static Public Member Functions

static int64_t & separator_frequency ()
 
static int64_t index (const string_t &_val, const vector_t< string_t > &_obj)
 
static int64_t insert (const string_t &_val, vector_t< string_t > &_obj)
 
template<typename Tp >
static int64_t index (const string_t &_val, const vector_t< pair_t< string_t, vector_t< Tp > > > &_obj)
 
template<typename Tp >
static int64_t insert (const string_t &_val, vector_t< pair_t< string_t, vector_t< Tp > > > &_obj)
 
template<typename... Tp, template< typename... > class _Tuple, size_t... Idx>
static void write (stream &, const _Tuple< Tp... > &, index_sequence< Idx... >)
 

Friends

std::ostream & operator<< (std::ostream &os, const stream &obj)
 

Detailed Description

Definition at line 268 of file stream.hpp.

Member Typedef Documentation

◆ break_set_t

Definition at line 295 of file stream.hpp.

◆ entry_col_t

Definition at line 288 of file stream.hpp.

◆ entry_map_t

Definition at line 294 of file stream.hpp.

◆ entry_pair_t

◆ format_flags

using tim::data::stream::format_flags = std::ios_base::fmtflags

Definition at line 284 of file stream.hpp.

◆ header_col_t

Definition at line 287 of file stream.hpp.

◆ header_map_t

◆ header_pair_t

◆ map_t

template<typename K , typename M >
using tim::data::stream::map_t = std::map<K, M>

Definition at line 274 of file stream.hpp.

◆ order_map_t

Definition at line 285 of file stream.hpp.

◆ pair_t

template<typename K , typename M >
using tim::data::stream::pair_t = std::pair<K, M>

Definition at line 277 of file stream.hpp.

◆ set_t

template<typename T >
using tim::data::stream::set_t = std::set<T>

Definition at line 271 of file stream.hpp.

◆ string_t

using tim::data::stream::string_t = std::string

Definition at line 282 of file stream.hpp.

◆ stringstream_t

using tim::data::stream::stringstream_t = std::stringstream

Definition at line 283 of file stream.hpp.

◆ vector_t

template<typename T >
using tim::data::stream::vector_t = std::vector<T>

Definition at line 280 of file stream.hpp.

Constructor & Destructor Documentation

◆ stream()

tim::data::stream::stream ( char  _delim = '|',
char  _fill = '-',
format_flags  _fmt = {},
int  _width = 0,
int  _prec = 0,
bool  _center = false 
)
inlineexplicit

Definition at line 301 of file stream.hpp.

301 {},
302 int _width = 0, int _prec = 0, bool _center = false)
303 : m_center(_center)
304 , m_fill(_fill)
305 , m_delim(_delim)
306 , m_width(_width)
307 , m_precision(_prec)
308 , m_format(_fmt)
309 {}

Member Function Documentation

◆ add_row()

int tim::data::stream::add_row ( )
inline

indicate that a row of data has been finished

Definition at line 693 of file stream.hpp.

694 {
695 m_cols = 0;
696 return ++m_rows;
697 }

Referenced by tim::operation::finalize::print< Tp, true >::write_stream().

◆ center() [1/2]

bool tim::data::stream::center ( ) const
inline

Definition at line 311 of file stream.hpp.

311{ return m_center; }

◆ center() [2/2]

void tim::data::stream::center ( bool  v)
inline

Definition at line 318 of file stream.hpp.

318{ m_center = v; }

◆ clear()

void tim::data::stream::clear ( )
inline

Definition at line 665 of file stream.hpp.

666 {
667 m_name = "";
668 m_headers.clear();
669 m_entries.clear();
670 }

◆ delim() [1/2]

char tim::data::stream::delim ( ) const
inline

Definition at line 314 of file stream.hpp.

314{ return m_delim; }

◆ delim() [2/2]

void tim::data::stream::delim ( char  v)
inline

Definition at line 321 of file stream.hpp.

321{ m_delim = v; }

◆ flags()

format_flags tim::data::stream::flags ( ) const
inline

Definition at line 315 of file stream.hpp.

315{ return m_format; }

◆ freq()

int64_t tim::data::stream::freq ( ) const
inline

Definition at line 316 of file stream.hpp.

316{ return m_separator_freq; }

◆ get_header()

header & tim::data::stream::get_header ( const string_t _key,
int64_t  _n 
)
inline

Definition at line 672 of file stream.hpp.

673 {
674 auto idx = index(_key, m_headers);
675 if(idx < 0)
676 {
678 ss << "Missing header '" << _key << "'";
679 throw std::runtime_error(ss.str());
680 }
681
682 if(!(_n < (int64_t) m_headers[idx].second.size()))
683 {
684 auto _size = m_headers[idx].second.size();
685 return m_headers[idx].second[_n % _size];
686 }
687
688 return m_headers[idx].second[_n];
689 }
static int64_t index(const string_t &_val, const vector_t< string_t > &_obj)
Definition: stream.hpp:330
std::stringstream stringstream_t
Definition: stream.hpp:283

References index().

Referenced by tim::data::write_entry().

◆ index() [1/2]

template<typename Tp >
static int64_t tim::data::stream::index ( const string_t _val,
const vector_t< pair_t< string_t, vector_t< Tp > > > &  _obj 
)
inlinestatic

Definition at line 354 of file stream.hpp.

356 {
357 for(size_t i = 0; i < _obj.size(); ++i)
358 {
359 if(_obj.at(i).first == _val)
360 return static_cast<int64_t>(i);
361 }
362 return -1;
363 }

◆ index() [2/2]

static int64_t tim::data::stream::index ( const string_t _val,
const vector_t< string_t > &  _obj 
)
inlinestatic

Definition at line 330 of file stream.hpp.

331 {
332 for(size_t i = 0; i < _obj.size(); ++i)
333 {
334 if(_obj.at(i) == _val)
335 return static_cast<int64_t>(i);
336 }
337 return -1;
338 }

Referenced by get_header(), insert(), operator()(), write_banner(), and write_separator().

◆ insert() [1/2]

template<typename Tp >
static int64_t tim::data::stream::insert ( const string_t _val,
vector_t< pair_t< string_t, vector_t< Tp > > > &  _obj 
)
inlinestatic

Definition at line 366 of file stream.hpp.

368 {
369 auto idx = index(_val, _obj);
370 if(idx < 0)
371 {
372 idx = _obj.size();
373 _obj.resize(_obj.size() + 1);
374 _obj[idx].first = _val;
375 if(settings::debug())
376 printf("[%s]> inserted '%s'...\n", demangle<Tp>().c_str(), _val.c_str());
377 }
378 return idx;
379 }

References tim::debug, and index().

◆ insert() [2/2]

static int64_t tim::data::stream::insert ( const string_t _val,
vector_t< string_t > &  _obj 
)
inlinestatic

Definition at line 340 of file stream.hpp.

341 {
342 auto idx = index(_val, _obj);
343 if(idx < 0)
344 {
345 idx = _obj.size();
346 _obj.push_back(_val);
347 if(settings::debug())
348 printf("> inserted '%s'...\n", _val.c_str());
349 }
350 return idx;
351 }

References tim::debug, and index().

Referenced by operator()().

◆ insert_break()

void tim::data::stream::insert_break ( int  val = -1)
inline

Definition at line 391 of file stream.hpp.

392 {
393 m_break.insert((val < 0) ? ((int) m_order.size()) : val);
394 }

Referenced by tim::operation::print_header< Tp >::print_header().

◆ operator()() [1/2]

void tim::data::stream::operator() ( entry  _obj)
inline

Definition at line 413 of file stream.hpp.

414 {
415 if(_obj.get().empty() && !_obj.permit_empty())
416 throw std::runtime_error("Entry has no value");
417
418 auto _w = std::max<int>(m_width, _obj.get().length() + 2);
419 _w = std::max<int>(_w, _obj.get_header().width());
420
421 _obj.width(_w);
422 _obj.get_header().width(_w);
423
424 auto _o = index(m_name, m_order);
425 if(_o < 0)
426 throw std::runtime_error(string_t("Missing entry for ") + m_name);
427
428 auto _r = insert(m_name, m_entries);
429 _obj.center(false);
430 _obj.row(m_rows + 1);
431 _obj.column(m_cols);
432 m_entries[_r].second.push_back(_obj);
433 ++m_cols;
434 }
static int64_t insert(const string_t &_val, vector_t< string_t > &_obj)
Definition: stream.hpp:340
std::string string_t
Definition: stream.hpp:282

References tim::data::base::stream_entry::center(), tim::data::base::stream_entry::column(), tim::data::base::stream_entry::get(), tim::data::entry::get_header(), index(), insert(), tim::data::entry::permit_empty(), tim::data::base::stream_entry::row(), tim::data::base::stream_entry::width(), and tim::data::entry::width().

◆ operator()() [2/2]

void tim::data::stream::operator() ( header  _hdr)
inline

Definition at line 396 of file stream.hpp.

397 {
398 if(_hdr.get().empty())
399 throw std::runtime_error("Header has no value");
400
401 auto _w = std::max<int>(m_width, _hdr.get().length() + 2);
402 _hdr.width(_w);
403
404 m_order.push_back(m_name);
405 auto _h = insert(m_name, m_headers);
406 auto _n = m_headers[_h].second.size();
407 _hdr.center(true);
408 _hdr.row(0);
409 _hdr.column(_n);
410 m_headers[_h].second.push_back(_hdr);
411 }

References tim::data::base::stream_entry::center(), tim::data::base::stream_entry::column(), tim::data::base::stream_entry::get(), insert(), tim::data::base::stream_entry::row(), and tim::data::base::stream_entry::width().

◆ precision() [1/2]

int tim::data::stream::precision ( ) const
inline

Definition at line 312 of file stream.hpp.

312{ return m_precision; }

◆ precision() [2/2]

void tim::data::stream::precision ( int  v)
inline

Definition at line 319 of file stream.hpp.

319{ m_precision = v; }

◆ separator_frequency()

static int64_t & tim::data::stream::separator_frequency ( )
inlinestatic

Definition at line 298 of file stream.hpp.

separator_frequency
Definition: settings.cpp:1785

References tim::separator_frequency.

◆ set_banner()

void tim::data::stream::set_banner ( string_t  v)
inline

Definition at line 328 of file stream.hpp.

328{ m_banner = v; }

◆ set_name()

void tim::data::stream::set_name ( string_t  v)
inline

Definition at line 326 of file stream.hpp.

326{ m_name = v; }

Referenced by tim::data::write_entry().

◆ set_prefix_begin()

void tim::data::stream::set_prefix_begin ( int  val = -1)
inline

Definition at line 381 of file stream.hpp.

382 {
383 m_prefix_begin = (val < 0) ? ((int) m_order.size()) : val;
384 }

Referenced by tim::operation::print_header< Tp >::print_header().

◆ set_prefix_end()

void tim::data::stream::set_prefix_end ( int  val = -1)
inline

Definition at line 386 of file stream.hpp.

387 {
388 m_prefix_end = (val < 0) ? ((int) m_order.size()) : val;
389 }

Referenced by tim::operation::print_header< Tp >::print_header().

◆ setf()

void tim::data::stream::setf ( format_flags  v)
inline

Definition at line 322 of file stream.hpp.

322{ m_format = v; }

◆ setfreq()

void tim::data::stream::setfreq ( int64_t  v)
inline

Definition at line 323 of file stream.hpp.

323{ m_separator_freq = v; }

◆ sort()

void tim::data::stream::sort ( const std::function< bool(const std::string &, const std::string &)> &  sorter,
std::vector< std::string >  keys = {},
const std::set< std::string > &  exclude = {} 
)
inline

Provide a.

Parameters
sorterfunctor that operates on all or a specific set of header keys. If
keysis empty, all header keys are sorted. If
keysis non-empty, the sorted keys are placed at the front of the container and any remaining keys not list in
excludewill be added to the end of the container in the order consistent with the origial construction

Definition at line 705 of file stream.hpp.

706 {},
707 const std::set<std::string>& exclude = {})
708 {
709 // if no keys were provided, add all of them
710 if(keys.empty())
711 {
712 for(const auto& itr : m_order)
713 keys.push_back(itr);
714 }
715
716 // the new headers
717 order_map_t _order{};
718
719 // sort the keys
720 std::sort(keys.begin(), keys.end(), sorter);
721
722 // generate the new layout in the order specified
723 for(const auto& itr : keys)
724 {
725 bool found = false;
726 for(auto hitr = m_order.begin(); hitr != m_order.end(); ++hitr)
727 {
728 if(*hitr == itr)
729 {
730 _order.push_back(*hitr);
731 // remove entry
732 m_order.erase(hitr);
733 found = true;
734 break;
735 }
736 }
737 if(!found)
738 {
739 PRINT_HERE("Warning! Expected header tag '%s' not found when sorting",
740 itr.c_str());
741 }
742 }
743
744 // insert any remaining not excluded
745 for(const auto& itr : m_order)
746 {
747 if(exclude.count(itr) == 0)
748 _order.push_back(itr);
749 }
750
751 // set the new headers
752 m_order = _order;
753 }
vector_t< string_t > order_map_t
Definition: stream.hpp:285
#define PRINT_HERE(...)
Definition: macros.hpp:152

◆ width() [1/2]

int tim::data::stream::width ( ) const
inline

Definition at line 313 of file stream.hpp.

313{ return m_width; }

◆ width() [2/2]

void tim::data::stream::width ( int  v)
inline

Definition at line 320 of file stream.hpp.

320{ m_width = v; }

◆ write()

template<typename... Tp, template< typename... > class _Tuple, size_t... Idx>
static void tim::data::stream::write ( stream ,
const _Tuple< Tp... > &  ,
index_sequence< Idx... >   
)
static

◆ write_banner()

template<typename StreamT >
void tim::data::stream::write_banner ( StreamT &  os) const
inline

Definition at line 589 of file stream.hpp.

590 {
591 if(m_banner.length() == 0)
592 return;
593
594 write_separator(os, '-');
595
596 map_t<string_t, int> offset;
597
598 int64_t tot_w = 0;
599 int64_t norder_col = 0;
600 for(const auto& _key : m_order)
601 {
602 int64_t col = ++norder_col;
603 auto _offset = offset[_key]++;
604 auto _hidx = index(_key, m_headers);
605 assert(_hidx >= 0);
606 const auto& _hitr = m_headers[_hidx].second;
607 auto _hsize = _hitr.size();
608 const auto& _hdr = _hitr.at(_offset % _hsize);
609 tot_w += _hdr.width() + 1;
610 if(m_break.count(col) > 0)
611 break;
612 }
613
614 auto _trim = [&](string_t _banner) {
615 // trim the banner
616 if(_banner.length() > static_cast<size_t>(tot_w))
617 {
618 auto _hlen = (tot_w / 2) - 4; // half-length
619 auto _beg = _banner.substr(0, _hlen);
620 auto _end = _banner.substr(_banner.length() - _hlen);
621 _banner = _beg + "..." + _end;
622 }
623 return _banner;
624 };
625
626 auto _delim = delimit(m_banner, " \t");
627 std::vector<std::string> r_banner(1, "");
628 for(auto itr : _delim)
629 {
630 itr = _trim(itr);
631 auto nlen = r_banner.back().length() + itr.length() + 2;
632 if(nlen >= static_cast<size_t>(tot_w))
633 r_banner.emplace_back("");
634 if(r_banner.back().empty())
635 {
636 r_banner.back() += itr;
637 }
638 else
639 {
640 r_banner.back() += " " + itr;
641 }
642 }
643
645
646 auto _write_row = [&](const string_t& _banner) {
647 auto obeg = tot_w / 2;
648 obeg -= _banner.length() / 2;
649 obeg += _banner.length();
650 auto oend = tot_w - obeg;
651
652 ss << m_delim << std::setw(obeg) << std::right << _banner << std::setw(oend)
653 << std::right << m_delim << '\n';
654 };
655
656 for(const auto& itr : r_banner)
657 _write_row(itr);
658
659 os << ss.str();
660 }
std::string string_t
Definition: library.cpp:57
const std::string std::ostream * os
ContainerT delimit(const std::string &line, const std::string &delimiters="\"',;: ", PredicateT &&predicate=[](const std::string &s) -> std::string { return s;})
Definition: delimit.hpp:68
void write_separator(StreamT &os, char _delim) const
Definition: stream.hpp:554

References tim::delimit(), index(), tim::os, and write_separator().

◆ write_separator()

template<typename StreamT >
void tim::data::stream::write_separator ( StreamT &  os,
char  _delim 
) const
inline

Definition at line 554 of file stream.hpp.

555 {
556 map_t<string_t, int> offset;
558 ss.fill(m_fill);
559
560 int64_t norder_col = 0;
561 for(const auto& _key : m_order)
562 {
563 int64_t col = ++norder_col;
564 stringstream_t _ss;
565 auto _offset = offset[_key]++;
566 auto _hidx = index(_key, m_headers);
567 assert(_hidx >= 0);
568 const auto& _hitr = m_headers[_hidx].second;
569 auto _hsize = _hitr.size();
570 const auto& _hdr = _hitr.at(_offset % _hsize);
571 auto _w = _hdr.width();
572 if(col == 1)
573 {
574 ss << m_delim << std::setw(_w) << "";
575 }
576 else
577 {
578 ss << _delim << std::setw(_w) << "";
579 }
580 if(m_break.count(col) > 0)
581 break;
582 }
583
584 ss << m_delim << '\n';
585 os << ss.str();
586 }

References index(), and tim::os.

Referenced by write_banner().

Friends And Related Function Documentation

◆ operator<<

std::ostream & operator<< ( std::ostream &  os,
const stream obj 
)
friend

Definition at line 436 of file stream.hpp.

437 {
438 // return if completely empty
439 if(obj.m_headers.empty())
440 return os;
441
442 // return if not entries
443 if(obj.m_entries.empty())
444 return os;
445
447 map_t<string_t, int> offset;
448
449 obj.write_banner(ss);
450
451 obj.write_separator(ss, '-');
452
453 int64_t norder_col = 0;
454 for(const auto& itr : obj.m_order)
455 {
456 int64_t col = ++norder_col;
457
458 stringstream_t _ss;
459 // NOLINTNEXTLINE
460 auto _key = itr;
461 auto _offset = offset[_key]++;
462 auto _idx = index(_key, obj.m_headers);
463 if(_idx < 0 ||
464 (_idx >= 0 && !(_offset < (int) obj.m_headers[_idx].second.size())))
465 {
466 throw std::runtime_error("Error! indexing issue!");
467 }
468
469 const auto& hitr = obj.m_headers[_idx].second.at(_offset);
470 base::write_entry(_ss, hitr);
471
472 ss << obj.delim() << ' ' << _ss.str() << ' ';
473
474 if(obj.m_break.count(col) > 0)
475 break;
476 }
477
478 // end the line
479 ss << obj.delim() << '\n';
480
481 obj.write_separator(ss, obj.m_delim);
482
483 auto write_empty = [&](stringstream_t& _ss, int64_t _hidx, int64_t _offset) {
484 const auto& _hitr = obj.m_headers[_hidx].second;
485 auto _hsize = _hitr.size();
486 const auto& _hdr = _hitr.at(_offset % _hsize);
487 _ss << obj.delim() << ' ' << std::setw(_hdr.width() - 2) << "" << ' ';
488 };
489
490 offset.clear();
491
492 for(int i = 0; i < obj.m_rows; ++i)
493 {
494 bool just_broke = false;
495 norder_col = 0;
496 for(const auto& itr : obj.m_order)
497 {
498 just_broke = false;
499 int64_t col = ++norder_col;
500
501 stringstream_t _ss;
502 auto _key = itr; // NOLINT
503 auto _offset = offset[_key]++;
504
505 auto _hidx = index(_key, obj.m_headers);
506 auto _eidx = index(_key, obj.m_entries);
507
508 if(_eidx < 0 && _hidx >= 0)
509 {
510 write_empty(ss, _hidx, _offset);
511 }
512 else
513 {
514 assert(_hidx >= 0);
515 assert(_eidx >= 0);
516
517 const auto& _eitr = obj.m_entries[_eidx].second;
518 auto _esize = _eitr.size();
519 const auto& _itr = _eitr.at(_offset % _esize);
520
521 base::write_entry(_ss, _itr);
522 ss << obj.delim() << ' ' << _ss.str() << ' ';
523 }
524
525 // printf("column: %i, order size: %i, count: %i\n", col,
526 // obj.m_order.size(),
527 // obj.m_break.count(col));
528 if(col < (int64_t) obj.m_order.size() && obj.m_break.count(col) > 0)
529 {
530 ss << obj.m_delim << '\n';
531 just_broke = true;
532 for(auto j = obj.m_prefix_begin; j < obj.m_prefix_end; ++j)
533 write_empty(ss, j, 0);
534 }
535 }
536 if(!just_broke)
537 ss << obj.m_delim << '\n';
538
539 if(obj.m_separator_freq > 0)
540 {
541 if((i + 1) < obj.m_rows &&
542 (i % obj.m_separator_freq) == (obj.m_separator_freq - 1))
543 obj.write_separator(ss, obj.m_delim);
544 }
545 }
546
547 obj.write_separator(ss, '-');
548
549 os << ss.str();
550 return os;
551 }

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