13 #include <dolfinx/graph/AdjacencyList.h>
18 #include <type_traits>
22 #define MPICH_IGNORE_CXX_SEEK 1
35 explicit Comm(MPI_Comm
comm,
bool duplicate =
true);
53 MPI_Comm
comm()
const noexcept;
61 int rank(MPI_Comm comm);
65 int size(MPI_Comm comm);
100 std::tuple<std::vector<int>, std::vector<int>>
117 const std::int64_t n = N /
size;
118 const std::int64_t r = N %
size;
122 return {{
rank * (n + 1),
rank * (n + 1) + n + 1}};
124 return {{
rank * n + r,
rank * n + r + n}};
137 const std::size_t n = N /
size;
138 const std::size_t r = N %
size;
141 if (index < r * (n + 1))
142 return index / (n + 1);
145 return r + (index - r * (n + 1)) / n;
148 template <
typename T>
154 template <
typename T>
157 if constexpr (std::is_same<T, float>::value)
159 else if constexpr (std::is_same<T, double>::value)
161 else if constexpr (std::is_same<T, std::complex<double>>::value)
162 return MPI_DOUBLE_COMPLEX;
163 else if constexpr (std::is_same<T, short int>::value)
165 else if constexpr (std::is_same<T, int>::value)
167 else if constexpr (std::is_same<T, unsigned int>::value)
169 else if constexpr (std::is_same<T, long int>::value)
171 else if constexpr (std::is_same<T, unsigned long>::value)
172 return MPI_UNSIGNED_LONG;
173 else if constexpr (std::is_same<T, long long>::value)
174 return MPI_LONG_LONG;
175 else if constexpr (std::is_same<T, unsigned long long>::value)
176 return MPI_UNSIGNED_LONG_LONG;
177 else if constexpr (std::is_same<T, bool>::value)
182 template <
typename T>
186 const std::vector<std::int32_t>& send_offsets = send_data.
offsets();
187 const std::vector<T>& values_in = send_data.
array();
190 assert(send_data.
num_nodes() == comm_size);
193 std::vector<int> send_size(comm_size);
194 std::adjacent_difference(std::next(send_offsets.begin(), +1),
195 send_offsets.end(), send_size.begin());
198 std::vector<int> recv_size(comm_size);
199 MPI_Alltoall(send_size.data(), 1, mpi_type<int>(), recv_size.data(), 1,
200 mpi_type<int>(), comm);
203 std::vector<std::int32_t> recv_offset(comm_size + 1);
205 std::partial_sum(recv_size.begin(), recv_size.end(),
206 std::next(recv_offset.begin()));
209 std::vector<T> recv_values(recv_offset[comm_size]);
210 MPI_Alltoallv(values_in.data(), send_size.data(), send_offsets.data(),
211 mpi_type<T>(), recv_values.data(), recv_size.data(),
212 recv_offset.data(), mpi_type<T>(), comm);
215 std::move(recv_offset));
218 template <
typename T>
224 int indegree(-1), outdegree(-2), weighted(-1);
225 MPI_Dist_graph_neighbors_count(neighbor_comm, &indegree, &outdegree,
230 std::vector<int> send_sizes(outdegree + 1, 0);
231 std::vector<int> recv_sizes(indegree + 1);
232 std::adjacent_difference(std::next(send_data.
offsets().begin()),
233 send_data.
offsets().end(), send_sizes.begin());
235 MPI_Neighbor_alltoall(send_sizes.data(), 1, MPI::mpi_type<int>(),
236 recv_sizes.data(), 1, MPI::mpi_type<int>(),
241 std::vector<int> recv_offsets(indegree + 1);
243 std::partial_sum(recv_sizes.begin(), std::prev(recv_sizes.end()),
244 std::next(recv_offsets.begin(), 1));
246 std::vector<T> recv_data(recv_offsets[recv_offsets.size() - 1]);
247 MPI_Neighbor_alltoallv(
248 send_data.
array().data(), send_sizes.data(), send_data.
offsets().data(),
249 MPI::mpi_type<T>(), recv_data.data(), recv_sizes.data(),
250 recv_offsets.data(), MPI::mpi_type<T>(), neighbor_comm);
A duplicate MPI communicator and manage lifetime of the communicator.
Definition: MPI.h:32
MPI_Comm comm() const noexcept
Return the underlying MPI_Comm object.
Definition: MPI.cpp:72
~Comm()
Destructor (frees wrapped communicator)
Definition: MPI.cpp:38
Comm(MPI_Comm comm, bool duplicate=true)
Duplicate communicator and wrap duplicate.
Definition: MPI.cpp:11
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:47
const std::vector< std::int32_t > & offsets() const
Offset for each node in array() (const version)
Definition: AdjacencyList.h:153
std::int32_t num_nodes() const
Get the number of nodes.
Definition: AdjacencyList.h:115
const std::vector< T > & array() const
Return contiguous array of links for all nodes (const version)
Definition: AdjacencyList.h:147
MPI support functionality.
Definition: MPI.h:27
graph::AdjacencyList< T > neighbor_all_to_all(MPI_Comm neighbor_comm, const graph::AdjacencyList< T > &send_data)
Neighborhood all-to-all. Send data to neighbors. Send in_values[n0] to neighbor process n0 and receiv...
Definition: MPI.h:220
std::vector< int > compute_graph_edges(MPI_Comm comm, const std::set< int > &edges)
Definition: MPI.cpp:89
int rank(MPI_Comm comm)
Return process rank for the communicator.
Definition: MPI.cpp:74
int size(MPI_Comm comm)
Return size of the group (number of processes) associated with the communicator.
Definition: MPI.cpp:82
constexpr int index_owner(int size, std::size_t index, std::size_t N)
Return which process owns index (inverse of local_range)
Definition: MPI.h:132
constexpr MPI_Datatype mpi_type()
MPI Type.
Definition: MPI.h:155
std::tuple< std::vector< int >, std::vector< int > > neighbors(MPI_Comm neighbor_comm)
Definition: MPI.cpp:110
graph::AdjacencyList< T > all_to_all(MPI_Comm comm, const graph::AdjacencyList< T > &send_data)
Send in_values[p0] to process p0 and receive values from process p1 in out_values[p1].
Definition: MPI.h:183
constexpr std::array< std::int64_t, 2 > local_range(int rank, std::int64_t N, int size)
Return local range for given process, splitting [0, N - 1] into size() portions of almost equal size.
Definition: MPI.h:109