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 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 
65 namespace 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 
88 class ParaIsendRequest;
89 
90 ///
91 /// Communicator object for MPI communications
92 ///
93 class ParaCommMpi : public ParaComm
94 {
95 protected:
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  ///
128  virtual bool tagStringTableIsSetUpCoorectly(
129  );
130 
131 public:
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  ///
203  double getStartTime(
204  )
205  {
206  return startTime;
207  }
208 
209  ///
210  /// get rank of caller's thread
211  /// @return rank of caller's thread
212  ///
213  int getRank(
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  ///
223  int getSize(
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  ///
265  virtual bool waitTerminatedMessage(
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  {
323  applicationLockMutex.lock();
324  }
325 
326  using ParaComm::unlockApp;
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  /// @return always 0 (for future extensions)
397  ///
399  const int source, ///< source rank which the message should come from
400  const int tag, ///< tag which the message should wait
401  int *receivedTag ///< tag of the message which is arrived
402  );
403 
404  ///
405  /// probe function which waits a new message
406  /// @return always true
407  ///
408  bool probe(
409  int *source, ///< source rank of the message arrived
410  int *tag ///< tag of the message arrived
411  );
412 
413  ///
414  /// iProbe function which checks if a new message is arrived or not
415  /// @return true when a new message exists
416  ///
417  bool iProbe(
418  int *source, ///< source rank of the message arrived
419  int *tag ///< tag of the message arrived
420  );
421 
422  ///
423  /// User type bcast for created data type
424  /// @return always 0 (for future extensions)
425  ///
426  int ubcast(
427  void* buffer, ///< point to the head of sending message
428  int count, ///< the number of created data type
429  MPI_Datatype datatype, ///< MPI data type
430  int root ///< root rank for brodcasting
431  );
432 
433  ///
434  /// User type send for created data type
435  /// @return always 0 (for future extensions)
436  ///
437  int usend(
438  void* bufer, ///< point to the head of sending message
439  int count, ///< the number of created data type
440  MPI_Datatype datatype, ///< created data type
441  int dest, ///< destination rank
442  int tag ///< tag of the message
443  );
444 
445  ///
446  /// User type send for created data type
447  /// @return always 0 (for future extensions)
448  ///
449  int iUsend(
450  void* bufer, ///< point to the head of sending message
451  int count, ///< the number of created data type
452  MPI_Datatype datatype, ///< created data type
453  int dest, ///< destination rank
454  int tag, ///< tag of the message
455  MPI_Request *req ///< point to MPI_Request
456  );
457 
458  ///
459  /// User type receive for created data type
460  /// @return always 0 (for future extensions)
461  ///
462  int ureceive(
463  void* bufer, ///< point to the head of receiving message
464  int count, ///< the number of created data type
465  MPI_Datatype datatype, ///< created data type
466  int source, ///< source rank
467  int tag ///< tag of the message
468  );
469 
470  int testAllIsends(
471  );
472 
473  void waitAllIsends();
474 
475  ///
476  /// get Tag string for debugging
477  /// @return string which shows Tag
478  ///
479  virtual const char *getTagString(
480  int tag /// tag to be converted to string
481  );
482 
483 };
484 
485 #define DEF_PARA_COMM( para_comm, comm ) ParaCommMpi *para_comm = dynamic_cast< ParaCommMpi* >(comm)
486 
487 }
488 
489 #endif // __PARA_COMM_MPI_H__
pthread_mutex_t tokenAccessLock
mutex for pthread thread
Definition: paraCommMpi.h:116
void lcInit(ParaParamSet *paraParamSet)
initializer for LoadCoordinator
Definition: paraCommMpi.cpp:69
static const char * tagStringTable[]
table for tag name string
Definition: paraCommMpi.h:111
static ScipParaCommTh * comm
Definition: fscip.cpp:73
static ScipParaParamSet * paraParamSet
Definition: fscip.cpp:74
MPI_Comm & getMpiComm()
getter of MPI_Comm
Definition: paraCommMpi.h:185
Base class for a container which has difference between instance and subproblem.
virtual void init(int argc, char **argv)
initializer of this communicator
ParaCommMpi()
default constructor of ParaCommMpi
Definition: paraCommMpi.h:138
virtual void unlockApp()
unlock UG application to synchronize with other threads
Definition: paraCommMpi.h:330
bool tagTraceFlag
indicate if tags are traced or not
Definition: paraCommMpi.h:101
int myCommSize
communicator size : number of processes joined in this system
Definition: paraCommMpi.h:97
std::ofstream ofs
output file stream for tag trace
Definition: paraCommMpi.h:102
int ureceive(void *bufer, int count, MPI_Datatype datatype, int source, int tag)
User type receive for created data type.
virtual void unlockApp()=0
unlock UG application to synchronize with other threads
int getRank()
get rank of caller&#39;s thread
Definition: paraCommMpi.h:213
ParaTimer extension for MPI timer.
ParaCommMpi(MPI_Comm comm)
constructor of ParaCommMpi with MPI communicator
Definition: paraCommMpi.h:161
virtual ~ParaCommMpi()
destructor of this communicator
static const int TYPE_LIST_SIZE
Definition: paraComm.h:81
Defines for UG Framework.
void waitSpecTagFromSpecSource(const int source, const int tag, int *receivedTag)
wait function for a specific tag from a specific source coming from
std::deque< ParaIsendRequest * > iSendRequestDeque
Definition: paraCommMpi.h:133
double startTime
start time of this communicator
Definition: paraCommMpi.h:104
int getSize()
get size of this communicator, which indicates how many threads in a UG process
Definition: paraCommMpi.h:223
virtual void setToken(int rank, int *inToken)
set received token to this communicator
Definition: paraCommMpi.h:297
class ParaTimerMpi (Timer used in MPI communication)
Definition: paraTimerMpi.h:50
virtual void lockApp()
lock UG application to synchronize with other threads
Definition: paraCommMpi.h:320
virtual void lockApp()=0
lock UG application to synchronize with other threads
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)
send function for standard ParaData types
Communicator object for MPI communications.
Definition: paraCommMpi.h:93
Base class of communicator for UG Framework.
bool probe(int *source, int *tag)
probe function which waits a new message
Base class for instance data.
class ParaParamSet
Definition: paraParamSet.h:850
MPI_Comm myComm
MPI communicator.
Definition: paraCommMpi.h:96
virtual bool waitTerminatedMessage()
function to wait Terminated message (This function is not used currently)
Definition: paraCommMpi.h:265
char procName[MPI_MAX_PROCESSOR_NAME]
process name
Definition: paraCommMpi.h:100
std::mutex applicationLockMutex
mutex for applications
Definition: paraCommMpi.h:118
int token[2]
index 0: token index 1: token color -1: green > 0: yellow ( termination origin solver number ) -2: re...
Definition: paraCommMpi.h:105
virtual const char * getTagString(int tag)
get Tag string for debugging
virtual bool waitToken(int rank)
wait token when UG runs with deterministic mode
int iUsend(void *bufer, int count, MPI_Datatype datatype, int dest, int tag, MPI_Request *req)
User type send for created data type.
static MPI_Datatype datatypes[TYPE_LIST_SIZE]
data type mapping table to MPI data type
Definition: paraCommMpi.h:110
virtual bool passTermToken(int rank)
pass termination token from the rank to the next
int receive(void *bufer, int count, const int datatypeId, int source, const int tag)
receive function for standard ParaData types
int bcast(void *buffer, int count, const int datatypeId, int root)
broadcast function for standard ParaData types
void abort()
abort. How it works sometimes depends on communicator used
int ubcast(void *buffer, int count, MPI_Datatype datatype, int root)
User type bcast for created data type.
class ParaTimer
Definition: paraTimer.h:48
virtual void passToken(int rank)
pass token to from the rank to the next
ParaParamSet extension for MPI communication.
std::ostream * tos
output file stream for tag trace to change file name
Definition: paraCommMpi.h:103
int getNumOfMessagesWaitingToSend(int dest=-1)
get size of the messageQueueTable
Definition: paraCommMpi.h:233
ParaTimer * createParaTimer()
create ParaTimer object
Definition: paraCommMpi.h:340
int namelen
length of this process name
Definition: paraCommMpi.h:99
double getStartTime()
get start time of this communicator
Definition: paraCommMpi.h:203
virtual bool tagStringTableIsSetUpCoorectly()
check if tag string table (for debugging) set up correctly
int myRank
rank of this process
Definition: paraCommMpi.h:98
Base class of communicator object.
Definition: paraComm.h:101
Base class for solution.
int usend(void *bufer, int count, MPI_Datatype datatype, int dest, int tag)
User type send for created data type.
int iSend(void *bufer, int count, const int datatypeId, int dest, const int tag, MPI_Request *req)
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