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-2026 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_APIVERSION >= 163
90 SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
91 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &success) );
92#elif SCIP_APIVERSION >= 131
93 SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
94 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &success) );
95#elif SCIP_APIVERSION >= 101
96 SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
97 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &success) );
98#elif SCIP_APIVERSION >= 100
99 SCIP_CALL_ABORT( SCIPcopyPlugins(scip, tempScip, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
100 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &success) );
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, TRUE, &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, TRUE, &success) );
107#endif
108 SCIP_CALL_ABORT( SCIPcopyParamSettings(scip, tempScip) );
109
110 /* create the variable mapping hash map */
111 SCIP_HASHMAP* varmap = 0;
112 if( SCIPgetNVars(scip) > 0 )
113 {
114 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmap, SCIPblkmem(tempScip), SCIPgetNVars(scip)) );
115 }
116 SCIP_HASHMAP* conssmap = 0;
117 if( SCIPgetNConss(scip) > 0 )
118 {
119 SCIP_CALL_ABORT( SCIPhashmapCreate(&conssmap, SCIPblkmem(tempScip), SCIPgetNConss(scip)) );
120 }
121
122 /* create problem in the target SCIP */
123 SCIP_CALL_ABORT( SCIPcopyProb(scip, tempScip, varmap, conssmap, TRUE, "") );
124
125 // commPth->lockApp();
126 /* copy all variables and constraints */
127 if( SCIPgetNVars(scip) > 0 )
128 {
129#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
130 SCIP_CALL_ABORT( SCIPcopyVars(scip, tempScip, varmap, conssmap, TRUE) );
131#else
132 SCIP_CALL_ABORT( SCIPcopyVars(scip, tempScip, varmap, conssmap, NULL, NULL, 0, TRUE) );
133#endif
134 }
135 if( SCIPgetNConss(scip) > 0 )
136 {
137 SCIP_CALL_ABORT( SCIPcopyConss(scip, tempScip, varmap, conssmap, TRUE, FALSE, &success) );
138 }
139
140#if SCIP_APIVERSION > 39
141 if( success )
142 {
143 SCIP_Bool valid;
144
145 /* copy the Benders' decomposition plugins explicitly, because it requires the variable mapping hash map */
146 SCIP_CALL_ABORT( SCIPcopyBenders(scip, tempScip, NULL, TRUE, &valid) );
147 }
148#endif
149
150 if( !success )
151 {
152 if( SCIPgetNConss(scip) > 0 )
153 {
154 SCIPhashmapFree(&conssmap);
155 }
156 if( SCIPgetNVars(scip) > 0 )
157 {
158 SCIPhashmapFree(&varmap);
159 }
160 SCIPfree(&tempScip);
161 std::cerr << "Some constraint handler did not perform a valid copy. Cannot solve this instance." << std::endl;
162 exit(1);
163 }
164
165 nVars = SCIPgetNVars(scip); // original number
167 int n = SCIPgetNVars(tempScip); // copy may increase the number
168
169 if( nVars == n )
170 {
172 if( SCIPgetNConss(scip) > 0 )
173 {
174 SCIPhashmapFree(&conssmap);
175 }
176 if( SCIPgetNVars(scip) > 0 )
177 {
178 SCIPhashmapFree(&varmap);
179 }
180 SCIPfree(&tempScip);
182 nCopies = 1;
183 std::cout << "** ParaScipInstance copy does not increase the number of variables. **" << std::endl;
184 }
185 else
186 {
187 assert(n > nVars);
188 std::cout << "** ParaScipInstance copy increased the number of variables. **" << std::endl;
189 varIndexRange = SCIPgetNTotalVars(tempScip);
191 nCopies = 1;
192 /**
193 assert(n > nVars);
194 mapToOriginalIndecies = new int[SCIPgetNTotalVars(tempScip)]; // need to allocate enough for SCIPvarGetIndex(copyvar)
195 mapToSolverLocalIndecies = new int[SCIPgetNTotalVars(tempScip)];
196 for( int i = 0; i < SCIPgetNTotalVars(tempScip); i++ )
197 {
198 mapToOriginalIndecies[i] = -1;
199 mapToSolverLocalIndecies[i] = -1;
200 }
201 SCIP_VAR **tempVars = SCIPgetVars(tempScip);
202 for( int i = 0; i < n; i++ )
203 {
204 mapToOriginalIndecies[SCIPvarGetIndex(tempVars[i])] = i;
205 mapToSolverLocalIndecies[i] = SCIPvarGetIndex(tempVars[i]);
206 }
207
208 orgScip = scip;
209 nVars = n;
210 varIndexRange = SCIPgetNTotalVars(tempScip);
211 paraInstanceScip = tempScip;
212
213 if( SCIPgetNConss(scip) > 0 )
214 {
215 SCIPhashmapFree(&conssmap);
216 }
217 if( SCIPgetNVars(scip) > 0 )
218 {
219 SCIPhashmapFree(&varmap);
220 }
221 SCIP_CALL_ABORT( SCIPtransformProb(paraInstanceScip));
222 nCopies = 2;
223 std::cout << "** ParaScipInstance is copied twice. **" << std::endl;
224 ***/
225 }
226
227 nVars = SCIPgetNVars(paraInstanceScip);
228 SCIP_VAR **vars = SCIPgetVars(paraInstanceScip);
229
230 /* make varName and objCoefs and ovnm */
231 posVarNames = new int[nVars];
232 objCoefs = new SCIP_Real[nVars];
233 // mapToOriginalIndecies = new int[nVars];
234
235 lVarNames = 0;
236 for(int v = 0; v < nVars; ++v)
237 {
239 objCoefs[v] = SCIPvarGetObj(vars[v]);
240 assert(SCIPvarGetProbindex(vars[v])!=-1);
241 assert(SCIPvarGetProbindex(vars[v]) == v);
242 lVarNames += strlen(SCIPvarGetName(vars[v])) + 1;
243 }
244 varNames = new char[lVarNames];
245 varLbs = new SCIP_Real[nVars];
246 varUbs = new SCIP_Real[nVars];
247 varTypes = new int[nVars];
248 for(int v = 0; v < nVars; ++v )
249 {
250 SCIP_VAR *var = vars[v];
251 strcpy (&varNames[posVarNames[v]], SCIPvarGetName(var) );
252 varLbs[SCIPvarGetProbindex(var)] = SCIPvarGetLbLocal(var); //* we should use global?
253 varUbs[SCIPvarGetProbindex(var)] = SCIPvarGetUbLocal(var); //* we should use global?
254 varTypes[SCIPvarGetProbindex(var)] = SCIPvarGetType(var);
255 }
256 }
257 }
258
259 /** destractor */
261 )
262 {
263 if( orgScip )
264 {
265 SCIPfree(&paraInstanceScip);
266 }
267 }
268
269 /** create presolved problem instance that is solved by ParaSCIP form scip environment in this object */
271 SCIP **scip
272 )
273 {
274 /** this routine for Pthread version. So, this should not be used **/
275 abort();
276 }
277
278 SCIP *getScip(
279 )
280 {
281 /** this routine for Pthread version. So, this should not be used **/
282 abort();
283 }
284
285 void setFileName(const char *inFileName)
286 {
287 fileName = inFileName;
288 }
289
290 /** broadcasts instance to all solvers */
291 int bcast(UG::ParaComm *comm, int rank, int method);
292
294
296 {
298 }
299
301 {
303 }
304
305};
306
308
309}
310
311#endif // __SCIP_PARA_INSTANCE_MPI_H__
312
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.