Scippy

UG

Ubiquity Generator framework

parascip.cpp
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and software framework */
4/* UG --- Ubquity Generator Framework */
5/* */
6/* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7/* Copyright (C) 2021-2025 by Zuse Institute Berlin, */
8/* licensed under LGPL version 3 or later. */
9/* Commercial licenses are available through <licenses@zib.de> */
10/* */
11/* This code is free software; you can redistribute it and/or */
12/* modify it under the terms of the GNU Lesser General Public License */
13/* as published by the Free Software Foundation; either version 3 */
14/* of the License, or (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU Lesser General Public License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file parascip.cpp
27 * @brief ParaSCIP MAIN.
28 * @author Yuji Shinano
29 *
30 *
31 *
32 */
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36
37#include <cfloat>
38#include "ug/paraInstance.h"
40#include "ug/paraParamSet.h"
42#include "ug/paraInitiator.h"
43#include "ug_bb/bbParaNodeMpi.h"
44#include "ug/paraSysTimer.h"
45#include "scip/scip.h"
46#include "scipParaCommMpi.h"
47#include "scipParaInstance.h"
49#include "scipParaSolver.h"
50#include "scipParaInitiator.h"
52
53using namespace UG;
54using namespace ParaSCIP;
55
56extern void
58extern void
60extern void
62
63void
65 char **argv
66 )
67{
68 std::cout << std::endl;
69 std::cout << "syntax: mpirun(command provided by MPI) #MPI_processes(#solvers + 1) " << argv[0] << " parascip_param_file problem_file_name "
70 << "[-l <logfile>] [-q] [-sl <settings>] [-s <settings>] [-sr <root_settings>] [-w <prefix_warm>] [-sth <number>] [-fsol <solution_file>] [-isol <initial solution file]" << std::endl;
71 std::cout << " -l <logfile> : copy output into log file" << std::endl;
72 std::cout << " -q : suppress screen messages" << std::endl;
73 std::cout << " -sl <settings> : load parameter settings (.set) file for LC presolving" << std::endl;
74 std::cout << " -s <settings> : load parameter settings (.set) file for solvers" << std::endl;
75 std::cout << " -sr <root_settings> : load parameter settings (.set) file for root" << std::endl;
76 std::cout << " -w <prefix_warm> : warm start file prefix ( prefix_warm_nodes.gz and prefix_warm_solution.txt are read )" << std::endl;
77 std::cout << " -fsol <solution file> : specify output solution file" << std::endl;
78 std::cout << " -isol <intial solution file> : specify initial solution file" << std::endl;
79 std::cout << "File names need to be specified by full path form." << std::endl;
80
81// std::cout << "TagKeepRacing == " << TagKeepRacing << std::endl;
82// std::cout << "TagTerminateSolvingToRestart == " << TagTerminateSolvingToRestart << std::endl;
83// std::cout << "TagSelfSplitFinished == " << TagSelfSplitFinished << std::endl;
84}
85
86void
90 )
91{
93 {
94 std::ofstream ofsParamsOutputFile;
95 std::ostringstream s;
97 {
99 }
100 else
101 {
104 }
105 s << ".prm";
106 ofsParamsOutputFile.open(s.str().c_str());
107 if( !ofsParamsOutputFile ){
108 std::cout << "Cannot open ParaParams output file: file name = " << s.str() << std::endl;
109 exit(1);
110 }
111 paraParamSet->write(&ofsParamsOutputFile);
112 ofsParamsOutputFile.close();
113 }
114}
115
116void
120 )
121{
123 {
124 std::ofstream ofsSolverParamsOutputFile;
125 std::ostringstream s;
127 {
129 }
130 else
131 {
134 }
135 s << "_solver.prm";
136 ofsSolverParamsOutputFile.open(s.str().c_str());
137 if( !ofsSolverParamsOutputFile ){
138 std::cout << "Cannot open Solver parameters output file: file name = " << s.str() << std::endl;
139 exit(1);
140 }
141 paraInitiator->writeSolverParameters(&ofsSolverParamsOutputFile);
142 ofsSolverParamsOutputFile.close();
143 }
144}
145
146/**************************************************************************************
147 * *
148 * Command line see outputCommandLineMessages() *
149 * *
150 **************************************************************************************/
151int
153 int argc,
154 char **argv
155 )
156{
157 // mtrace();
158 static const int solverOrigin = 1;
159
160 bool racingSolversExist = false;
161 ParaDeterministicTimer *detTimer = 0;
162
163 ParaSysTimer sysTimer;
164 sysTimer.start();
165
166#ifdef UG_WITH_UGS
167 char *configFileName = 0;
168 for( int i = 1; i < argc; ++i )
169 {
170 if ( strcmp(argv[i], "-ugsc") == 0 )
171 {
172 i++;
173 if( i < argc )
174 {
175 configFileName = argv[i];
176 break;
177 }
178 else
179 {
180 std::cerr << "missing file name after parameter '-ugsc" << std::endl;
181 exit(1);
182 }
183 }
184 }
185
187 UGS::UgsParaCommMpi *commUgs = 0; // commUgs != 0 means ParaScip runs under UGS
188 if( configFileName )
189 {
190 commUgs = new UGS::UgsParaCommMpi();
191 commUgs->init(argc,argv);
192 comm = new ScipParaCommMpi(commUgs->getSolverMPIComm());
193 comm->setUgsComm(commUgs);
194 }
195 else
196 {
197 comm = new ScipParaCommMpi();
198 }
199#else
200 // ParaComm *comm = new PARA_COMM_TYPE();
202#endif
203
204 comm->init(argc,argv);
205
206 ParaTimer *paraTimer = new ParaTimerMpi();
207 paraTimer->init(comm);
208
210
211#ifndef SCIP_THREADSAFE_MESSAGEHDLRS
212 SCIP_CALL_ABORT( SCIPcreateMesshdlrPThreads(1) );
213 SCIPmessageSetDefaultHandler();
214#endif
215
216 if( comm->getRank() == 0 )
217 {
218 if( argc < 3 )
219 {
221 return 1;
222 }
223 paraParamSet->read(comm, argv[1]);
224
229 if( paraInitiator->init(paraParamSet, argc, argv) )
230 {
231 if( dynamic_cast<ScipParaInitiator *>(paraInitiator)->isSolvedAtInit() )
232 {
234 delete paraInitiator;
235 delete paraParamSet;
236 delete paraTimer;
237 if( detTimer ) delete detTimer;
238// sysTimer.stop();
239// std::cout << "[ Rank: " << comm->getRank() << " ], UTime = " << sysTimer.getUTime()
240// << ", STime = " << sysTimer.getSTime() << ", RTime = " << sysTimer.getRTime() << std::endl;
241 comm->abort();
242 delete comm;
243#ifdef UG_WITH_UGS
244 if( commUgs ) delete commUgs;
245#endif
246 return 0;
247 }
248 }
249 std::cout << "** Initiatior was initilized after " << paraTimer->getElapsedTime() << " sec." << std::endl;
250 ParaInstance *paraInstance = paraInitiator->getParaInstance();
252 {
255 }
257 paraInitiator->sendSolverInitializationMessage(); // This messages should be received in constructor of the target Solver
258 std::cout << "** Instance data were sent to all solvers after " << paraTimer->getElapsedTime() << " sec." << std::endl;
261 {
262 detTimer = new ScipParaDeterministicTimer();
263 }
264 if( dynamic_cast<ScipParaInitiator *>(paraInitiator)->isSolvedAtInit() )
265 {
266#ifdef UG_WITH_UGS
267 paraLc = new ScipParaLoadCoordinator(commUgs, comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
268#else
269 paraLc = new ScipParaLoadCoordinator(comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
270#endif
271 delete paraLc;
272 delete paraInitiator;
273 delete paraParamSet;
274 delete paraTimer;
275 if( detTimer ) delete detTimer;
276
277// sysTimer.stop();
278// std::cout << "[ Rank: " << comm->getRank() << " ], UTime = " << sysTimer.getUTime()
279// << ", STime = " << sysTimer.getSTime() << ", RTime = " << sysTimer.getRTime() << std::endl;
280
281 comm->abort();
282 delete comm;
283#ifdef UG_WITH_UGS
284 if( commUgs ) delete commUgs;
285#endif
286 return 0;
287 }
288 else
289 {
290#ifdef UG_WITH_UGS
291 paraLc = new ScipParaLoadCoordinator(commUgs, comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
292#else
293 paraLc = new ScipParaLoadCoordinator(comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
294#endif
295 }
297 {
298#ifdef UG_WITH_ZLIB
299 paraLc->warmStart();
300#endif
301 }
302 else
303 {
306 {
307 ParaTask *rootNode = new BbParaNodeMpi(
308 TaskId(), TaskId(), 0, -DBL_MAX, -DBL_MAX, -DBL_MAX,
309 dynamic_cast<ScipParaInitiator *>(paraInitiator)->makeRootNodeDiffSubproblem());
310 paraLc->run(rootNode);
311 }
313 paraParamSet->getIntParamValue(RampUpPhaseProcess) <= 2 ) // racing ramp-up
314 {
316 paraInitiator->generateRacingRampUpParameterSets( (comm->getSize()-1), racingRampUpParams );
317 for( int i = 1; i < comm->getSize(); i++ )
318 {
319 int noKeep = 0;
321 comm->send( &noKeep, 1, ParaINT, i, UG::TagKeepRacing)
322 );
324 racingRampUpParams[i-solverOrigin]->send(comm, i)
325 );
326 }
327 ParaTask *rootNode = new BbParaNodeMpi(
328 TaskId(), TaskId(), 0, -DBL_MAX, -DBL_MAX, -DBL_MAX,
329 dynamic_cast<ScipParaInitiator *>(paraInitiator)->makeRootNodeDiffSubproblem());
330 paraLc->run(rootNode, (comm->getSize()-1), racingRampUpParams );
331 for( int i = 1; i < comm->getSize(); i++ )
332 {
333 if( racingRampUpParams[i-solverOrigin] ) delete racingRampUpParams[i-solverOrigin];
334 }
335 delete [] racingRampUpParams;
336 }
337 else
338 {
339 THROW_LOGICAL_ERROR2("Invalid RampUpPhaseProcess: ", paraParamSet->getIntParamValue(RampUpPhaseProcess) )
340 }
341 }
342 delete paraLc;
343 if( paraInitiator ) delete paraInitiator;
344 }
345 else
346 {
347 if( argc < 3 )
348 {
349 return 1;
350 }
353 int nNonLinearConsHdlrs = 0;
355 comm->bcast( &nNonLinearConsHdlrs, 1, ParaINT, 0 )
356 );
357 ParaInstance *paraInstance = comm->createParaInstance();
358 setUserPlugins(paraInstance);
359 if( nNonLinearConsHdlrs > 0 )
360 {
362 }
364 {
365 ScipParaInstanceMpi *scipParaInstanceMpi = dynamic_cast<ScipParaInstanceMpi *>(paraInstance);
366 scipParaInstanceMpi->setFileName(argv[2]);
367 }
370 {
371 detTimer = new ScipParaDeterministicTimer();
372 }
373 ParaSolver *paraSolver = new ScipParaSolver(argc, argv, comm, paraParamSet, paraInstance, detTimer);
374 // setUserPlugins(paraSolver); too late!! user plugin is necessary when instance data are read
375 dynamic_cast<ScipParaSolver *>(paraSolver)->setProblemFileName(argv[2]);
376 // if( paraParamSet->getIntParamValue(RampUpPhaseProcess) == 0 || paraSolver->isWarmStarted() )
379 {
380 paraSolver->run();
381 }
383 paraParamSet->getIntParamValue(RampUpPhaseProcess) <= 2 ) // racing ramp-up
384 {
385 int source;
386 int tag;
387 (void)comm->probe(&source, &tag);
388 if( tag == TagKeepRacing )
389 {
390 int keep = 0;
392 comm->receive( &keep, 1, ParaINT, 0, UG::TagKeepRacing)
393 );
394 if( keep == 0 )
395 {
396 dynamic_cast<BbParaSolver *>(paraSolver)->setKeepRacing(false);
397 }
398 else
399 {
400 dynamic_cast<BbParaSolver *>(paraSolver)->setKeepRacing(true);
401 }
402 (void)comm->probe(&source, &tag);
403 ParaRacingRampUpParamSet *racingRampUpParamSet = new ScipParaRacingRampUpParamSetMpi();
405 racingRampUpParamSet->receive(comm, 0)
406 );
407 paraSolver->run( racingRampUpParamSet );
408 // delete racingRampUpParamSet; // racingRampUpParamSet is set in Solver object and deleted in the object
409 }
410 else
411 {
412 if( tag == TagTerminateRequest )
413 {
415 comm->receive( NULL, 0, ParaBYTE, source, TagTerminateRequest )
416 );
417 // when solver is deleted, solver's destructor sends termination status
418 }
419 else
420 {
421 THROW_LOGICAL_ERROR2("Invalid Tag is recicv3ed in ParaSCIP solver main: ", tag )
422 }
423 }
424 }
425 else
426 {
427 THROW_LOGICAL_ERROR2("Invalid RampUpPhaseProcess: ", paraParamSet->getIntParamValue(RampUpPhaseProcess) )
428 }
429 delete paraSolver;
430 //if( paraInstance ) delete paraInstance; /** deleted in paraSolver destructor */
431 }
432
433 delete paraParamSet;
434
435// sysTimer.stop();
436// std::cout << "[ Rank: " << comm->getRank() << " ], UTime = " << sysTimer.getUTime()
437// << ", STime = " << sysTimer.getSTime() << ", RTime = " << sysTimer.getRTime() << std::endl;
438
439
440#ifndef SCIP_THREADSAFE_MESSAGEHDLRS
441 SCIPfreeMesshdlrPThreads();
442#endif
443
444 delete paraTimer;
445 if( detTimer ) delete detTimer;
446
447 if( racingSolversExist ) comm->abort();
448
449 delete comm;
450
451#ifdef UG_WITH_UGS
452 if( commUgs ) delete commUgs;
453#endif
454
455 return 0;
456
457} /* END main */
BbParaNode extension for MIP communication.
UG::ParaInstance * createParaInstance()
UG::ParaParamSet * createParaParamSet()
void outputFinalSolverStatistics(std::ostream *os, double time)
void generateRacingRampUpParameterSets(int nParamSets, UG::ParaRacingRampUpParamSet **racingRampUpParamSets)
void writeSolverParameters(std::ostream *os)
UG::ParaInstance * getParaInstance()
virtual int init(UG::ParaParamSet *paraParams, int argc, char **argv)
void setFileName(const char *inFileName)
virtual void run()
run function to start main process
virtual void warmStart()
warm start (restart)
class BbParaNodeMpi
Definition: bbParaNodeMpi.h:53
void read(ParaComm *comm, const char *filename)
read ParaParams from file
class BbParaSolver
Definition: bbParaSolver.h:64
virtual void solverInit(ParaParamSet *paraParamSet)
initializer for Solvers
bool probe(int *source, int *tag)
probe function which waits a new message
int send(void *bufer, int count, const int datatypeId, int dest, const int tag)
send function for standard ParaData types
int receive(void *bufer, int count, const int datatypeId, int source, const int tag)
receive function for standard ParaData types
int getSize()
get size of this communicator, which indicates how many threads in a UG process
int getRank()
get rank of caller's thread
virtual void init(int argc, char **argv)
initializer of this communicator
void abort()
abort. How it works sometimes depends on communicator used
int bcast(void *buffer, int count, const int datatypeId, int root)
broadcast function for standard ParaData types
virtual void lcInit(ParaParamSet *paraParamSet)
initializer for LoadCoordinator
class for deterministic timer
Class for initiator.
Definition: paraInitiator.h:63
const char * getPrefixWarm()
get prefix of warm start (restart) files
bool isWarmStarted()
check if the execution is warm started (restarted) or not
class for instance data
Definition: paraInstance.h:51
virtual int bcast(ParaComm *comm, int rank, int method)=0
broadcast function to all solvers
virtual const char * getProbName()=0
get problem name
Class for LoadCoordinator.
int bcast(ParaComm *comm, int root)
broadcast ParaParams
class ParaParamSet
Definition: paraParamSet.h:850
bool getBoolParamValue(int param)
get bool parameter value
void write(std::ostream *os)
write ParaParams to output stream
void setIntParamValue(int param, int value)
set int parameter value
int getIntParamValue(int param)
get int parameter value
const char * getStringParamValue(int param)
get string parameter value
class ParaRacingRampUpParamSet (parameter set for racing ramp-up)
virtual int receive(ParaComm *comm, int source)=0
receive ParaRacingRampUpParamSet
class ParaSolver
Definition: paraSolver.h:71
virtual void run()=0
run this Solver
Class ParaSysTimer.
Definition: paraSysTimer.h:107
void start(void)
start timer
class ParaTask
Definition: paraTask.h:542
class ParaTimerMpi (Timer used in MPI communication)
Definition: paraTimerMpi.h:51
class ParaTimer
Definition: paraTimer.h:49
virtual void init(ParaComm *paraComm)=0
initialize timer
virtual double getElapsedTime()=0
get elapsed time
TaskId class.
Definition: paraTask.h:223
static ScipParaCommTh * comm
Definition: fscip.cpp:73
static ScipParaLoadCoordinator * paraLc
Definition: fscip.cpp:77
static ScipParaInitiator * paraInitiator
Definition: fscip.cpp:76
static ScipParaParamSet * paraParamSet
Definition: fscip.cpp:74
static const int OutputParaParams
Definition: paraParamSet.h:87
static const int ParaINT
Definition: paraComm.h:66
static const int InstanceTransferMethod
static const int LogSolvingStatusFilePath
Definition: paraParamSet.h:127
static const int TagTerminateRequest
Definition: paraTagDef.h:56
static const int ParaBYTE
Definition: paraComm.h:79
static const int Deterministic
Definition: paraParamSet.h:76
static const int RampUpPhaseProcess
static const int TagKeepRacing
Definition: bbParaTagDef.h:69
static const int Quiet
Definition: paraParamSet.h:71
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
Base class of initiator that maintains original problem and incumbent solution.
Base class for instance data.
Load Coordinator.
Parameter set for UG framework.
Base class for racing ramp-up parameter set.
System timer.
int main(int argc, char **argv)
Definition: parascip.cpp:152
void outputParaParamSet(ParaParamSet *paraParamSet, ParaInitiator *paraInitiator)
Definition: parascip.cpp:87
void outputCommandLineMessages(char **argv)
Definition: parascip.cpp:64
void setUserPlugins(ParaInitiator *initiator)
void outputSolverParams(ParaParamSet *paraParamSet, ParaInitiator *paraInitiator)
Definition: parascip.cpp:117
SCIP ParaComm extension for MPI communication.
ParaDeterministicTimer extension for SCIP.
ParaInitiator extension for SCIP solver.
ParaInstance extenstion for SCIP solver.
ParaSolver extension for SCIP: Parallelized solver implementation for SCIP.