1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 Konrad-Zuse-Zentrum                            */
7 /*                            fuer Informationstechnik Berlin                */
8 /*                                                                           */
9 /*  SCIP is distributed under the terms of the ZIB Academic License.         */
10 /*                                                                           */
11 /*  You should have received a copy of the ZIB Academic License              */
12 /*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
13 /*                                                                           */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file   stat.h
17  * @ingroup INTERNALAPI
18  * @brief  internal methods for problem statistics
19  * @author Tobias Achterberg
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #ifndef __SCIP_STAT_H__
25 #define __SCIP_STAT_H__
26 
27 
28 #include "scip/def.h"
29 #include "blockmemshell/memory.h"
30 #include "scip/type_prob.h"
31 #include "scip/type_retcode.h"
32 #include "scip/type_set.h"
33 #include "scip/type_stat.h"
34 #include "scip/type_mem.h"
35 #include "scip/pub_message.h"
36 #include "scip/concurrent.h"
37 
38 #include "scip/struct_stat.h"
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /** creates problem statistics data */
45 SCIP_RETCODE SCIPstatCreate(
46    SCIP_STAT**           stat,               /**< pointer to problem statistics data */
47    BMS_BLKMEM*           blkmem,             /**< block memory */
48    SCIP_SET*             set,                /**< global SCIP settings */
49    SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
50    SCIP_PROB*            origprob,           /**< original problem, or NULL */
51    SCIP_MESSAGEHDLR*     messagehdlr         /**< message handler */
52    );
53 
54 /** frees problem statistics data */
55 SCIP_RETCODE SCIPstatFree(
56    SCIP_STAT**           stat,               /**< pointer to problem statistics data */
57    BMS_BLKMEM*           blkmem              /**< block memory */
58    );
59 
60 /** diables the collection of any statistic for a variable */
61 void SCIPstatDisableVarHistory(
62    SCIP_STAT*            stat                /**< problem statistics data */
63    );
64 
65 /** enables the collection of statistics for a variable */
66 void SCIPstatEnableVarHistory(
67    SCIP_STAT*            stat                /**< problem statistics data */
68    );
69 
70 /** marks statistics to be able to reset them when solving process is freed */
71 void SCIPstatMark(
72    SCIP_STAT*            stat                /**< problem statistics data */
73    );
74 
75 /** reset statistics to the data before solving started */
76 void SCIPstatReset(
77    SCIP_STAT*            stat,               /**< problem statistics data */
78    SCIP_SET*             set,                /**< global SCIP settings */
79    SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
80    SCIP_PROB*            origprob            /**< original problem, or NULL */
81    );
82 
83 /** reset implication counter */
84 void SCIPstatResetImplications(
85    SCIP_STAT*            stat                /**< problem statistics data */
86    );
87 
88 /** reset presolving and current run specific statistics */
89 void SCIPstatResetPresolving(
90    SCIP_STAT*            stat,               /**< problem statistics data */
91    SCIP_SET*             set,                /**< global SCIP settings */
92    SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
93    SCIP_PROB*            origprob            /**< original problem, or NULL */
94    );
95 
96 /** reset primal-dual, primal-reference, and dual-reference integral */
97 void SCIPstatResetPrimalDualIntegrals(
98    SCIP_STAT*            stat,               /**< problem statistics data */
99    SCIP_SET*             set,                /**< global SCIP settings */
100    SCIP_Bool             partialreset        /**< should time and integral value be kept? (in combination with no statistical
101                                               *  reset, integrals are added for each problem to be solved) */
102    );
103 
104 /** update the primal-dual, primal-reference, and reference-dual integral statistics.
105  *  method accepts + and - SCIPsetInfinity() as values for upper and lower bound, respectively
106  */
107 void SCIPstatUpdatePrimalDualIntegrals(
108    SCIP_STAT*            stat,               /**< problem statistics data */
109    SCIP_SET*             set,                /**< global SCIP settings */
110    SCIP_PROB*            transprob,          /**< transformed problem */
111    SCIP_PROB*            origprob,           /**< original problem */
112    SCIP_Real             primalbound,        /**< current primal bound in transformed problem, or infinity */
113    SCIP_Real             dualbound           /**< current lower bound in transformed space, or -infinity */
114    );
115 
116 /** optionally update and return the reference-dual integral statistic */
117 SCIP_Real SCIPstatGetDualReferenceIntegral(
118    SCIP_STAT*            stat,               /**< problem statistics data */
119    SCIP_SET*             set,                /**< global SCIP settings */
120    SCIP_PROB*            transprob,          /**< transformed problem */
121    SCIP_PROB*            origprob,           /**< original problem */
122    SCIP_Bool             update              /**< should the value be updated first? */
123    );
124 
125 /** optionally update and return the primal-reference integral statistic */
126 SCIP_Real SCIPstatGetPrimalReferenceIntegral(
127    SCIP_STAT*            stat,               /**< problem statistics data */
128    SCIP_SET*             set,                /**< global SCIP settings */
129    SCIP_PROB*            transprob,          /**< transformed problem */
130    SCIP_PROB*            origprob,           /**< original problem */
131    SCIP_Bool             update              /**< should the value be updated first? */
132    );
133 
134 /** optionally update and return the primal-dual integral statistic */
135 SCIP_Real SCIPstatGetPrimalDualIntegral(
136    SCIP_STAT*            stat,               /**< problem statistics data */
137    SCIP_SET*             set,                /**< global SCIP settings */
138    SCIP_PROB*            transprob,          /**< transformed problem */
139    SCIP_PROB*            origprob,           /**< original problem */
140    SCIP_Bool             update              /**< should the value be updated first? */
141    );
142 
143 /** reset current branch and bound run specific statistics */
144 void SCIPstatResetCurrentRun(
145    SCIP_STAT*            stat,               /**< problem statistics data */
146    SCIP_SET*             set,                /**< global SCIP settings */
147    SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
148    SCIP_PROB*            origprob,           /**< original problem, or NULL */
149    SCIP_Bool             solved              /**< is problem already solved? */
150    );
151 
152 /** resets display statistics, such that a new header line is displayed before the next display line */
153 void SCIPstatResetDisplay(
154    SCIP_STAT*            stat                /**< problem statistics data */
155    );
156 
157 /** increases LP count, such that all lazy updates depending on the LP are enforced again */
158 void SCIPstatEnforceLPUpdates(
159    SCIP_STAT*            stat                /**< problem statistics data */
160    );
161 
162 /** depending on the current memory usage, switches mode flag to standard or memory saving mode */
163 void SCIPstatUpdateMemsaveMode(
164    SCIP_STAT*            stat,               /**< problem statistics data */
165    SCIP_SET*             set,                /**< global SCIP settings */
166    SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
167    SCIP_MEM*             mem                 /**< block memory pools */
168    );
169 
170 /** returns the estimated number of bytes used by extern software, e.g., the LP solver */
171 SCIP_Longint SCIPstatGetMemExternEstim(
172    SCIP_STAT*            stat                /**< dynamic SCIP statistics */
173    );
174 
175 /** enables or disables all statistic clocks of \p stat concerning LP execution time, strong branching time, etc.
176  *
177  *  @note: The (pre-)solving time clocks which are relevant for the output during (pre-)solving
178  *         are not affected by this method
179  *
180  *  @see: For completely disabling all timing of SCIP, consider setting the parameter timing/enabled to FALSE
181  */
182 void SCIPstatEnableOrDisableStatClocks(
183    SCIP_STAT*            stat,               /**< SCIP statistics */
184    SCIP_Bool             enable              /**< should the LP clocks be enabled? */
185    );
186 
187 /** recompute root LP best-estimate from scratch */
188 void SCIPstatComputeRootLPBestEstimate(
189    SCIP_STAT*            stat,               /**< SCIP statistics */
190    SCIP_SET*             set,                /**< global SCIP settings */
191    SCIP_Real             rootlpobjval,       /**< root LP objective value */
192    SCIP_VAR**            vars,               /**< problem variables */
193    int                   nvars               /**< number of variables */
194    );
195 
196 /** update root LP best-estimate with changed variable pseudo-costs */
197 SCIP_RETCODE SCIPstatUpdateVarRootLPBestEstimate(
198    SCIP_STAT*            stat,               /**< SCIP statistics */
199    SCIP_SET*             set,                /**< global SCIP settings */
200    SCIP_VAR*             var,                /**< variable with changed pseudo costs */
201    SCIP_Real             oldrootpscostscore  /**< old minimum pseudo cost score of variable */
202    );
203 
204 #ifdef TPI_NONE
205 /* no TPI included so just update the stats */
206 
207 #define SCIPstatUpdate(stat, set, field, val) do { \
208   (stat)->field = (val); \
209   } while(0)
210 
211 #define SCIPstatIncrement(stat, set, field) do { \
212    ++(stat)->field; \
213    } while(0)
214 
215 #define SCIPstatAdd(stat, set, field, val) do { \
216    (stat)->field += (val); \
217    } while(0)
218 
219 #else
220 /* TPI not none, so increment deterministic time for relevant stats */
221 
222 #define SCIPupdateDeterministicTimeCount(stat, set, val) do { \
223         (stat)->detertimecnt += (val); \
224         if( (stat)->detertimecnt > 10000.0 ) { \
225            SCIP_CALL_ABORT( SCIPincrementConcurrentTime( (set)->scip, (stat)->detertimecnt ) ); \
226            (stat)->detertimecnt = 0.0;                                  \
227         }\
228     } while(0) \
229 
230 #define SCIPstatUpdate(stat, set, field, val) do { \
231    switch( offsetof(SCIP_STAT, field) ) \
232    { \
233       default: \
234          break; \
235       case offsetof(SCIP_STAT, nprimalresolvelpiterations): \
236          SCIPupdateDeterministicTimeCount(stat, set, 0.00328285264101 * ((val) - (stat)->field) * (stat)->nnz ); \
237          break; \
238       case offsetof(SCIP_STAT, ndualresolvelpiterations): \
239          SCIPupdateDeterministicTimeCount(stat, set, 0.00531625104146 * ((val) - (stat)->field) * (stat)->nnz ); \
240          break; \
241       case offsetof(SCIP_STAT, nprobboundchgs): \
242          SCIPupdateDeterministicTimeCount(stat, set, 0.000738719124051 * ((val) - (stat)->field) * (stat)->nnz ); \
243          break; \
244       case offsetof(SCIP_STAT, nisstoppedcalls): \
245          SCIPupdateDeterministicTimeCount(stat, set, 0.0011123144764 * ((val) - (stat)->field) * (stat)->nnz ); \
246    } \
247    (stat)->field = (val); \
248    } while(0)
249 
250 
251 #define SCIPstatIncrement(stat, set, field) do { \
252    switch( offsetof(SCIP_STAT, field) ) \
253    { \
254       default: \
255          break; \
256       case offsetof(SCIP_STAT, nprimalresolvelpiterations): \
257          SCIPupdateDeterministicTimeCount(stat, set, 0.00328285264101 * (stat)->nnz ); \
258          break; \
259       case offsetof(SCIP_STAT, ndualresolvelpiterations): \
260          SCIPupdateDeterministicTimeCount(stat, set, 0.00531625104146 * (stat)->nnz ); \
261          break; \
262       case offsetof(SCIP_STAT, nprobboundchgs): \
263          SCIPupdateDeterministicTimeCount(stat, set, 0.000738719124051 * (stat)->nnz ); \
264          break; \
265       case offsetof(SCIP_STAT, nisstoppedcalls): \
266          SCIPupdateDeterministicTimeCount(stat, set, 0.0011123144764 * (stat)->nnz ); \
267    } \
268    ++(stat)->field; \
269    } while(0)
270 
271 #define SCIPstatAdd(stat, set, field, val) do { \
272    switch( offsetof(SCIP_STAT, field) ) \
273    { \
274       default: \
275          break; \
276       case offsetof(SCIP_STAT, nprimalresolvelpiterations): \
277          SCIPupdateDeterministicTimeCount(stat, set, 0.00328285264101 * (val) * (stat)->nnz); \
278          break; \
279       case offsetof(SCIP_STAT, ndualresolvelpiterations): \
280          SCIPupdateDeterministicTimeCount(stat, set, 0.00531625104146 * (val) * (stat)->nnz); \
281          break; \
282       case offsetof(SCIP_STAT, nprobboundchgs): \
283          SCIPupdateDeterministicTimeCount(stat, set, 0.000738719124051 * (val) * (stat)->nnz ); \
284          break; \
285       case offsetof(SCIP_STAT, nisstoppedcalls): \
286          SCIPupdateDeterministicTimeCount(stat, set, 0.0011123144764 * (val) * (stat)->nnz ); \
287    } \
288    (stat)->field += (val); \
289    } while(0)
290 #endif
291 
292 
293 /* if we have a C99 compiler */
294 #ifdef SCIP_HAVE_VARIADIC_MACROS
295 
296 /** prints a debugging message if SCIP_DEBUG flag is set */
297 #ifdef SCIP_DEBUG
298 #define SCIPstatDebugMsg(set, ...)      SCIPstatPrintDebugMessage(stat, __FILE__, __LINE__, __VA_ARGS__)
299 #define SCIPstatDebugMsgPrint(set, ...) SCIPstatPrintDebugMessagePrint(stat, __VA_ARGS__)
300 #else
301 #define SCIPstatDebugMsg(set, ...)      while ( FALSE ) SCIPstatPrintDebugMessage(stat, __FILE__, __LINE__, __VA_ARGS__)
302 #define SCIPstatDebugMsgPrint(set, ...) while ( FALSE ) SCIPstatPrintDebugMessagePrint(stat, __VA_ARGS__)
303 #endif
304 
305 #else
306 /* if we do not have a C99 compiler, use a workaround that prints a message, but not the file and linenumber */
307 
308 /** prints a debugging message if SCIP_DEBUG flag is set */
309 #ifdef SCIP_DEBUG
310 #define SCIPstatDebugMsg                printf("debug: "), SCIPstatDebugMessagePrint
311 #define SCIPstatDebugMsgPrint           SCIPstatDebugMessagePrint
312 #else
313 #define SCIPstatDebugMsg                while ( FALSE ) SCIPstatDebugMessagePrint
314 #define SCIPstatDebugMsgPrint           while ( FALSE ) SCIPstatDebugMessagePrint
315 #endif
316 
317 #endif
318 
319 
320 /** prints a debug message */
321 #ifdef __GNUC__
322 __attribute__((format(printf, 4, 5)))
323 #endif
324 SCIP_EXPORT
325 void SCIPstatPrintDebugMessage(
326    SCIP_STAT*            stat,               /**< SCIP statistics */
327    const char*           sourcefile,         /**< name of the source file that called the function */
328    int                   sourceline,         /**< line in the source file where the function was called */
329    const char*           formatstr,          /**< format string like in printf() function */
330    ...                                       /**< format arguments line in printf() function */
331    );
332 
333 /** prints a debug message without precode */
334 #ifdef __GNUC__
335 __attribute__((format(printf, 2, 3)))
336 #endif
337 SCIP_EXPORT
338 void SCIPstatDebugMessagePrint(
339    SCIP_STAT*            stat,               /**< SCIP statistics */
340    const char*           formatstr,          /**< format string like in printf() function */
341    ...                                       /**< format arguments line in printf() function */
342    );
343 
344 #ifdef __cplusplus
345 }
346 #endif
347 
348 #endif
349