00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __deal2__mpi_h
00014 #define __deal2__mpi_h
00015
00016 #include <deal.II/base/config.h>
00017 #include <vector>
00018
00019 #if defined(DEAL_II_COMPILER_SUPPORTS_MPI) || defined(DEAL_II_USE_PETSC)
00020 # include <mpi.h>
00021 #else
00022
00023
00024
00025 typedef int MPI_Comm;
00026 const int MPI_COMM_SELF = 0;
00027 typedef int MPI_Datatype;
00028 typedef int MPI_Op;
00029 namespace MPI
00030 {
00031 static const unsigned int UNSIGNED = 0;
00032 static const unsigned int LONG_DOUBLE = 0;
00033 static const unsigned int LONG_DOUBLE_COMPLEX = 0;
00034 static const unsigned int MAX = 0;
00035 static const unsigned int MIN = 0;
00036 static const unsigned int SUM = 0;
00037 }
00038 #endif
00039
00040 DEAL_II_NAMESPACE_OPEN
00041
00042
00043 namespace Utilities
00044 {
00055 namespace MPI
00056 {
00063 unsigned int n_mpi_processes (const MPI_Comm &mpi_communicator);
00064
00075 unsigned int this_mpi_process (const MPI_Comm &mpi_communicator);
00076
00115 std::vector<unsigned int>
00116 compute_point_to_point_communication_pattern (const MPI_Comm & mpi_comm,
00117 const std::vector<unsigned int> & destinations);
00118
00137 MPI_Comm duplicate_communicator (const MPI_Comm &mpi_communicator);
00138
00151 template <typename T>
00152 T sum (const T &t,
00153 const MPI_Comm &mpi_communicator);
00154
00165 template <typename T, unsigned int N>
00166 inline
00167 void sum (const T (&values)[N],
00168 const MPI_Comm &mpi_communicator,
00169 T (&sums)[N]);
00170
00180 template <typename T>
00181 inline
00182 void sum (const std::vector<T> &values,
00183 const MPI_Comm &mpi_communicator,
00184 std::vector<T> &sums);
00185
00198 template <typename T>
00199 T max (const T &t,
00200 const MPI_Comm &mpi_communicator);
00201
00212 template <typename T, unsigned int N>
00213 inline
00214 void max (const T (&values)[N],
00215 const MPI_Comm &mpi_communicator,
00216 T (&maxima)[N]);
00217
00227 template <typename T>
00228 inline
00229 void max (const std::vector<T> &values,
00230 const MPI_Comm &mpi_communicator,
00231 std::vector<T> &maxima);
00232
00237 struct MinMaxAvg
00238 {
00239 double sum;
00240 double min;
00241 double max;
00242 unsigned int min_index;
00243 unsigned int max_index;
00244 double avg;
00245 };
00246
00258 MinMaxAvg
00259 min_max_avg (const double my_value,
00260 const MPI_Comm &mpi_communicator);
00261
00262
00263
00284 class MPI_InitFinalize
00285 {
00286 public:
00298 MPI_InitFinalize (int &argc,
00299 char** &argv);
00300
00307 ~MPI_InitFinalize();
00308
00309 private:
00321 const bool owns_mpi;
00322 };
00323
00324 namespace internal
00325 {
00326 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00327
00331 inline MPI_Datatype mpi_type_id (const int *)
00332 {
00333 return MPI_INT;
00334 }
00335
00336
00337 inline MPI_Datatype mpi_type_id (const long int *)
00338 {
00339 return MPI_LONG;
00340 }
00341
00342
00343 inline MPI_Datatype mpi_type_id (const unsigned int *)
00344 {
00345 return MPI_UNSIGNED;
00346 }
00347
00348
00349 inline MPI_Datatype mpi_type_id (const unsigned long int *)
00350 {
00351 return MPI_UNSIGNED_LONG;
00352 }
00353
00354
00355 inline MPI_Datatype mpi_type_id (const float *)
00356 {
00357 return MPI_FLOAT;
00358 }
00359
00360
00361 inline MPI_Datatype mpi_type_id (const double *)
00362 {
00363 return MPI_DOUBLE;
00364 }
00365
00366
00367 inline MPI_Datatype mpi_type_id (const long double *)
00368 {
00369 return MPI_LONG_DOUBLE;
00370 }
00371 #endif
00372 }
00373
00374
00375 template <typename T>
00376 inline
00377 T sum (const T &t,
00378 const MPI_Comm &mpi_communicator)
00379 {
00380 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00381 T sum;
00382 MPI_Allreduce (const_cast<void*>(static_cast<const void*>(&t)),
00383 &sum, 1, internal::mpi_type_id(&t), MPI_SUM,
00384 mpi_communicator);
00385 return sum;
00386 #else
00387 (void)mpi_communicator;
00388 return t;
00389 #endif
00390 }
00391
00392
00393 template <typename T, unsigned int N>
00394 inline
00395 void sum (const T (&values)[N],
00396 const MPI_Comm &mpi_communicator,
00397 T (&sums)[N])
00398 {
00399 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00400 MPI_Allreduce (const_cast<void*>(static_cast<const void*>(&values[0])),
00401 &sums[0], N, internal::mpi_type_id(values), MPI_SUM,
00402 mpi_communicator);
00403 #else
00404 (void)mpi_communicator;
00405 for (unsigned int i=0; i<N; ++i)
00406 sums[i] = values[i];
00407 #endif
00408 }
00409
00410
00411 template <typename T>
00412 inline
00413 void sum (const std::vector<T> &values,
00414 const MPI_Comm &mpi_communicator,
00415 std::vector<T> &sums)
00416 {
00417 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00418 sums.resize (values.size());
00419 MPI_Allreduce (const_cast<void*>(static_cast<const void*>(&values[0])),
00420 &sums[0], values.size(), internal::mpi_type_id((T*)0), MPI_SUM,
00421 mpi_communicator);
00422 #else
00423 (void)mpi_communicator;
00424 sums = values;
00425 #endif
00426 }
00427
00428
00429 template <typename T>
00430 inline
00431 T max (const T &t,
00432 const MPI_Comm &mpi_communicator)
00433 {
00434 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00435 T sum;
00436 MPI_Allreduce (const_cast<void*>(static_cast<const void*>(&t)),
00437 &sum, 1, internal::mpi_type_id(&t), MPI_MAX,
00438 mpi_communicator);
00439 return sum;
00440 #else
00441 (void)mpi_communicator;
00442 return t;
00443 #endif
00444 }
00445
00446
00447 template <typename T, unsigned int N>
00448 inline
00449 void max (const T (&values)[N],
00450 const MPI_Comm &mpi_communicator,
00451 T (&maxima)[N])
00452 {
00453 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00454 MPI_Allreduce (const_cast<void*>(static_cast<const void*>(&values[0])),
00455 &maxima[0], N, internal::mpi_type_id(values), MPI_MAX,
00456 mpi_communicator);
00457 #else
00458 (void)mpi_communicator;
00459 for (unsigned int i=0; i<N; ++i)
00460 maxima[i] = values[i];
00461 #endif
00462 }
00463
00464
00465 template <typename T>
00466 inline
00467 void max (const std::vector<T> &values,
00468 const MPI_Comm &mpi_communicator,
00469 std::vector<T> &maxima)
00470 {
00471 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00472 maxima.resize (values.size());
00473 MPI_Allreduce (const_cast<void*>(static_cast<const void*>(&values[0])),
00474 &maxima[0], values.size(), internal::mpi_type_id((T*)0), MPI_MAX,
00475 mpi_communicator);
00476 #else
00477 (void)mpi_communicator;
00478 maxima = values;
00479 #endif
00480 }
00481 }
00482 }
00483
00484
00485 DEAL_II_NAMESPACE_CLOSE
00486
00487 #endif
00488