Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
gather_str.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
16#include "shambase/checksum.hpp"
18#include "shambase/string.hpp"
21#include "shamcomm/wrapper.hpp"
22#include <unordered_map>
23#include <string>
24#include <vector>
25
26namespace {
27
39 template<class Tchar>
40 inline void _internal_gather_str(
41 const std::basic_string<Tchar> &send_vec, std::basic_string<Tchar> &recv_vec) {
42 StackEntry stack_loc{};
43
44 if (shamcomm::world_size() == 1) {
45 recv_vec = send_vec;
46 return;
47 }
48
49 u32 wsize = shamcomm::world_size();
50
51 std::vector<int> counts(wsize);
52 std::vector<int> disps(wsize);
53
54 u32 local_count = send_vec.size();
55
56 shamcomm::mpi::Gather(&local_count, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD);
57
58 for (int i = 0; i < wsize; i++) {
59 disps[i] = (i > 0) ? (disps[i - 1] + counts[i - 1]) : 0;
60 }
61
62 std::string result = "";
63
64 if (shamcomm::world_rank() == 0) {
65 u32 global_len = disps[wsize - 1] + counts[wsize - 1];
66 result.resize(global_len);
67 }
68
70 send_vec.data(),
71 send_vec.size(),
72 MPI_CHAR,
73 result.data(),
74 counts.data(),
75 disps.data(),
76 MPI_CHAR,
77 0,
78 MPI_COMM_WORLD);
79
80 recv_vec = result;
81 }
82
88 template<class Tchar>
89 inline void _internal_allgather_str(
90 const std::basic_string<Tchar> &send_vec, std::basic_string<Tchar> &recv_vec) {
91 StackEntry stack_loc{};
92
93 if (shamcomm::world_size() == 1) {
94 recv_vec = send_vec;
95 return;
96 }
97
98 i32 wsize = shamcomm::world_size();
99 size_t wsize_sz = static_cast<size_t>(wsize);
100
101 // counts/displacements are expressed in number of characters.
102 std::vector<int> counts(wsize_sz);
103 std::vector<int> disps(wsize_sz);
104
105 // MPI counts/displacements use `int`.
106 int local_count = static_cast<int>(send_vec.size());
107
109 &local_count, 1, MPI_INT, counts.data(), 1, MPI_INT, MPI_COMM_WORLD);
110
111 for (size_t i = 0; i < wsize_sz; i++) {
112 disps[i] = (i > 0) ? (disps[i - 1] + counts[i - 1]) : 0;
113 }
114
115 int global_len = disps[wsize_sz - 1] + counts[wsize_sz - 1];
116
117 std::basic_string<Tchar> result;
118 result.resize(static_cast<size_t>(global_len));
119
121 send_vec.data(),
122 local_count,
123 MPI_CHAR,
124 result.data(),
125 counts.data(),
126 disps.data(),
127 MPI_CHAR,
128 MPI_COMM_WORLD);
129
130 recv_vec = result;
131 }
132
133} // namespace
134
135void shamalgs::collective::gather_str(const std::string &send_vec, std::string &recv_vec) {
136 StackEntry stack_loc{};
137 _internal_gather_str(send_vec, recv_vec);
138}
139
141 const std::basic_string<byte> &send_vec, std::basic_string<byte> &recv_vec) {
142 StackEntry stack_loc{};
143 _internal_gather_str(send_vec, recv_vec);
144}
145
146void shamalgs::collective::allgather_str(const std::string &send_vec, std::string &recv_vec) {
147 StackEntry stack_loc{};
148 _internal_allgather_str(send_vec, recv_vec);
149}
150
152 const std::basic_string<byte> &send_vec, std::basic_string<byte> &recv_vec) {
153 StackEntry stack_loc{};
154 _internal_allgather_str(send_vec, recv_vec);
155}
std::uint32_t u32
32 bit unsigned integer
std::int32_t i32
32 bit integer
MPI string gather / allgather helpers (declarations; implementations in shamalgs/src/collective/gathe...
void allgather_basic_str(const std::basic_string< byte > &send_vec, std::basic_string< byte > &recv_vec)
same as allgather_str but with std::basic_string
void allgather_str(const std::string &send_vec, std::string &recv_vec)
Allgathers a string from all nodes and concatenates it in a std::string.
void gather_basic_str(const std::basic_string< byte > &send_vec, std::basic_string< byte > &recv_vec)
same as gather_str but with std::basic_string
void gather_str(const std::string &send_vec, std::string &recv_vec)
Gathers a string from all nodes and store the result in a std::string.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
Definition worldInfo.cpp:40
i32 world_size()
Gives the size of the MPI communicator.
Definition worldInfo.cpp:38
This file contains the definition for the stacktrace related functionality.
Functions related to the MPI communicator.
void Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm)
MPI wrapper for MPI_Gatherv.
Definition wrapper.cpp:342
void Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm)
MPI wrapper for MPI_Allgatherv.
Definition wrapper.cpp:149
void Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
MPI wrapper for MPI_Gather.
Definition wrapper.cpp:326
void Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
MPI wrapper for MPI_Allgather.
Definition wrapper.cpp:133