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-2024 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: " << argv[0] << " #MPI_processes(#solvers + 1) 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
82void
86 )
87{
89 {
90 std::ofstream ofsParamsOutputFile;
91 std::ostringstream s;
93 {
95 }
96 else
97 {
100 }
101 s << ".prm";
102 ofsParamsOutputFile.open(s.str().c_str());
103 if( !ofsParamsOutputFile ){
104 std::cout << "Cannot open ParaParams output file: file name = " << s.str() << std::endl;
105 exit(1);
106 }
107 paraParamSet->write(&ofsParamsOutputFile);
108 ofsParamsOutputFile.close();
109 }
110}
111
112void
116 )
117{
119 {
120 std::ofstream ofsSolverParamsOutputFile;
121 std::ostringstream s;
123 {
125 }
126 else
127 {
130 }
131 s << "_solver.prm";
132 ofsSolverParamsOutputFile.open(s.str().c_str());
133 if( !ofsSolverParamsOutputFile ){
134 std::cout << "Cannot open Solver parameters output file: file name = " << s.str() << std::endl;
135 exit(1);
136 }
137 paraInitiator->writeSolverParameters(&ofsSolverParamsOutputFile);
138 ofsSolverParamsOutputFile.close();
139 }
140}
141
142/**************************************************************************************
143 * *
144 * Command line see outputCommandLineMessages() *
145 * *
146 **************************************************************************************/
147int
149 int argc,
150 char **argv
151 )
152{
153 // mtrace();
154 static const int solverOrigin = 1;
155
156 bool racingSolversExist = false;
157 ParaDeterministicTimer *detTimer = 0;
158
159 ParaSysTimer sysTimer;
160 sysTimer.start();
161
162#ifdef UG_WITH_UGS
163 char *configFileName = 0;
164 for( int i = 1; i < argc; ++i )
165 {
166 if ( strcmp(argv[i], "-ugsc") == 0 )
167 {
168 i++;
169 if( i < argc )
170 {
171 configFileName = argv[i];
172 break;
173 }
174 else
175 {
176 std::cerr << "missing file name after parameter '-ugsc" << std::endl;
177 exit(1);
178 }
179 }
180 }
181
183 UGS::UgsParaCommMpi *commUgs = 0; // commUgs != 0 means ParaScip runs under UGS
184 if( configFileName )
185 {
186 commUgs = new UGS::UgsParaCommMpi();
187 commUgs->init(argc,argv);
188 comm = new ScipParaCommMpi(commUgs->getSolverMPIComm());
189 comm->setUgsComm(commUgs);
190 }
191 else
192 {
193 comm = new ScipParaCommMpi();
194 }
195#else
196 // ParaComm *comm = new PARA_COMM_TYPE();
198#endif
199
200 comm->init(argc,argv);
201
202 ParaTimer *paraTimer = new ParaTimerMpi();
203 paraTimer->init(comm);
204
206
207#ifndef SCIP_THREADSAFE_MESSAGEHDLRS
208 SCIP_CALL_ABORT( SCIPcreateMesshdlrPThreads(1) );
209 SCIPmessageSetDefaultHandler();
210#endif
211
212 if( comm->getRank() == 0 )
213 {
214 if( argc < 3 )
215 {
217 return 1;
218 }
219 paraParamSet->read(comm, argv[1]);
220
225 if( paraInitiator->init(paraParamSet, argc, argv) )
226 {
227 if( dynamic_cast<ScipParaInitiator *>(paraInitiator)->isSolvedAtInit() )
228 {
230 delete paraInitiator;
231 delete paraParamSet;
232 delete paraTimer;
233 if( detTimer ) delete detTimer;
234// sysTimer.stop();
235// std::cout << "[ Rank: " << comm->getRank() << " ], UTime = " << sysTimer.getUTime()
236// << ", STime = " << sysTimer.getSTime() << ", RTime = " << sysTimer.getRTime() << std::endl;
237 comm->abort();
238 delete comm;
239#ifdef UG_WITH_UGS
240 if( commUgs ) delete commUgs;
241#endif
242 return 0;
243 }
244 }
245 std::cout << "** Initiatior was initilized after " << paraTimer->getElapsedTime() << " sec." << std::endl;
246 ParaInstance *paraInstance = paraInitiator->getParaInstance();
248 {
251 }
253 paraInitiator->sendSolverInitializationMessage(); // This messages should be received in constructor of the target Solver
254 std::cout << "** Instance data were sent to all solvers after " << paraTimer->getElapsedTime() << " sec." << std::endl;
257 {
258 detTimer = new ScipParaDeterministicTimer();
259 }
260 if( dynamic_cast<ScipParaInitiator *>(paraInitiator)->isSolvedAtInit() )
261 {
262#ifdef UG_WITH_UGS
263 paraLc = new ScipParaLoadCoordinator(commUgs, comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
264#else
265 paraLc = new ScipParaLoadCoordinator(comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
266#endif
267 delete paraLc;
268 delete paraInitiator;
269 delete paraParamSet;
270 delete paraTimer;
271 if( detTimer ) delete detTimer;
272
273// sysTimer.stop();
274// std::cout << "[ Rank: " << comm->getRank() << " ], UTime = " << sysTimer.getUTime()
275// << ", STime = " << sysTimer.getSTime() << ", RTime = " << sysTimer.getRTime() << std::endl;
276
277 comm->abort();
278 delete comm;
279#ifdef UG_WITH_UGS
280 if( commUgs ) delete commUgs;
281#endif
282 return 0;
283 }
284 else
285 {
286#ifdef UG_WITH_UGS
287 paraLc = new ScipParaLoadCoordinator(commUgs, comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
288#else
289 paraLc = new ScipParaLoadCoordinator(comm, paraParamSet, paraInitiator, &racingSolversExist, paraTimer, detTimer);
290#endif
291 }
293 {
294#ifdef UG_WITH_ZLIB
295 paraLc->warmStart();
296#endif
297 }
298 else
299 {
302 {
303 ParaTask *rootNode = new BbParaNodeMpi(
304 TaskId(), TaskId(), 0, -DBL_MAX, -DBL_MAX, -DBL_MAX,
305 dynamic_cast<ScipParaInitiator *>(paraInitiator)->makeRootNodeDiffSubproblem());
306 paraLc->run(rootNode);
307 }
309 paraParamSet->getIntParamValue(RampUpPhaseProcess) <= 2 ) // racing ramp-up
310 {
312 paraInitiator->generateRacingRampUpParameterSets( (comm->getSize()-1), racingRampUpParams );
313 for( int i = 1; i < comm->getSize(); i++ )
314 {
315 int noKeep = 0;
317 comm->send( &noKeep, 1, ParaINT, i, UG::TagKeepRacing)
318 );
320 racingRampUpParams[i-solverOrigin]->send(comm, i)
321 );
322 }
323 ParaTask *rootNode = new BbParaNodeMpi(
324 TaskId(), TaskId(), 0, -DBL_MAX, -DBL_MAX, -DBL_MAX,
325 dynamic_cast<ScipParaInitiator *>(paraInitiator)->makeRootNodeDiffSubproblem());
326 paraLc->run(rootNode, (comm->getSize()-1), racingRampUpParams );
327 for( int i = 1; i < comm->getSize(); i++ )
328 {
329 if( racingRampUpParams[i-solverOrigin] ) delete racingRampUpParams[i-solverOrigin];
330 }
331 delete [] racingRampUpParams;
332 }
333 else
334 {
335 THROW_LOGICAL_ERROR2("Invalid RampUpPhaseProcess: ", paraParamSet->getIntParamValue(RampUpPhaseProcess) )
336 }
337 }
338 delete paraLc;
339 if( paraInitiator ) delete paraInitiator;
340 }
341 else
342 {
343 if( argc < 3 )
344 {
345 return 1;
346 }
349 int nNonLinearConsHdlrs = 0;
351 comm->bcast( &nNonLinearConsHdlrs, 1, ParaINT, 0 )
352 );
353 ParaInstance *paraInstance = comm->createParaInstance();
354 setUserPlugins(paraInstance);
355 if( nNonLinearConsHdlrs > 0 )
356 {
358 }
360 {
361 ScipParaInstanceMpi *scipParaInstanceMpi = dynamic_cast<ScipParaInstanceMpi *>(paraInstance);
362 scipParaInstanceMpi->setFileName(argv[2]);
363 }
366 {
367 detTimer = new ScipParaDeterministicTimer();
368 }
369 ParaSolver *paraSolver = new ScipParaSolver(argc, argv, comm, paraParamSet, paraInstance, detTimer);
370 // setUserPlugins(paraSolver); too late!! user plugin is necessary when instance data are read
371 dynamic_cast<ScipParaSolver *>(paraSolver)->setProblemFileName(argv[2]);
372 // if( paraParamSet->getIntParamValue(RampUpPhaseProcess) == 0 || paraSolver->isWarmStarted() )
375 {
376 paraSolver->run();
377 }
379 paraParamSet->getIntParamValue(RampUpPhaseProcess) <= 2 ) // racing ramp-up
380 {
381 int source;
382 int tag;
383 (void)comm->probe(&source, &tag);
384 if( tag == TagKeepRacing )
385 {
386 int keep = 0;
388 comm->receive( &keep, 1, ParaINT, 0, UG::TagKeepRacing)
389 );
390 if( keep == 0 )
391 {
392 dynamic_cast<BbParaSolver *>(paraSolver)->setKeepRacing(false);
393 }
394 else
395 {
396 dynamic_cast<BbParaSolver *>(paraSolver)->setKeepRacing(true);
397 }
398 (void)comm->probe(&source, &tag);
399 ParaRacingRampUpParamSet *racingRampUpParamSet = new ScipParaRacingRampUpParamSetMpi();
401 racingRampUpParamSet->receive(comm, 0)
402 );
403 paraSolver->run( racingRampUpParamSet );
404 // delete racingRampUpParamSet; // racingRampUpParamSet is set in Solver object and deleted in the object
405 }
406 else
407 {
408 if( tag == TagTerminateRequest )
409 {
411 comm->receive( NULL, 0, ParaBYTE, source, TagTerminateRequest )
412 );
413 // when solver is deleted, solver's destructor sends termination status
414 }
415 else
416 {
417 THROW_LOGICAL_ERROR2("Invalid Tag is recicv3ed in ParaSCIP solver main: ", tag )
418 }
419 }
420 }
421 else
422 {
423 THROW_LOGICAL_ERROR2("Invalid RampUpPhaseProcess: ", paraParamSet->getIntParamValue(RampUpPhaseProcess) )
424 }
425 delete paraSolver;
426 //if( paraInstance ) delete paraInstance; /** deleted in paraSolver destructor */
427 }
428
429 delete paraParamSet;
430
431// sysTimer.stop();
432// std::cout << "[ Rank: " << comm->getRank() << " ], UTime = " << sysTimer.getUTime()
433// << ", STime = " << sysTimer.getSTime() << ", RTime = " << sysTimer.getRTime() << std::endl;
434
435
436#ifndef SCIP_THREADSAFE_MESSAGEHDLRS
437 SCIPfreeMesshdlrPThreads();
438#endif
439
440 delete paraTimer;
441 if( detTimer ) delete detTimer;
442
443 if( racingSolversExist ) comm->abort();
444
445 delete comm;
446
447#ifdef UG_WITH_UGS
448 if( commUgs ) delete commUgs;
449#endif
450
451 return 0;
452
453} /* 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:148
void outputParaParamSet(ParaParamSet *paraParamSet, ParaInitiator *paraInitiator)
Definition: parascip.cpp:83
void outputCommandLineMessages(char **argv)
Definition: parascip.cpp:64
void setUserPlugins(ParaInitiator *initiator)
void outputSolverParams(ParaParamSet *paraParamSet, ParaInitiator *paraInitiator)
Definition: parascip.cpp:113
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.