Skip to content

Commit 85aa8b3

Browse files
committed
Add new MPI helper: collectStringsTo()
1 parent e7a6f57 commit 85aa8b3

3 files changed

Lines changed: 158 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ set(CORE_SOURCE
353353
src/auxiliary/Date.cpp
354354
src/auxiliary/Filesystem.cpp
355355
src/auxiliary/JSON.cpp
356+
src/auxiliary/MPI.cpp
356357
src/backend/Attributable.cpp
357358
src/backend/BaseRecordComponent.cpp
358359
src/backend/MeshRecordComponent.cpp

include/openPMD/auxiliary/MPI.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#pragma once
2+
3+
#include "openPMD/config.hpp"
4+
5+
#if openPMD_HAVE_MPI
6+
7+
# include <mpi.h>
8+
# include <string>
9+
# include <vector>
10+
11+
namespace openPMD
12+
{
13+
namespace auxiliary
14+
{
15+
std::vector< std::string >
16+
collectStringsTo(
17+
MPI_Comm communicator,
18+
int destRank,
19+
std::string const & thisRankString );
20+
21+
std::vector< std::string >
22+
distributeStringsToAllRanks(
23+
MPI_Comm communicator,
24+
std::string const & thisRankString );
25+
} // namespace auxiliary
26+
} // namespace openPMD
27+
#endif

src/auxiliary/MPI.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#include "openPMD/auxiliary/MPI.hpp"
2+
3+
#if openPMD_HAVE_MPI
4+
5+
namespace openPMD
6+
{
7+
namespace auxiliary
8+
{
9+
std::vector< std::string >
10+
collectStringsTo(
11+
MPI_Comm communicator,
12+
int destRank,
13+
std::string const & thisRankString )
14+
{
15+
int rank, size;
16+
MPI_Comm_rank( communicator, &rank );
17+
MPI_Comm_size( communicator, &size );
18+
int sendLength = thisRankString.size() + 1;
19+
20+
int * sizesBuffer = nullptr;
21+
int * displs = nullptr;
22+
if( rank == destRank )
23+
{
24+
sizesBuffer = new int[ size ];
25+
displs = new int[ size ];
26+
}
27+
28+
MPI_Gather(
29+
&sendLength,
30+
1,
31+
MPI_INT,
32+
sizesBuffer,
33+
1,
34+
MPI_INT,
35+
destRank,
36+
MPI_COMM_WORLD );
37+
38+
char * namesBuffer = nullptr;
39+
if( rank == destRank )
40+
{
41+
size_t sum = 0;
42+
for( int i = 0; i < size; ++i )
43+
{
44+
displs[ i ] = sum;
45+
sum += sizesBuffer[ i ];
46+
}
47+
namesBuffer = new char[ sum ];
48+
}
49+
50+
MPI_Gatherv(
51+
thisRankString.c_str(),
52+
sendLength,
53+
MPI_CHAR,
54+
namesBuffer,
55+
sizesBuffer,
56+
displs,
57+
MPI_CHAR,
58+
destRank,
59+
MPI_COMM_WORLD );
60+
61+
if( rank == destRank )
62+
{
63+
std::vector< std::string > hostnames( size );
64+
for( int i = 0; i < size; ++i )
65+
{
66+
hostnames[ i ] = std::string( namesBuffer + displs[ i ] );
67+
}
68+
69+
delete[] sizesBuffer;
70+
delete[] displs;
71+
delete[] namesBuffer;
72+
return hostnames;
73+
}
74+
else
75+
{
76+
return std::vector< std::string >();
77+
}
78+
}
79+
80+
std::vector< std::string >
81+
distributeStringsToAllRanks(
82+
MPI_Comm communicator,
83+
std::string const & thisRankString )
84+
{
85+
int rank, size;
86+
MPI_Comm_rank( communicator, &rank );
87+
MPI_Comm_size( communicator, &size );
88+
int sendLength = thisRankString.size() + 1;
89+
90+
int * sizesBuffer = new int[ size ];
91+
int * displs = new int[ size ];
92+
93+
MPI_Allgather(
94+
&sendLength, 1, MPI_INT, sizesBuffer, 1, MPI_INT, MPI_COMM_WORLD );
95+
96+
char * namesBuffer;
97+
{
98+
size_t sum = 0;
99+
for( int i = 0; i < size; ++i )
100+
{
101+
displs[ i ] = sum;
102+
sum += sizesBuffer[ i ];
103+
}
104+
namesBuffer = new char[ sum ];
105+
}
106+
107+
MPI_Allgatherv(
108+
thisRankString.c_str(),
109+
sendLength,
110+
MPI_CHAR,
111+
namesBuffer,
112+
sizesBuffer,
113+
displs,
114+
MPI_CHAR,
115+
MPI_COMM_WORLD );
116+
117+
std::vector< std::string > hostnames( size );
118+
for( int i = 0; i < size; ++i )
119+
{
120+
hostnames[ i ] = std::string( namesBuffer + displs[ i ] );
121+
}
122+
123+
delete[] sizesBuffer;
124+
delete[] displs;
125+
delete[] namesBuffer;
126+
return hostnames;
127+
}
128+
} // namespace auxiliary
129+
} // namespace openPMD
130+
#endif

0 commit comments

Comments
 (0)