From: Timo Heister Date: Tue, 12 May 2015 18:50:55 +0000 (-0400) Subject: implement MPI::min() X-Git-Tag: v8.3.0-rc1~174^2~6 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4492baa7a77b9499e3c85304f206a2a4b72fc6c4;p=dealii.git implement MPI::min() --- diff --git a/include/deal.II/base/mpi.h b/include/deal.II/base/mpi.h index 09550080bd..e574ad5b42 100644 --- a/include/deal.II/base/mpi.h +++ b/include/deal.II/base/mpi.h @@ -237,6 +237,58 @@ namespace Utilities const MPI_Comm &mpi_communicator, std::vector &maxima); + /** + * Return the minimum over all processors of the value @p t. This function + * is collective over all processors given in the communicator. If deal.II + * is not configured for use of MPI, this function simply returns the + * value of @p t. This function corresponds to the + * MPI_Allreduce function, i.e. all processors receive the + * result of this operation. + * + * @note Sometimes, not all processors need a results and in that case one + * would call the MPI_Reduce function instead of the + * MPI_Allreduce function. The latter is at most twice as + * expensive, so if you are concerned about performance, it may be + * worthwhile investigating whether your algorithm indeed needs the result + * everywhere or whether you could get away with calling the current + * function and getting the result everywhere. + * + * @note This function is only implemented for certain template arguments + * T, namely float, double, int, unsigned int. + */ + template + T min (const T &t, + const MPI_Comm &mpi_communicator); + + /** + * Like the previous function, but take the minima over the elements of an + * array of length N. In other words, the i-th element of the results + * array is the minimum of the i-th entries of the input arrays from each + * processor. + * + * Input and output arrays may be the same. + */ + template + inline + void min (const T (&values)[N], + const MPI_Comm &mpi_communicator, + T (&minima)[N]); + + /** + * Like the previous function, but take the minimum over the elements of a + * std::vector. In other words, the i-th element of the results array is + * the minimum over the i-th entries of the input arrays from each + * processor. + * + * Input and output vectors may be the same. + */ + template + inline + void min (const std::vector &values, + const MPI_Comm &mpi_communicator, + std::vector &minima); + + /** * Data structure to store the result of min_max_avg(). */ @@ -615,6 +667,83 @@ namespace Utilities } + template + inline + T min (const T &t, + const MPI_Comm &mpi_communicator) + { +#ifdef DEAL_II_WITH_MPI + if (job_supports_mpi()) + { + T sum; + MPI_Allreduce (const_cast(static_cast(&t)), + &sum, 1, internal::mpi_type_id(&t), MPI_MIN, + mpi_communicator); + return sum; + } + else +#endif + { + (void)mpi_communicator; + return t; + } + } + + + template + inline + void min (const T (&values)[N], + const MPI_Comm &mpi_communicator, + T (&minima)[N]) + { +#ifdef DEAL_II_WITH_MPI + if (job_supports_mpi()) + { + MPI_Allreduce ((&values[0] != &minima[0] + ? + const_cast(static_cast(&values[0])) + : + MPI_IN_PLACE), + &minima[0], N, internal::mpi_type_id(values), MPI_MIN, + mpi_communicator); + } + else +#endif + { + (void)mpi_communicator; + for (unsigned int i=0; i + inline + void min (const std::vector &values, + const MPI_Comm &mpi_communicator, + std::vector &minima) + { +#ifdef DEAL_II_WITH_MPI + if (job_supports_mpi()) + { + minima.resize (values.size()); + MPI_Allreduce ((&values[0] != &minima[0] + ? + const_cast(static_cast(&values[0])) + : + MPI_IN_PLACE), + &minima[0], values.size(), internal::mpi_type_id((T *)0), MPI_MIN, + mpi_communicator); + } + else +#endif + { + (void)mpi_communicator; + minima = values; + } + } + + inline bool job_supports_mpi () {