Scippy

UG

Ubiquity Generator framework

scipParaInstanceMpi.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 scipParaInstanceMpi.h
27  * @brief ScipParaInstance extension for MPI communication.
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_INSTANCE_MPI_H__
38 #define __SCIP_PARA_INSTANCE_MPI_H__
39 
40 #include <cstring>
41 #include <mpi.h>
42 #include "ug/paraDef.h"
43 #include "ug/paraComm.h"
44 #include "scipParaInstance.h"
45 
46 namespace ParaSCIP
47 {
48 
49 /** ScipInstanceMpi */
51 {
52 
54  const char *fileName;
55 
56  /** create scipDiffParamSetPreType */
57  MPI_Datatype createDatatype1();
58  /** create scipDiffParamSetPreType */
59  MPI_Datatype createDatatype2(bool memAllocNecessary);
60  /** create scipDiffParamSetType */
61  MPI_Datatype createDatatype3(bool memAllocNecessary);
62 
65 
66  const char *getFileName(){ return fileName; }
67 
68 public:
69  /** constructor */
71  )
72  : dummyToKeepStartPos(0), fileName(0)
73  {
74  }
75 
76  /** constructor : only called from ScipInitiator */
78  SCIP *scip,
79  int method
80  ) : ScipParaInstance(scip, method), dummyToKeepStartPos(0), fileName(0)
81  {
82  if( method == 2 && SCIPgetStage(scip) != SCIP_STAGE_SOLVED )
83  {
84  SCIP *tempScip;
85  SCIP_Bool success = TRUE;
86  SCIP_CALL_ABORT( SCIPcreate(&tempScip) );
87 
88  /* copy all plugins and settings */
89  #if SCIP_VERSION == 211 && SCIP_SUBVERSION == 0
90  SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
91  TRUE, TRUE, TRUE, TRUE, &success) );
92  #else
93  #if SCIP_APIVERSION >= 100
94  #if SCIP_APIVERSION >= 101
95  SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
96  TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, &success) );
97  #else
98  SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
99  TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, &success) );
100  #endif
101  #elif SCIP_APIVERSION >= 17
102  SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
103  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, &success) );
104  #else
105  SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
106  TRUE, TRUE, TRUE, TRUE, FALSE, &success) );
107  #endif
108  #endif
109  SCIP_CALL_ABORT( SCIPcopyParamSettings(scip, tempScip) );
110 
111  /* create the variable mapping hash map */
112  SCIP_HASHMAP* varmap = 0;
113  if( SCIPgetNVars(scip) > 0 )
114  {
115  SCIP_CALL_ABORT( SCIPhashmapCreate(&varmap, SCIPblkmem(tempScip), SCIPgetNVars(scip)) );
116  }
117  SCIP_HASHMAP* conssmap = 0;
118  if( SCIPgetNConss(scip) > 0 )
119  {
120  SCIP_CALL_ABORT( SCIPhashmapCreate(&conssmap, SCIPblkmem(tempScip), SCIPgetNConss(scip)) );
121  }
122 
123  /* create problem in the target SCIP */
124  SCIP_CALL_ABORT( SCIPcopyProb(scip, tempScip, varmap, conssmap, TRUE, "") );
125 
126  // commPth->lockApp();
127  /* copy all variables and constraints */
128  if( SCIPgetNVars(scip) > 0 )
129  {
130 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
131  SCIP_CALL_ABORT( SCIPcopyVars(scip, tempScip, varmap, conssmap, TRUE) );
132 #else
133  SCIP_CALL_ABORT( SCIPcopyVars(scip, tempScip, varmap, conssmap, NULL, NULL, 0, TRUE) );
134 #endif
135  }
136  if( SCIPgetNConss(scip) > 0 )
137  {
138  SCIP_CALL_ABORT( SCIPcopyConss(scip, tempScip, varmap, conssmap, TRUE, FALSE, &success) );
139  }
140 
141 #if SCIP_APIVERSION > 39
142  if( success )
143  {
144  SCIP_Bool valid;
145 
146  /* copy the Benders' decomposition plugins explicitly, because it requires the variable mapping hash map */
147  SCIP_CALL_ABORT( SCIPcopyBenders(scip, tempScip, NULL, TRUE, &valid) );
148  }
149 #endif
150 
151  if( !success )
152  {
153  if( SCIPgetNConss(scip) > 0 )
154  {
155  SCIPhashmapFree(&conssmap);
156  }
157  if( SCIPgetNVars(scip) > 0 )
158  {
159  SCIPhashmapFree(&varmap);
160  }
161  SCIPfree(&tempScip);
162  std::cerr << "Some constraint handler did not perform a valid copy. Cannot solve this instance." << std::endl;
163  exit(1);
164  }
165 
166  nVars = SCIPgetNVars(scip); // original number
168  int n = SCIPgetNVars(tempScip); // copy may increase the number
169 
170  if( nVars == n )
171  {
173  if( SCIPgetNConss(scip) > 0 )
174  {
175  SCIPhashmapFree(&conssmap);
176  }
177  if( SCIPgetNVars(scip) > 0 )
178  {
179  SCIPhashmapFree(&varmap);
180  }
181  SCIPfree(&tempScip);
182  paraInstanceScip = scip;
183  nCopies = 1;
184  std::cout << "** ParaScipInstance copy does not increase the number of variables. **" << std::endl;
185  }
186  else
187  {
188  assert(n > nVars);
189  std::cout << "** ParaScipInstance copy increased the number of variables. **" << std::endl;
190  varIndexRange = SCIPgetNTotalVars(tempScip);
191  copyIncreasedVariables = true;
192  nCopies = 1;
193  /**
194  assert(n > nVars);
195  mapToOriginalIndecies = new int[SCIPgetNTotalVars(tempScip)]; // need to allocate enough for SCIPvarGetIndex(copyvar)
196  mapToSolverLocalIndecies = new int[SCIPgetNTotalVars(tempScip)];
197  for( int i = 0; i < SCIPgetNTotalVars(tempScip); i++ )
198  {
199  mapToOriginalIndecies[i] = -1;
200  mapToSolverLocalIndecies[i] = -1;
201  }
202  SCIP_VAR **tempVars = SCIPgetVars(tempScip);
203  for( int i = 0; i < n; i++ )
204  {
205  mapToOriginalIndecies[SCIPvarGetIndex(tempVars[i])] = i;
206  mapToSolverLocalIndecies[i] = SCIPvarGetIndex(tempVars[i]);
207  }
208 
209  orgScip = scip;
210  nVars = n;
211  varIndexRange = SCIPgetNTotalVars(tempScip);
212  paraInstanceScip = tempScip;
213 
214  if( SCIPgetNConss(scip) > 0 )
215  {
216  SCIPhashmapFree(&conssmap);
217  }
218  if( SCIPgetNVars(scip) > 0 )
219  {
220  SCIPhashmapFree(&varmap);
221  }
222  SCIP_CALL_ABORT( SCIPtransformProb(paraInstanceScip));
223  nCopies = 2;
224  std::cout << "** ParaScipInstance is copied twice. **" << std::endl;
225  ***/
226  }
227 
228  nVars = SCIPgetNVars(paraInstanceScip);
229  SCIP_VAR **vars = SCIPgetVars(paraInstanceScip);
230 
231  /* make varName and objCoefs and ovnm */
232  posVarNames = new int[nVars];
233  objCoefs = new SCIP_Real[nVars];
234  // mapToOriginalIndecies = new int[nVars];
235 
236  lVarNames = 0;
237  for(int v = 0; v < nVars; ++v)
238  {
239  posVarNames[v] = lVarNames;
240  objCoefs[v] = SCIPvarGetObj(vars[v]);
241  assert(SCIPvarGetProbindex(vars[v])!=-1);
242  assert(SCIPvarGetProbindex(vars[v]) == v);
243  lVarNames += strlen(SCIPvarGetName(vars[v])) + 1;
244  }
245  varNames = new char[lVarNames];
246  varLbs = new SCIP_Real[nVars];
247  varUbs = new SCIP_Real[nVars];
248  varTypes = new int[nVars];
249  for(int v = 0; v < nVars; ++v )
250  {
251  SCIP_VAR *var = vars[v];
252  strcpy (&varNames[posVarNames[v]], SCIPvarGetName(var) );
253  varLbs[SCIPvarGetProbindex(var)] = SCIPvarGetLbLocal(var); //* we should use global?
254  varUbs[SCIPvarGetProbindex(var)] = SCIPvarGetUbLocal(var); //* we should use global?
255  varTypes[SCIPvarGetProbindex(var)] = SCIPvarGetType(var);
256  }
257  }
258  }
259 
260  /** destractor */
262  )
263  {
264  if( orgScip )
265  {
266  SCIPfree(&paraInstanceScip);
267  }
268  }
269 
270  /** create presolved problem instance that is solved by ParaSCIP form scip environment in this object */
272  SCIP **scip
273  )
274  {
275  /** this routine for Pthread version. So, this should not be used **/
276  abort();
277  }
278 
279  SCIP *getScip(
280  )
281  {
282  /** this routine for Pthread version. So, this should not be used **/
283  abort();
284  }
285 
286  void setFileName(const char *inFileName)
287  {
288  fileName = inFileName;
289  }
290 
291  /** broadcasts instance to all solvers */
292  int bcast(UG::ParaComm *comm, int rank, int method);
293 
295 
297  {
298  return copyIncreasedVariables;
299  }
300 
302  {
303  copyIncreasedVariables = true;
304  }
305 
306 };
307 
309 
310 }
311 
312 #endif // __SCIP_PARA_INSTANCE_MPI_H__
313 
MPI_Datatype createDatatype3(bool memAllocNecessary)
ParaInstance extenstion for SCIP solver.
static ScipParaCommTh * comm
Definition: fscip.cpp:73
MPI_Datatype createDatatype2(bool memAllocNecessary)
int bcast(UG::ParaComm *comm, int rank, int method)
Defines for UG Framework.
void setFileName(const char *inFileName)
Base class of communicator for UG Framework.
ScipParaInstanceMpi * ScipParaInstanceMpiPtr
ScipParaInstanceMpi(SCIP *scip, int method)
Base class of communicator object.
Definition: paraComm.h:101