diff --git a/src/backends/detection/detection.cpp b/src/backends/detection/detection.cpp index 3fb20fa11c928f4ee86dc81589c538c04451f5fb..2be1c928bd6b6b6cfc4b724085277ab4bbf988d4 100644 --- a/src/backends/detection/detection.cpp +++ b/src/backends/detection/detection.cpp @@ -44,7 +44,7 @@ ThreadStore getThreadStoreOfCaller() { double getTimeStamp() { #ifdef WITH_MPI - return MPI_Wtime(); + return PMPI_Wtime(); #else using clock = std::chrono::system_clock; auto now = clock::now(); diff --git a/src/backends/dlb_talp_tree/dlb_talp_tree.cpp b/src/backends/dlb_talp_tree/dlb_talp_tree.cpp index 19e7bcb50293fc35c1e946e17ba862fcc7833927..50802a7a27eff0ac652c56a4f4d1e525599784e0 100644 --- a/src/backends/dlb_talp_tree/dlb_talp_tree.cpp +++ b/src/backends/dlb_talp_tree/dlb_talp_tree.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -101,16 +103,72 @@ void DLBTalpTreeStrategy::Finalize() noexcept { // Stop the top region which was automatically started by TALP. talp_profiling_strategy_.RegionStop({.name = top_region_}); - // Collect the POP metrics from all the regions + int num_regions = regions_.size(); + + std::vector region_hashes; + region_hashes.reserve(num_regions); + for (auto ®ion : regions_) { - std::string name = region_hash_to_string(region.first); - if (region.second.name.compare(top_region_) == 0) { + region_hashes.push_back(region.first); + } + + std::set unique_regions; + if (mpi_helper_.IsUsingMPI()) { +#ifdef WITH_MPI + int mpi_size = mpi_helper_.getCommSize(); + std::vector counts; + std::vector displs; + counts.resize(mpi_size); + displs.resize(mpi_size); + + MPI_Allgather(&num_regions, 1, MPI_INT, counts.data(), 1, MPI_INT, + MPI_COMM_WORLD); + + int num_all_regions = 0; + for (int i = 0; i < counts.size(); i++) { + num_all_regions += counts[i]; + } + + int last = 0; + for (int i = 0; i < counts.size(); i++) { + counts[i] *= sizeof(std::size_t); + displs[i] = last; + last += counts[i]; + } + + std::vector all_regions(num_all_regions); + PMPI_Allgatherv( + // What we send + region_hashes.data(), region_hashes.size() * sizeof(std::size_t), + MPI_BYTE, + + // What we receive + all_regions.data(), counts.data(), displs.data(), MPI_BYTE, + + // To whom + MPI_COMM_WORLD); + + for (std::size_t region_hash : all_regions) { + unique_regions.insert(region_hash); + } +#endif + } else { + for (std::size_t region_hash : region_hashes) { + unique_regions.insert(region_hash); + } + } + + // Collect the POP metrics from all the regions + for (auto ®ion_hash : unique_regions) { + auto ®ion = regions_[region_hash]; + + std::string name = region_hash_to_string(region_hash); + if (region.name.compare(top_region_) == 0) { name = top_region_; } auto handle = DLB_MonitoringRegionRegister(name.c_str()); - int dlb_error = - DLB_TALP_CollectPOPMetrics(handle, ®ion.second.pop_metrics); + int dlb_error = DLB_TALP_CollectPOPMetrics(handle, ®ion.pop_metrics); if (dlb_error != DLB_SUCCESS) { // Warn about the error trying to close region name with hash diff --git a/src/utils/parallelism_helper.cpp b/src/utils/parallelism_helper.cpp index 2955cc4108acd2643eae001bdecdbf7e53140134..7b63ba3329d8c41b6828c2943f442315e9fbf046 100644 --- a/src/utils/parallelism_helper.cpp +++ b/src/utils/parallelism_helper.cpp @@ -24,14 +24,16 @@ bool MPIHelper::IsRankNumber(int asked_rank) const { int MPIHelper::getRankNumber() const { return mpi_comm_rank; } +int MPIHelper::getCommSize() const { return mpi_comm_size; } + MPIHelper::MPIHelper() { if (!mpi_information.valid) { int is_initialized; - MPI_Initialized(&is_initialized); + PMPI_Initialized(&is_initialized); mpi_information.mpi_is_initialized = static_cast(is_initialized); if (mpi_information.mpi_is_initialized) { - MPI_Comm_size(MPI_COMM_WORLD, &mpi_information.comm_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_information.rank); + PMPI_Comm_size(MPI_COMM_WORLD, &mpi_information.comm_size); + PMPI_Comm_rank(MPI_COMM_WORLD, &mpi_information.rank); } mpi_information.valid = true; } @@ -52,6 +54,8 @@ bool MPIHelper::IsRankNumber(int asked_rank) const { return asked_rank == 0; } int MPIHelper::getRankNumber() const { return mpi_comm_rank; } +int MPIHelper::getCommSize() const { return mpi_comm_size; } + MPIHelper::MPIHelper() {} #endif diff --git a/src/utils/parallelism_helper.hpp b/src/utils/parallelism_helper.hpp index 7561d026345079f38b3035538cf2753391f296e3..e92bf2117e42ded0590f70db5a6ff7c641a84153 100644 --- a/src/utils/parallelism_helper.hpp +++ b/src/utils/parallelism_helper.hpp @@ -23,6 +23,8 @@ class MPIHelper { bool IsRankNumber(int asked_rank) const; int getRankNumber() const; + + int getCommSize() const; }; #endif // NESMIK_PARALLELISM_HELPER_HPP diff --git a/src/utils/terminator.cpp b/src/utils/terminator.cpp index b9b3ca0653db87e9e8a35874ea57823bcee8b4ee..527198ffe0f76be6c06e59627fc0ba72bac77572 100644 --- a/src/utils/terminator.cpp +++ b/src/utils/terminator.cpp @@ -13,7 +13,7 @@ void Terminator::exit(int exitcode) { } #ifdef WITH_MPI if (mpi_helper.IsUsingMPI()) { - MPI_Abort(MPI_COMM_WORLD, exitcode); + PMPI_Abort(MPI_COMM_WORLD, exitcode); } else #endif { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 384053429942e9a7ca5d6aae9b6b43be418d5862..9223038c8cfd3f81239e8e7805592ea0f053ff4e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -43,7 +43,15 @@ add_test(NAME TestCppTalpTree PRIVATE ${NESMIK_PUBLIC_HEADERS}) add_test(NAME TestCppTalpTreeMPI - COMMAND mpirun -np 2 TestCppTalpTree) + COMMAND TestCppTalpTree) + + add_executable(TestCppTalpTreeMPI_MPMD cpp/TestCppTalpTreeMPI_MPMD.cpp) + target_link_libraries(TestCppTalpTreeMPI_MPMD nesmik::nesmik MPI::MPI_CXX) + target_include_directories(TestCppTalpTreeMPI_MPMD + PRIVATE ${NESMIK_PUBLIC_HEADERS}) + + add_test(NAME TestCppTalpTreeMPI_MPMD + COMMAND TestCppTalpTreeMPI_MPMD) endif() diff --git a/tests/cpp/TestCppTalpTreeMPI_MPMD.cpp b/tests/cpp/TestCppTalpTreeMPI_MPMD.cpp new file mode 100644 index 0000000000000000000000000000000000000000..600f2d3b49e80b7e762143a0642378a7e6b0fd4d --- /dev/null +++ b/tests/cpp/TestCppTalpTreeMPI_MPMD.cpp @@ -0,0 +1,15 @@ +#include + +#include "nesmik/nesmik.hpp" +int main() { + MPI_Init(NULL, NULL); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + nesmik::nesmik_init(); + nesmik::region_start("Top"); + nesmik::region_start(std::to_string(rank)); + nesmik::region_stop(std::to_string(rank)); + nesmik::region_stop("Top"); + nesmik::nesmik_finalize(); + MPI_Finalize(); +}