ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
profile.hpp
Go to the documentation of this file.
1#ifndef _profiles_h_INCLUDED
2#define _profiles_h_INCLUDED
3
4#include "global.h"
5
7
8/*------------------------------------------------------------------------*/
9#ifndef CADICAL_QUIET
10/*------------------------------------------------------------------------*/
11
12namespace CaDiCaL {
13
14struct Internal;
15
16/*------------------------------------------------------------------------*/
17
18// The solver contains some built in profiling (even for optimized code).
19// The idea is that even without using external tools it is possible to get
20// an overview of where time is spent. This is enabled with the option
21// 'profile', e.g., you might want to use '--profile=3', or even higher
22// values for more detailed profiling information. Currently the default is
23// '--profile=2', which should only induce a tiny profiling overhead.
24//
25// Profiling has a Heisenberg effect, since we rely on calling 'getrusage'
26// instead of using profile counters and sampling. For functions which are
27// executed many times, this overhead is substantial (say 10%-20%). For
28// functions which are not executed many times there is in essence no
29// overhead in measuring time spent in them. These get a smaller profiling
30// level, which is the second argument in the 'PROFILE' macro below. Thus
31// using '--profile=1' for instance should not add any penalty to the
32// run-time, while '--profile=3' and higher levels slow down the solver.
33//
34// To profile say 'foo', just add another line 'PROFILE(foo,LEVEL)' and wrap
35// the code to be profiled within a 'START (foo)' / 'STOP (foo)' block.
36
37/*------------------------------------------------------------------------*/
38
39// Profile counters for functions which are not compiled in should be
40// removed. This is achieved by adding a wrapper macro for them here.
41
42/*------------------------------------------------------------------------*/
43
44#ifdef PROFILE_MODE
45#define MROFILE PROFILE
46#else
47#define MROFILE(...) /**/
48#endif
49
50#define PROFILES \
51 PROFILE (analyze, 3) \
52 MROFILE (analyzestable, 4) \
53 MROFILE (analyzeunstable, 4) \
54 PROFILE (backward, 3) \
55 PROFILE (block, 2) \
56 PROFILE (bump, 4) \
57 PROFILE (checking, 2) \
58 PROFILE (cdcl, 1) \
59 PROFILE (collect, 3) \
60 PROFILE (compact, 3) \
61 PROFILE (condition, 2) \
62 PROFILE (congruence, 2) \
63 PROFILE (congruencemerge, 4) \
64 PROFILE (congruencematching, 4) \
65 PROFILE (connect, 3) \
66 PROFILE (copy, 4) \
67 PROFILE (cover, 2) \
68 PROFILE (decide, 3) \
69 PROFILE (decompose, 3) \
70 PROFILE (definition, 2) \
71 PROFILE (elim, 2) \
72 PROFILE (factor, 2) \
73 PROFILE (fastelim, 2) \
74 PROFILE (extend, 3) \
75 PROFILE (extract, 3) \
76 PROFILE (extractands, 4) \
77 PROFILE (extractbinaries, 4) \
78 PROFILE (extractites, 4) \
79 PROFILE (extractxors, 4) \
80 PROFILE (instantiate, 2) \
81 PROFILE (lucky, 2) \
82 PROFILE (lookahead, 2) \
83 PROFILE (minimize, 4) \
84 PROFILE (shrink, 4) \
85 PROFILE (parse, 0) /* As 'opts.profile' might change in parsing*/ \
86 PROFILE (probe, 2) \
87 PROFILE (deduplicate, 3) \
88 PROFILE (propagate, 4) \
89 MROFILE (propstable, 4) \
90 MROFILE (propunstable, 4) \
91 PROFILE (reduce, 3) \
92 PROFILE (restart, 3) \
93 PROFILE (restore, 2) \
94 PROFILE (search, 1) \
95 PROFILE (solve, 0) \
96 PROFILE (stable, 2) \
97 PROFILE (sweep, 2) \
98 PROFILE (sweepbackbone, 3) \
99 PROFILE (sweepequivalences, 3) \
100 PROFILE (sweepflip, 4) \
101 PROFILE (sweepimplicant, 4) \
102 PROFILE (sweepsolve, 4) \
103 PROFILE (preprocess, 2) \
104 PROFILE (simplify, 1) \
105 PROFILE (subsume, 2) \
106 PROFILE (ternary, 2) \
107 PROFILE (transred, 3) \
108 PROFILE (unstable, 2) \
109 PROFILE (vivify, 2) \
110 PROFILE (walk, 2)
111
112/*------------------------------------------------------------------------*/
113
114// See 'START' and 'STOP' in 'macros.hpp' too.
115
116struct Profile {
117
118 bool active;
119 double value; // accumulated time
120 double started; // started time if active
121 const char *name; // name of the profiled function (or 'phase')
122 const int level; // allows to cheaply test if profiling is enabled
123
124 Profile (const char *n, int l)
125 : active (false), value (0), name (n), level (l) {}
126};
127
128struct Profiles {
129 Internal *internal;
130#define PROFILE(NAME, LEVEL) Profile NAME;
131 PROFILES
132#undef PROFILE
133 Profiles (Internal *);
134};
135
136} // namespace CaDiCaL
137
138#define NON_CADICAL_QUIET_PROFILE_CODE(CODE) CODE
139
140#else // !defined(CADICAL_QUIET)
141
142#define NON_CADICAL_QUIET_PROFILE_CODE(CODE) /**/
143
144#endif
145
146/*------------------------------------------------------------------------*/
147
148// Macros for Profiling support and checking and changing the mode.
149
150#define START(P) \
151 do { \
152 NON_CADICAL_QUIET_PROFILE_CODE ( \
153 if (internal->profiles.P.level <= internal->opts.profile) \
154 internal->start_profiling (internal->profiles.P, \
155 internal->time ());) \
156 } while (0)
157
158#define STOP(P) \
159 do { \
160 NON_CADICAL_QUIET_PROFILE_CODE ( \
161 if (internal->profiles.P.level <= internal->opts.profile) \
162 internal->stop_profiling (internal->profiles.P, \
163 internal->time ());) \
164 } while (0)
165
166#define PROFILE_ACTIVE(P) \
167 ((internal->profiles.P.level <= internal->opts.profile) && \
168 (internal->profiles.P.active))
169
170/*------------------------------------------------------------------------*/
171
172#define START_SIMPLIFIER(S, M) \
173 do { \
174 NON_CADICAL_QUIET_PROFILE_CODE (const double N = time (); \
175 const int L = internal->opts.profile;) \
176 if (!preprocessing && !lookingahead) { \
177 NON_CADICAL_QUIET_PROFILE_CODE ( \
178 if (stable && internal->profiles.stable.level <= L) \
179 internal->stop_profiling (internal->profiles.stable, N); \
180 if (!stable && internal->profiles.unstable.level <= L) \
181 internal->stop_profiling (internal->profiles.unstable, N); \
182 if (internal->profiles.search.level <= L) \
183 internal->stop_profiling (internal->profiles.search, N);) \
184 reset_mode (SEARCH); \
185 } \
186 NON_CADICAL_QUIET_PROFILE_CODE ( \
187 if (internal->profiles.simplify.level <= L) \
188 internal->start_profiling (internal->profiles.simplify, N); \
189 if (internal->profiles.S.level <= L) \
190 internal->start_profiling (internal->profiles.S, N);) \
191 set_mode (SIMPLIFY); \
192 set_mode (M); \
193 } while (0)
194
195/*------------------------------------------------------------------------*/
196
197#define STOP_SIMPLIFIER(S, M) \
198 do { \
199 NON_CADICAL_QUIET_PROFILE_CODE ( \
200 const double N = time (); const int L = internal->opts.profile; \
201 if (internal->profiles.S.level <= L) \
202 internal->stop_profiling (internal->profiles.S, N); \
203 if (internal->profiles.simplify.level <= L) \
204 internal->stop_profiling (internal->profiles.simplify, N);) \
205 reset_mode (M); \
206 reset_mode (SIMPLIFY); \
207 if (!preprocessing && !lookingahead) { \
208 NON_CADICAL_QUIET_PROFILE_CODE ( \
209 if (internal->profiles.search.level <= L) \
210 internal->start_profiling (internal->profiles.search, N); \
211 if (stable && internal->profiles.stable.level <= L) \
212 internal->start_profiling (internal->profiles.stable, N); \
213 if (!stable && internal->profiles.unstable.level <= L) \
214 internal->start_profiling (internal->profiles.unstable, N);) \
215 set_mode (SEARCH); \
216 } \
217 } while (0)
218
219/*------------------------------------------------------------------------*/
220// Used in 'walk' before calling 'walk_round' within the CDCL loop.
221
222#define START_INNER_WALK() \
223 do { \
224 require_mode (SEARCH); \
225 CADICAL_assert (!preprocessing); \
226 NON_CADICAL_QUIET_PROFILE_CODE ( \
227 const double N = time (); const int L = internal->opts.profile; \
228 if (stable && internal->profiles.stable.level <= L) \
229 internal->stop_profiling (internal->profiles.stable, N); \
230 if (!stable && internal->profiles.unstable.level <= L) \
231 internal->stop_profiling (internal->profiles.unstable, N); \
232 if (internal->profiles.walk.level <= L) \
233 internal->start_profiling (internal->profiles.walk, N);) \
234 set_mode (WALK); \
235 } while (0)
236
237/*------------------------------------------------------------------------*/
238// Used in 'walk' after calling 'walk_round' within the CDCL loop.
239
240#define STOP_INNER_WALK() \
241 do { \
242 require_mode (SEARCH); \
243 CADICAL_assert (!preprocessing); \
244 reset_mode (WALK); \
245 NON_CADICAL_QUIET_PROFILE_CODE ( \
246 const double N = time (); const int L = internal->opts.profile; \
247 if (internal->profiles.walk.level <= L) \
248 internal->stop_profiling (internal->profiles.walk, N); \
249 if (stable && internal->profiles.stable.level <= L) \
250 internal->start_profiling (internal->profiles.stable, N); \
251 if (!stable && internal->profiles.unstable.level <= L) \
252 internal->start_profiling (internal->profiles.unstable, N); \
253 internal->profiles.walk.started = (N);) \
254 } while (0)
255
256/*------------------------------------------------------------------------*/
257// Used in 'local_search' before calling 'walk_round'.
258
259#define START_OUTER_WALK() \
260 do { \
261 require_mode (SEARCH); \
262 CADICAL_assert (!preprocessing); \
263 NON_CADICAL_QUIET_PROFILE_CODE (START (walk);) \
264 set_mode (WALK); \
265 } while (0)
266
267/*------------------------------------------------------------------------*/
268// Used in 'local_search' after calling 'walk_round'.
269
270#define STOP_OUTER_WALK() \
271 do { \
272 require_mode (SEARCH); \
273 CADICAL_assert (!preprocessing); \
274 reset_mode (WALK); \
275 NON_CADICAL_QUIET_PROFILE_CODE (STOP (walk);) \
276 } while (0)
277
279
280#endif // ifndef _profiles_h_INCLUDED
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
ABC_NAMESPACE_IMPL_START typedef signed char value
char * name
Definition main.h:24
#define false
Definition place_base.h:29