From 3bfbe9e3bece53acc2f8be042e49dd6a78862b0a Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Fri, 19 Jul 2024 11:36:55 +0200 Subject: [PATCH 1/2] add SCIPtpiIsAvailable(), SCIPtpiGetLibraryName(), SCIPtpiGetLibraryDesc() - and use to setup info on external libraries in doScipCreate() (instead of SCIPincludeDefaultPlugins(), which is wrong) --- CHANGELOG | 4 ++++ src/scip/scip_general.c | 10 ++++++++++ src/scip/scipdefplugins.c | 4 ---- src/tpi/tpi.h | 18 ++++++++++++++++++ src/tpi/tpi_none.c | 30 ++++++++++++++++++++++++++++++ src/tpi/tpi_openmp.c | 29 +++++++++++++++++++++++++++++ src/tpi/tpi_tnycthrd.c | 29 +++++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d53ef8d1d9..f849632585 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,10 @@ Interface changes ----------------- ### New callbacks ### New API functions + +- added SCIPtpiIsAvailable() to check whether a working task processing interface is available (TPI != none) +- added SCIPtpiGetLibraryName() and SCIPtpiGetLibraryDesc() + ### Command line interface ### Interfaces to external software ### New parameters diff --git a/src/scip/scip_general.c b/src/scip/scip_general.c index 0879b709c1..b09091102c 100644 --- a/src/scip/scip_general.c +++ b/src/scip/scip_general.c @@ -73,6 +73,7 @@ #include "scip/struct_stat.h" #include "scip/syncstore.h" #include "scip/lapack_calls.h" +#include "tpi/tpi.h" #include #if defined(_WIN32) || defined(_WIN64) @@ -288,6 +289,15 @@ SCIP_RETCODE doScipCreate( } #endif + if( SCIPtpiIsAvailable() ) + { + char name[20]; + char desc[80]; + SCIPtpiGetLibraryName(name, (int)sizeof(name)); + SCIPtpiGetLibraryDesc(desc, (int)sizeof(desc)); + SCIP_CALL( SCIPsetIncludeExternalCode((*scip)->set, name, desc) ); + } + return SCIP_OKAY; } diff --git a/src/scip/scipdefplugins.c b/src/scip/scipdefplugins.c index f4568cba05..0b0f1a635a 100644 --- a/src/scip/scipdefplugins.c +++ b/src/scip/scipdefplugins.c @@ -272,10 +272,6 @@ SCIP_RETCODE SCIPincludeDefaultPlugins( SCIP_CALL( SCIPincludeNlpSolverWorhp(scip, FALSE) ); SCIP_CALL( SCIPincludeNlpSolverAll(scip) ); -#ifdef TPI_TNY - SCIP_CALL( SCIPincludeExternalCodeInformation(scip, "TinyCThread", "Small, portable implementation of the C11 threads API (tinycthread.github.io)") ); -#endif - SCIP_CALL( SCIPdebugIncludeProp(scip) ); /*lint !e506 !e774*/ return SCIP_OKAY; diff --git a/src/tpi/tpi.h b/src/tpi/tpi.h index 0b367a235f..89c89b34b6 100644 --- a/src/tpi/tpi.h +++ b/src/tpi/tpi.h @@ -153,4 +153,22 @@ SCIP_RETCODE SCIPtpiExit( void ); +/** indicate whether a working TPI is available */ +SCIP_EXPORT +SCIP_Bool SCIPtpiIsAvailable(void); + +/** get name of library that the TPI interfaces to */ +SCIP_EXPORT +void SCIPtpiGetLibraryName( + char* name, /**< buffer to store name */ + int namesize /**< length of name buffer */ + ); + +/** get description of library that the TPI interfaces to */ +SCIP_EXPORT +void SCIPtpiGetLibraryDesc( + char* desc, /**< buffer to store description */ + int descsize /**< length of description */ + ); + #endif diff --git a/src/tpi/tpi_none.c b/src/tpi/tpi_none.c index 5d04a16b11..341361e00c 100644 --- a/src/tpi/tpi_none.c +++ b/src/tpi/tpi_none.c @@ -33,6 +33,7 @@ /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ #include "tpi/tpi.h" +#include "scip/pub_misc.h" /* do not define struct SCIP_Lock and struct SCIP_Condition, since they are not used */ @@ -219,3 +220,32 @@ SCIP_RETCODE SCIPtpiExit( { return SCIP_ERROR; } + +/** indicate whether a working TPI is available */ +SCIP_Bool SCIPtpiIsAvailable(void) +{ + return FALSE; +} + +/** get name of library that the TPI interfaces to */ +void SCIPtpiGetLibraryName( + char* name, /**< buffer to store name */ + int namesize /**< length of name buffer */ + ) +{ + assert(name != NULL); + + (void) SCIPsnprintf(name, namesize, "none"); +} + +/** get description of library that the TPI interfaces to */ +void SCIPtpiGetLibraryDesc( + char* desc, /**< buffer to store description */ + int descsize /**< length of description */ + ) +{ + assert(desc != NULL); + assert(descsize >= 1); + + *desc = '\0'; +} diff --git a/src/tpi/tpi_openmp.c b/src/tpi/tpi_openmp.c index 29814cfda1..905a33d0a1 100644 --- a/src/tpi/tpi_openmp.c +++ b/src/tpi/tpi_openmp.c @@ -35,6 +35,7 @@ #include "tpi/tpi.h" #include "blockmemshell/memory.h" #include "scip/pub_message.h" +#include "scip/pub_misc.h" #include /* macros for direct access */ @@ -702,3 +703,31 @@ void SCIPtpiDestroyCondition( BMSfreeMemory(condition); } + +/** indicate whether a working TPI is available */ +SCIP_Bool SCIPtpiIsAvailable(void) +{ + return TRUE; +} + +/** get name of library that the TPI interfaces to */ +void SCIPtpiGetLibraryName( + char* name, /**< buffer to store name */ + int namesize /**< length of name buffer */ + ) +{ + assert(name != NULL); + + (void) SCIPsnprintf(name, namesize, "OpenMP %d", _OPENMP); /*lint !e40*/ +} + +/** get description of library that the TPI interfaces to */ +void SCIPtpiGetLibraryDesc( + char* desc, /**< buffer to store description */ + int descsize /**< length of description */ + ) +{ + assert(desc != NULL); + + (void) SCIPsnprintf(desc, descsize, "shared-memory multiprocessing library (openmp.org)"); +} diff --git a/src/tpi/tpi_tnycthrd.c b/src/tpi/tpi_tnycthrd.c index 587ac6e9af..9432c61c43 100644 --- a/src/tpi/tpi_tnycthrd.c +++ b/src/tpi/tpi_tnycthrd.c @@ -36,6 +36,7 @@ #include "blockmemshell/memory.h" #include "tinycthread/tinycthread.h" #include "scip/pub_message.h" +#include "scip/pub_misc.h" /* macros for direct access */ @@ -840,3 +841,31 @@ int SCIPtpiGetThreadNum( { return _threadnumber; } + +/** indicate whether a working TPI is available */ +SCIP_Bool SCIPtpiIsAvailable(void) +{ + return TRUE; +} + +/** get name of library that the TPI interfaces to */ +void SCIPtpiGetLibraryName( + char* name, /**< buffer to store name */ + int namesize /**< length of name buffer */ + ) +{ + assert(name != NULL); + + (void) SCIPsnprintf(name, namesize, "TinyCThread %d.%d", TINYCTHREAD_VERSION_MAJOR, TINYCTHREAD_VERSION_MINOR); +} + +/** get description of library that the TPI interfaces to */ +void SCIPtpiGetLibraryDesc( + char* desc, /**< buffer to store description */ + int descsize /**< length of description */ + ) +{ + assert(desc != NULL); + + (void) SCIPsnprintf(desc, descsize, "small portable implementation of the C11 threads API (tinycthread.github.io)"); +} From 7ad21be55c309e476645bba48d044b0a425c4cc1 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Fri, 19 Jul 2024 11:43:10 +0200 Subject: [PATCH 2/2] switch to SCIPtpiIsAvailable() in SCIPsolveConcurrent() - and fix lint warnings that became visible now --- src/scip/scip_solve.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/scip/scip_solve.c b/src/scip/scip_solve.c index 8ec6cff921..f3a7d040ad 100644 --- a/src/scip/scip_solve.c +++ b/src/scip/scip_solve.c @@ -112,6 +112,7 @@ #include "scip/tree.h" #include "scip/var.h" #include "scip/visual.h" +#include "tpi/tpi.h" /** calculates number of nonzeros in problem */ static @@ -2861,10 +2862,6 @@ SCIP_RETCODE SCIPsolveConcurrent( SCIP* scip /**< SCIP data structure */ ) { -#ifdef TPI_NONE - SCIPerrorMessage("SCIP was compiled without task processing interface. Concurrent solve not possible\n"); - return SCIP_PLUGINNOTFOUND; -#else SCIP_RETCODE retcode; int i; SCIP_RANDNUMGEN* rndgen; @@ -2873,7 +2870,13 @@ SCIP_RETCODE SCIPsolveConcurrent( SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveConcurrent", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); - SCIP_CALL( SCIPsetIntParam(scip, "timing/clocktype", SCIP_CLOCKTYPE_WALL) ); + if( !SCIPtpiIsAvailable() ) + { + SCIPerrorMessage("SCIP was compiled without task processing interface. Concurrent solve not possible\n"); + return SCIP_PLUGINNOTFOUND; + } + + SCIP_CALL( SCIPsetIntParam(scip, "timing/clocktype", (int)SCIP_CLOCKTYPE_WALL) ); minnthreads = scip->set->parallel_minnthreads; maxnthreads = scip->set->parallel_maxnthreads; @@ -2887,7 +2890,7 @@ SCIP_RETCODE SCIPsolveConcurrent( { int nconcsolvertypes; SCIP_CONCSOLVERTYPE** concsolvertypes; - SCIP_Longint nthreads; + int nthreads; SCIP_Real memorylimit; int* solvertypes; SCIP_Longint* weights; @@ -2933,8 +2936,8 @@ SCIP_RETCODE SCIPsolveConcurrent( /* estimate maximum number of copies that be created based on memory limit */ if( !scip->set->misc_avoidmemout ) { - nthreads = MAX(1, memorylimit / (4.0*SCIPgetMemExternEstim(scip)/1048576.0)); - SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "estimated a maximum of %lli threads based on memory limit\n", nthreads); + nthreads = MAX(1, memorylimit / (4.0*SCIPgetMemExternEstim(scip)/1048576.0)); /*lint !e666 !e524*/ + SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "estimated a maximum of %d threads based on memory limit\n", nthreads); } else { @@ -2962,7 +2965,7 @@ SCIP_RETCODE SCIPsolveConcurrent( return SCIPsolve(scip); } nthreads = MIN(nthreads, maxnthreads); - SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "using %lli threads for concurrent solve\n", nthreads); + SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "using %d threads for concurrent solve\n", nthreads); /* now set up nthreads many concurrent solvers that will be used for the concurrent solve * using the preferred priorities of each concurrent solver @@ -2970,6 +2973,7 @@ SCIP_RETCODE SCIPsolveConcurrent( prefpriosum = 0.0; for( i = 0; i < nconcsolvertypes; ++i ) prefpriosum += SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]); + assert(prefpriosum != 0.0); ncandsolvertypes = 0; SCIP_CALL( SCIPallocBufferArray(scip, &solvertypes, nthreads + nconcsolvertypes) ); @@ -3005,7 +3009,7 @@ SCIP_RETCODE SCIPsolveConcurrent( SCIP_CALL( SCIPconcsolverCreateInstance(scip->set, concsolvertypes[solvertypes[i]], &concsolver) ); if( scip->set->concurrent_changeseeds && SCIPgetNConcurrentSolvers(scip) > 1 ) - SCIP_CALL( SCIPconcsolverInitSeeds(concsolver, SCIPrandomGetInt(rndgen, 0, INT_MAX)) ); + SCIP_CALL( SCIPconcsolverInitSeeds(concsolver, (unsigned int)SCIPrandomGetInt(rndgen, 0, INT_MAX)) ); } SCIPfreeRandom(scip, &rndgen); SCIPfreeBufferArray(scip, &prios); @@ -3029,7 +3033,6 @@ SCIP_RETCODE SCIPsolveConcurrent( SCIP_CALL( displayRelevantStats(scip) ); return retcode; -#endif } /** include specific heuristics and branching rules for reoptimization