SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
syncstore.c
Go to the documentation of this file.
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 syncstore.c
26 * @ingroup PARALLEL
27 * @brief the function definitions of the synchronization store
28 * @author Leona Gottwald
29 * @author Stephen J. Maher
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
34#include <assert.h>
35
36#include "scip/def.h"
37#include "scip/pub_message.h"
38#include "scip/concsolver.h"
40#include "scip/prob.h"
41#include "scip/scip.h"
43#include "tpi/tpi.h"
45#include "scip/concurrent.h"
46#include "scip/syncstore.h"
47#include "scip/boundstore.h"
48
49
50/** computes the size of the array of synchronization datas, such that
51 * it cannot ever happen that a synchronization data is reused while still
52 * not read by any thread */
53static
55 SCIP* scip /**< SCIP main datastructure */
56 )
57{
58 int maxnsyncdelay;
59
60 SCIP_CALL_ABORT( SCIPgetIntParam(scip, "concurrent/sync/maxnsyncdelay", &maxnsyncdelay) );
61
62 return 2 * (maxnsyncdelay + 1);
63}
64
65/** creates and captures a new synchronization store */
67 SCIP_SYNCSTORE** syncstore /**< pointer to return the created synchronization store */
68 )
69{
70 assert(syncstore != NULL);
71
72 SCIPdebugMessage("SCIPsyncstoreCreate()\n");
73
74 SCIP_ALLOC( BMSallocMemory(syncstore) );
75
76 (*syncstore)->mode = SCIP_PARA_DETERMINISTIC; /* initialising the mode */
77 (*syncstore)->initialized = FALSE;
78 (*syncstore)->syncdata = NULL;
79 (*syncstore)->stopped = FALSE;
80 (*syncstore)->nuses = 1;
81 SCIP_CALL( SCIPtpiInitLock(&(*syncstore)->lock) );
82
83 return SCIP_OKAY;
84}
85
86/** releases a synchronization store */
88 SCIP_SYNCSTORE** syncstore /**< pointer to the synchronization store */
89 )
90{
91 int references;
92
93 assert(syncstore != NULL);
94 if( *syncstore == NULL )
95 return SCIP_OKAY;
96
97 SCIP_CALL( SCIPtpiAcquireLock(&(*syncstore)->lock) );
98 (*syncstore)->nuses -= 1;
99 references = (*syncstore)->nuses;
100 SCIP_CALL( SCIPtpiReleaseLock(&(*syncstore)->lock) );
101
102 if( references == 0 )
103 {
104 if( (*syncstore)->initialized )
105 {
106 SCIP_CALL( SCIPsyncstoreExit(*syncstore) );
107 }
108
109 assert(!(*syncstore)->initialized);
110 SCIPtpiDestroyLock(&(*syncstore)->lock);
111 BMSfreeMemory(syncstore);
112 }
113 else
114 {
115 *syncstore = NULL;
116 }
117
118 return SCIP_OKAY;
119}
120
121/** captures a synchronization store */
123 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
124 )
125{
126 SCIP_CALL( SCIPtpiAcquireLock(&syncstore->lock) );
127
128 ++(syncstore->nuses);
129
130 SCIP_CALL( SCIPtpiReleaseLock(&syncstore->lock) );
131
132 return SCIP_OKAY;
133}
134
135/** initialize the syncstore for the given SCIP instance */
137 SCIP* scip /**< SCIP main datastructure */
138 )
139{
140 SCIP_SYNCSTORE* syncstore;
141 int i;
142 int j;
143 int paramode;
144
145 assert(scip != NULL);
146 syncstore = SCIPgetSyncstore(scip);
147 assert(syncstore != NULL);
148 syncstore->mainscip = scip;
149 syncstore->lastsync = NULL;
151
152 syncstore->ninitvars = SCIPgetNVars(scip);
153 SCIP_CALL( SCIPgetIntParam(scip, "concurrent/sync/maxnsols", &syncstore->maxnsols) );
154 SCIP_CALL( SCIPgetIntParam(scip, "concurrent/sync/maxnsyncdelay", &syncstore->maxnsyncdelay) );
155 SCIP_CALL( SCIPgetRealParam(scip, "concurrent/sync/minsyncdelay", &syncstore->minsyncdelay) );
156 SCIP_CALL( SCIPgetRealParam(scip, "concurrent/sync/freqinit", &syncstore->syncfreqinit) );
157 SCIP_CALL( SCIPgetRealParam(scip, "concurrent/sync/freqmax", &syncstore->syncfreqmax) );
158 syncstore->nsyncdata = getNSyncdata(scip);
159 SCIP_CALL( SCIPallocBlockMemoryArray(syncstore->mainscip, &(syncstore->syncdata), syncstore->nsyncdata) );
160
161 for( i = 0; i < syncstore->nsyncdata; ++i )
162 {
163 syncstore->syncdata[i].syncnum = -1;
164 SCIP_CALL( SCIPboundstoreCreate(syncstore->mainscip, &syncstore->syncdata[i].boundstore, syncstore->ninitvars) );
165 SCIP_CALL( SCIPallocBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].solobj, syncstore->maxnsols) );
166 SCIP_CALL( SCIPallocBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].solsource, syncstore->maxnsols) );
167 SCIP_CALL( SCIPallocBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].sols, syncstore->maxnsols) );
168
169 for( j = 0; j < syncstore->maxnsols; ++j )
170 {
171 SCIP_CALL( SCIPallocBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].sols[j], syncstore->ninitvars) );
172 }
173
174 SCIP_CALL( SCIPtpiInitLock(&(syncstore->syncdata[i].lock)) );
175 SCIP_CALL( SCIPtpiInitCondition(&(syncstore->syncdata[i].allsynced)) );
176 }
177
178 syncstore->initialized = TRUE;
179 syncstore->stopped = FALSE;
180
181 SCIP_CALL( SCIPgetIntParam(scip, "parallel/mode", &paramode) );
182 syncstore->mode = (SCIP_PARALLELMODE) paramode;
183
184 SCIP_CALL( SCIPtpiInit(syncstore->nsolvers, INT_MAX, FALSE) );
186
187 if( syncstore->mode == SCIP_PARA_DETERMINISTIC )
188 {
189 /* in deterministic mode use the number of non-zeros and the number of variables to get a good
190 * syncdelay and maximum syncfreq
191 */
192 syncstore->minsyncdelay *= 0.01 * (SCIPgetNNZs(scip) * SCIPgetNVars(scip)); /*lint !e790*/
193 syncstore->syncfreqmax *= 0.01 * (SCIPgetNNZs(scip) * SCIPgetNVars(scip)); /*lint !e790*/
194 }
195
196 return SCIP_OKAY;
197}
198
199/** deinitializes the synchronization store */
201 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
202 )
203{
204 int i;
205 int j;
206
207 assert(syncstore != NULL);
208 assert(syncstore->initialized);
209
211
212 for( i = 0; i < syncstore->nsyncdata; ++i )
213 {
214 SCIPtpiDestroyLock(&(syncstore->syncdata[i].lock));
215 SCIPtpiDestroyCondition(&(syncstore->syncdata[i].allsynced));
216 SCIPfreeBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].solobj, syncstore->maxnsols);
217 SCIPfreeBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].solsource, syncstore->maxnsols);
218 SCIPboundstoreFree(syncstore->mainscip, &syncstore->syncdata[i].boundstore);
219
220 for( j = 0; j < syncstore->maxnsols; ++j )
221 {
222 SCIPfreeBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].sols[j], syncstore->ninitvars);
223 }
224
225 SCIPfreeBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata[i].sols, syncstore->maxnsols);
226 }
227
228 SCIPfreeBlockMemoryArray(syncstore->mainscip, &syncstore->syncdata, syncstore->nsyncdata);
229
230 syncstore->initialized = FALSE;
231 syncstore->stopped = FALSE;
232
233 return SCIP_OKAY;
234}
235
236/** checks whether the solve-is-stopped flag in the syncstore has been set by any thread */
238 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
239 )
240{
241 SCIP_Bool stopped;
242
244
245 stopped = syncstore->stopped;
246
248
249 return stopped;
250}
251
252/** sets the solve-is-stopped flag in the syncstore so that subsequent calls to
253 * SCIPsyncstoreSolveIsStopped will return the given value in any thread
254 */
256 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
257 SCIP_Bool stopped /**< flag if the solve is stopped */
258 )
259{
261
262 syncstore->stopped = stopped;
263
265}
266
267/** gets the upperbound from the last synchronization */
269 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
270 )
271{
272 assert(syncstore != NULL);
273 assert(syncstore->initialized);
274
275 return syncstore->lastsync == NULL ? SCIPinfinity(syncstore->mainscip) : syncstore->lastsync->bestupperbound;
276}
277
278/** gets the lowerbound from the last synchronization */
280 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
281 )
282{
283 assert(syncstore != NULL);
284 assert(syncstore->initialized);
285
286 return syncstore->lastsync == NULL ? -SCIPinfinity(syncstore->mainscip) : syncstore->lastsync->bestlowerbound;
287}
288
289/** gets the number of solutions from the last synchronization */
291 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
292 )
293{
294 assert(syncstore != NULL);
295 assert(syncstore->initialized);
296
297 return syncstore->lastsync == NULL ? 0 : syncstore->lastsync->nsols;
298}
299
300/** gets the number of boundchanges from the last synchronization */
302 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
303 )
304{
305 assert(syncstore != NULL);
306 assert(syncstore->initialized);
307
308 return syncstore->lastsync == NULL ? 0 : SCIPboundstoreGetNChgs(syncstore->lastsync->boundstore);
309}
310
311/** gets total memory used by all solvers from the last synchronization */
313 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
314 )
315{
316 assert(syncstore != NULL);
317 assert(syncstore->initialized);
318
319 return syncstore->lastsync == NULL ? 0 : syncstore->lastsync->memtotal;
320}
321
322/** gets the synchronization frequency from the last synchronization */
324 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
325 )
326{
327 assert(syncstore != NULL);
328 assert(syncstore->initialized);
329
330 return syncstore->lastsync == NULL ? 0.0 : syncstore->lastsync->syncfreq;
331}
332
333/** get synchronization data with given number. It is the responsibility of the caller
334 * to only ask for a synchronization number that still exists, which is checked
335 * with an assert in debug mode. */
337 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
338 SCIP_Longint syncnum /**< the number of the synchronization to start, which
339 * must be increasing between calls of the same thread */
340 )
341{
342 int j;
343
344 assert(syncstore != NULL);
345 assert(syncstore->initialized);
346
347 j = (int) syncnum % syncstore->nsyncdata;
348
349 /* check if requested syncnumber still exists if in debug mode */
350 assert(syncstore->syncdata[j].syncnum == syncnum);
351
352 return &syncstore->syncdata[j];
353}
354
355/** get the next synchronization data that should be read and
356 * adjust the delay. Returns NULL if no more data should be read due to minimum delay */
358 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
359 SCIP_SYNCDATA* syncdata, /**< the synchronization data */
360 SCIP_Real syncfreq, /**< the current synchronization frequency */
361 SCIP_Longint writenum, /**< number of synchronizations the solver has written to */
362 SCIP_Real* delay /**< pointer holding the current synchronization delay */
363 )
364{
365 SCIP_Real newdelay;
366 SCIP_Longint nextsyncnum;
367
368 assert(syncstore != NULL);
369 assert(syncstore->initialized);
370 assert(delay != NULL);
371
372 if( syncdata == NULL )
373 {
374 nextsyncnum = 0;
375 }
376 else
377 {
378 if( syncdata->status != SCIP_STATUS_UNKNOWN )
379 return NULL;
380
381 nextsyncnum = syncdata->syncnum + 1;
382 }
383
384 if( nextsyncnum == writenum )
385 return NULL;
386
387 newdelay = *delay - syncfreq;
388
389 /* if the delay would get too small we dont want to read the next syncdata.
390 * But due to the limited length of the syncdata array we might need to
391 * read this synchronization data anyways which is checked by the second part
392 * of the if condition
393 */
394 if( newdelay < syncstore->minsyncdelay && nextsyncnum >= writenum - syncstore->maxnsyncdelay )
395 return NULL;
396
397 *delay = newdelay;
398 assert(syncstore->syncdata[nextsyncnum % syncstore->nsyncdata].syncnum == nextsyncnum);
399
400 return &syncstore->syncdata[nextsyncnum % syncstore->nsyncdata];
401}
402
403/** ensures that the given synchronization data has been written by
404 * all solvers upon return of this function and blocks the caller if necessary. */
406 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
407 SCIP_SYNCDATA* syncdata /**< the synchronization data */
408 )
409{
410 assert(syncdata != NULL);
411 assert(syncstore != NULL);
412 assert(syncstore->initialized);
413
414 /* check if waiting is required, make sure to hold the lock */
415 SCIP_CALL( SCIPtpiAcquireLock(&syncdata->lock) );
416
417 while( syncdata->syncedcount < syncstore->nsolvers )
418 {
419 /* yes, so wait on the condition variable
420 * (automatically releases the lock and reacquires it after the waiting)
421 */
422 SCIP_CALL( SCIPtpiWaitCondition(&syncdata->allsynced, &syncdata->lock) );
423 }
424
425 SCIP_CALL( SCIPtpiReleaseLock(&syncdata->lock) );
426
427 return SCIP_OKAY;
428}
429
430/** Start synchronization for the given concurrent solver.
431 * Needs to be followed by a call to SCIPsyncstoreFinishSync if
432 * the syncdata that is returned is not NULL
433 */
435 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
436 SCIP_Longint syncnum, /**< the number of the synchronization to start, which
437 * must be increasing between calls of the same thread */
438 SCIP_SYNCDATA** syncdata /**< pointer to return the synchronization data */
439 )
440{
441 int i;
442
443 assert(syncdata != NULL);
444 assert(syncstore != NULL);
445 assert(syncstore->initialized);
446
447 if( SCIPsyncstoreSolveIsStopped(syncstore) )
448 {
449 *syncdata = NULL;
450 return SCIP_OKAY;
451 }
452
453 i = syncnum % syncstore->nsyncdata; /*lint !e712*/
454 *syncdata = &syncstore->syncdata[i];
455 assert(*syncdata != NULL);
456
457 SCIP_CALL( SCIPtpiAcquireLock(&(*syncdata)->lock) );
458
459 if( (*syncdata)->syncnum != syncnum )
460 {
461 SCIPboundstoreClear((*syncdata)->boundstore);
462 (*syncdata)->nsols = 0;
463 (*syncdata)->memtotal = SCIPgetMemTotal(syncstore->mainscip);
464 (*syncdata)->syncedcount = 0;
465 (*syncdata)->bestupperbound = SCIPinfinity(syncstore->mainscip);
466 (*syncdata)->bestlowerbound = -(*syncdata)->bestupperbound;
467 (*syncdata)->status = SCIP_STATUS_UNKNOWN;
468 (*syncdata)->winner = 0;
469 (*syncdata)->syncnum = syncnum;
470 (*syncdata)->syncfreq = 0.0;
471 }
472
473 return SCIP_OKAY;
474}
475
476/** finishes synchronization for the synchronization data */
478 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
479 SCIP_SYNCDATA** syncdata /**< the synchronization data */
480 )
481{
482 SCIP_Bool printline = FALSE;
483
484 assert(syncdata != NULL);
485 assert((*syncdata) != NULL);
486 assert(syncstore != NULL);
487 assert(syncstore->initialized);
488
489 ++(*syncdata)->syncedcount;
490
491 if( (*syncdata)->syncedcount == syncstore->nsolvers )
492 {
493 if( (*syncdata)->status != SCIP_STATUS_UNKNOWN )
495
496 syncstore->lastsync = *syncdata;
497 printline = TRUE;
498
499 SCIP_CALL( SCIPtpiBroadcastCondition(&(*syncdata)->allsynced) );
500 }
501
502 SCIP_CALL( SCIPtpiReleaseLock(&(*syncdata)->lock) );
503
504 if( printline )
505 {
507 }
508
509 *syncdata = NULL;
510
511 return SCIP_OKAY;
512}
513
514/** gets status in synchronization data */
516 SCIP_SYNCDATA* syncdata /**< the synchronization data */
517 )
518{
519 assert(syncdata != NULL);
520
521 return syncdata->status;
522}
523
524/** gets the solver that had the best status, or -1 if solve is not stopped yet */
526 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
527 )
528{
529 assert(syncstore != NULL);
530 assert(syncstore->initialized);
531
532 if( syncstore->lastsync == NULL || syncstore->lastsync->status == SCIP_STATUS_UNKNOWN )
533 return -1;
534
535 return syncstore->lastsync->winner;
536}
537
538/** how many solvers have already finished synchronizing on this sychronization data */
540 SCIP_SYNCDATA* syncdata /**< the synchronization data */
541 )
542{
543 assert(syncdata != NULL);
544
545 return syncdata->syncedcount;
546}
547
548/** how many solvers have are running concurrently */
550 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
551 )
552{
553 assert(syncstore != NULL);
554 assert(syncstore->initialized);
555
556 return syncstore->nsolvers;
557}
558
559/** read amount total memory used from synchronization data */
561 SCIP_SYNCDATA* syncdata /**< the synchronization data */
562 )
563{
564 assert(syncdata != NULL);
565
566 return syncdata->memtotal;
567}
568
569/** read the synchronization frequency from a synchronization data */
571 SCIP_SYNCDATA* syncdata /**< the synchronization data */
572 )
573{
574 assert(syncdata != NULL);
575
576 return syncdata->syncfreq;
577}
578
579/** read the upperbound stored in a synchronization data */
581 SCIP_SYNCDATA* syncdata /**< the synchronization data */
582 )
583{
584 assert(syncdata != NULL);
585
586 return syncdata->bestupperbound;
587}
588
589/** read the lowerbound stored in a synchronization data */
591 SCIP_SYNCDATA* syncdata /**< the synchronization data */
592 )
593{
594 assert(syncdata != NULL);
595
596 return syncdata->bestlowerbound;
597}
598
599/** read the solutions stored in a synchronization data */
601 SCIP_SYNCDATA* syncdata, /**< the synchronization data */
602 SCIP_Real*** solvalues, /**< array of buffers containing the solution values */
603 int** solowner, /**< array of ownerids of solutions */
604 int* nsols /**< pointer to return number of solutions */
605 )
606{
607 assert(syncdata != NULL);
609 assert(solowner != NULL);
610 assert(nsols != NULL);
611
612 *solvalues = syncdata->sols;
613 *solowner = syncdata->solsource;
614 *nsols = syncdata->nsols;
615}
616
617/** read bound changes stored in the synchronization data */
619 SCIP_SYNCDATA* syncdata /**< the synchronization data */
620 )
621{
622 assert(syncdata != NULL);
623
624 return syncdata->boundstore;
625}
626
627/** write the synchronization frequency to a synchronization data */
629 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
630 SCIP_SYNCDATA* syncdata, /**< the synchronization data */
631 SCIP_Real syncfreq /**< the synchronization frequency */
632 )
633{
634 assert(syncstore != NULL);
635 assert(syncstore->initialized);
636 assert(syncdata != NULL);
637
638 syncdata->syncfreq = MIN(syncfreq, syncstore->syncfreqmax);
639}
640
641/** set status in the synchronization data */
643 SCIP_SYNCDATA* syncdata, /**< the synchronization data the upperbound should be added to */
644 SCIP_STATUS status, /**< the status */
645 int solverid /**< identifier of te solver that has this status */
646 )
647{
648 assert(syncdata != NULL);
649
650 /* check if status is better than current one (closer to SCIP_STATUS_OPTIMAL),
651 * break ties by the solverid, and remember the solver wit the best status
652 * so that the winner will be selected deterministically
653 */
654 if( syncdata->status < SCIP_STATUS_OPTIMAL )
655 {
656 if( status > syncdata->status || (status == syncdata->status && solverid < syncdata->winner) )
657 {
658 syncdata->status = status;
659 syncdata->winner = solverid;
660 }
661 }
662 else if( syncdata->status > SCIP_STATUS_OPTIMAL && status >= SCIP_STATUS_OPTIMAL )
663 {
664 if( status < syncdata->status || (status == syncdata->status && solverid < syncdata->winner) )
665 {
666 syncdata->status = status;
667 syncdata->winner = solverid;
668 }
669 }
670 else if( syncdata->winner < 0 )
671 {
672 syncdata->status = status;
673 syncdata->winner = solverid;
674 }
675}
676
677/** adds memory used to the synchronization data */
679 SCIP_SYNCDATA* syncdata, /**< the synchronization data the solution should be added to */
680 SCIP_Longint memtotal /**< the number of bytes used */
681 )
682{
683 assert(syncdata != NULL);
684
685 syncdata->memtotal += memtotal;
686}
687
688/** set upperbound to the synchronization data */
690 SCIP_SYNCDATA* syncdata, /**< the synchronization data the upperbound should be added to */
691 SCIP_Real upperbound /**< the upperbound */
692 )
693{
694 assert(syncdata != NULL);
695
696 syncdata->bestupperbound = MIN(syncdata->bestupperbound, upperbound);
697}
698
699/** set lowerbound to the synchronization data */
701 SCIP_SYNCDATA* syncdata, /**< the synchronization data the lowerbound should be added to */
702 SCIP_Real lowerbound /**< the lowerbound */
703 )
704{
705 assert(syncdata != NULL);
706
707 syncdata->bestlowerbound = MAX(syncdata->bestlowerbound, lowerbound);
708}
709
710/** gives a buffer to store the solution values, or NULL if solution should not be stored
711 * because there are already better solutions stored.
712 */
714 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
715 SCIP_SYNCDATA* syncdata, /**< the synchronization data the solution should be added to */
716 SCIP_Real solobj, /**< the objective value of the solution */
717 int ownerid, /**< an identifier for the owner of the solution, e.g. the thread number */
718 SCIP_Real** buffer /**< pointer to return a buffer for the solution values, which must be set
719 * if the buffer is not NULL */
720 )
721{
722 int pos;
723 int i;
724
725 assert(syncstore != NULL);
726 assert(syncstore->initialized);
727 assert(syncdata != NULL);
728 assert(buffer != NULL);
729
730 for( pos = 0; pos < syncdata->nsols; ++pos )
731 {
732 if( syncdata->solobj[pos] < solobj || (syncdata->solobj[pos] == solobj && ownerid < syncdata->solsource[pos]) ) /*lint !e777*/
733 break;
734 }
735
736 if( syncdata->nsols < syncstore->maxnsols )
737 {
738 for( i = syncdata->nsols; i > pos; --i )
739 {
740 syncdata->solobj[i] = syncdata->solobj[i - 1];
741 syncdata->solsource[i] = syncdata->solsource[i - 1];
742 SCIPswapPointers((void**) &syncdata->sols[i], (void**) &syncdata->sols[i - 1]);
743 }
744
745 ++syncdata->nsols;
746 }
747 else
748 {
749 --pos;
750
751 for( i = 0; i < pos; ++i )
752 {
753 syncdata->solobj[i] = syncdata->solobj[i + 1];
754 syncdata->solsource[i] = syncdata->solsource[i + 1];
755 SCIPswapPointers((void**) &syncdata->sols[i], (void**) &syncdata->sols[i + 1]);
756 }
757 }
758
759 if( pos >= 0 )
760 {
761 syncdata->solobj[pos] = solobj;
762 syncdata->solsource[pos] = ownerid;
763 *buffer = syncdata->sols[pos];
764 }
765 else
766 {
767 *buffer = NULL;
768 }
769}
770
771/** adds bound changes to the synchronization data */
773 SCIP_SYNCSTORE* syncstore, /**< the synchronization store */
774 SCIP_SYNCDATA* syncdata, /**< the synchronization data */
775 SCIP_BOUNDSTORE* boundstore /**< bound store containing the bounds to add */
776 )
777{
778 assert(syncstore != NULL);
779 assert(syncstore->initialized);
780 assert(syncdata != NULL);
781 assert(boundstore != NULL);
782
783 SCIP_CALL( SCIPboundstoreMerge(syncstore->mainscip, syncdata->boundstore, boundstore) );
784
785 return SCIP_OKAY;
786}
787
788/** is synchronization store initialized */
790 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
791 )
792{
793 assert(syncstore != NULL);
794
795 return syncstore->initialized;
796}
797
798/** returns the mode of the synchronization store */
800 SCIP_SYNCSTORE* syncstore /**< the synchronization store */
801 )
802{
803 assert(syncstore != NULL);
804
805 return syncstore->mode;
806}
SCIP_RETCODE SCIPboundstoreMerge(SCIP *scip, SCIP_BOUNDSTORE *target, SCIP_BOUNDSTORE *source)
Definition boundstore.c:124
void SCIPboundstoreFree(SCIP *scip, SCIP_BOUNDSTORE **boundstore)
Definition boundstore.c:60
SCIP_RETCODE SCIPboundstoreCreate(SCIP *scip, SCIP_BOUNDSTORE **boundstore, int nvars)
Definition boundstore.c:39
void SCIPboundstoreClear(SCIP_BOUNDSTORE *boundstore)
Definition boundstore.c:146
int SCIPboundstoreGetNChgs(SCIP_BOUNDSTORE *boundstore)
Definition boundstore.c:197
the interface of the boundstore structure
datastructures for concurrent solvers
int SCIPgetNConcurrentSolvers(SCIP *scip)
Definition concurrent.c:116
helper functions for concurrent scip solvers
common defines and data types used in all packages of SCIP
#define SCIP_ALLOC(x)
Definition def.h:399
#define TRUE
Definition def.h:95
#define FALSE
Definition def.h:96
#define SCIP_CALL_ABORT(x)
Definition def.h:367
#define SCIP_CALL(x)
Definition def.h:388
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:1992
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition scip_param.c:307
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition scip_param.c:269
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition misc.c:10307
SCIP_RETCODE SCIPautoselectDisps(SCIP *scip)
Definition scip_disp.c:132
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
SCIP_Longint SCIPgetMemTotal(SCIP *scip)
Definition scip_mem.c:113
SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
SCIP_RETCODE SCIPprintDisplayLine(SCIP *scip, FILE *file, SCIP_VERBLEVEL verblevel, SCIP_Bool endline)
SCIP_Longint SCIPgetNNZs(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
#define NULL
Definition lpi_spx1.cpp:161
memory allocation routines
#define BMSfreeMemory(ptr)
Definition memory.h:147
#define BMSallocMemory(ptr)
Definition memory.h:120
internal methods for storing and manipulating the main problem
public methods for message output
#define SCIPdebugMessage
Definition pub_message.h:96
SCIP callable library.
SCIP_Bool initialized
SCIP_SYNCDATA * syncdata
SCIP_Real syncfreqmax
SCIP_Real syncfreqinit
SCIP_PARALLELMODE mode
SCIP_SYNCDATA * lastsync
SCIP_Real minsyncdelay
datastructures for concurrent solvers
the struct definitions for the synchronization store
SCIP_Bool SCIPsyncstoreSolveIsStopped(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:237
SCIP_Real SCIPsyncdataGetSyncFreq(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:570
SCIP_Longint SCIPsyncdataGetMemTotal(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:560
SCIP_BOUNDSTORE * SCIPsyncdataGetBoundChgs(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:618
SCIP_Real SCIPsyncstoreGetLastUpperbound(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:268
SCIP_RETCODE SCIPsyncstoreFinishSync(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA **syncdata)
Definition syncstore.c:477
SCIP_Real SCIPsyncstoreGetLastLowerbound(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:279
SCIP_Real SCIPsyncdataGetUpperbound(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:580
void SCIPsyncdataSetUpperbound(SCIP_SYNCDATA *syncdata, SCIP_Real upperbound)
Definition syncstore.c:689
SCIP_RETCODE SCIPsyncdataAddBoundChanges(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata, SCIP_BOUNDSTORE *boundstore)
Definition syncstore.c:772
int SCIPsyncstoreGetWinner(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:525
SCIP_RETCODE SCIPsyncstoreEnsureAllSynced(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata)
Definition syncstore.c:405
void SCIPsyncdataSetSyncFreq(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata, SCIP_Real syncfreq)
Definition syncstore.c:628
SCIP_Real SCIPsyncstoreGetLastSyncfreq(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:323
void SCIPsyncdataGetSolutions(SCIP_SYNCDATA *syncdata, SCIP_Real ***solvalues, int **solowner, int *nsols)
Definition syncstore.c:600
void SCIPsyncdataSetStatus(SCIP_SYNCDATA *syncdata, SCIP_STATUS status, int solverid)
Definition syncstore.c:642
void SCIPsyncstoreSetSolveIsStopped(SCIP_SYNCSTORE *syncstore, SCIP_Bool stopped)
Definition syncstore.c:255
SCIP_RETCODE SCIPsyncstoreRelease(SCIP_SYNCSTORE **syncstore)
Definition syncstore.c:87
SCIP_Longint SCIPsyncstoreGetLastMemTotal(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:312
SCIP_RETCODE SCIPsyncstoreExit(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:200
void SCIPsyncdataSetLowerbound(SCIP_SYNCDATA *syncdata, SCIP_Real lowerbound)
Definition syncstore.c:700
SCIP_RETCODE SCIPsyncstoreCapture(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:122
int SCIPsyncstoreGetLastNBounds(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:301
static int getNSyncdata(SCIP *scip)
Definition syncstore.c:54
int SCIPsyncstoreGetLastNSols(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:290
SCIP_RETCODE SCIPsyncstoreStartSync(SCIP_SYNCSTORE *syncstore, SCIP_Longint syncnum, SCIP_SYNCDATA **syncdata)
Definition syncstore.c:434
void SCIPsyncdataGetSolutionBuffer(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata, SCIP_Real solobj, int ownerid, SCIP_Real **buffer)
Definition syncstore.c:713
SCIP_Real SCIPsyncdataGetLowerbound(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:590
SCIP_PARALLELMODE SCIPsyncstoreGetMode(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:799
SCIP_RETCODE SCIPsyncstoreCreate(SCIP_SYNCSTORE **syncstore)
Definition syncstore.c:66
int SCIPsyncdataGetNSynced(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:539
SCIP_SYNCDATA * SCIPsyncstoreGetSyncdata(SCIP_SYNCSTORE *syncstore, SCIP_Longint syncnum)
Definition syncstore.c:336
SCIP_Bool SCIPsyncstoreIsInitialized(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:789
SCIP_SYNCDATA * SCIPsyncstoreGetNextSyncdata(SCIP_SYNCSTORE *syncstore, SCIP_SYNCDATA *syncdata, SCIP_Real syncfreq, SCIP_Longint writenum, SCIP_Real *delay)
Definition syncstore.c:357
void SCIPsyncdataAddMemTotal(SCIP_SYNCDATA *syncdata, SCIP_Longint memtotal)
Definition syncstore.c:678
int SCIPsyncstoreGetNSolvers(SCIP_SYNCSTORE *syncstore)
Definition syncstore.c:549
SCIP_STATUS SCIPsyncdataGetStatus(SCIP_SYNCDATA *syncdata)
Definition syncstore.c:515
SCIP_RETCODE SCIPsyncstoreInit(SCIP *scip)
Definition syncstore.c:136
the function declarations for the synchronization store
#define MAX(x, y)
Definition tclique_def.h:92
the type definitions for the SCIP parallel interface
SCIP_RETCODE SCIPtpiInitCondition(SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiWaitCondition(SCIP_CONDITION *condition, SCIP_LOCK *lock)
Definition tpi_openmp.c:304
SCIP_RETCODE SCIPtpiAcquireLock(SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiInitLock(SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiExit(void)
Definition tpi_none.c:90
SCIP_RETCODE SCIPtpiBroadcastCondition(SCIP_CONDITION *condition)
Definition tpi_openmp.c:289
void SCIPtpiDestroyLock(SCIP_LOCK *lock)
void SCIPtpiDestroyCondition(SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiReleaseLock(SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiInit(int nthreads, int queuesize, SCIP_Bool blockwhenfull)
Definition tpi_none.c:76
@ SCIP_VERBLEVEL_HIGH
enum SCIP_Retcode SCIP_RETCODE
@ SCIP_STATUS_OPTIMAL
Definition type_stat.h:61
@ SCIP_STATUS_UNKNOWN
Definition type_stat.h:42
enum SCIP_Status SCIP_STATUS
Definition type_stat.h:67
enum SCIP_Parallelmode SCIP_PARALLELMODE
@ SCIP_PARA_DETERMINISTIC
struct SCIP_SyncData SCIP_SYNCDATA