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 table.c 26 * @ingroup OTHER_CFILES 27 * @brief methods and datastructures for displaying statistics tables 28 * @author Tristan Gally 29 */ 30 31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 32 33 #include <stdio.h> 34 #include <assert.h> 35 #include <string.h> 36 37 #include "scip/def.h" 38 #include "blockmemshell/memory.h" 39 #include "scip/set.h" 40 #include "scip/stat.h" 41 #include "scip/scip.h" 42 #include "scip/table.h" 43 #include "scip/pub_message.h" 44 #include "scip/pub_misc.h" 45 #include "scip/syncstore.h" 46 #include "scip/struct_table.h" 47 48 49 50 /* 51 * statistics table methods 52 */ 53 54 /** copies the given statistics table to a new scip */ 55 SCIP_RETCODE SCIPtableCopyInclude( 56 SCIP_TABLE* table, /**< statistics table */ 57 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */ 58 ) 59 { 60 assert(table != NULL); 61 assert(set != NULL); 62 assert(set->scip != NULL); 63 64 if( table->tablecopy != NULL ) 65 { 66 SCIPsetDebugMsg(set, "including statistics table %s in subscip %p\n", SCIPtableGetName(table), (void*)set->scip); 67 SCIP_CALL( table->tablecopy(set->scip, table) ); 68 } 69 return SCIP_OKAY; 70 } 71 72 /** internal method for creating a statistics table */ 73 static 74 SCIP_RETCODE doTableCreate( 75 SCIP_TABLE** table, /**< pointer to store statistics table */ 76 SCIP_SET* set, /**< global SCIP settings */ 77 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ 78 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ 79 const char* name, /**< name of statistics table */ 80 const char* desc, /**< description of statistics table */ 81 SCIP_Bool active, /**< should the table be activated by default? */ 82 SCIP_DECL_TABLECOPY ((*tablecopy)), /**< copy method of statistics table or NULL if you don't want to copy your plugin into sub-SCIPs */ 83 SCIP_DECL_TABLEFREE ((*tablefree)), /**< destructor of statistics table */ 84 SCIP_DECL_TABLEINIT ((*tableinit)), /**< initialize statistics table */ 85 SCIP_DECL_TABLEEXIT ((*tableexit)), /**< deinitialize statistics table */ 86 SCIP_DECL_TABLEINITSOL ((*tableinitsol)), /**< solving process initialization method of statistics table */ 87 SCIP_DECL_TABLEEXITSOL ((*tableexitsol)), /**< solving process deinitialization method of statistics table */ 88 SCIP_DECL_TABLEOUTPUT ((*tableoutput)), /**< output method */ 89 SCIP_TABLEDATA* tabledata, /**< display statistics table */ 90 int position, /**< position of statistics table */ 91 SCIP_STAGE earlieststage /**< output of the statistics table is only printed from this stage onwards */ 92 ) 93 { 94 char paramname[SCIP_MAXSTRLEN]; 95 char paramdesc[SCIP_MAXSTRLEN]; 96 97 assert(table != NULL); 98 assert(name != NULL); 99 assert(desc != NULL); 100 assert(tableoutput != NULL); 101 102 SCIP_ALLOC( BMSallocMemory(table) ); 103 BMSclearMemory(*table); 104 105 SCIP_ALLOC( BMSduplicateMemoryArray(&(*table)->name, name, strlen(name)+1) ); 106 SCIP_ALLOC( BMSduplicateMemoryArray(&(*table)->desc, desc, strlen(desc)+1) ); 107 (*table)->tablecopy = tablecopy; 108 (*table)->tablefree = tablefree; 109 (*table)->tableinit = tableinit; 110 (*table)->tableexit = tableexit; 111 (*table)->tableinitsol = tableinitsol; 112 (*table)->tableexitsol = tableexitsol; 113 (*table)->tableoutput = tableoutput; 114 (*table)->tabledata = tabledata; 115 (*table)->position = position; 116 (*table)->earlieststage = earlieststage; 117 (*table)->initialized = FALSE; 118 (*table)->active = active; 119 120 /* add parameters */ 121 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "table/%s/active", name); 122 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "is statistics table <%s> active", name); 123 SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, paramdesc, 124 &(*table)->active, FALSE, active, NULL, NULL) ); 125 126 return SCIP_OKAY; 127 } 128 129 /** creates a statistics table */ 130 SCIP_RETCODE SCIPtableCreate( 131 SCIP_TABLE** table, /**< pointer to store statistics table */ 132 SCIP_SET* set, /**< global SCIP settings */ 133 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ 134 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ 135 const char* name, /**< name of statistics table */ 136 const char* desc, /**< description of statistics table */ 137 SCIP_Bool active, /**< should the table be activated by default? */ 138 SCIP_DECL_TABLECOPY ((*tablecopy)), /**< copy method of statistics table or NULL if you don't want to copy your plugin into sub-SCIPs */ 139 SCIP_DECL_TABLEFREE ((*tablefree)), /**< destructor of statistics table */ 140 SCIP_DECL_TABLEINIT ((*tableinit)), /**< initialize statistics table */ 141 SCIP_DECL_TABLEEXIT ((*tableexit)), /**< deinitialize statistics table */ 142 SCIP_DECL_TABLEINITSOL ((*tableinitsol)), /**< solving process initialization method of statistics table */ 143 SCIP_DECL_TABLEEXITSOL ((*tableexitsol)), /**< solving process deinitialization method of statistics table */ 144 SCIP_DECL_TABLEOUTPUT ((*tableoutput)), /**< output method */ 145 SCIP_TABLEDATA* tabledata, /**< display statistics table */ 146 int position, /**< position of statistics table */ 147 SCIP_STAGE earlieststage /**< output of the statistics table is only printed from this stage onwards */ 148 ) 149 { 150 assert(table != NULL); 151 assert(name != NULL); 152 assert(desc != NULL); 153 assert(tableoutput != NULL); 154 155 SCIP_CALL_FINALLY( doTableCreate(table, set, messagehdlr, blkmem, name, desc, active, tablecopy, tablefree, 156 tableinit, tableexit, tableinitsol, tableexitsol, tableoutput, tabledata, position, earlieststage), 157 (void) SCIPtableFree(table, set) ); 158 159 return SCIP_OKAY; 160 } 161 162 /** frees memory of statistics table */ 163 SCIP_RETCODE SCIPtableFree( 164 SCIP_TABLE** table, /**< pointer to statistics table data structure */ 165 SCIP_SET* set /**< global SCIP settings */ 166 ) 167 { 168 assert(table != NULL); 169 if( *table == NULL ) 170 return SCIP_OKAY; 171 assert(!(*table)->initialized); 172 assert(set != NULL); 173 174 /* call destructor of statistics table */ 175 if( (*table)->tablefree != NULL ) 176 { 177 SCIP_CALL( (*table)->tablefree(set->scip, *table) ); 178 } 179 180 BMSfreeMemoryArrayNull(&(*table)->name); 181 BMSfreeMemoryArrayNull(&(*table)->desc); 182 BMSfreeMemory(table); 183 184 return SCIP_OKAY; 185 } 186 187 /** initializes statistics table */ 188 SCIP_RETCODE SCIPtableInit( 189 SCIP_TABLE* table, /**< statistics table */ 190 SCIP_SET* set /**< global SCIP settings */ 191 ) 192 { 193 assert(table != NULL); 194 assert(set != NULL); 195 196 if( table->initialized ) 197 { 198 SCIPerrorMessage("statistics table <%s> already initialized\n", table->name); 199 return SCIP_INVALIDCALL; 200 } 201 202 if( table->tableinit != NULL ) 203 { 204 SCIP_CALL( table->tableinit(set->scip, table) ); 205 } 206 table->initialized = TRUE; 207 208 return SCIP_OKAY; 209 } 210 211 /** deinitializes statistics table */ 212 SCIP_RETCODE SCIPtableExit( 213 SCIP_TABLE* table, /**< statistics table */ 214 SCIP_SET* set /**< global SCIP settings */ 215 ) 216 { 217 assert(table != NULL); 218 assert(set != NULL); 219 220 if( !table->initialized ) 221 { 222 SCIPerrorMessage("statistics table <%s> not initialized\n", table->name); 223 return SCIP_INVALIDCALL; 224 } 225 226 if( table->tableexit != NULL ) 227 { 228 SCIP_CALL( table->tableexit(set->scip, table) ); 229 } 230 table->initialized = FALSE; 231 232 return SCIP_OKAY; 233 } 234 235 /** informs statistics table that the branch and bound process is being started */ 236 SCIP_RETCODE SCIPtableInitsol( 237 SCIP_TABLE* table, /**< statistics table */ 238 SCIP_SET* set /**< global SCIP settings */ 239 ) 240 { 241 assert(table != NULL); 242 assert(set != NULL); 243 244 /* call solving process initialization method of statistics table */ 245 if( table->tableinitsol != NULL ) 246 { 247 SCIP_CALL( table->tableinitsol(set->scip, table) ); 248 } 249 250 return SCIP_OKAY; 251 } 252 253 /** informs statistics table that the branch and bound process data is being freed */ 254 SCIP_RETCODE SCIPtableExitsol( 255 SCIP_TABLE* table, /**< statistics table */ 256 SCIP_SET* set /**< global SCIP settings */ 257 ) 258 { 259 assert(table != NULL); 260 assert(set != NULL); 261 262 /* call solving process deinitialization method of statistics table */ 263 if( table->tableexitsol != NULL ) 264 { 265 SCIP_CALL( table->tableexitsol(set->scip, table) ); 266 } 267 268 return SCIP_OKAY; 269 } 270 271 /** output statistics table to screen */ 272 SCIP_RETCODE SCIPtableOutput( 273 SCIP_TABLE* table, /**< statistics table */ 274 SCIP_SET* set, /**< global SCIP settings */ 275 FILE* file /**< output file (or NULL for standard output) */ 276 ) 277 { 278 assert(table != NULL); 279 assert(table->tableoutput != NULL); 280 assert(set != NULL); 281 282 SCIP_CALL( table->tableoutput(set->scip, table, file) ); 283 284 return SCIP_OKAY; 285 } 286 287 /** gets user data of statistics table */ 288 SCIP_TABLEDATA* SCIPtableGetData( 289 SCIP_TABLE* table /**< statistics table */ 290 ) 291 { 292 assert(table != NULL); 293 294 return table->tabledata; 295 } 296 297 /** sets user data of statistics table; user has to free old data in advance! */ 298 void SCIPtableSetData( 299 SCIP_TABLE* table, /**< statistics table */ 300 SCIP_TABLEDATA* tabledata /**< new statistics table user data */ 301 ) 302 { 303 assert(table != NULL); 304 305 table->tabledata = tabledata; 306 } 307 308 /** gets name of statistics table */ 309 const char* SCIPtableGetName( 310 SCIP_TABLE* table /**< statistics table */ 311 ) 312 { 313 assert(table != NULL); 314 315 return table->name; 316 } 317 318 /** gets description of statistics table */ 319 const char* SCIPtableGetDesc( 320 SCIP_TABLE* table /**< statistics table */ 321 ) 322 { 323 assert(table != NULL); 324 325 return table->desc; 326 } 327 328 /** gets position of statistics table */ 329 int SCIPtableGetPosition( 330 SCIP_TABLE* table /**< statistics table */ 331 ) 332 { 333 assert(table != NULL); 334 335 return table->position; 336 } 337 338 /** gets earliest stage of statistics table */ 339 SCIP_STAGE SCIPtableGetEarliestStage( 340 SCIP_TABLE* table /**< statistics table */ 341 ) 342 { 343 assert(table != NULL); 344 345 return table->earlieststage; 346 } 347 348 /** is statistics table currently active? */ 349 SCIP_Bool SCIPtableIsActive( 350 SCIP_TABLE* table /**< statistics table */ 351 ) 352 { 353 assert(table != NULL); 354 355 return table->active; 356 } 357 358 /** is statistics table initialized? */ 359 SCIP_Bool SCIPtableIsInitialized( 360 SCIP_TABLE* table /**< statistics table */ 361 ) 362 { 363 assert(table != NULL); 364 365 return table->initialized; 366 } 367