Scippy

UG

Ubiquity Generator framework

scipParaSolver.h
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 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 scipParaSolver.h
27  * @brief ParaSolver extension for SCIP: Parallelized solver implementation for SCIP.
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 #ifndef __SCIP_PARA_SOLVER_H__
38 #define __SCIP_PARA_SOLVER_H__
39 
40 #include <list>
41 #include <thread>
42 #include "ug_bb/bbParaSolver.h"
43 #include "scipUserPlugins.h"
44 #include "scipParaDiffSubproblem.h"
46 #include "scipDiffParamSet.h"
47 #include "scipParaTagDef.h"
48 
49 #define ENFORCED_THRESHOLD 5
50 
51 namespace ParaSCIP
52 {
53 
54 class ScipParaObjCommPointHdlr;
55 class ScipParaObjNodesel;
56 class ScipParaObjSelfSplitNodesel;
57 class ScipParaObjProp;
58 
59 typedef struct LocalNodeInfo_t
60 {
61  /********************************
62  * for local cuts and conflicts *
63  * *****************************/
64  SCIP_Real linearLhs; /**< array of lhs */
65  SCIP_Real linearRhs; /**< array of rhs */
66  int nLinearCoefs; /**< array of number of coefficient values for linear constrains */
67  SCIP_Real *linearCoefs; /**< array of non-zero coefficient values of linear constrains */
68  int *idxLinearCoefsVars; /**< array of indices of no-zero coefficient values of linear constrains */
71 
73 {
74 
75 protected:
76 
77  typedef int(ScipParaSolver::*ScipMessageHandlerFunctionPointer)(int, int);
78 
79  SCIP *scip;
83  SCIP_MESSAGEHDLR *messagehdlr;
84  FILE *logfile;
86  std::list<LocalNodeInfoPtr> *conflictConsList;
88 
91 #if SCIP_APIVERSION >= 101
92  ScipParaObjSelfSplitNodesel *selfSplitNodesel;
93 #endif
94 
96 
97  ScipParaInterruptMsgMonitor *interruptMsgMonitor; ///< interrupt message monitor
98  // std::thread interruptMsgMonitorThread; ///< interrupt message monitor thread
99 
100  long long nPreviousNodesLeft; /**< number of nodes left in the previous notification */
101 
102  int originalPriority; /**< original priority of changing node selector */
103  int orgMaxRestart; /**< original value of presolving/maxrestart parameter */
104 
105  int nOrgVars; /**< number of original variables in LC */
106  int nOrgVarsInSolvers; /**< number of original variables in Solvers */
107  SCIP_Real *orgVarLbs; /**< array of original lower bound of variable */
108  SCIP_Real *orgVarUbs; /**< array of original upper bound of variable */
109  SCIP_Real *tightenedVarLbs; /**< array of tightened lower bound of variable */
110  SCIP_Real *tightenedVarUbs; /**< array of tightened upper bound of variable */
111  int *mapToOriginalIndecies; /**< array of indices to map to original problem's probindices */
112  int *mapToSolverLocalIndecies; /**< array of reverse indices mapToOriginalIndecies */
113  int *mapToProbIndecies; /**< map from index to probindex */
114 
115  // Dropping settings when variable bounds exchange is performed during racing
116  // int stuffingMaxrounds;
117  // int domcolMaxrounds;
118  // int dualcompMaxrounds;
119  // int dualinferMaxrounds;
120  // int dualaggMaxrounds;
121  // unsigned int abspowerDualpresolve;
122  // unsigned int andDualpresolving;
123  // unsigned int cumulativeDualpresolve;
124  // unsigned int knapsackDualpresolving;
125  // unsigned int linearDualpresolving;
126  // unsigned int setppcDualpresolving;
127  // unsigned int logicorDualpresolving;
128  unsigned int miscAllowdualreds;
129 
130  //
132  SCIP_CONS** addedConss;
133  SCIP_CONS* addedDualCons;
134 
135  char *settingsNameLC; /**< parameter settings file name for LC */
136  bool fiberSCIP;
137  bool quiet;
138  bool collectingModeIsProhibited; /**< indicate that collecting mode is prohibited */
139 
140  const char *problemFileName; /**< keep the name for restart, in case of file read */
141 
142  SCIP_Real orgFeastol; /**< original feasibility tolerance */
143  SCIP_Real orgLpfeastol; /**< original lp feasibility tolerance */
144 
145  bool copyIncreasedVariables; /**< indicate that SCIP copy increaded variables */
146 
147  void setRacingParams(UG::ParaRacingRampUpParamSet *inRacingParams, bool winnerParam);
148  void setWinnerRacingParams(UG::ParaRacingRampUpParamSet *inRacingParams);
149  virtual void createSubproblem();
150  virtual void freeSubproblem();
151  virtual void solve();
152  long long getNNodesSolved();
153  int getNNodesLeft();
154  double getDualBoundValue();
155  void reinitialize();
156  void setOriginalNodeSelectionStrategy();
157 
158  void solveToCheckEffectOfRootNodePreprocesses();
159  void saveOrgProblemBounds();
160 
161  void setBakSettings();
162 
163  int lbBoundTightened(int source, int tag);
164  int ubBoundTightened(int source, int tag);
165 
166  void saveOriginalSettings();
167  void dropSettingsForVariableBoundsExchnage();
168  void recoverOriginalSettings();
169 
170  void saveImprovedSolution();
171 
172  static void runInterruptMsgMonitorThread(void *threadData)
173  {
174  ScipParaInterruptMsgMonitor *monitor = static_cast<ScipParaInterruptMsgMonitor *>(threadData);
175  monitor->run();
176  }
177 
178 
179 public:
180  ScipParaSolver(int argc, char **argv,
182  ScipParaSolver(argc, argv, N_SCIP_TAGS, comm, paraParamSet, inParaInstance, detTimer )
183  {
184  }
185  ScipParaSolver(int argc, char **argv,
186  UG::ParaComm *comm, UG::ParaParamSet *paraParamSet, UG::ParaInstance *inParaInstance, UG::ParaDeterministicTimer *detTimer, double timeOffset, bool thread) :
187  ScipParaSolver(argc, argv, N_SCIP_TAGS, comm, paraParamSet, inParaInstance, detTimer, timeOffset, thread)
188  {
189  }
190  ScipParaSolver(int argc, char **argv, int nhanders,
192  ScipParaSolver(int argc, char **argv, int nhanders,
193  UG::ParaComm *comm, UG::ParaParamSet *paraParamSet, UG::ParaInstance *paraInstance, UG::ParaDeterministicTimer *detTimer, double timeOffset, bool thread);
194  virtual ~ScipParaSolver();
195  const char *getChangeNodeSelName(){
196  if( paraParams->getIntParamValue(UG::NodeTransferMode) == 0 ) return "estimate";
197  // else return "bfs";
198  else return "ScipParaObjNodesel";
199  }
201  return originalPriority;
202  }
203 
205  int numnodesels = SCIPgetNNodesels( scip );
206  SCIP_NODESEL** nodesels = SCIPgetNodesels( scip );
207  const char *changeNodeSelName = getChangeNodeSelName();
208  int i;
209  for( i = 0; i < numnodesels; ++i )
210  {
211  std::string nodeselname(SCIPnodeselGetName(nodesels[i]));
212  if( std::string(nodeselname) == std::string(changeNodeSelName) )
213  {
214  originalPriority = SCIPnodeselGetStdPriority(nodesels[i]);
215  break;
216  }
217  }
218  assert( i != numnodesels );
219  }
220 
222  int numnodesels = SCIPgetNNodesels( scip );
223  SCIP_NODESEL** nodesels = SCIPgetNodesels( scip );
224  const char *changeNodeSelName = getChangeNodeSelName();
225  int i;
226  for( i = 0; i < numnodesels; ++i )
227  {
228  std::string nodeselname(SCIPnodeselGetName(nodesels[i]));
229  if( std::string(nodeselname) == std::string(changeNodeSelName) )
230  {
231  SCIP_CALL_ABORT( SCIPsetNodeselStdPriority(scip, nodesels[i], originalPriority ) );
232  break;
233  }
234  }
235  assert( i != numnodesels );
236  }
237 
239  SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrestarts", &orgMaxRestart) );
240  }
241 
242  int getOriginalMaxRestart(){ return orgMaxRestart; }
243 
244  ScipParaDiffSubproblem *getParentDiffSubproblem(){ return dynamic_cast< ScipParaDiffSubproblem * >(currentTask->getDiffSubproblem() ); }
245  void writeCurrentTaskProblem(const std::string& filename);
246  void tryNewSolution(UG::ParaSolution *sol);
247  void setLightWeightRootNodeProcess();
248  void setOriginalRootNodeProcess();
249 
251  {
252  if( currentTask->getDiffSubproblem() )
253  {
254  ScipParaDiffSubproblem *scipDiffSubproblem = dynamic_cast<ScipParaDiffSubproblem *>(currentTask->getDiffSubproblem());
255  return scipDiffSubproblem->getOffset();
256  }
257  else
258  {
259  return 0;
260  }
261  }
262 
263  SCIP *getScip(){
264  return scip;
265  }
266 
267  std::list<LocalNodeInfoPtr> *getConflictConsList(
268  )
269  {
270  return conflictConsList;
271  }
272 
273  void writeSubproblem();
274 
275  long long getSimplexIter(
276  )
277  {
278  SCIP_STAGE stage = SCIPgetStage(scip);
279  if( stage == SCIP_STAGE_PRESOLVED || stage == SCIP_STAGE_SOLVING || stage == SCIP_STAGE_SOLVED )
280  {
281  return SCIPgetNLPIterations(scip);
282  }
283  else
284  {
285  return 0;
286  }
287  }
288 
290  {
291  SCIP_STAGE stage = SCIPgetStage(scip);
292  if( stage != SCIP_STAGE_INIT )
293  {
294  return SCIPgetNRuns(scip);
295  }
296  else
297  {
298  return 0;
299  }
300  }
301 
302  /** set user plugins */
303  void setUserPlugins(ScipUserPlugins *inUi) { userPlugins = inUi; }
304 
305  /** include user plugins */
306  void includeUserPlugins(SCIP *inScip)
307  {
308  if( userPlugins )
309  {
310  (*userPlugins)(inScip);
311  }
312  }
313 
315  )
316  {
317  return true;
318  }
319 
321  const char *fileName
322  )
323  {
324  problemFileName = fileName;
325  }
326 
328  )
329  {
330  return collectingModeIsProhibited;
331  }
332 
334  )
335  {
336  collectingModeIsProhibited = false;
337  }
338 
340  )
341  {
342  collectingModeIsProhibited = true;
343  }
344 
345  bool isOriginalIndeciesMap() { return (mapToOriginalIndecies != 0); }
346 
347  int getOriginalIndex(int index)
348  {
349  assert(mapToOriginalIndecies);
350  return mapToOriginalIndecies[index];
351  }
352 
353  bool isProbIndeciesMap() { return (mapToProbIndecies != 0); }
354 
355  int getProbIndex(int index)
356  {
357  assert(mapToProbIndecies);
358  return mapToProbIndecies[index];
359  }
360 
361  long long getNPreviousNodesLeft(){ return nPreviousNodesLeft; }
362  void setNPreviousNodesLeft(long long n){ nPreviousNodesLeft = n; }
363  int getNOrgVars() { return nOrgVars; }
364  double getOrgVarLb(int i){ return orgVarLbs[i]; }
365  double getOrgVarUb(int i){ return orgVarUbs[i]; }
366  void setOrgVarLb(int i, double v){ orgVarLbs[i] = v; }
367  void setOrgVarUb(int i, double v){ orgVarUbs[i] = v; }
368 
369  double getTightenedVarLb(int i){ return tightenedVarLbs[i]; }
370  double getTightenedVarUb(int i){ return tightenedVarUbs[i]; }
371  void setTightenedVarLb(int i, double v){ tightenedVarLbs[i] = v; }
372  void setTightenedVarUb(int i, double v){ tightenedVarUbs[i] = v; }
373 
374  void checkVarsAndIndex(const char *string, SCIP* inScip)
375  {
376  std::cout << "R" << paraComm->getRank() << ":" << string << std::endl;
377  int nVars;
378  SCIP_VAR **vars;
379  SCIP_CALL_ABORT( SCIPgetOrigVarsData(inScip, &vars, &nVars, NULL, NULL, NULL, NULL) );
380  for( int i = 0; i < nVars; i++ )
381  {
382  std::cout << "R" << paraComm->getRank() << ": idx = " << i << ": " << SCIPvarGetName(vars[i]) << std::endl;
383  }
384 
385  }
386 
387  /** get number of tightened variables during racing */
388  int getNTightened();
389 
390  /** get number of tightened integral variables during racing */
391  int getNTightenedInt();
392 
394  {
395  return copyIncreasedVariables;
396  }
397 
399  {
400  copyIncreasedVariables = true;
401  }
402 
403  void issueInterruptSolve();
404 
405  bool isInterrupting();
406 
407  int processTagInterruptRequest(int source, int tag)
408  {
409  if( scip )
410  {
412  }
413  else
414  {
415  return 0;
416  }
417  }
418 
419 };
420 
421 }
422 
423 #endif // __SCIP_PARA_SOLVER_H__
ScipUserPlugins * userPlugins
ScipParaSolver(int argc, char **argv, UG::ParaComm *comm, UG::ParaParamSet *paraParamSet, UG::ParaInstance *inParaInstance, UG::ParaDeterministicTimer *detTimer)
void setTightenedVarUb(int i, double v)
static const int NodeTransferMode
int getOriginalIndex(int index)
int getProbIndex(int index)
static ScipParaCommTh * comm
Definition: fscip.cpp:73
unsigned int miscAllowdualreds
static ScipParaParamSet * paraParamSet
Definition: fscip.cpp:74
ParaInitialStat extension for SCIP solver.
C++ wrapper for propagators.
int processTagInterruptRequest(int source, int tag)
void setOrgVarUb(int i, double v)
void checkVarsAndIndex(const char *string, SCIP *inScip)
SCIP user plugins.
Interrupt message monitor thread class.
class BbParaSolver
Definition: bbParaSolver.h:63
void setProblemFileName(const char *fileName)
double getTightenedVarUb(int i)
class for deterministic timer
SCIP * scipToCheckEffectOfRootNodeProcesses
ScipParaSolver(int argc, char **argv, UG::ParaComm *comm, UG::ParaParamSet *paraParamSet, UG::ParaInstance *inParaInstance, UG::ParaDeterministicTimer *detTimer, double timeOffset, bool thread)
LocalNodeInfo * LocalNodeInfoPtr
SCIP_MESSAGEHDLR * messagehdlr
ScipDiffParamSet * scipDiffParamSetRoot
ScipParaInterruptMsgMonitor * interruptMsgMonitor
interrupt message monitor
std::list< LocalNodeInfoPtr > * conflictConsList
struct ParaSCIP::LocalNodeInfo_t LocalNodeInfo
void setUserPlugins(ScipUserPlugins *inUi)
ScipParaDiffSubproblem * getParentDiffSubproblem()
ScipParaObjCommPointHdlr * commPointHdlr
void setTightenedVarLb(int i, double v)
double getTightenedVarLb(int i)
void includeUserPlugins(SCIP *inScip)
class ParaParamSet
Definition: paraParamSet.h:850
SCIP parameter set to be transferred ( Only keep difference between default settings )...
class for instance data
Definition: paraInstance.h:50
void setOrgVarLb(int i, double v)
ScipParaObjNodesel * nodesel
std::list< LocalNodeInfoPtr > * getConflictConsList()
ScipParaObjProp * scipPropagator
C++ wrapper for primal heuristics.
static void runInterruptMsgMonitorThread(void *threadData)
const char * getChangeNodeSelName()
ScipDiffParamSet * scipDiffParamSet
void setNPreviousNodesLeft(long long n)
ScipDiffParamSet * originalParamSet
class ParaRacingRampUpParamSet (parameter set for racing ramp-up)
Base class of communicator object.
Definition: paraComm.h:101
virtual int processTagInterruptRequest(int source, int tag)
process TagInterruptRequest
class for solution
Definition: paraSolution.h:53
long long getNPreviousNodesLeft()