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