IMP logo
IMP Reference Guide  develop.d4e9f3251e,2024/04/26
The Integrative Modeling Platform
benchmark_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/benchmark/benchmark_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBENCHMARK_MACROS_H
10 #define IMPBENCHMARK_MACROS_H
11 
12 #include <IMP/benchmark/benchmark_config.h>
13 #include <IMP/flags.h>
14 #include <IMP/internal/SimpleTimer.h>
15 #include <boost/scoped_ptr.hpp>
16 #include "internal/control.h"
17 #include "internal/flags.h"
18 #include <IMP/exception.h>
19 #include <boost/date_time/posix_time/posix_time.hpp>
20 #include <boost/date_time/posix_time/posix_time_types.hpp>
21 #include <boost/date_time/posix_time/posix_time_duration.hpp>
22 
23 #if IMP_KERNEL_HAS_GPERFTOOLS
24 #include <gperftools/profiler.h>
25 #endif
26 #if IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
27 #include <gperftools/heap-profiler.h>
28 #endif
29 #if IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
30 #include <gperftools/heap-checker.h>
31 #endif
32 
33 #define IMP_BENCHMARK_RUN \
34  ++IMP::benchmark::internal::current_benchmark; \
35  if ((IMP::benchmark::internal::run_only < 0 || \
36  (IMP::benchmark::internal::run_only >= 0 && \
37  IMP::benchmark::internal::run_only == \
38  IMP::benchmark::internal::current_benchmark)))
39 
40 #if IMP_KERNEL_HAS_GPERFTOOLS
41 #define IMP_BENCHMARK_CPU_PROFILING_BEGIN \
42  if (IMP::benchmark::internal::cpu_profile_benchmarks) { \
43  ProfilerStart(IMP::benchmark::internal::get_file_name(".pprof").c_str()); \
44  }
45 #define IMP_BENCHMARK_CPU_PROFILING_END \
46  if (IMP::benchmark::internal::cpu_profile_benchmarks) { \
47  ProfilerStop(); \
48  }
49 #else
50 #define IMP_BENCHMARK_CPU_PROFILING_BEGIN
51 #define IMP_BENCHMARK_CPU_PROFILING_END
52 #endif
53 
54 #if IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
55 #define IMP_BENCHMARK_HEAP_PROFILING_BEGIN \
56  if (IMP::benchmark::internal::heap_profile_benchmarks) { \
57  HeapProfilerStart( \
58  IMP::benchmark::internal::get_file_name(".hprof").c_str()); \
59  }
60 #define IMP_BENCHMARK_HEAP_PROFILING_END \
61  if (IMP::benchmark::internal::heap_profile_benchmarks) { \
62  HeapProfilerStop(); \
63  }
64 #else
65 #define IMP_BENCHMARK_HEAP_PROFILING_BEGIN
66 #define IMP_BENCHMARK_HEAP_PROFILING_END
67 #endif
68 
69 #if IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
70 #define IMP_BENCHMARK_HEAP_CHECKING_BEGIN \
71  boost::scoped_ptr<HeapLeakChecker> heap_checker; \
72  if (IMP::benchmark::internal::heap_check_benchmarks) { \
73  heap_checker.reset(new HeapLeakChecker( \
74  IMP::benchmark::internal::get_file_name("").c_str())); \
75  }
76 #define IMP_BENCHMARK_HEAP_CHECKING_END \
77  if (IMP::benchmark::internal::heap_check_benchmarks) { \
78  if (!heap_checker->NoLeaks()) std::cerr << "Leaks found\n"; \
79  heap_checker.reset(nullptr); \
80  }
81 #else
82 #define IMP_BENCHMARK_HEAP_CHECKING_BEGIN
83 #define IMP_BENCHMARK_HEAP_CHECKING_END
84 #endif
85 
86 #define IMP_BENCHMARK_PROFILING_BEGIN \
87  IMP_BENCHMARK_CPU_PROFILING_BEGIN IMP_BENCHMARK_HEAP_CHECKING_BEGIN \
88  IMP_BENCHMARK_HEAP_PROFILING_BEGIN
89 
90 #define IMP_BENCHMARK_PROFILING_END \
91  IMP_BENCHMARK_CPU_PROFILING_END IMP_BENCHMARK_HEAP_CHECKING_END \
92  IMP_BENCHMARK_HEAP_PROFILING_END
93 
94 //! Time the given command and assign the time of one iteration to the variable
95 /** The units for the time are in seconds. \see IMP_TIME_N */
96 #define IMP_TIME(block, timev) \
97  IMP_BENCHMARK_RUN { \
98  IMP::internal::SimpleTimer imp_timer; \
99  unsigned int imp_reps = 0; \
100  IMP_BENCHMARK_PROFILING_BEGIN; \
101  try { \
102  do { \
103  block; \
104  ++imp_reps; \
105  } while (imp_timer.elapsed() < 2.5 && !IMP::run_quick_test); \
106  } \
107  catch (const IMP::Exception& e) { \
108  std::cerr << "Caught exception " << e.what() << std::endl; \
109  } \
110  IMP_BENCHMARK_PROFILING_END; \
111  timev = imp_timer.elapsed() / imp_reps; \
112  } \
113  else { \
114  timev = -1; \
115  }
116 
117 //! Time the given command and assign the time of one iteration to the variable
118 /** The units for the time are in seconds. \see IMP_TIME_N */
119 #define IMP_WALLTIME(block, timev) \
120  IMP_BENCHMARK_RUN { \
121  using namespace boost::posix_time; \
122  ptime start = microsec_clock::local_time(); \
123  unsigned int imp_reps = 0; \
124  IMP_BENCHMARK_PROFILING_BEGIN; \
125  try { \
126  do { \
127  block; \
128  ++imp_reps; \
129  } while (microsec_clock::local_time() - start < seconds(2) && \
130  !IMP::run_quick_test); \
131  } \
132  catch (const IMP::Exception& e) { \
133  std::cerr << "Caught exception " << e.what() << std::endl; \
134  } \
135  IMP_BENCHMARK_PROFILING_END; \
136  timev = (microsec_clock::local_time() - start).total_milliseconds() / \
137  1000.0 / imp_reps; \
138  } \
139  else { \
140  timev = -1; \
141  }
142 
143 //! Time the given command and assign the time of one iteration to the variable
144 /** The units for the time are in seconds. The bit of code is run
145  exactly N times. \see IMP_TIME */
146 #define IMP_TIME_N(block, timev, N) \
147  IMP_BENCHMARK_RUN { \
148  IMP::internal::SimpleTimer imp_timer; \
149  IMP_BENCHMARK_PROFILING_BEGIN; \
150  for (unsigned int i = 0; i < (N); ++i) { \
151  try { \
152  block; \
153  } \
154  catch (const IMP::Exception& e) { \
155  std::cerr << "Caught exception " << e.what() << std::endl; \
156  break; \
157  } \
158  if (IMP::run_quick_test) break; \
159  } \
160  IMP_BENCHMARK_PROFILING_END; \
161  timev = imp_timer.elapsed() / (N); \
162  } \
163  else { \
164  timev = -1; \
165  }
166 
167 #endif /* IMPBENCHMARK_MACROS_H */
Exception definitions and assertions.
Support for shared command line flags.