28#include "timemory/backends/dmp.hpp"
29#include "timemory/backends/process.hpp"
30#include "timemory/backends/threading.hpp"
39#include "timemory/tpls/cereal/cereal.hpp"
45#include <unordered_map>
48#if defined(TIMEMORY_UNIX)
78 uint64_t, size_t, float,
double>;
82 using data_type = std::unordered_map<string_view_t, value_type>;
87 template <
typename Tp,
typename Vp>
90 template <
typename Tag = TIMEMORY_API>
92 template <
typename Tag>
247 static
strvector_t& command_line() TIMEMORY_VISIBILITY("default");
254 get_env<bool>(
"TIMEMORY_USE_OUTPUT_SUFFIX",
false))
255#if defined(TIMEMORY_USE_MPI) || defined(TIMEMORY_USE_UPCXX)
261 static strvector_t get_global_environment() TIMEMORY_VISIBILITY("default");
266 TIMEMORY_VISIBILITY("default");
269 bool _use_suffix = use_output_suffix(),
271 bool _make_dir =
false,
272 std::
string _explicit = {})
273 TIMEMORY_VISIBILITY(
"default");
275 bool _use_suffix = use_output_suffix(),
278 TIMEMORY_VISIBILITY(
"default");
281 TIMEMORY_VISIBILITY("default");
283 static
void parse(const
std::shared_ptr<
settings>&) TIMEMORY_VISIBILITY("default");
286 TIMEMORY_VISIBILITY("hidden");
288 std::
string _ext) TIMEMORY_VISIBILITY("hidden");
292 void load(Archive& ar,
unsigned int);
295 void save(Archive& ar,
unsigned int) const;
310 template <
size_t Idx = 0>
312 TIMEMORY_VISIBILITY("default");
314 template <
typename Tp,
size_t Idx = 0>
316 TIMEMORY_VISIBILITY("default");
327 template <
typename Sp =
string_t>
328 auto find(Sp&& _key,
bool _exact =
true);
330 template <
typename Tp,
typename Sp =
string_t>
331 Tp
get(Sp&& _key,
bool _exact =
true);
333 template <
typename Tp,
typename Sp =
string_t>
334 bool get(Sp&& _key, Tp& _val,
bool _exact);
336 template <
typename Tp,
typename Sp =
string_t>
337 bool set(Sp&& _key, Tp&& _val,
bool _exact =
true);
351 template <
typename Tp,
typename Vp,
typename Sp,
typename... Args>
358 template <
typename Tp,
typename Vp,
typename Sp =
string_t>
359 auto insert(tsetting_pointer_t<Tp, Vp> _ptr, Sp&& _env = {});
368 template <
typename Tag>
374 template <
typename Tag>
378 template <
typename Archive,
typename Tp>
381 using serialize_func_t = std::function<void(Archive&,
value_type)>;
382 using serialize_pair_t = std::pair<std::type_index, serialize_func_t>;
384 auto _func = [](Archive& _ar,
value_type _val) {
387 _val = std::make_shared<Up>();
388 _ar(cereal::make_nvp(_val->get_env_name(), *
static_cast<Up*
>(_val.get())));
390 return serialize_pair_t{ std::type_index(
typeid(Tp)), _func };
393 template <
typename Archive,
typename... Tail>
396 using serialize_func_t = std::function<void(Archive&,
value_type)>;
397 using serialize_map_t = std::map<std::type_index, serialize_func_t>;
399 serialize_map_t _val{};
405 using settings_stack_t = std::stack<pointer_t>;
407 template <
typename Tag>
408 static TIMEMORY_HOT
pointer_t& private_shared_instance(
409 enable_if_t<std::is_same<Tag, TIMEMORY_API>::value,
int> = 0);
411 template <
typename Tag>
412 static TIMEMORY_HOT
pointer_t& private_shared_instance(
413 enable_if_t<!std::is_same<Tag, TIMEMORY_API>::value,
long> = 0);
415 template <
typename Tag>
416 static settings_stack_t& get_stack()
418 static auto _instance = settings_stack_t{};
423 bool m_initialized =
false;
428 strvector_t m_environment = get_global_environment();
429 std::set<std::string> m_read_configs = {};
432 void set_initialized(
bool _v) { m_initialized = _v; }
435 void initialize_core() TIMEMORY_VISIBILITY("hidden");
436 void initialize_components() TIMEMORY_VISIBILITY("hidden");
437 void initialize_io() TIMEMORY_VISIBILITY("hidden");
438 void initialize_format() TIMEMORY_VISIBILITY("hidden");
439 void initialize_parallel() TIMEMORY_VISIBILITY("hidden");
440 void initialize_tpls() TIMEMORY_VISIBILITY("hidden");
441 void initialize_roofline() TIMEMORY_VISIBILITY("hidden");
442 void initialize_miscellaneous() TIMEMORY_VISIBILITY("hidden");
443 void initialize_ert() TIMEMORY_VISIBILITY("hidden");
444 void initialize_dart() TIMEMORY_VISIBILITY("hidden");
446 static auto& indent_width_map()
448 static std::map<size_t, std::map<std::type_index, int64_t>> _instance{};
455template <
typename Tag>
459 static std::time_t* _time =
new std::time_t{ std::time(
nullptr) };
465template <
typename Tag>
466std::shared_ptr<settings>& settings::private_shared_instance(
467 enable_if_t<std::is_same<Tag, TIMEMORY_API>::value,
int>)
470 static std::shared_ptr<settings> _instance = std::make_shared<settings>();
476template <
typename Tag>
477std::shared_ptr<settings>& settings::private_shared_instance(
478 enable_if_t<!std::is_same<Tag, TIMEMORY_API>::value,
long>)
481 static std::shared_ptr<settings> _instance =
482 std::make_shared<settings>(*private_shared_instance<TIMEMORY_API>());
488template <
typename Tag>
489std::shared_ptr<settings>
493 static auto* _discard_ptr =
instance();
494 static auto* _discard_sptr = instance<TIMEMORY_API>();
497 auto _old = shared_instance<Tag>();
498 get_stack<Tag>().push(_old);
499 private_shared_instance<Tag>() = std::make_shared<settings>(*_old);
500 return private_shared_instance<Tag>();
505template <
typename Tag>
506std::shared_ptr<settings>
509 auto& _stack = get_stack<Tag>();
512 PRINT_HERE(
"%s",
"Ignoring settings::pop() on empty stack");
513 return shared_instance<Tag>();
516 auto _top = _stack.top();
517 private_shared_instance<Tag>() = _top;
524template <
typename Tag>
525std::shared_ptr<settings>
528 static std::shared_ptr<settings>& _instance = private_shared_instance<Tag>();
534template <
typename Tag>
538 return shared_instance<Tag>().
get();
548 auto_lock_t _lk{ type_mutex<settings, TIMEMORY_API>() };
549 auto& _itr = indent_width_map()[Idx][_tidx];
550 return (_itr = std::max<int64_t>(_itr, _w));
555template <
typename Tp,
size_t Idx>
559 auto _tidx = std::type_index{
typeid(Tp) };
560 auto_lock_t _lk{ type_mutex<settings, TIMEMORY_API>() };
561 auto& _itr = indent_width_map()[Idx][_tidx];
562 return (_itr = std::max<int64_t>(_itr, _w));
567template <
typename Archive>
577template <
typename Archive>
581 ar(cereal::make_nvp(
"settings", _obj));
586template <
typename Archive>
590#if !defined(TIMEMORY_DISABLE_SETTINGS_SERIALIZATION)
591 using map_type = std::map<std::string, std::shared_ptr<vsettings>>;
593 for(
const auto& itr : m_data)
594 _data.insert({
std::string{ itr.first }, itr.second->clone() });
596 for(
const auto& itr : _data)
598 auto mitr = _map.find(itr.second->get_type_index());
599 if(mitr != _map.end())
600 mitr->second(ar, itr.second);
602 ar(cereal::make_nvp(
"command_line", m_command_line),
603 cereal::make_nvp(
"environment", m_environment));
604 for(
const auto& itr : _data)
606 auto ditr = m_data.find(itr.first);
607 if(ditr != m_data.end())
609 ditr->second->clone(itr.second);
613 m_order.push_back(itr.first);
614 m_data.insert({ m_order.back(), itr.second });
624template <
typename Archive>
628#if !defined(TIMEMORY_DISABLE_SETTINGS_SERIALIZATION)
629 using map_type = std::map<std::string, std::shared_ptr<vsettings>>;
631 for(
const auto& itr : m_data)
632 _data.insert({
std::string{ itr.first }, itr.second->clone() });
635 for(
const auto& itr : _data)
637 auto mitr = _map.find(itr.second->get_type_index());
638 if(mitr != _map.end())
639 mitr->second(ar, itr.second);
641 ar(cereal::make_nvp(
"command_line", m_command_line),
642 cereal::make_nvp(
"environment", m_environment));
650template <
typename Sp>
655 auto itr = m_data.find(std::forward<Sp>(_key));
656 if(itr != m_data.end())
660 for(
auto ditr =
begin(); ditr !=
end(); ++ditr)
662 if(ditr->second && ditr->second->matches(std::forward<Sp>(_key), _exact))
672template <
typename Tp,
typename Sp>
676 auto itr =
find(std::forward<Sp>(_key), _exact);
677 if(itr != m_data.end() && itr->second)
679 auto _vptr = itr->second;
680 auto _tidx = std::type_index(
typeid(Tp));
681 auto _vidx = std::type_index(
typeid(Tp&));
682 if(_vptr->get_type_index() == _tidx && _vptr->get_value_index() == _tidx)
684 if(_vptr->get_type_index() == _tidx && _vptr->get_value_index() == _vidx)
692template <
typename Tp,
typename Sp>
696 auto itr =
find(std::forward<Sp>(_key), _exact);
697 if(itr != m_data.end() && itr->second)
699 auto _vptr = itr->second;
700 auto _tidx = std::type_index(
typeid(Tp));
701 auto _vidx = std::type_index(
typeid(Tp&));
702 if(_vptr->get_type_index() == _tidx && _vptr->get_value_index() == _tidx)
704 if(_vptr->get_type_index() == _tidx && _vptr->get_value_index() == _vidx)
712template <
typename Tp,
typename Sp>
716 auto itr =
find(std::forward<Sp>(_key), _exact);
717 if(itr != m_data.end() && itr->second)
720 auto _tidx = std::type_index(
typeid(Up));
721 auto _vidx = std::type_index(
typeid(Up&));
722 auto _tobj =
dynamic_cast<tsettings<Up>*
>(itr->second.get());
724 if(itr->second->get_type_index() == _tidx &&
725 itr->second->get_value_index() == _tidx && _tobj)
727 return (_tobj->set(std::forward<Tp>(_val)),
true);
729 else if(itr->second->get_type_index() == _tidx &&
730 itr->second->get_value_index() == _vidx && _robj)
732 return (_robj->
set(std::forward<Tp>(_val)),
true);
736 throw std::runtime_error(
std::string{
"tim::settings::set(" } +
748 auto itr =
find(_key, _exact);
749 if(itr == m_data.end())
751 if(get_verbose() > 0 || get_debug())
752 PRINT_HERE(
"Key: \"%s\" did not match any known setting", _key.c_str());
756 itr->second->parse(_val);
762template <
typename Tp,
typename Vp,
typename Sp,
typename... Args>
768 "Error! Data type is not supported. See settings::data_type_list_t");
769 static_assert(std::is_same<decay_t<Tp>,
decay_t<Vp>>::value,
770 "Error! Initializing value is not the same as the declared type");
775 m_order.push_back(_sid);
776 return m_data.insert(
778 std::make_shared<tsettings<Tp, Vp>>(_init, _name, _sid, _desc,
779 std::forward<Args>(
_args)...) });
784template <
typename Tp,
typename Vp,
typename Sp>
789 "Error! Data type is not supported. See settings::data_type_list_t");
794 _sid = _ptr->get_env_name();
798 set_env(_sid, _ptr->as_string(), 0);
799 m_order.push_back(_sid);
800 return m_data.insert({
string_view_t{ m_order.back() }, _ptr });
804 return std::make_pair(m_data.end(),
false);
std::array< char *, 4 > _args
char const std::string & _prefix
std::string string_view_t
void set_env(const std::string &env_var, const Tp &_val, int override)
std::unique_lock< mutex_t > auto_lock_t
Unique lock type around mutex_t.
typename std::decay< T >::type decay_t
Alias template for decay.
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
tim::mpl::apply< std::string > string
typename impl::is_one_of< Tp, Types > is_one_of
check if type is in expansion
void consume_parameters(ArgsT &&...)
char const std::string const std::string & _suffix
lightweight tuple-alternative for meta-programming logic
bool read(const string_t &)
read a configuration file
bool update(const std::string &_key, const std::string &_val, bool _exact=false)
Update a setting via a string. Returns whether a matching setting for the identifier was found (NOT w...
static pointer_t shared_instance()
void save(Archive &ar, unsigned int) const
static void store_command_line(int argc, char **argv)
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 get_global_output_prefix(bool _make_dir=false)
typename data_type::const_iterator const_iterator
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={})
Tp get(Sp &&_key, bool _exact=true)
auto find(Sp &&_key, bool _exact=true)
static std::time_t * get_launch_time(Tag={})
TIMEMORY_STATIC_ACCESSOR(bool, use_output_suffix, get_env< bool >("TIMEMORY_USE_OUTPUT_SUFFIX", false)) TIMEMORY_STATIC_ACCESSOR(int32_t
const_iterator end() const
std::shared_ptr< settings > pointer_t
static void serialize_settings(Archive &)
suppress_parsing enabled cout_output text_output tree_output time_output diff_output ctest_notes debug collapse_threads max_depth precision max_width timing_precision timing_units memory_precision memory_units output_path input_path input_extensions dart_count max_thread_bookmarks stack_clearing throttle_count global_components list_components mpip_components trace_components kokkos_components mpi_init mpi_thread upcxx_init papi_threading papi_fail_on_error papi_events papi_overflow nvtx_marker_device_sync cupti_activity_kinds cupti_metrics roofline_mode gpu_roofline_mode gpu_roofline_events roofline_type_labels_cpu instruction_roofline ert_num_threads_cpu ert_num_streams ert_block_size ert_min_working_size ert_min_working_size_gpu ert_max_data_size_cpu ert_skip_ops node_count python_exe enable_signal_handler TIMEMORY_SETTINGS_REFERENCE_DECL(bool, allow_signal_handler) TIMEMORY_SETTINGS_REFERENCE_DECL(bool
static string_t toupper(string_t str)
static string_t get_global_input_prefix()
typename data_type::iterator iterator
auto insert(Sp &&_env, const std::string &_name, const std::string &_desc, Vp _init, Args &&... _args)
const_iterator cend() const
auto get_serialize_pair() const
static std::string get_fallback_tag()
if the tag is not explicitly set, try to compute it. Otherwise use the TIMEMORY_SETTINGS_PREFIX_
friend void timemory_finalize()
finalization of the specified types
static pointer_t pop()
Restore the settings from a previous push operations.
bool get_initialized() const
returns whether timemory_init has been invoked
strvector_t & get_command_line()
TIMEMORY_SETTINGS_MEMBER_DECL(string_t, config_file) TIMEMORY_SETTINGS_MEMBER_DECL(bool
std::shared_ptr< tsettings< Tp, Vp > > tsetting_pointer_t
std::shared_ptr< vsettings > value_type
std::unordered_map< string_view_t, value_type > data_type
bool set(Sp &&_key, Tp &&_val, bool _exact=true)
static int64_t indent_width(int64_t _w=settings::width())
void set_tag(std::string _v)
the "tag" for settings should generally be the basename of exe
strvector_t & get_environment()
static void parse(settings *=instance< TIMEMORY_API >())
const_iterator begin() const
const_iterator cbegin() const
static settings * instance()
friend void timemory_init(int, char **, const std::string &, const std::string &)
initialization (creates manager and configures output path)
static std::string format(std::string _fpath, const std::string &_tag)
auto get_serialize_map(tim::type_list< Tail... >) const
void init_config(bool search_default=true)
static pointer_t push()
Make a copy of the current settings and return a new instance whose values can be modified,...
std::vector< std::string > strvector_t
void load(Archive &ar, unsigned int)
static string_t tolower(string_t str)
suppress_parsing enabled cout_output text_output tree_output time_output diff_output ctest_notes debug collapse_threads max_depth precision max_width timing_precision timing_units memory_precision memory_units output_path input_path input_extensions dart_count max_thread_bookmarks stack_clearing throttle_count global_components list_components mpip_components trace_components kokkos_components mpi_init mpi_thread upcxx_init papi_threading papi_fail_on_error papi_events papi_overflow nvtx_marker_device_sync cupti_activity_kinds cupti_metrics roofline_mode gpu_roofline_mode gpu_roofline_events roofline_type_labels_cpu instruction_roofline ert_num_threads_cpu ert_num_streams ert_block_size ert_min_working_size ert_min_working_size_gpu ert_max_data_size_cpu ert_skip_ops node_count python_exe enable_signal_handler enable_all_signals flat_profile static TIMEMORY_SETTINGS_REFERENCE_DECL(bool, timeline_profile) TIMEMORY_SETTINGS_REFERENCE_DECL(process strvector_t & environment()
std::string get_tag() const
the "tag" for settings should generally be the basename of exe
Implements a specific setting.
#define TIMEMORY_FOLD_EXPRESSION(...)
typename typename typename