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-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 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
46namespace 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
68public:
69 /** constructor */
71 )
73 {
74 }
75
76 /** constructor : only called from ScipInitiator */
78 SCIP *scip,
79 int method
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);
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);
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 {
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 {
299 }
300
302 {
304 }
305
306};
307
309
310}
311
312#endif // __SCIP_PARA_INSTANCE_MPI_H__
313
MPI_Datatype createDatatype3(bool memAllocNecessary)
ScipParaInstanceMpi(SCIP *scip, int method)
MPI_Datatype createDatatype2(bool memAllocNecessary)
int bcast(UG::ParaComm *comm, int rank, int method)
void setFileName(const char *inFileName)
Base class of communicator object.
Definition: paraComm.h:102
static ScipParaCommTh * comm
Definition: fscip.cpp:73
ScipParaInstanceMpi * ScipParaInstanceMpiPtr
Base class of communicator for UG Framework.
Defines for UG Framework.
ParaInstance extenstion for SCIP solver.