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