diff options
Diffstat (limited to 'Source/ablastr/parallelization')
-rw-r--r-- | Source/ablastr/parallelization/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Source/ablastr/parallelization/MPIInitHelpers.H | 45 | ||||
-rw-r--r-- | Source/ablastr/parallelization/MPIInitHelpers.cpp | 93 | ||||
-rw-r--r-- | Source/ablastr/parallelization/Make.package | 2 |
4 files changed, 147 insertions, 0 deletions
diff --git a/Source/ablastr/parallelization/CMakeLists.txt b/Source/ablastr/parallelization/CMakeLists.txt new file mode 100644 index 000000000..a6957d4d5 --- /dev/null +++ b/Source/ablastr/parallelization/CMakeLists.txt @@ -0,0 +1,7 @@ +foreach(D IN LISTS WarpX_DIMS) + warpx_set_suffix_dims(SD ${D}) + target_sources(ablastr_${SD} + PRIVATE + MPIInitHelpers.cpp + ) +endforeach() diff --git a/Source/ablastr/parallelization/MPIInitHelpers.H b/Source/ablastr/parallelization/MPIInitHelpers.H new file mode 100644 index 000000000..6b9bdfa47 --- /dev/null +++ b/Source/ablastr/parallelization/MPIInitHelpers.H @@ -0,0 +1,45 @@ +/* Copyright 2020 Axel Huebl + * + * This file is part of ABLASTR. + * + * License: BSD-3-Clause-LBNL + */ +#ifndef ABLASTR_MPI_INIT_HELPERS_H_ +#define ABLASTR_MPI_INIT_HELPERS_H_ + +#include <utility> + +namespace ablastr::parallelization +{ + /** Return the required MPI threading + * + * @return the MPI_THREAD_* level required for MPI_Init_thread + */ + int + mpi_thread_required (); + + /** Initialize MPI + * + * @return pair(required, provided) of MPI thread level from MPI_Init_thread + */ + std::pair< int, int > + mpi_init (int argc, char* argv[]); + + /** Finalize MPI + * + * This function is simply a wrapper around MPI_Finalize(). It is a no-op if + * ABLASTR is compiled without MPI support. + */ + void + mpi_finalize (); + + /** Check if the requested MPI thread level is valid + * + * Prints warnings and notes otherwise. + */ + void + check_mpi_thread_level (); + +} // namespace ablastr::parallelization + +#endif // ABLASTR_MPI_INIT_HELPERS_H_ diff --git a/Source/ablastr/parallelization/MPIInitHelpers.cpp b/Source/ablastr/parallelization/MPIInitHelpers.cpp new file mode 100644 index 000000000..cdf458213 --- /dev/null +++ b/Source/ablastr/parallelization/MPIInitHelpers.cpp @@ -0,0 +1,93 @@ +/* Copyright 2020 Axel Huebl + * + * This file is part of ABLASTR. + * + * License: BSD-3-Clause-LBNL + */ +#include "MPIInitHelpers.H" + +#include <ablastr/warn_manager/WarnManager.H> + +#include <AMReX_Config.H> +#include <AMReX_ParallelDescriptor.H> +#include <AMReX_Print.H> + +#if defined(AMREX_USE_MPI) +# include <mpi.h> +#endif + +#include <string> +#include <utility> +#include <sstream> + +namespace ablastr::parallelization +{ + int + mpi_thread_required () + { + int thread_required = -1; +#ifdef AMREX_USE_MPI + thread_required = MPI_THREAD_SINGLE; // equiv. to MPI_Init +# ifdef AMREX_USE_OMP + thread_required = MPI_THREAD_FUNNELED; +# endif +# ifdef AMREX_MPI_THREAD_MULTIPLE // i.e. for async_io + thread_required = MPI_THREAD_MULTIPLE; +# endif +#endif + return thread_required; + } + + std::pair< int, int > + mpi_init (int argc, char* argv[]) + { + const int thread_required = mpi_thread_required(); +#ifdef AMREX_USE_MPI + int thread_provided = -1; + MPI_Init_thread(&argc, &argv, thread_required, &thread_provided); +#else + amrex::ignore_unused(argc, argv); + const int thread_provided = -1; +#endif + return std::make_pair(thread_required, thread_provided); + } + + + void + mpi_finalize () + { +#ifdef AMREX_USE_MPI + MPI_Finalize(); +#endif + } + + void + check_mpi_thread_level () + { +#ifdef AMREX_USE_MPI + const int thread_required = mpi_thread_required(); + int thread_provided = -1; + MPI_Query_thread(&thread_provided); + auto mtn = amrex::ParallelDescriptor::mpi_level_to_string; + + std::stringstream ss; + if( thread_provided < thread_required ){ + ss << "WARNING: Provided MPI thread safety level (" + << mtn(thread_provided) << ") is LOWER than requested " + << mtn(thread_required) << "). This might lead to undefined " + << "results in asynchronous operations (e.g. async_io)."; + ablastr::warn_manager::WMRecordWarning( + "MPI", ss.str(), ablastr::warn_manager::WarnPriority::high); + } + if( thread_provided > thread_required ){ + ss << "NOTE: Provided MPI thread safety level (" + << mtn(thread_provided) << ") is stricter than requested " + << mtn(thread_required) << "). This might reduce multi-node " + << "communication performance."; + ablastr::warn_manager::WMRecordWarning( + "MPI", ss.str()); + } +#endif + } + +} // namespace ablastr::parallelization diff --git a/Source/ablastr/parallelization/Make.package b/Source/ablastr/parallelization/Make.package index 9b248b7fa..a70a8a61e 100644 --- a/Source/ablastr/parallelization/Make.package +++ b/Source/ablastr/parallelization/Make.package @@ -1 +1,3 @@ +CEXE_sources += MPIInitHelpers.cpp + VPATH_LOCATIONS += $(WARPX_HOME)/Source/ablastr/parallelization |