G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsMpi.h
Go to the documentation of this file.
1
14#pragma once
15
17
18#ifdef GISMO_WITH_MPI
19#include <string.h>
20#include <mpi.h>
21// #if MPI_VERSION < 2
22// # ifdef _MSC_VER
23// # pragma message ("The MPI version is older than MPI-2.")
24// # else
25// # warning "The MPI version is older than MPI-2."
26// # endif
27//#endif
30#endif
31
33
34namespace gismo
35{
36
37class gsMpi;
38
40GISMO_EXPORT gsMpi & gsMpiSingleton(const int& argc, char** argv);
41
58class gsMpi
59{
60
61public:
62
63 friend GISMO_EXPORT gsMpi & gsMpiSingleton(const int& argc, char** argv);
64
65# ifdef GISMO_WITH_MPI
69 typedef MPI_Comm Communicator;
70# else
71 typedef gsSerialComm Communicator;
72# endif
73
80 static Communicator worldComm()
81 {
82# ifdef GISMO_WITH_MPI
83 return MPI_COMM_WORLD;
84# else
85 return localComm();
86# endif
87 }
88
95 static Communicator localComm()
96 {
97 return gsSerialComm();
98 }
99
115 static gsMpi& init(const int& argc = 0, char** argv = NULL)
116 {
117 GISMO_ASSERT( 0 == argc || NULL!=argv, "Need both argc and argv (or none)");
118 return gsMpiSingleton(argc,argv);
119 }
120
124 static int worldRank () { return gsMpiComm(worldComm()).rank(); }
128 static int worldSize () { return gsMpiComm(worldComm()).size(); }
129
130 static inline double wallTime()
131 {
132# ifdef GISMO_WITH_MPI
133 return MPI_Wtime();
134# else
135 return 0;
136# endif
137 }
138
139 static inline std::string getProcessorName()
140 {
141# ifdef GISMO_WITH_MPI
142 char processor_name[MPI_MAX_PROCESSOR_NAME];
143 int name_len;
144 MPI_Get_processor_name(processor_name, &name_len);
145 return std::string(processor_name, name_len);
146# else
147
148 //linux: gethostname(processor_name, HOST_NAME_MAX);
149 //mswin: GetComputerName(processor_name, &name_len)
150 return "SingleCPU";
151# endif
152 }
153
154 bool initialized() const
155 {
156# ifdef GISMO_WITH_MPI
157 int init = -1;
158 MPI_Initialized( &init );
159 return (0 != init);
160# endif
161 return false;
162 }
163
164private:
165
166 gsMpi();
167
169 gsMpi(const int& argc, char** argv)
170 {
171 initMpi(const_cast<int*>(&argc), argv);
172 }
173
174 void initMpi(int * argc = NULL, char** argv = NULL) const
175 {
176# ifdef GISMO_WITH_MPI
177 if( !initialized() )
178 {
179#ifdef _OPENMP
180 // Initialize MPI with multi-threading support
181 char* thread_level = getenv("GISMO_MPI_THREAD_LEVEL");
182 const int req_level = ( NULL != thread_level ? atoi(getenv("GISMO_MPI_THREAD_LEVEL")) : 0);
183 int MPI_thread_required = MPI_THREAD_SINGLE, MPI_thread_provided;
184 switch(req_level)
185 {
186 case 0:
187 MPI_thread_required = MPI_THREAD_SINGLE;
188 break;
189 case 1:
190 MPI_thread_required = MPI_THREAD_FUNNELED;
191 break;
192 case 2:
193 MPI_thread_required = MPI_THREAD_SERIALIZED;
194 break;
195 case 3:
196 MPI_thread_required = MPI_THREAD_MULTIPLE;
197 break;
198 default:
199 GISMO_ERROR("Invalid value for environment variable GISMO_MPI_THREAD_LEVEL");
200 };
201
202 const int init = MPI_Init_thread(argc, &argv, MPI_thread_required, &MPI_thread_provided);
203 GISMO_ENSURE(MPI_SUCCESS==init &&
204 MPI_thread_required <= MPI_thread_provided, "MPI failed to initialize");
205#else
206 //Note: valgrind false positive here, see
207 // https://www.open-mpi.org/faq/?category=debugging#valgrind_clean
208 const int init = MPI_Init(argc, &argv);
209 GISMO_ENSURE(MPI_SUCCESS==init, "MPI failed to initialize");
210#endif
211 }
212# ifndef NDEBUG
213 MPI_Comm_create_errhandler(gsMpiComm::ErrCallBack, &gsMpiComm::ErrHandler);
214 MPI_Comm_set_errhandler(worldComm(), gsMpiComm::ErrHandler);
215# endif
216# else
217 GISMO_UNUSED(argc);
218 GISMO_UNUSED(argv);
219# endif
220 //gsDebug << "Called MPI_Init on p=" << rank_ << "!" << std::endl;
221 }
222
225 {
226# ifdef GISMO_WITH_MPI
227 int wasFinalized = -1;
228 MPI_Finalized( &wasFinalized );
229 if( 0 == wasFinalized)
230 {
231 MPI_Finalize();
232 }
233# endif
234 //gsDebug << "Called MPI_Finalize on p=" << rank_ << "!" <<std::endl;
235 }
236
237 gsMpi(const gsMpi&);
238 gsMpi& operator=(const gsMpi&);
239
240};
241
242}
int rank() const
return rank of process, i.e. zero
Definition gsMpiComm.h:297
static int size()
return rank of process, i.e. one
Definition gsMpiComm.h:302
Various helper classes derived from from std::binary_function for stl-style functional programming.
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides forward declarations of types and structs.
A wrapper for MPI communicators.
Traits classes for mapping types onto MPI_Datatype.
The G+Smo namespace, containing all definitions for the library.
gsMpi & gsMpiSingleton(const int &argc, char **argv)
Singleton function returning the gsMpi helper object.
Definition gsMpi.cpp:9
~gsMpi()
calls MPI_Finalize
Definition gsMpi.h:224