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