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