Scippy

UG

Ubiquity Generator framework

paraCommMpi.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 paraCommMpi.h
27 * @brief ParaComm 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 __PARA_COMM_MPI_H__
38#define __PARA_COMM_MPI_H__
39
40#include <thread>
41#include <mutex>
42#include <mpi.h>
43#include <stdexcept>
44#include <iostream>
45#include <ostream>
46#include <fstream>
47#include <sstream>
48#include <string>
49#include <iomanip>
50#include <deque>
51#include "paraDef.h"
52#include "paraComm.h"
53#include "paraInstance.h"
54#include "paraDiffSubproblem.h"
55#include "paraSolution.h"
56// #include "paraCalculationStateMpi.h"
57#include "paraParamSetMpi.h"
58// #include "paraSolverStateMpi.h"
59// #include "paraSolverTerminationStateMpi.h"
60#include "paraTimerMpi.h"
61#ifdef UG_WITH_UGS
62#include "ugs/ugsParaCommMpi.h"
63#endif
64
65namespace UG
66{
67
68#define MPI_CALL( mpicall ) do \
69 { \
70 int _error_value_; \
71 _error_value_ = ( mpicall ); \
72 if( _error_value_ != MPI_SUCCESS ) \
73 { \
74 std::cout << "[MPI ERROR: " << __FILE__ << "] func = " \
75 << __func__ << ", line = " << __LINE__ << ": " \
76 << "error_code = " << _error_value_ << std::endl; \
77 MPI_Abort(MPI_COMM_WORLD, 1); \
78 } \
79 } while (0)
80
81#define TAG_TRACE( call, fromTo, sourceDest, tag ) \
82 if( tagTraceFlag ) \
83 { \
84 *tos << (MPI_Wtime() - startTime) << " [Rank = " << myRank << "] " << #call << " " << #fromTo \
85 << " " << sourceDest << " with Tag = " << getTagString(tag) << std::endl; \
86 }
87
88class ParaIsendRequest;
89
90///
91/// Communicator object for MPI communications
92///
93class ParaCommMpi : public ParaComm
94{
95protected:
96 MPI_Comm myComm; ///< MPI communicator
97 int myCommSize; ///< communicator size : number of processes joined in this system
98 int myRank; ///< rank of this process
99 int namelen; ///< length of this process name
100 char procName[MPI_MAX_PROCESSOR_NAME]; ///< process name
101 bool tagTraceFlag; ///< indicate if tags are traced or not
102 std::ofstream ofs; ///< output file stream for tag trace
103 std::ostream *tos; ///< output file stream for tag trace to change file name
104 double startTime; ///< start time of this communicator
105 int token[2]; ///< index 0: token
106 ///< index 1: token color
107 ///< -1: green
108 ///< > 0: yellow ( termination origin solver number )
109 ///< -2: red ( means the solver can terminate )
110 static MPI_Datatype datatypes[TYPE_LIST_SIZE]; ///< data type mapping table to MPI data type
111 static const char *tagStringTable[]; ///< table for tag name string
112
113#ifdef _MUTEX_CPP11
114 std::mutex tokenAccessLock; ///< mutex for c++11 thread
115#else
116 pthread_mutex_t tokenAccessLock; ///< mutex for pthread thread
117#endif
118 std::mutex applicationLockMutex; ///< mutex for applications
119
120#ifdef UG_WITH_UGS
121 UGS::UgsParaCommMpi *commUgs; ///< communicator for UGS
122#endif
123
124 ///
125 /// check if tag string table (for debugging) set up correctly
126 /// @return true if tag string table is set up correctly, false otherwise
127 ///
129 );
130
131public:
132
133 std::deque<ParaIsendRequest *> iSendRequestDeque;
134
135 ///
136 /// default constructor of ParaCommMpi
137 ///
139 )
140 : myComm(MPI_COMM_NULL),
141 myCommSize(-1),
142 myRank(-1),
143 namelen(-1),
144 tagTraceFlag(false),
145 tos(0),
146 startTime(0.0)
147#ifdef UG_WITH_UGS
148 , commUgs(0)
149#endif
150 {
151#ifndef _MUTEX_CPP11
152 pthread_mutex_init(&tokenAccessLock, NULL);
153#endif
154 token[0]=-1;
155 token[1]=-1;
156 }
157
158 ///
159 /// constructor of ParaCommMpi with MPI communicator
160 ///
162 MPI_Comm comm ///< my communicator
163 )
164 : myComm(comm),
165 myCommSize(-1),
166 myRank(-1),
167 namelen(-1),
168 tagTraceFlag(false),
169 tos(0),
170 startTime(0.0)
171#ifdef UG_WITH_UGS
172 , commUgs(0)
173#endif
174 {
175 }
176
177 ///
178 /// destructor of this communicator
179 ///
180 virtual ~ParaCommMpi();
181
182 ///
183 /// getter of MPI_Comm
184 ///
185 MPI_Comm &getMpiComm(
186 )
187 {
188 return myComm;
189 }
190
191 ///
192 /// initializer of this communicator
193 ///
194 virtual void init(
195 int argc, ///< the number of arguments
196 char **argv ///< pointers to the arguments
197 );
198
199 ///
200 /// get start time of this communicator
201 /// @return start time
202 ///
204 )
205 {
206 return startTime;
207 }
208
209 ///
210 /// get rank of caller's thread
211 /// @return rank of caller's thread
212 ///
214 )
215 {
216 return myRank;
217 }
218
219 ///
220 /// get size of this communicator, which indicates how many threads in a UG process
221 /// @return the number of threads
222 ///
224 )
225 {
226 return myCommSize;
227 }
228
229 ///
230 /// get size of the messageQueueTable
231 /// @return the size of the messageQueueTable
232 ///
234 int dest=-1
235 )
236 {
237 return iSendRequestDeque.size();
238 }
239
240 ///
241 /// initializer for LoadCoordinator
242 ///
243 void lcInit(
244 ParaParamSet *paraParamSet ///< UG parameter set
245 );
246
247 ///
248 /// initializer for Solvers
249 ///
250 void solverInit(
251 ParaParamSet *paraParamSet ///< UG parameter set
252 );
253
254 ///
255 /// abort. How it works sometimes depends on communicator used
256 ///
257 void abort(
258 );
259
260 ///
261 /// function to wait Terminated message
262 /// (This function is not used currently)
263 /// @return true when MPI communication is used, false when thread communication used
264 ///
266 )
267 {
268 return true;
269 }
270
271 ///
272 /// wait token when UG runs with deterministic mode
273 /// @return true, when token is arrived to the rank
274 ///
275 virtual bool waitToken(
276 int rank ///< rank to check if token is arrived
277 );
278
279 ///
280 /// pass token to from the rank to the next
281 ///
282 virtual void passToken(
283 int rank ///< from this rank, the token is passed
284 );
285
286 ///
287 /// pass termination token from the rank to the next
288 /// @return true, when the termination token is passed from this rank, false otherwise
289 ///
290 virtual bool passTermToken(
291 int rank
292 );
293
294 ///
295 /// set received token to this communicator
296 ///
297 virtual void setToken(
298 int rank, ///< rank to set the token
299 int *inToken ///< token to be set
300 )
301 {
302#ifdef _MUTEX_CPP11
303 std::lock_guard<std::mutex> lock(tokenAccessLock);
304#else
305 pthread_mutex_lock(&tokenAccessLock);
306#endif
307 token[0] = inToken[0]; token[1] = inToken[1];
308#ifndef _MUTEX_CPP11
309 pthread_mutex_unlock(&tokenAccessLock);
310#endif
311 }
312
313 // this is just to silence a compiler warning
314 // tell compiler that we want the lockApp(char const *f,int l)
315 // from the upper class, and overwrite lockApp() only
316 using ParaComm::lockApp;
317 ///
318 /// lock UG application to synchronize with other threads
319 ///
320 virtual void lockApp(
321 )
322 {
324 }
325
327 ///
328 /// unlock UG application to synchronize with other threads
329 ///
330 virtual void unlockApp(
331 )
332 {
333 applicationLockMutex.unlock();
334 }
335
336 ///
337 /// create ParaTimer object
338 /// @return pointer to ParaTimer object
339 ///
341 )
342 {
343 return new ParaTimerMpi();
344 }
345
346 ///
347 /// broadcast function for standard ParaData types
348 /// @return always 0 (for future extensions)
349 ///
350 int bcast(
351 void* buffer, ///< point to the head of sending message
352 int count, ///< the number of data in the message
353 const int datatypeId, ///< data type in the message
354 int root ///< root rank for broadcasting
355 );
356
357 ///
358 /// send function for standard ParaData types
359 /// @return always 0 (for future extensions)
360 ///
361 virtual int send(
362 void* bufer, ///< point to the head of sending message
363 int count, ///< the number of data in the message
364 const int datatypeId, ///< data type in the message
365 int dest, ///< destination to send the message
366 const int tag ///< tag of this message
367 );
368
369 ///
370 /// send function for standard ParaData types
371 /// @return always 0 (for future extensions)
372 ///
373 int iSend(
374 void* bufer, ///< point to the head of sending message
375 int count, ///< the number of data in the message
376 const int datatypeId, ///< data type in the message
377 int dest, ///< destination to send the message
378 const int tag, ///< tag of this message
379 MPI_Request *req ///< point to MPI_Request
380 );
381
382 ///
383 /// receive function for standard ParaData types
384 /// @return always 0 (for future extensions)
385 ///
386 int receive(
387 void* bufer, ///< point to the head of receiving message
388 int count, ///< the number of data in the message
389 const int datatypeId, ///< data type in the message
390 int source, ///< source of the message coming from
391 const int tag ///< tag of the message
392 );
393
394 ///
395 /// wait function for a specific tag from a specific source coming from
396 ///
398 const int source, ///< source rank which the message should come from
399 const int tag, ///< tag which the message should wait
400 int *receivedTag ///< tag of the message which is arrived
401 );
402
403 ///
404 /// probe function which waits a new message
405 /// @return always true
406 ///
407 bool probe(
408 int *source, ///< source rank of the message arrived
409 int *tag ///< tag of the message arrived
410 );
411
412 ///
413 /// iProbe function which checks if a new message is arrived or not
414 /// @return true when a new message exists
415 ///
416 bool iProbe(
417 int *source, ///< source rank of the message arrived
418 int *tag ///< tag of the message arrived
419 );
420
421 ///
422 /// User type bcast for created data type
423 /// @return always 0 (for future extensions)
424 ///
425 int ubcast(
426 void* buffer, ///< point to the head of sending message
427 int count, ///< the number of created data type
428 MPI_Datatype datatype, ///< MPI data type
429 int root ///< root rank for brodcasting
430 );
431
432 ///
433 /// User type send for created data type
434 /// @return always 0 (for future extensions)
435 ///
436 int usend(
437 void* bufer, ///< point to the head of sending message
438 int count, ///< the number of created data type
439 MPI_Datatype datatype, ///< created data type
440 int dest, ///< destination rank
441 int tag ///< tag of the message
442 );
443
444 ///
445 /// User type send for created data type
446 /// @return always 0 (for future extensions)
447 ///
448 int iUsend(
449 void* bufer, ///< point to the head of sending message
450 int count, ///< the number of created data type
451 MPI_Datatype datatype, ///< created data type
452 int dest, ///< destination rank
453 int tag, ///< tag of the message
454 MPI_Request *req ///< point to MPI_Request
455 );
456
457 ///
458 /// User type receive for created data type
459 /// @return always 0 (for future extensions)
460 ///
461 int ureceive(
462 void* bufer, ///< point to the head of receiving message
463 int count, ///< the number of created data type
464 MPI_Datatype datatype, ///< created data type
465 int source, ///< source rank
466 int tag ///< tag of the message
467 );
468
469 int testAllIsends(
470 );
471
472 void waitAllIsends();
473
474 ///
475 /// get Tag string for debugging
476 /// @return string which shows Tag
477 ///
478 virtual const char *getTagString(
479 int tag /// tag to be converted to string
480 );
481
482};
483
484#define DEF_PARA_COMM( para_comm, comm ) ParaCommMpi *para_comm = dynamic_cast< ParaCommMpi* >(comm)
485
486}
487
488#endif // __PARA_COMM_MPI_H__
Communicator object for MPI communications.
Definition: paraCommMpi.h:94
double startTime
start time of this communicator
Definition: paraCommMpi.h:104
virtual void lockApp()
lock UG application to synchronize with other threads
Definition: paraCommMpi.h:320
bool probe(int *source, int *tag)
probe function which waits a new message
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)
send function for standard ParaData types
bool iProbe(int *source, int *tag)
iProbe function which checks if a new message is arrived or not
void solverInit(ParaParamSet *paraParamSet)
initializer for Solvers
Definition: paraCommMpi.cpp:96
static MPI_Datatype datatypes[TYPE_LIST_SIZE]
data type mapping table to MPI data type
Definition: paraCommMpi.h:110
int receive(void *bufer, int count, const int datatypeId, int source, const int tag)
receive function for standard ParaData types
int token[2]
index 0: token index 1: token color -1: green > 0: yellow ( termination origin solver number ) -2: re...
Definition: paraCommMpi.h:105
MPI_Comm myComm
MPI communicator.
Definition: paraCommMpi.h:96
int getSize()
get size of this communicator, which indicates how many threads in a UG process
Definition: paraCommMpi.h:223
virtual bool tagStringTableIsSetUpCoorectly()
check if tag string table (for debugging) set up correctly
bool tagTraceFlag
indicate if tags are traced or not
Definition: paraCommMpi.h:101
std::deque< ParaIsendRequest * > iSendRequestDeque
Definition: paraCommMpi.h:133
int myRank
rank of this process
Definition: paraCommMpi.h:98
ParaCommMpi()
default constructor of ParaCommMpi
Definition: paraCommMpi.h:138
ParaCommMpi(MPI_Comm comm)
constructor of ParaCommMpi with MPI communicator
Definition: paraCommMpi.h:161
std::mutex applicationLockMutex
mutex for applications
Definition: paraCommMpi.h:118
std::ostream * tos
output file stream for tag trace to change file name
Definition: paraCommMpi.h:103
virtual const char * getTagString(int tag)
get Tag string for debugging
int iSend(void *bufer, int count, const int datatypeId, int dest, const int tag, MPI_Request *req)
send function for standard ParaData types
virtual void passToken(int rank)
pass token to from the rank to the next
char procName[MPI_MAX_PROCESSOR_NAME]
process name
Definition: paraCommMpi.h:100
int ubcast(void *buffer, int count, MPI_Datatype datatype, int root)
User type bcast for created data type.
int namelen
length of this process name
Definition: paraCommMpi.h:99
static const char * tagStringTable[]
table for tag name string
Definition: paraCommMpi.h:111
int ureceive(void *bufer, int count, MPI_Datatype datatype, int source, int tag)
User type receive for created data type.
pthread_mutex_t tokenAccessLock
mutex for pthread thread
Definition: paraCommMpi.h:116
int iUsend(void *bufer, int count, MPI_Datatype datatype, int dest, int tag, MPI_Request *req)
User type send for created data type.
double getStartTime()
get start time of this communicator
Definition: paraCommMpi.h:203
int getRank()
get rank of caller's thread
Definition: paraCommMpi.h:213
int myCommSize
communicator size : number of processes joined in this system
Definition: paraCommMpi.h:97
virtual void init(int argc, char **argv)
initializer of this communicator
int getNumOfMessagesWaitingToSend(int dest=-1)
get size of the messageQueueTable
Definition: paraCommMpi.h:233
ParaTimer * createParaTimer()
create ParaTimer object
Definition: paraCommMpi.h:340
virtual ~ParaCommMpi()
destructor of this communicator
virtual bool waitTerminatedMessage()
function to wait Terminated message (This function is not used currently)
Definition: paraCommMpi.h:265
virtual void unlockApp()
unlock UG application to synchronize with other threads
Definition: paraCommMpi.h:330
void abort()
abort. How it works sometimes depends on communicator used
MPI_Comm & getMpiComm()
getter of MPI_Comm
Definition: paraCommMpi.h:185
virtual bool passTermToken(int rank)
pass termination token from the rank to the next
int bcast(void *buffer, int count, const int datatypeId, int root)
broadcast function for standard ParaData types
void waitSpecTagFromSpecSource(const int source, const int tag, int *receivedTag)
wait function for a specific tag from a specific source coming from
void lcInit(ParaParamSet *paraParamSet)
initializer for LoadCoordinator
Definition: paraCommMpi.cpp:69
virtual void setToken(int rank, int *inToken)
set received token to this communicator
Definition: paraCommMpi.h:297
int usend(void *bufer, int count, MPI_Datatype datatype, int dest, int tag)
User type send for created data type.
std::ofstream ofs
output file stream for tag trace
Definition: paraCommMpi.h:102
virtual bool waitToken(int rank)
wait token when UG runs with deterministic mode
Base class of communicator object.
Definition: paraComm.h:102
virtual void lockApp()=0
lock UG application to synchronize with other threads
virtual void unlockApp()=0
unlock UG application to synchronize with other threads
class ParaParamSet
Definition: paraParamSet.h:850
class ParaTimerMpi (Timer used in MPI communication)
Definition: paraTimerMpi.h:51
class ParaTimer
Definition: paraTimer.h:49
static ScipParaCommTh * comm
Definition: fscip.cpp:73
static ScipParaParamSet * paraParamSet
Definition: fscip.cpp:74
static const int TYPE_LIST_SIZE
Definition: paraComm.h:81
Base class of communicator for UG Framework.
Defines for UG Framework.
Base class for a container which has difference between instance and subproblem.
Base class for instance data.
ParaParamSet extension for MPI communication.
Base class for solution.
ParaTimer extension for MPI timer.