include/deal.II/base/mpi.h

00001 //---------------------------------------------------------------------------
00002 //    @f$Id: mpi.h 25345 2012-03-31 08:37:04Z bangerth @f$
00003 //    Version: @f$Name@f$
00004 //
00005 //    Copyright (C) 2011, 2012 by deal.II authors
00006 //
00007 //    This file is subject to QPL and may not be  distributed
00008 //    without copyright and license information. Please refer
00009 //    to the file deal.II/doc/license.html for the  text  and
00010 //    further information on this license.
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                                  // without MPI, we would still like to use
00023                                  // some constructs with MPI data
00024                                  // types. Therefore, create some dummies
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   } // end of namespace MPI
00482 } // end of namespace Utilities
00483 
00484 
00485 DEAL_II_NAMESPACE_CLOSE
00486 
00487 #endif
00488 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

deal.II documentation generated on Tue May 22 2012 12:06:05 by doxygen 1.7.3