53#if defined(TIMEMORY_OPERATIONS_SOURCE) || !defined(TIMEMORY_USE_OPERATIONS_EXTERN)
62 auto plot_label =
label;
95 if(outfname.length() > 0 &&
stream)
100 printf(
"[%s]|%i> Outputting '%s'...\n", label.c_str(), node_rank,
107 fprintf(stderr,
"[storage<%s>::%s @ %i]|%i> Error opening '%s'...\n",
108 label.c_str(), __FUNCTION__, __LINE__, node_rank, outfname.c_str());
117template <
typename Tp>
123 node_init = dmp::is_initialized();
124 node_rank = dmp::rank();
125 node_size = dmp::size();
126 node_results = data->dmp_get();
128 node_tree = data->dmp_get(node_tree);
131 settings::indent_width<Tp, 0>(Tp::get_width());
132 settings::indent_width<Tp, 1>(4);
133 settings::indent_width<Tp, 2>(4);
140 for(
const auto& mitr : node_results)
142 for(
const auto& itr : mitr)
144 const auto& itr_obj = itr.data();
145 const auto& itr_prefix = itr.prefix();
146 const auto& itr_depth = itr.depth();
148 if(itr_depth < 0 || itr_depth > m_settings->get_max_depth() ||
149 itr_depth > max_call_stack)
155 settings::indent_width<Tp, 0>(itr_prefix.length());
156 settings::indent_width<Tp, 1>(std::log10(itr_obj.get_laps()) + 1);
157 settings::indent_width<Tp, 2>(std::log10(itr_depth) + 1);
164template <
typename Tp>
168 settings::indent_width<Tp, 0>(Tp::get_width());
169 settings::indent_width<Tp, 1>(4);
170 settings::indent_width<Tp, 2>(4);
177 for(
const auto& mitr : node_results)
179 for(
const auto& itr : mitr)
181 const auto& itr_obj = itr.data();
182 const auto& itr_prefix = itr.prefix();
183 const auto& itr_depth = itr.depth();
185 if(itr_depth < 0 || itr_depth > m_settings->get_max_depth() ||
186 itr_depth > max_call_stack)
192 settings::indent_width<Tp, 0>(itr_prefix.length());
193 settings::indent_width<Tp, 1>(std::log10(itr_obj.get_laps()) + 1);
194 settings::indent_width<Tp, 2>(std::log10(itr_depth) + 1);
199 std::cout <<
"Checking for existing input at " << fname <<
"...\n";
200 std::ifstream inpf(fname.c_str());
201 auto success = inpf.is_open();
207 auto extensions =
tim::delimit(m_settings->get_input_extensions(),
",; ");
213 if(m_settings->get_diff_output())
215 extensions.insert(extensions.begin(), fext);
216 for(
const auto& itr : extensions)
219 if(file_exists(inpfname))
221 json_inpfname = inpfname;
227 if(!json_inpfname.empty())
232 if(m_settings->get_debug())
234 printf(
"difference filenames: '%s' and '%s'\n", json_diffname.c_str(),
235 text_diffname.c_str());
242 write_stream(data_stream, node_results);
245 if(!node_delta.empty())
247 write_stream(diff_stream, node_delta);
248 std::stringstream ss;
250 diff_stream->set_banner(ss.str());
256template <
typename Tp>
260 auto stream_fmt = Tp::get_format_flags();
261 auto stream_width = Tp::get_width();
262 auto stream_prec = Tp::get_precision();
264 stream = std::make_shared<utility::stream>(
'|',
'-', stream_fmt, stream_width,
267 using get_return_type =
decltype(std::declval<const Tp>().get());
274 auto result = get_flattened(result_array);
275 for(
auto itr = result.begin(); itr != result.end(); ++itr)
277 auto& itr_obj = (*itr)->data();
278 auto& itr_prefix = (*itr)->prefix();
279 auto& itr_depth = (*itr)->depth();
280 auto itr_laps = itr_obj.get_laps();
282 if(itr_depth < 0 || itr_depth > get_max_depth())
286 int64_t nexclusive = 0;
288 get_return_type exclusive_values{};
296 std::advance(eitr, 1);
300 exclusive_values = get_return_type{};
303 if(eitr != result.end())
305 auto eitr_depth = (*eitr)->depth();
306 while(eitr_depth != itr_depth)
308 auto& eitr_obj = (*eitr)->data();
311 if(eitr_depth == itr_depth + 1)
316 exclusive_values = eitr_obj.get();
327 if(eitr == result.end())
329 eitr_depth = (*eitr)->depth();
335 auto itr_stats = (*itr)->stats();
337 bool _first = std::distance(result.begin(), itr) == 0;
342 itr_self, itr_stats);
350template <
typename Tp>
355 node_init = dmp::is_initialized();
356 node_rank = dmp::rank();
357 node_size = dmp::size();
358 node_results = data->dmp_get();
360 node_tree = data->dmp_get(node_tree);
363 if(m_settings->get_debug())
365 printf(
"[%s]|%i> dmp results size: %i\n", label.c_str(), node_rank,
366 (
int) node_results.size());
373 if(!node_input.empty() && node_rank == 0)
375 node_delta.resize(node_input.size());
377 size_t num_ranks = std::min<size_t>(node_input.size(), node_results.size());
379 for(
size_t i = 0; i < num_ranks; ++i)
381 for(
auto& iitr : node_input.at(i))
383 for(
auto& ritr : node_results.at(i))
387 node_delta.at(i).push_back(ritr);
388 node_delta.at(i).back() -= iitr;
394 write_stream(diff_stream, node_delta);
395 std::stringstream ss;
397 diff_stream->set_banner(ss.str());
401 if(m_settings->get_debug() && m_settings->get_verbose() > 3)
403 auto indiv_results = get_flattened(node_results);
406 for(
const auto& itr : indiv_results)
407 w = std::max<size_t>(w, data->get_prefix(itr->hash()).length());
408 for(
const auto& itr : indiv_results)
410 std::cout << std::setw(w) << std::left << data->get_prefix(itr->hash())
411 <<
" : " << itr->data();
412 auto _hierarchy = itr->hierarchy();
413 for(
size_t i = 0; i < _hierarchy.size(); ++i)
417 std::cout << data->get_prefix(_hierarchy[i]);
418 if(i + 1 < _hierarchy.size())
421 std::cout << std::endl;
433template <
typename Tp>
438 if(outfname.length() > 0)
443 auto fext = outfname.substr(outfname.find_last_of(
'.') + 1);
447 printf(
"[%s]|%i> Outputting '%s'...\n", label.c_str(), node_rank,
453 oa->setNextName(
"timemory");
460 fprintf(stderr,
"[storage<%s>::%s @ %i]|%i> Error opening '%s'...\n",
461 label.c_str(), __FUNCTION__, __LINE__, node_rank, outfname.c_str());
472template <
typename Tp>
478 if(outfname.length() > 0)
480 auto fext = outfname.substr(outfname.find_last_of(
'.') + 1);
484 printf(
"[%s]|%i> Outputting '%s'...\n", label.c_str(), node_rank,
492 oa->setNextName(
"timemory");
499 fprintf(stderr,
"[storage<%s>::%s @ %i]|%i> Error opening '%s'...\n",
500 label.c_str(), __FUNCTION__, __LINE__, node_rank, outfname.c_str());
510template <
typename Tp>
514 using strvector_t = std::vector<std::string>;
517 if(m_settings->get_dart_type().length() > 0)
519 auto dtype = m_settings->get_dart_type();
529 auto indiv_results = get_flattened(node_results);
530 for(
auto& itr : indiv_results)
532 auto& itr_depth = itr->depth();
534 if(itr_depth < 0 || itr_depth >
max_depth)
538 if(m_settings->get_dart_count() > 0 && _nitr >= m_settings->get_dart_count())
541 auto& itr_obj = itr->data();
542 auto& itr_hierarchy = itr->hierarchy();
543 strvector_t str_hierarchy{};
544 for(
const auto& hitr : itr_hierarchy)
545 str_hierarchy.push_back(data->get_prefix(hitr));
553template <
typename Tp>
559 if(json_inpfname.length() > 0)
561 std::ifstream ifs(json_inpfname.c_str());
564 printf(
"[%s]|%i> Reading '%s'...\n", label.c_str(), node_rank,
565 json_inpfname.c_str());
572 ia->setNextName(
"timemory");
576 }
catch(tim::cereal::Exception& e)
578 PRINT_HERE(
"Exception reading %s :: %s", json_inpfname.c_str(), e.what());
579#if defined(TIMEMORY_INTERNAL_TESTING)
581 throw std::runtime_error(
"error reading json");
587 fprintf(stderr,
"[%s]|%i> Failure opening '%s' for input...\n", label.c_str(),
588 node_rank, json_inpfname.c_str());
589#if defined(TIMEMORY_INTERNAL_TESTING)
590 throw std::runtime_error(
"error opening file");
static pointer_t instance()
Get a shared pointer to the instance for the current thread.
The declaration for the types for manager without definitions.
bool open(std::ofstream &_ofs, std::string _fpath, Args &&... _args)
Tp & plus(Tp &, const Up &)
Tp percent_diff(const Tp &, const Tp &)
TIMEMORY_OPERATIONS_LINKAGE(void) base
This operation class echoes DartMeasurements for a CDash dashboard.
void plot(const std::string &_label, const std::string &_prefix, const std::string &_dir, bool _echo_dart, const std::string &_json_file)
MutexT & type_mutex(uint64_t _n=0)
A simple way to get a mutex for a class or common behavior, e.g. type_mutex<decltype(std::cout)>() pr...
std::unique_lock< mutex_t > auto_lock_t
Unique lock type around mutex_t.
char argparse::argument_parser tim::settings * _settings
tim::mpl::apply< std::string > string
const std::string std::ostream * os
auto get(const auto_bundle< Tag, Types... > &_obj)
description("A generic option for any setting. Each argument MUST be passed in " "form: 'NAME=VALUE'. E.g. --timemory-args " "\"papi_events=PAPI_TOT_INS,PAPI_TOT_CYC\" text_output=off") .action([&](parser_t &p)
ContainerT delimit(const std::string &line, const std::string &delimiters="\"',;: ", PredicateT &&predicate=[](const std::string &s) -> std::string { return s;})
The declaration for the types for operations without definitions.
Include the macros for operations.
Declare the operations types.
int add_row()
indicate that a row of data has been finished
Struct for performing math operations on complex data structures without using globally overload oper...
std::shared_ptr< settings > settings_t
virtual void print_cout(stream_type stream)
std::shared_ptr< utility::stream > stream_type
virtual void print_plot(const std::string &fname, std::string suffix)
virtual void write(std::ostream &os, stream_type stream)
print(bool _forced_json=false, settings_t _settings=settings::shared_instance())
virtual void print_text(const std::string &fname, stream_type stream)
impl::storage< Tp, has_data > storage_type
typename storage_type::dmp_result_t result_type
std::map< std::string, std::vector< basic_tree_vector_type > > result_tree
print routines for individual components
Provides a static get() function which return a shared pointer to an instance of the given archive fo...
static string_t compose_output_filename(string_t _tag, string_t _ext, bool _use_suffix=use_output_suffix(), int32_t _suffix=default_process_suffix(), bool _make_dir=false, std::string _explicit={})
static string_t compose_input_filename(string_t _tag, string_t _ext, bool _use_suffix=use_output_suffix(), int32_t _suffix=default_process_suffix(), std::string _explicit={})
Extension for the input or output archive types. It will throw an error if used on new archive types ...
#define TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE(CONDITION, DEPTH)