ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
scatter_buffer.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2022 The ESPResSo project
3 * Max-Planck-Institute for Polymer Research, Theory Group
4 *
5 * This file is part of ESPResSo.
6 *
7 * ESPResSo is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * ESPResSo is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef UTILS_MPI_SCATTER_BUFFER_HPP
22#define UTILS_MPI_SCATTER_BUFFER_HPP
23
25
26#include <boost/mpi/communicator.hpp>
27
28#include <algorithm>
29#include <type_traits>
30#include <vector>
31
32namespace Utils {
33namespace Mpi {
34
35/**
36 * @brief Scatter buffer with different size on each node.
37 *
38 * Scatter a buffer to the nodes, where every node gets
39 * a different chunk of the buffer, controlled by the worker node.
40 *
41 * This is a collective call.
42 */
43template <typename T>
44void scatter_buffer(T *buffer, int n_elem, boost::mpi::communicator comm,
45 int root = 0) {
46 static_assert(std::is_trivial_v<T>);
47 if (comm.rank() == root) {
48 static std::vector<int> sizes;
49 static std::vector<int> displ;
50
51 detail::size_and_offset<T>(sizes, displ, n_elem, comm, root);
52
53 for (auto i = 0u; i < static_cast<unsigned>(comm.size()); i++) {
54 sizes[i] *= sizeof(T);
55 displ[i] *= sizeof(T);
56 }
57
58 /* Send data */
59 MPI_Scatterv(buffer, sizes.data(), displ.data(), MPI_BYTE, MPI_IN_PLACE, 0,
60 MPI_BYTE, root, comm);
61 } else {
62 detail::size_and_offset(n_elem, comm, root);
63 /* Recv data */
64 MPI_Scatterv(nullptr, nullptr, nullptr, MPI_BYTE, buffer,
65 n_elem * sizeof(T), MPI_BYTE, root, comm);
66 }
67}
68} // namespace Mpi
69} // namespace Utils
70
71#endif
void scatter_buffer(T *buffer, int n_elem, boost::mpi::communicator comm, int root=0)
Scatter buffer with different size on each node.