Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/v80-bugfix'
Browse files Browse the repository at this point in the history
  • Loading branch information
scip-ci committed Jul 28, 2023
2 parents 1863c3b + 7764eb4 commit 875aca4
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ Fixed bugs
----------

- ensure that delayed cutpool separation does not happen if enough cuts have been found already
- fixed that a Gurobi or Mosek interface (LPI) could not be freed from a thread different than the one it was created in, which lead to problems when, e.g., using the concurrent optimizer

@section RN804 SCIP 8.0.4
*************************
Expand Down
47 changes: 29 additions & 18 deletions src/lpi/lpi_grb.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@
#error "The Gurobi intreface only works for Gurobi versions at least 7.0.2"
#endif

#ifdef SCIP_THREADSAFE
#if defined(_Thread_local)
/* Use thread local environment in order to not create a new environment for each new LP. */
static _Thread_local GRBenv* reusegrbenv = NULL; /**< thread local Gurobi environment */
static _Thread_local int numlp = 0; /**< number of open LP objects */
#define SCIP_REUSEENV
#endif
#else
/* Global Gurobi environment in order to not create a new environment for each new LP. This is not thread safe. */
static GRBenv* reusegrbenv = NULL; /**< global Gurobi environment */
static int numlp = 0; /**< number of open LP objects */
#define SCIP_REUSEENV
#endif

/* macro for checking return codes of Gurobi */
#define CHECK_ZERO(messagehdlr, x) do { int _restat_; \
if( (_restat_ = (x)) != 0 ) \
Expand Down Expand Up @@ -142,6 +156,10 @@ typedef struct GRBParam GRBPARAM;
struct SCIP_LPi
{
GRBenv* grbenv; /**< environment corresponding to model */
#ifdef SCIP_REUSEENV
int* numlp; /**< pointer to count on number of models in environment */
GRBenv** reusegrbenv; /**< pointer to reused Gurobi environment */
#endif
GRBmodel* grbmodel; /**< Gurobi model pointer */
int solstat; /**< solution status of last optimization call */
GRBPARAM defparam; /**< default parameter values */
Expand Down Expand Up @@ -196,20 +214,6 @@ struct SCIP_LPiNorms
};


#ifdef SCIP_THREADSAFE
#if defined(_Thread_local)
/* Use thread local environment in order to not create a new environment for each new LP. */
static _Thread_local GRBenv* reusegrbenv = NULL; /**< thread local Gurobi environment */
static _Thread_local int numlp = 0; /**< number of open LP objects */
#define SCIP_REUSEENV
#endif
#else
/* Global Gurobi environment in order to not create a new environment for each new LP. This is not thread safe. */
static GRBenv* reusegrbenv = NULL; /**< global Gurobi environment */
static int numlp = 0; /**< number of open LP objects */
#define SCIP_REUSEENV
#endif


/*
* dynamic memory arrays
Expand Down Expand Up @@ -1395,6 +1399,10 @@ SCIP_RETCODE SCIPlpiCreate(

/* replace by local copy of environment */
(*lpi)->grbenv = GRBgetenv((*lpi)->grbmodel);

/* remember address of numlp and reusegrbenv, in case they are thread-local and SCIPlpiFree is called from different thread */
(*lpi)->numlp = &numlp;
(*lpi)->reusegrbenv = &reusegrbenv;
++numlp;

#else
Expand Down Expand Up @@ -1497,12 +1505,15 @@ SCIP_RETCODE SCIPlpiFree(

/* free environment */
#ifdef SCIP_REUSEENV
--numlp;
if( numlp == 0 )
/* decrement the numlp that belongs to the thread where SCIPlpiCreate was called */
assert(*(*lpi)->numlp > 0);
--(*(*lpi)->numlp);
/* if numlp reached zero, then also free the Gurobi environment (that belongs to the thread where SCIPlpiCreate was called) */
if( *(*lpi)->numlp == 0 )
{
/* free reused environment */
GRBfreeenv(reusegrbenv);
reusegrbenv = NULL;
GRBfreeenv(*(*lpi)->reusegrbenv);
*(*lpi)->reusegrbenv = NULL;
}
#else
/* free local environment */
Expand Down
21 changes: 16 additions & 5 deletions src/lpi/lpi_msk.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ static int numdualobj = 0;
struct SCIP_LPi
{
MSKenv_t mosekenv; /**< Mosek environment */
#ifdef SCIP_REUSEENV
int* numlp; /**< pointer to count on number of tasks in environment */
MSKenv_t* reusemosekenv; /**< pointer to reused Mosek environment */
#endif
MSKtask_t task; /**< Mosek task */
int optimizecount; /**< optimization counter (mainly for debugging) */
MSKrescodee termcode; /**< termination code of last optimization run */
Expand Down Expand Up @@ -859,6 +863,10 @@ SCIP_RETCODE SCIPlpiCreate(
(*lpi)->mosekenv = reusemosekenv;
(*lpi)->lpid = numlp++;

/* remember address of numlp and reusemosekenv, in case they are thread-local and SCIPlpiFree is called from different thread */
(*lpi)->numlp = &numlp;
(*lpi)->reusemosekenv = &reusemosekenv;

#else

MOSEK_CALL( MSK_makeenv(&(*lpi)->mosekenv, NULL) );
Expand Down Expand Up @@ -938,12 +946,15 @@ SCIP_RETCODE SCIPlpiFree(
BMSfreeMemoryArrayNull(&(*lpi)->skc);

#ifdef SCIP_REUSEENV
assert(numlp > 0);
numlp--;
if ( numlp == 0 )
/* decrement the numlp that belongs to the thread where SCIPlpiCreate was called */
assert(*(*lpi)->numlp > 0);
--(*(*lpi)->numlp);
/* if numlp reached zero, then also free the Mosek environment (that belongs to the thread where SCIPlpiCreate was called) */
if( *(*lpi)->numlp == 0 )
{
MOSEK_CALL( MSK_deleteenv(&reusemosekenv) );
reusemosekenv = NULL;
/* free reused environment */
MOSEK_CALL( MSK_deleteenv((*lpi)->reusemosekenv) );
*(*lpi)->reusemosekenv = NULL;
}
#else
MOSEK_CALL( MSK_deleteenv(&(*lpi)->mosekenv) );
Expand Down
2 changes: 1 addition & 1 deletion src/scip/concurrent.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ SCIP_RETCODE SCIPfreeConcurrent(

assert(scip->concurrent->varperm != NULL);

/* check if we are the SCIP that is responsible for freeing this concurent struct
/* check if we are the SCIP that is responsible for freeing this concurrent struct
* or just a subscip */
if( scip->concurrent->mainscip != scip )
{
Expand Down

0 comments on commit 875aca4

Please sign in to comment.