Skip to content

Commit c51fa63

Browse files
committed
Merge branch 'fix-variable-indexing-in-concurrent-mode' into 'v92-bugfix'
Fix variable indexing in concurrent mode See merge request integer/scip!4029
2 parents c6227b4 + 432bb3d commit c51fa63

File tree

8 files changed

+172
-97
lines changed

8 files changed

+172
-97
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Fixed bugs
2323
- recompute activity bounds before checking infeasibility and redundancy in linear constraint presolving
2424
- skip integer variables with fractional value in reference solution when finding additional variable fixings in ALNS heuristic
2525
- fix call of SCIPaddExprsViolScoreNonlinear() with constant expressions (no variables)
26+
- fixed bug with concurrent solve w.r.t. variable indices that led to segmentation faults and fix termination test
2627
- adjust further bounds before checking feasibility in SCIPvarAddVlb() and SCIPvarAddVub() to detect integrality cutoff
2728
- fixed issue in cons_linking.c where the last fixed binary variable was not set after the binary variables are created.
2829
- fixed issue in cons_linking.c where the number of binary variable is 1, but the constraint is added during solving.

src/scip/concsolver_scip.c

Lines changed: 118 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ SCIP_RETCODE disableConflictingDualReductions(
215215
return SCIP_OKAY;
216216

217217
SCIP_CALL( SCIPsetBoolParam(scip, "misc/allowstrongdualreds", FALSE) );
218+
218219
return SCIP_OKAY;
219220
}
220221

