32#include "timemory/backends/dmp.hpp"
33#include "timemory/backends/threading.hpp"
42#include "timemory/tpls/cereal/cereal.hpp"
68 template <
typename... Args>
69 using uomap_t = std::unordered_map<Args...>;
90 using filemap_t = std::map<string_t, std::map<string_t, std::set<string_t>>>;
94 template <
typename Tp>
109 template <
typename Func>
112 template <
typename Func>
115 template <
typename InitFuncT>
118 template <
typename StackFuncT,
typename FinalFuncT>
189 template <
typename Tp>
198 template <
typename Tp>
199 void do_init_storage();
201 template <
typename Tp>
202 void do_print_storage(
const enum_set_t& = {});
204 template <
typename Tp>
207 template <
typename Arch,
typename Tp>
208 void do_serialize(Arch& ar,
const enum_set_t& = {});
210 template <
typename Tp>
211 void do_size(uint64_t& _sz);
213 template <
typename Tp>
214 void do_size(enum_map_t<uint64_t>& _sz);
219 template <
typename... Types>
226 static uint64_t size(
pointer_t _manager = {});
244 static enum_map_t<uint64_t> size(
const enum_set_t& _types)
246 return size(
pointer_t{
nullptr }, _types);
252 template <
template <
typename...>
class Tuple,
typename... Types>
256 using base_type::clear;
260 using base_type::size;
271 template <
typename... Types>
275 using base_type::clear;
279 using base_type::size;
284 template <
template <
typename...>
class Tuple,
typename... Types>
289 using base_type::clear;
293 using base_type::size;
297 template <
typename... Types>
300 template <
typename... Types>
307 int64_t
get_tid()
const {
return m_thread_index; }
319 bool m_is_initialized =
false;
320 bool m_is_finalizing =
false;
321 bool m_is_finalized =
false;
322 short m_write_metadata = 0;
323 int32_t m_instance_count = 0;
325 uint64_t m_num_entries = 0;
326 int64_t m_metadata_entries = 0;
327 int64_t m_thread_index = threading::get_id();
328 std::thread::id m_thread_id = threading::get_tid();
348 struct persistent_data
350 persistent_data() =
default;
358 persistent_data(
const persistent_data&) =
delete;
359 persistent_data(persistent_data&&) =
delete;
360 persistent_data&
operator=(
const persistent_data&) =
delete;
361 persistent_data&
operator=(persistent_data&&) =
delete;
364 std::atomic<int32_t> thread_count{ 0 };
369 int64_t metadata_count = 0;
376 static persistent_data& f_manager_persistent_data();
378 static std::atomic<int32_t>& f_manager_instance_count()
380 return f_manager_persistent_data().instance_count;
383 static std::atomic<int32_t>& f_thread_counter()
385 return f_manager_persistent_data().thread_count;
388 static bool& f_use_exit_hook() {
return f_manager_persistent_data().use_exit_hook; }
389 static auto& f_debug() {
return f_manager_persistent_data().debug; }
390 static auto& f_verbose() {
return f_manager_persistent_data().verbose; }
391 static auto f_settings() {
return f_manager_persistent_data().config; }
397 tim::manager::f_manager_persistent_data().master_instance = std::move(_pinst);
403 f_settings() = std::make_shared<settings>(
_settings);
406#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
410 settings&& _tmp = std::move(*(f_settings()));
412 return std::move(_tmp);
419template <
typename Func>
424 m_pointer_fini.insert({ _key, std::forward<Func>(_func) });
429template <
typename Func>
436 m_finalizer_cleanups.emplace_back(_key, std::forward<Func>(_func));
441template <
typename InitFuncT>
445 bool _owns = m_lock->owns_lock();
448 m_initializers.emplace_back(std::forward<InitFuncT>(_init_func));
455template <
typename StackFuncT,
typename FinalFuncT>
458 FinalFuncT&& _inst_func,
bool _is_master, int32_t _priority)
465 if(m_write_metadata == 0)
466 m_write_metadata = 1;
468 auto& _cleanup_target = (_is_master) ? m_master_cleanup : m_worker_cleanup;
469 auto& _finalizer_target = (_is_master) ? m_master_finalizers : m_worker_finalizers;
471 _cleanup_target[_priority].emplace_back(_key, std::forward<StackFuncT>(_stack_func));
472 _finalizer_target[_priority].emplace_back(_key, std::forward<FinalFuncT>(_inst_func));
477template <
typename Tp>
482 ++f_manager_persistent_data().metadata_count;
483 f_manager_persistent_data().func_metadata.push_back([_key, _value](
void* _varchive) {
486 auto* ar =
static_cast<cereal::PrettyJSONOutputArchive*
>(_varchive);
487 (*ar)(cereal::make_nvp(_key.c_str(), _value));
493template <
typename Tp>
495manager::do_init_storage()
497 using storage_type =
typename Tp::storage_type;
499 static thread_local auto tmp = [&]() {
502 auto ret = storage_type::instance();
508 printf(
"[%s]> pointer: %p. has storage: %s. empty: %s...\n",
509 demangle<Tp>().c_str(), (
void*) ret,
511 (ret) ? ((ret->empty()) ?
"true" :
"false") :
"false");
521template <
typename Tp>
523manager::do_print_storage(
const enum_set_t& _types)
525 using storage_type =
typename Tp::storage_type;
527 if(!_types.empty() && _types.count(component::properties<Tp>{}()) == 0)
530 auto ret = storage_type::noninit_instance();
531 if(ret && !ret->empty())
536 printf(
"[%s]> pointer: %p. has storage: %s. empty: %s...\n",
537 demangle<Tp>().c_str(), (
void*) ret,
539 (ret) ? ((ret->empty()) ?
"true" :
"false") :
"false");
545template <
typename Tp>
547manager::do_clear(
const enum_set_t& _types)
549 using storage_type =
typename Tp::storage_type;
551 if(!_types.empty() && _types.count(component::properties<Tp>{}()) == 0)
554 auto ret = storage_type::noninit_instance();
560 printf(
"[%s]> pointer: %p. has storage: %s. empty: %s...\n",
561 demangle<Tp>().c_str(), (
void*) ret,
563 (ret) ? ((ret->empty()) ?
"true" :
"false") :
"false");
569template <
typename Archive,
typename Tp>
573 using storage_type =
typename Tp::storage_type;
578 auto ret = storage_type::noninit_instance();
579 if(ret && !ret->empty())
580 ret->do_serialize(ar);
584 printf(
"[%s]> pointer: %p. has storage: %s. empty: %s...\n",
585 demangle<Tp>().c_str(), (
void*) ret,
587 (ret) ? ((ret->empty()) ?
"true" :
"false") :
"false");
593template <
typename Tp>
595manager::do_size(uint64_t& _sz)
597 auto label = tim::demangle<Tp>();
598 using storage_type =
typename Tp::storage_type;
599 label +=
std::string(
" (") + tim::demangle<storage_type>() +
")";
601 auto ret = storage_type::noninit_instance();
602 if(ret && !ret->empty())
607 printf(
"[%s]> pointer: %p. has storage: %s. empty: %s...\n",
608 demangle<Tp>().c_str(), (
void*) ret,
610 (ret) ? ((ret->empty()) ?
"true" :
"false") :
"false");
616template <
typename Tp>
618manager::do_size(enum_map_t<uint64_t>& _sz)
620 using storage_type =
typename Tp::storage_type;
622 auto itr = _sz.find(component::properties<Tp>{}());
626 auto ret = storage_type::noninit_instance();
627 if(ret && !ret->empty())
628 itr->second = ret->true_size();
633template <
typename... Types>
637 if(_manager.get() ==
nullptr)
646template <
typename... Types>
649 const enum_set_t& _types)
651 if(_manager.get() ==
nullptr)
655 std::stringstream ss;
657 using archive_type = trait::output_archive_t<manager>;
658 using policy_type = policy::output_archive_t<manager>;
660 oa->setNextName(
"timemory");
664 _manager->do_serialize<archive_type, Types>(*oa, _types));
673template <
typename... Types>
675manager::filtered_get_storage<Types...>::clear(pointer_t _manager,
676 const enum_set_t& _types)
678 if(_manager.get() ==
nullptr)
687template <
typename... Types>
690 const enum_set_t& _types)
692 if(_manager.get() ==
nullptr)
701template <
typename... Types>
703manager::filtered_get_storage<Types...>::size(pointer_t _manager)
705 if(_manager.get() ==
nullptr)
716template <
typename... Types>
717manager::enum_map_t<uint64_t>
718manager::filtered_get_storage<Types...>::size(pointer_t _manager,
719 const enum_set_t& _types)
721 if(_manager.get() ==
nullptr)
724 enum_map_t<uint64_t> _sz{};
727 for(
const auto& itr : _types)
728 _sz.insert({ itr, 0 });
std::tuple< mpi::comm_t, int32_t > comm_group_t
int32_t get_rank() const
Get the dmp rank. This is stored to avoid having to do MPI/UPC++ query after finalization has been ca...
bool is_finalized() const
std::vector< std::function< void(void *)> > metadata_func_t
void add_file_output(const string_t &_category, const string_t &_label, const string_t &_file)
void is_finalizing(bool v)
Sets whether finalization is currently occuring.
int64_t get_tid() const
Get the thread-index for this manager instance.
std::function< void()> finalizer_func_t
int32_t instance_count() const
Get the instance ID for this manager instance.
std::deque< finalizer_pair_t > finalizer_list_t
std::shared_ptr< std::unique_lock< mutex_t > > auto_lock_ptr_t
manager & operator=(manager &&)=delete
std::pair< pointer_t, pointer_t > pointer_pair_t
void synchronize()
Synchronizes thread-data for storage.
void add_entries(uint64_t n)
Add number of component output data entries. If this value is zero, metadata output is suppressed unl...
std::unique_lock< mutex_t > auto_lock_t
friend struct filtered_get_storage
static void add_metadata(const std::string &, const Tp &)
Add a metadata entry of a non-string type. If this fails to serialize, either include either the appr...
void set_write_metadata(short v)
Set to 0 for yes if other output, -1 for never, or 1 for yes.
std::ostream & write_metadata(std::ostream &)
Write metadata to ostream.
void remove_cleanup(void *)
remove a cleanup functor
std::recursive_mutex mutex_t
bool is_initialized() const
static void add_metadata(const std::string &, const std::string &)
Add a metadata entry of a string.
manager(manager &&)=delete
std::pair< std::string, finalizer_func_t > finalizer_pair_t
std::map< TIMEMORY_COMPONENT, Tp > enum_map_t
void remove_synchronization(const std::string &, int64_t)
Remove function for synchronizing data in threads.
bool is_finalizing() const
Query whether finalization is currently occurring.
static void update_settings(const settings &_settings)
Updates the settings instance use by the manager instance.
static pointer_t instance()
Get a shared pointer to the instance for the current thread.
std::multimap< void *, finalizer_func_t > finalizer_void_t
void add_text_output(const string_t &_label, const string_t &_file)
static int32_t get_thread_count()
This effectively provides the total number of threads which collected data. It is only "decremented" ...
void cleanup(const std::string &)
execute a cleanup based on a key
static pointer_t master_instance()
Get a shared pointer to the instance on the primary thread.
void add_json_output(const string_t &_label, const string_t &_file)
std::map< int32_t, finalizer_list_t > finalizer_pmap_t
manager & operator=(const manager &)=delete
std::shared_ptr< this_type > pointer_t
std::map< string_t, std::map< string_t, std::set< string_t > > > filemap_t
static void use_exit_hook(bool val)
Enable setting std::exit callback.
std::deque< initializer_func_t > initializer_list_t
void add_cleanup(void *, Func &&)
add functors to destroy instances based on a pointer
static void set_persistent_master(pointer_t _pinst)
This function stores the primary manager instance for the application.
void update_metadata_prefix()
Updates settings, rank, output prefix, etc.
string_t get_prefix() const
static void exit_hook()
The exit hook function.
manager(const manager &)=delete
static bool get_is_main_thread()
Return whether this is the main thread.
void add_finalizer(const std::string &, StackFuncT &&, FinalFuncT &&, bool, int32_t=0)
this is used by storage classes for finalization.
void internal_write_metadata(const char *="")
void remove_cleanup(const std::string &)
remove a cleanup functor
uomap_t< string_t, uomap_t< int64_t, std::function< void()> > > synchronize_list_t
void add_initializer(InitFuncT &&)
this is used by storage classes for finalization.
std::shared_ptr< settings > settings_ptr_t
void write_metadata(const std::string &, const char *="")
Print metadata to filename.
static void add_metadata(const std::string &, const char *)
Add a metadata entry of a const character array. This only exists to avoid the template function from...
std::multimap< string_t, string_t > metadata_info_t
std::function< bool()> initializer_func_t
static int32_t total_instance_count()
Get the number of instances that are currently allocated. This is decremented during the destructor o...
std::set< TIMEMORY_COMPONENT > enum_set_t
void remove_finalizer(const std::string &)
remove a finalizer functor
void add_synchronization(const std::string &, int64_t, std::function< void()>)
Add function for synchronizing data in threads.
void serialize(std::string fname, exec_data< Counter > &obj)
std::shared_ptr< hash_alias_map_t > hash_alias_ptr_t
hash_alias_ptr_t & get_hash_aliases()
std::shared_ptr< hash_map_t > hash_map_ptr_t
hash_map_ptr_t & get_hash_ids()
void print(std::ostream &os, Args &&... args)
impl::filter_false_after_decay_t< trait::is_available, type_list< Types... > > implemented_t
filter out any types that are not available
std::recursive_mutex mutex_t
Recursive mutex is used for convenience since the performance penalty vs. a regular mutex is not real...
void initialize(CompList< CompTypes... > &obj, std::initializer_list< EnumT > components)
char argparse::argument_parser tim::settings * _settings
tim::mpl::apply< std::string > string
auto get(const auto_bundle< Tag, Types... > &_obj)
void consume_parameters(ArgsT &&...)
This is a critical specialization for mapping string and integers to component types at runtime....
static bool & has_storage()
filtered_get_storage< mpl::implemented_t< Types... > > base_type
This is used to apply/query storage data for multiple component types.
filtered_get_storage< mpl::implemented_t< Types... > > base_type
static pointer_t shared_instance()
static string_t get_global_output_prefix(bool _make_dir=false)
#define TIMEMORY_FOLD_EXPRESSION(...)