34#include "timemory/components/user_bundle/backends.hpp"
49#include <unordered_map>
66 std::unordered_map<size_t, std::vector<user_bundle_spec_t>>;
70template <
typename ApiT>
77#if defined(TIMEMORY_USER_BUNDLE_HEADER_MODE)
82inline std::vector<TIMEMORY_COMPONENT>
89std::vector<TIMEMORY_COMPONENT>
95template <
size_t Idx,
typename Api,
typename AltApi = Api>
101 auto itr = variables.find(Idx);
102 if(itr != variables.end())
106 "getting user bundle components for type %s (%s)",
107 demangle<user_bundle_type>().c_str(), user_bundle_type::label().c_str());
110 tim::configure<user_bundle_type>(_enum);
133 using lock_t = std::unique_lock<mutex_t>;
134 using opaque_array_t = std::vector<opaque>;
135 using typeid_vec_t = std::vector<size_t>;
136 using typeid_set_t = std::set<size_t>;
143 user_bundle(scope::config _cfg, typeid_vec_t _typeids, opaque_array_t _opaque_arr,
144 const char*
_prefix =
nullptr);
146 user_bundle(
const user_bundle& rhs);
147 user_bundle(user_bundle&& rhs)
noexcept;
148 user_bundle& operator=(
const user_bundle& rhs);
149 user_bundle& operator=(user_bundle&& rhs)
noexcept;
153 static void configure(opaque_array_t& _data, typeid_vec_t& _typeids,
mutex_t& _mtx,
154 opaque&& obj, std::set<size_t>&& _inp);
157 static void reset(opaque_array_t& _data, typeid_vec_t& _typeids,
mutex_t& _mtx);
166 void get(
void*& ptr,
size_t _hash)
const;
168 void set_scope(
const scope::config& val);
169 void update_statistics(
bool _v)
const;
170 size_t size()
const {
return m_bundle.size(); }
171 const char* get_prefix()
const {
return m_prefix; }
172 scope::config get_scope()
const {
return m_scope; }
176 void insert(opaque&& obj, typeid_set_t&& _typeids);
179 bool m_setup =
false;
180 scope::config m_scope = {};
181 const char* m_prefix =
nullptr;
182 typeid_vec_t m_typeids = {};
183 opaque_array_t m_bundle = {};
186 static bool contains(
size_t _val,
const typeid_vec_t& _targ);
190template <
size_t Idx,
typename Tag>
192:
public base<user_bundle<Idx, Tag>, void>
194,
private internal::user_bundle
199 using mutex_t = std::mutex;
202 using get_func_t = std::function<void(
void*,
void*&,
size_t)>;
204 using opaque_array_t = std::vector<opaque>;
205 using typeid_vec_t = std::vector<size_t>;
206 using typeid_set_t = std::set<size_t>;
220 static void global_init(
bool _preinit =
false) TIMEMORY_VISIBILITY("default");
224 using internal::user_bundle::label;
228 using internal::user_bundle::m_bundle;
229 using internal::user_bundle::m_prefix;
230 using internal::user_bundle::m_scope;
231 using internal::user_bundle::m_setup;
232 using internal::user_bundle::m_typeids;
259 m_typeids.reserve(_typeids.size());
260 for(
const auto& itr : _typeids)
261 m_typeids.emplace_back(itr);
276 std::forward<opaque>(obj),
277 std::forward<std::set<size_t>>(_typeids));
280 template <
typename Type,
typename...
Types,
typename... Args>
284 factory::get_typeids<Type>());
288 factory::get_typeids<Types>()));
295 "Resetting %s", demangle<this_type>().c_str());
300 using internal::user_bundle::get_prefix;
301 using internal::user_bundle::get_scope;
305 using internal::user_bundle::sample;
308 using internal::user_bundle::setup;
309 using internal::user_bundle::size;
312 using internal::user_bundle::update_statistics;
314 using base_type::operator+=;
315 using base_type::operator-=;
345 template <
typename T>
348 auto _typeid_hash = typeid_hash<T>();
349 void* void_ptr =
nullptr;
350 for(
auto& itr : m_bundle)
352 itr.get(void_ptr, _typeid_hash);
354 return static_cast<T*
>(void_ptr);
356 return static_cast<T*
>(void_ptr);
361 void get(
void*& ptr,
size_t _typeid_hash)
const
368 template <
typename Type,
typename...
Types,
typename... Args>
371 this->
insert(factory::get_opaque<Type>(args...), factory::get_typeids<Type>());
373 factory::get_typeids<Types>()));
377 static bool persistent_init();
378 struct persistent_data;
379 static persistent_data& get_persistent_data() TIMEMORY_VISIBILITY("default");
381 struct persistent_data
383 volatile bool m_init =
false;
384 bool m_preinit =
false;
390 bool init(
bool _preinit =
false)
396 if(m_settings && m_settings->get_initialized())
402 if(m_init || _preinit)
403 env::initialize_bundle<Idx, Tag>();
411 static opaque_array_t&
get_data() {
return get_persistent_data().m_data; }
414 static typeid_vec_t&
get_typeids() {
return get_persistent_data().m_typeids; }
417 static mutex_t&
get_lock() {
return get_persistent_data().m_lock; }
422template <
size_t Idx,
typename Tag>
427 PRINT_HERE(
"Global initialization of %s", demangle<this_type>().c_str());
428 get_persistent_data().init(_preinit);
433template <
size_t Idx,
typename Tag>
437 static persistent_data _instance{};
443template <
size_t Idx,
typename Tag>
445user_bundle<Idx, Tag>::persistent_init()
447 return get_persistent_data().init();
457#if defined(TIMEMORY_USER_BUNDLE_HEADER_MODE)
Forward declaration of user_bundle components. User-bundles are similar to the classical profiling in...
std::vector< TIMEMORY_COMPONENT > get_bundle_components(const std::vector< user_bundle_spec_t > &_priority)
void initialize_bundle(AltApi _api=AltApi{})
std::function< std::string()> user_bundle_spec_t
std::unordered_map< size_t, std::vector< user_bundle_spec_t > > user_bundle_variables_t
user_bundle_variables_t & get_user_bundle_variables(TIMEMORY_API)
static so that projects cannot globally change this
_reported insert(_hash_id)
void set_scope(TupleT< Tp... > &obj, Args &&... args)
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
void record(TupleT< Tp... > &obj, Args &&... args)
void pop(TupleT< Tp... > &obj, Args &&... args)
void stop(TupleT< Tp... > &obj, Args &&... args)
void push(TupleT< Tp... > &obj, Args &&... args)
void reset(TupleT< Tp... > &obj, Args &&... args)
void start(TupleT< Tp... > &obj, Args &&... args)
char const std::string & _prefix
void configure(std::initializer_list< EnumT > components, Args &&... args)
std::recursive_mutex mutex_t
Recursive mutex is used for convenience since the performance penalty vs. a regular mutex is not real...
void init(Args &&... args)
tim::mpl::apply< std::string > string
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)
void set_is_transient(bool v)
void set_is_on_stack(bool v)
auto get_iterator() const
bool get_depth_change() const
void set_is_running(bool v)
void set_iterator(graph_iterator itr)
int64_t get_laps() const
add a sample
bool get_is_on_stack() const
void set_stopped()
store that stop has been called
bool get_is_transient() const
void set_depth_change(bool v)
bool get_is_running() const
static opaque get_opaque(scope::config)
get the opaque binding for user-bundle
storage< Tp, Value > storage_type
auto get() const
retrieve the current measurement value in the units for the type
bool get_is_invalid() const
void set_is_invalid(bool v)
void set_started()
store that start has been called
user_bundle< Idx, Tag > Type
A very lightweight storage class which provides nothing.
user_bundle & operator=(const user_bundle &rhs)=default
user_bundle(const char *_prefix, opaque_array_t _bundle_vec, typeid_set_t _typeids, scope::config _scope=scope::get_default())
void get(void *&ptr, size_t _typeid_hash) const
static typeid_vec_t & get_typeids()
template instantiation-specific static set of type identifiers
user_bundle(const user_bundle &)=default
static void configure(opaque &&obj, std::set< size_t > &&_typeids)
static void global_init(storage_type *)
std::function< void(void *, void *&, size_t)> get_func_t
static void global_init(bool _preinit=false)
static constexpr auto index
user_bundle & operator=(user_bundle &&rhs) noexcept=default
user_bundle(user_bundle &&rhs) noexcept=default
static size_t bundle_size()
void insert(Args... args)
static opaque_array_t & get_data()
template instantiation-specific static opaque array
user_bundle(const char *_prefix, opaque_array_t _bundle_vec, typeid_vec_t _typeids, scope::config _scope=scope::get_default())
static void configure(Args &&... args)
user_bundle(const char *_prefix, scope::config _scope=scope::get_default())
std::function< void(void *)> delete_func_t
std::vector< opaque > opaque_array_t
static mutex_t & get_lock()
template instantiation-specific static mutex
std::function< void(void *)> stop_func_t
std::vector< size_t > typeid_vec_t
std::function< void *(const std::string &, scope::config)> start_func_t
This operation attempts to call a member function which the component provides to internally store wh...
This operation attempts to call a member function which the component provides to internally store wh...
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
static pointer_t shared_instance()
static settings * instance()
#define CONDITIONAL_PRINT_HERE(CONDITION,...)
#define TIMEMORY_FOLD_EXPRESSION(...)