diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 5152bf5285ece836b5e8137755ab4935b434913e..d2158492339ce637e699ad1c1e4dbe6c73539cdc 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -9,6 +9,7 @@ add_library( BacktraceManager.cpp ConsoleManager.cpp FPEManager.cpp + Messenger.cpp PastisOStream.cpp PastisUtils.cpp RevisionInfo.cpp diff --git a/src/utils/Messenger.cpp b/src/utils/Messenger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..027f5bb3fae435a33fec842594f80e038375e736 --- /dev/null +++ b/src/utils/Messenger.cpp @@ -0,0 +1,50 @@ +#include <Messenger.hpp> +#include <PastisOStream.hpp> + +#include <pastis_config.hpp> + +#ifdef PASTIS_HAS_MPI +#include <mpi.h> +#endif // PASTIS_HAS_MPI + +Messenger* Messenger::m_instance = nullptr; + +void Messenger::create(int& argc, char* argv[]) +{ + if (Messenger::m_instance == nullptr) { + Messenger::m_instance = new Messenger(argc, argv); + } else { + std::cerr << "Messenger already created\n"; + std::exit(1); + } +} + +void Messenger::destroy() +{ + // One allows multiple destruction to handle unexpected code exit + if (Messenger::m_instance != nullptr) { + delete Messenger::m_instance; + Messenger::m_instance = nullptr; + } +} + +Messenger:: +Messenger(int& argc, char* argv[]) +{ +#ifdef PASTIS_HAS_MPI + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &m_rank); + MPI_Comm_size(MPI_COMM_WORLD, &m_size); + + if (m_rank != 0) { + pout.setOutput(null_stream); + perr.setOutput(null_stream); + } +#endif // PASTIS_HAS_MPI +} + +Messenger:: +~Messenger() +{ + MPI_Finalize(); +} diff --git a/src/utils/Messenger.hpp b/src/utils/Messenger.hpp new file mode 100644 index 0000000000000000000000000000000000000000..275840eefd04bd049a7e99ec92ab6505012ae349 --- /dev/null +++ b/src/utils/Messenger.hpp @@ -0,0 +1,34 @@ +#ifndef MESSENGER_HPP +#define MESSENGER_HPP + +#include <PastisMacros.hpp> + +class Messenger +{ + private: + static Messenger* m_instance; + Messenger(int& argc, char* argv[]); + + int m_rank{0}; + int m_size{1}; + public: + static void create(int& argc, char* argv[]); + static void destroy(); + + PASTIS_INLINE + const int& rank() const + { + return m_rank; + } + + PASTIS_INLINE + const int& size() const + { + return m_size; + } + + Messenger(const Messenger&) = delete; + ~Messenger(); +}; + +#endif // MESSENGER_HPP diff --git a/src/utils/PastisUtils.cpp b/src/utils/PastisUtils.cpp index 9494c68a7f8fcf5e48a885c7def1269b55d366e2..66aa50b49fa598ea66b98f4ac9d0ab54cd2815c1 100644 --- a/src/utils/PastisUtils.cpp +++ b/src/utils/PastisUtils.cpp @@ -6,6 +6,8 @@ #include <RevisionInfo.hpp> #include <BuildInfo.hpp> +#include <Messenger.hpp> + #include <rang.hpp> #include <FPEManager.hpp> @@ -14,30 +16,9 @@ #include <CLI/CLI.hpp> -#include <pastis_config.hpp> - -#ifdef PASTIS_HAS_MPI -#include <mpi.h> -#endif // PASTIS_HAS_MPI - std::string initialize(int& argc, char* argv[]) { -#ifdef PASTIS_HAS_MPI - MPI_Init(&argc, &argv); - - { - const int mpi_rank - =[](){ - int mpi_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - return mpi_rank; - }(); - if (mpi_rank != 0) { - pout.setOutput(null_stream); - perr.setOutput(null_stream); - } - } -#endif // PASTIS_HAS_MPI + Messenger::create(argc, argv); long unsigned number = 10; std::string filename; @@ -97,6 +78,7 @@ std::string initialize(int& argc, char* argv[]) try { app.parse(argc, argv); } catch (const CLI::ParseError &e) { + Messenger::destroy(); std::exit(app.exit(e, pout(), perr())); } @@ -124,30 +106,6 @@ std::string initialize(int& argc, char* argv[]) void finalize() { -#ifdef PASTIS_HAS_MPI - MPI_Barrier(MPI_COMM_WORLD); - const int mpi_rank - =[](){ - int mpi_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - return mpi_rank; - }(); - - const int mpi_size - =[](){ - int mpi_size; - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - return mpi_size; - }(); - - pout() << rang::fgB::green << "Terminating process " << rang::fg::reset - << rang::fgB::yellow << mpi_rank << rang::fg::reset << " of " - << rang::style::bold << mpi_size << rang::style::reset << '\n';; -#endif // PASTIS_HAS_MPI - Kokkos::finalize(); - -#ifdef PASTIS_HAS_MPI - MPI_Finalize(); -#endif // PASTIS_HAS_MPI + Messenger::destroy(); }