VIPRA Documentation
Loading...
Searching...
No Matches
mpi_util.hpp
1#pragma once
2
3#include <vector>
4#include "vipra/util/mpi_types.hpp"
5
6#ifdef VIPRA_USE_MPI
7#include <mpi.h>
8
9namespace VIPRA::Util {
10
18template <typename data_t>
19[[nodiscard]] inline auto mpi_gather_all_vectors(std::vector<data_t> const& localData)
20 -> std::pair<std::vector<data_t>, std::vector<int>>
21{
22 MPI_Barrier(MPI_COMM_WORLD);
23
24 int rank{};
25 int size{};
26 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
27 MPI_Comm_size(MPI_COMM_WORLD, &size);
28
29 std::vector<int> counts;
30 std::vector<int> displacements;
31
32 if ( rank == 0 ) {
33 counts.resize(size);
34 displacements.resize(size);
35 }
36
37 int localSize = static_cast<int>(localData.size());
38 MPI_Gather(&localSize, 1, MPI_INT, counts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
39
40 std::vector<data_t> allData;
41 if ( rank == 0 ) {
42 int totalSize = 0;
43
44 for ( int i = 0; i < size; ++i ) {
45 displacements[i] = totalSize;
46 totalSize += counts[i];
47 }
48
49 allData.resize(totalSize); // Allocate space for all data
50 }
51
52 // Gather all vectors into the root process
53 MPI_Gatherv(localData.data(), localSize, VIPRA::Util::get_mpi_type<data_t>(),
54 allData.data(), counts.data(), displacements.data(),
55 VIPRA::Util::get_mpi_type<data_t>(), 0, MPI_COMM_WORLD);
56
57 MPI_Barrier(MPI_COMM_WORLD);
58
59 return {std::move(allData), std::move(counts)};
60}
61
67inline void master_do(auto&& func)
68{
69 int rank{};
70
71 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
72
73 if ( rank == 0 ) {
74 func();
75 }
76}
77
78} // namespace VIPRA::Util
79#else
80namespace VIPRA::Util {
81template <typename data_t>
82[[nodiscard]] inline auto mpi_gather_all_vectors(std::vector<data_t> const& localData)
83 -> std::pair<std::vector<data_t>, std::vector<int>>
84{
85 constexpr bool always_false = false;
86 static_assert(always_false,
87 "Attempting to use mpi_gather_all_vectors when MPI is not enabled");
88}
89
95inline void master_do(auto&& func) { func(); }
96} // namespace VIPRA::Util
97#endif