@@ -224,7 +225,7 @@ SCIP_RETCODE setChildSelRule(
224225
SCIP_CONCSOLVER* concsolver /**< the concurrent solver */
225226
)
226227
{
227-
SCIP_CONCSOLVERDATA* data;
228+
SCIP_CONCSOLVERDATA* data;
228229
static const char childsel[] = { 'h', 'i', 'p', 'r', 'l', 'd', 'u' };
229230

230231
assert(concsolver != NULL);
@@ -237,7 +238,7 @@ SCIP_RETCODE setChildSelRule(
237238
return SCIP_OKAY;
238239
}
239240

240-
/** initialize the concurrent SCIP solver, i.e. setup the copy of the problem and the
241+
/** initialize the concurrent SCIP solver, i.e., setup the copy of the problem and the
241242
* mapping of the variables */
242243
static
243244
SCIP_RETCODE initConcsolver(
@@ -274,8 +275,8 @@ SCIP_RETCODE initConcsolver(
274275
SCIP_CALL( SCIPcreate(&data->solverscip) );
275276
SCIPsetMessagehdlrQuiet(data->solverscip, SCIPmessagehdlrIsQuiet(SCIPgetMessagehdlr(scip)));
276277
SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(data->solverscip), data->nvars) );
277-
SCIP_CALL( SCIPcopy(scip, data->solverscip, varmapfw, NULL, SCIPconcsolverGetName(concsolver), TRUE, FALSE, FALSE,
278-
FALSE, &valid) );
278+
SCIP_CALL( SCIPcopyConsCompression(scip, data->solverscip, varmapfw, NULL, SCIPconcsolverGetName(concsolver),
279+
NULL, NULL, 0, TRUE, FALSE, FALSE, FALSE, &valid) );
279280
assert(valid);
280281

281282
/* allocate memory for the arrays to store the variable mapping */
@@ -286,27 +287,59 @@ SCIP_RETCODE initConcsolver(
286287
for( i = 0; i < data->nvars; i++ )
287288
{
288289
SCIP_VAR* var;
290+
int idx;
291+
289292
var = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
290293
assert(var != NULL);
291-
varperm[SCIPvarGetIndex(var)] = i;
294+
idx = SCIPvarGetIndex(var);
295+
assert(0 <= idx && idx < data->nvars);
296+
297+
/* Note that because some aggregations or fixed variables cannot be resolved by some constraint handlers (in
298+
* particular cons_orbitope_pp), the copied problem may contain more variables than the original problem has
299+
* active variables. These variables will be ignored in the following, since they depend on the other `active'
300+
* varibles. See concurrent.c:SCIPgetConcurrentVaridx(). */
301+
varperm[idx] = i;
292302
data->vars[i] = var;
293303
}
294304

305+
/* transfer solutions from original problem to concurent instances */
295306
if( SCIPgetNSols(scip) != 0 )
296307
{
297308
SCIP_Bool stored;
298309
SCIP_Real* solvals;
299310
SCIP_SOL* sol = SCIPgetBestSol(scip);
300311
SCIP_SOL* solversol;
312+
int norigvars;
301313

302314
SCIP_CALL( SCIPallocBufferArray(data->solverscip, &solvals, data->nvars) );
303315

304316
SCIP_CALL( SCIPgetSolVals(scip, sol, data->nvars, vars, solvals) );
305317
SCIP_CALL( SCIPcreateSol(data->solverscip, &solversol, NULL) );
306318
SCIP_CALL( SCIPsetSolVals(data->solverscip, solversol, data->nvars, data->vars, solvals) );
307-
308319
SCIPfreeBufferArray(data->solverscip, &solvals);
309320

321+
/* handle fixed variables */
322+
norigvars = SCIPgetNOrigVars(data->solverscip);
323+
if( norigvars > data->nvars )
324+
{
325+
SCIP_VAR** origvars;
326+
int v;
327+
328+
origvars = SCIPgetOrigVars(data->solverscip);
329+
for( v = 0; v < norigvars; ++v )
330+
{
331+
SCIP_VAR* var;
332+
var = origvars[v];
333+
if( SCIPisEQ(data->solverscip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
334+
{
335+
if( ! SCIPisZero(data->solverscip, SCIPvarGetLbGlobal(var)) )
336+
{
337+
SCIP_CALL( SCIPsetSolVal(data->solverscip, solversol, var, SCIPvarGetLbGlobal(var)) );
338+
}
339+
}
340+
}
341+
}
342+
310343
SCIP_CALL( SCIPaddSolFree(data->solverscip, &solversol, &stored) );
311344

312345
assert(stored);
@@ -318,7 +351,7 @@ SCIP_RETCODE initConcsolver(
318351
* also fails on check/instances/Symmetry/partorb_1-FullIns_3.cip
319352
* TODO: test if this leads to any problems
320353
*/
321-
SCIP_CALL( SCIPcreateConcurrent(data->solverscip, concsolver, varperm) );
354+
SCIP_CALL( SCIPcreateConcurrent(data->solverscip, concsolver, varperm, data->nvars) );
322355
SCIPfreeBufferArray(data->solverscip, &varperm);
323356

324357
/* free the hashmap */
@@ -403,7 +436,7 @@ SCIP_DECL_CONCSOLVERCREATEINST(concsolverScipCreateInstance)
403436
{
404437
/* print message about missing setting files only in verblevel full */
405438
SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "skipping non existent parameter file <%s> for concurrent solver <%s>\n",
406-
filename, SCIPconcsolverGetName(concsolver));
439+
filename, SCIPconcsolverGetName(concsolver));
407440
}
408441

409442
/* include eventhandler for synchronization */
@@ -494,55 +527,56 @@ static
494527
SCIP_DECL_CONCSOLVERCOPYSOLVINGDATA(concsolverGetSolvingData)
495528
{
496529
SCIP_CONCSOLVERDATA* data;
497-
SCIP_VAR** vars;
498-
int nvars;
499530
int nsols;
500-
SCIP_SOL** sols;
501-
SCIP_Real* solvals;
502-
SCIP_HEUR* heur;
503-
int i;
504531

532+
assert(scip != NULL);
505533
assert(concsolver != NULL);
506534

507535
data = SCIPconcsolverGetData(concsolver);
508536
assert(data != NULL);
509537
assert(data->solverscip != NULL);
510538

511-
assert(scip != NULL);
512-
vars = SCIPgetVars(scip);
513-
nvars = SCIPgetNVars(scip);
514-
515539
nsols = SCIPgetNSols(data->solverscip);
516-
sols = SCIPgetSols(data->solverscip);
540+
if( nsols > 0 )
541+
{
542+
SCIP_VAR** vars;
543+
SCIP_SOL** sols;
544+
SCIP_Real* solvals;
545+
int nvars;
546+
int i;
517547

518-
assert(nvars == data->nvars);
548+
vars = SCIPgetVars(scip);
549+
nvars = SCIPgetNVars(scip);
550+
assert(nvars == data->nvars);
519551

520-
/* allocate buffer array used for translating the solution to the given SCIP */
521-
SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
552+
sols = SCIPgetSols(data->solverscip);
522553

523-
/* add the solutions to the given SCIP */
524-
for( i = 0; i < nsols; ++i )
525-
{
526-
SCIP_SOL* sol;
527-
SCIP_Bool stored;
528-
SCIP_CALL( SCIPgetSolVals(data->solverscip, sols[i], nvars, data->vars, solvals) );
554+
/* allocate buffer array used for translating the solution to the given SCIP */
555+
SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
529556

530-
heur = SCIPsolGetHeur(sols[i]);
557+
/* add the solutions to the given SCIP */
558+
for( i = 0; i < nsols; ++i )
559+
{
560+
SCIP_SOL* sol;
561+
SCIP_HEUR* heur;
562+
SCIP_Bool stored;
531563

532-
if( heur != NULL )
533-
heur = SCIPfindHeur(scip, SCIPheurGetName(heur));
564+
SCIP_CALL( SCIPgetSolVals(data->solverscip, sols[i], nvars, data->vars, solvals) );
534565

535-
SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
536-
SCIP_CALL( SCIPsetSolVals(scip, sol, nvars, vars, solvals) );
566+
heur = SCIPsolGetHeur(sols[i]);
567+
if( heur != NULL )
568+
heur = SCIPfindHeur(scip, SCIPheurGetName(heur));
537569

538-
SCIP_CALL( SCIPcopySolStats(sols[i], sol) );
570+
SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
571+
SCIP_CALL( SCIPsetSolVals(scip, sol, nvars, vars, solvals) );
572+
SCIP_CALL( SCIPcopySolStats(sols[i], sol) );
573+
SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) );
574+
}
539575

540-
SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) );
576+
/* free the buffer array */
577+
SCIPfreeBufferArray(scip, &solvals);
541578
}
542579

543-
/* free the buffer array */
544-
SCIPfreeBufferArray(scip, &solvals);
545-
546580
/* copy solving statistics and status from the solver SCIP to the given SCIP */
547581
SCIP_CALL( SCIPcopyConcurrentSolvingStats(data->solverscip, scip) );
548582

@@ -661,7 +695,9 @@ SCIP_DECL_CONCSOLVERSYNCWRITE(concsolverScipSyncWrite)
661695
boundstore = SCIPgetConcurrentGlobalBoundChanges(data->solverscip);
662696

663697
if( boundstore != NULL )
698+
{
664699
SCIP_CALL( SCIPsyncdataAddBoundChanges(syncstore, syncdata, boundstore) );
700+
}
665701

666702
SCIPsyncdataAddMemTotal(syncdata, SCIPgetMemTotal(data->solverscip));
667703

@@ -693,6 +729,9 @@ SCIP_DECL_CONCSOLVERSYNCREAD(concsolverScipSyncRead)
693729
for( i = 0; i < nsols; ++i )
694730
{
695731
SCIP_SOL* newsol;
732+
SCIP_VAR** origvars;
733+
int norigvars;
734+
int v;
696735

697736
/* do not add own solutions */
698737
if( concsolverids[i] == concsolverid )
@@ -703,6 +742,26 @@ SCIP_DECL_CONCSOLVERSYNCREAD(concsolverScipSyncRead)
703742
SCIP_CALL( SCIPcreateOrigSol(data->solverscip, &newsol, NULL) );
704743

705744
SCIP_CALL( SCIPsetSolVals(data->solverscip, newsol, data->nvars, data->vars, solvals[i]) );
745+
746+
/* treat possible fixed original variables */
747+
norigvars = SCIPgetNOrigVars(data->solverscip);
748+
if( norigvars > data->nvars )
749+
{
750+
origvars = SCIPgetOrigVars(data->solverscip);
751+
for( v = 0; v < norigvars; ++v )
752+
{
753+
SCIP_VAR* var;
754+
var = origvars[v];
755+
if( SCIPisEQ(data->solverscip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
756+
{
757+
if( ! SCIPisZero(data->solverscip, SCIPvarGetLbGlobal(var)) )
758+
{
759+
SCIP_CALL( SCIPsetSolVal(data->solverscip, newsol, var, SCIPvarGetLbGlobal(var)) );
760+
}
761+
}
762+
}
763+
}
764+
706765
SCIPdebugMessage("adding solution in concurrent solver %s\n", SCIPconcsolverGetName(concsolver));
707766
SCIP_CALL( SCIPaddConcurrentSol(data->solverscip, newsol) );
708767
}
@@ -715,11 +774,14 @@ SCIP_DECL_CONCSOLVERSYNCREAD(concsolverScipSyncRead)
715774

716775
for( i = 0; i < nbndchgs; ++i )
717776
{
718-
SCIP_VAR* var;
777+
SCIP_VAR* var;
719778
SCIP_BOUNDTYPE boundtype;
720779
SCIP_Real newbound;
780+
int idx;
721781

722-
var = data->vars[SCIPboundstoreGetChgVaridx(boundstore, i)];
782+
idx = SCIPboundstoreGetChgVaridx(boundstore, i);
783+
assert(0 <= idx && idx < data->nvars);
784+
var = data->vars[idx];
723785
boundtype = SCIPboundstoreGetChgType(boundstore, i);
724786
newbound = SCIPboundstoreGetChgVal(boundstore, i);
725787

@@ -767,57 +829,57 @@ SCIP_RETCODE SCIPincludeConcurrentScipSolvers(
767829
SCIP_CALL( SCIPallocMemory(scip, &data) );
768830
data->loademphasis = FALSE;
769831
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip", 1.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
770-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
771-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
832+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
833+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
772834

773835
SCIP_CALL( SCIPallocMemory(scip, &data) );
774836
data->loademphasis = TRUE;
775837
data->emphasis = SCIP_PARAMEMPHASIS_DEFAULT;
776838
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-default", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
777-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
778-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
839+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
840+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
779841

780842
SCIP_CALL( SCIPallocMemory(scip, &data) );
781843
data->loademphasis = TRUE;
782844
data->emphasis = SCIP_PARAMEMPHASIS_CPSOLVER;
783845
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-cpsolver", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
784-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
785-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
846+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
847+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
786848

787849
SCIP_CALL( SCIPallocMemory(scip, &data) );
788850
data->loademphasis = TRUE;
789851
data->emphasis = SCIP_PARAMEMPHASIS_EASYCIP;
790852
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-easycip", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
791-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
792-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
853+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
854+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
793855

794856
SCIP_CALL( SCIPallocMemory(scip, &data) );
795857
data->loademphasis = TRUE;
796858
data->emphasis = SCIP_PARAMEMPHASIS_FEASIBILITY;
797859
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-feas", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
798-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
799-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
860+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
861+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
800862

801863
SCIP_CALL( SCIPallocMemory(scip, &data) );
802864
data->loademphasis = TRUE;
803865
data->emphasis = SCIP_PARAMEMPHASIS_HARDLP;
804866
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-hardlp", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
805-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
806-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
867+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
868+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
807869

808870
SCIP_CALL( SCIPallocMemory(scip, &data) );
809871
data->loademphasis = TRUE;
810872
data->emphasis = SCIP_PARAMEMPHASIS_OPTIMALITY;
811873
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-opti", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
812-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
813-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
874+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
875+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
814876

815877
SCIP_CALL( SCIPallocMemory(scip, &data) );
816878
data->loademphasis = TRUE;
817879
data->emphasis = SCIP_PARAMEMPHASIS_COUNTER;
818880
SCIP_CALL( SCIPincludeConcsolverType(scip, "scip-counter", 0.0, concsolverScipCreateInstance, concsolverScipDestroyInstance, concsolverScipInitSeeds,
819-
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
820-
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
881+
concsolverScipExec, concsolverGetSolvingData, concsolverScipStop, concsolverScipSyncWrite,
882+
concsolverScipSyncRead, concsolverTypeScipFreeData, data) );
821883

822884
return SCIP_OKAY;
823885
}

0 commit comments

Comments
 (0)