55 #include <unordered_map>
58 #include <boost/functional/hash/hash.hpp>
59 #include <boost/property_tree/ptree_fwd.hpp>
60 #include <boost/ref.hpp>
61 #include <boost/tuple/detail/tuple_basic.hpp>
70 namespace property_tree = boost::property_tree;
90 #define CONSTEXPR_ constexpr
96 #define _PASTE(a,b) a ## b
97 #define PASTE(a,b) _PASTE(a, b)
116 #ifdef FLOW123D_DEBUG_PROFILER
117 #define START_TIMER(tag) static CONSTEXPR_ CodePoint PASTE(cp_,__LINE__) = CODE_POINT(tag); TimerFrame PASTE(timer_,__LINE__) = TimerFrame( PASTE(cp_,__LINE__) )
119 #define START_TIMER(tag)
137 #ifdef FLOW123D_DEBUG_PROFILER
138 #define START_TIMER_EXT(tag, subtag) static CONSTEXPR_ CodePoint PASTE(cp_,__LINE__) = CODE_POINT_EXT(tag, subtag); TimerFrame PASTE(timer_,__LINE__) = TimerFrame( PASTE(cp_,__LINE__) )
140 #define START_TIMER_EXT(tag, subtag)
150 #ifdef FLOW123D_DEBUG_PROFILER
151 #define END_TIMER(tag) static CONSTEXPR_ CodePoint PASTE(cp_,__LINE__) = CODE_POINT(tag); Profiler::instance()->stop_timer( PASTE(cp_,__LINE__) )
153 #define END_TIMER(tag)
161 #ifdef FLOW123D_DEBUG_PROFILER
162 #define END_START_TIMER(tag) Profiler::instance()->stop_timer(); START_TIMER(tag);
164 #define END_START_TIMER(tag)
187 #ifdef FLOW123D_DEBUG_PROFILER
188 #define ADD_CALLS(n_calls) Profiler::instance()->add_calls(n_calls)
190 #define ADD_CALLS(n_calls)
197 #ifdef FLOW123D_DEBUG_PROFILER
202 #define PROFILER_EMPTY_SUBTAG ""
207 #define PROFILER_HASH_DEFAULT 0
216 inline CONSTEXPR_ unsigned int str_hash(
const char * str,
unsigned int default_value) {
217 #define SALT 0 //0xef50e38f
218 return (*str == 0 ? SALT : default_value + str_hash(str+1, PROFILER_HASH_DEFAULT) * 101 + (
unsigned int)(*str) );
224 #define CODE_POINT(tag) CodePoint(tag, __FILE__, __func__, __LINE__)
229 #define CODE_POINT_EXT(tag, subtag) CodePoint(tag, subtag, __FILE__, __func__, __LINE__)
244 CONSTEXPR_ CodePoint(
const char *tag,
const char * file,
const char * func,
const unsigned int line)
245 : tag_(tag), subtag_(PROFILER_EMPTY_SUBTAG), file_(file), func_(func), line_(line),
246 hash_(str_hash(tag, PROFILER_HASH_DEFAULT)),
247 hash_idx_( str_hash(tag, PROFILER_HASH_DEFAULT)%max_n_timer_childs )
249 CONSTEXPR_ CodePoint(
const char *tag,
const char *subtag,
const char * file,
const char * func,
const unsigned int line)
250 : tag_(tag), subtag_(subtag), file_(file), func_(func), line_(line),
251 hash_(str_hash(subtag, str_hash(tag, PROFILER_HASH_DEFAULT))),
252 hash_idx_( str_hash(subtag, str_hash(tag, PROFILER_HASH_DEFAULT))%max_n_timer_childs )
256 static const unsigned int max_n_timer_childs=13;
259 const char *
const tag_;
262 const char *
const subtag_;
265 const char *
const file_;
268 const char *
const func_;
271 const unsigned int line_;
277 unsigned int hash_idx_;
299 static const unsigned int max_n_childs=CodePoint::max_n_timer_childs;
304 Timer(
const CodePoint &cp,
int parent);
318 bool stop(
bool forced =
false);
322 inline string tag()
const {
323 string buf(code_point_->tag_);
324 buf.append(code_point_->subtag_);
329 inline bool running()
const
330 {
return start_count >0; }
333 std::string code_point_str()
const;
338 double cumulative_time()
const;
343 void add_child(
int child_index,
const Timer &child);
373 unsigned int call_count;
377 unsigned int start_count;
384 const CodePoint *code_point_;
386 unsigned int full_hash_;
388 unsigned int hash_idx_;
397 int child_timers[max_n_childs];
403 size_t total_allocated_;
408 size_t total_deallocated_;
414 size_t max_allocated_;
421 size_t current_allocated_;
432 #ifdef FLOW123D_HAVE_PETSC
436 PetscLogDouble petsc_start_memory;
440 PetscLogDouble petsc_end_memory;
444 PetscLogDouble petsc_memory_difference;
452 PetscLogDouble petsc_peak_memory;
458 PetscLogDouble petsc_local_peak_memory;
459 #endif // FLOW123D_HAVE_PETSC
531 static void initialize();
542 void set_task_info(
string description,
int size);
548 void set_program_info(
string program_name,
string program_version,
string branch,
string revision,
string build);
556 int start_timer(
const CodePoint &cp);
564 void stop_timer(
const CodePoint &cp);
572 void stop_timer(
int timer_index = -1);
578 void add_calls(
unsigned int n_calls);
583 void notify_malloc(
const size_t size,
const long p);
588 void notify_free(
const long p);
594 static double get_resolution ();
597 #ifdef FLOW123D_HAVE_MPI
609 void output(
MPI_Comm comm, std::ostream &os);
626 void output(std::ostream &os);
635 void transform_profiler_data (
const string &output_file_suffix,
const string &formatter);
640 static void uninitialize();
646 static void*
operator new (
size_t sz);
652 static void operator delete (
void* p);
659 void static set_memory_monitoring(
const bool global_monitor,
const bool petsc_monitor);
665 bool static get_global_memory_monitoring();
671 bool static get_petsc_memory_monitoring();
685 static bool global_monitor_memory;
690 static bool petsc_monitor_memory;
698 static const long malloc_map_reserve;
703 void propagate_timers ();
708 void accept_from_child (
Timer &parent,
Timer &child);
714 int find_child(
const CodePoint &cp);
722 void output_header (property_tree::ptree &root,
int mpi_size);
728 std::shared_ptr<std::ostream> get_default_output_stream();
731 static CodePoint null_code_point;
740 unsigned int actual_node;
758 string task_description_;
765 string flow_version_;
769 string flow_revision_;
773 string json_filepath;
781 template<
typename ReduceFunctor>
782 void add_timer_info(ReduceFunctor reduce, property_tree::ptree* node,
int timer_idx,
double parent_time);
812 int const timer_index_;
814 inline TimerFrame(
const CodePoint &cp)
815 : timer_index_(
Profiler::instance()->start_timer(cp) )
838 static unordered_map_with_alloc & malloc_map();
844 #else // FLOW123D_DEBUG_PROFILER
850 static void initialize();
855 void set_program_info(
string program_name,
string program_version,
string branch,
string revision,
string build)
877 static void uninitialize();