Skip to content

Commit 86d982f

Browse files
committed
Add some distribution strategies
1 parent 116f7ed commit 86d982f

3 files changed

Lines changed: 668 additions & 0 deletions

File tree

include/openPMD/Chunk.hpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <vector>
2424

2525
#include "openPMD/Dataset.hpp" // Offset, Extent
26+
#include "openPMD/benchmark/mpi/BlockSlicer.hpp"
2627

2728
namespace openPMD
2829
{
@@ -73,4 +74,120 @@ struct WrittenChunkInfo : ChunkInfo
7374
};
7475

7576
using ChunkTable = std::vector< WrittenChunkInfo >;
77+
78+
namespace chunk_assignment
79+
{
80+
constexpr char const * HOSTFILE_VARNAME = "MPI_WRITTEN_HOSTFILE";
81+
82+
using RankMeta = std::map< unsigned int, std::string >;
83+
84+
struct PartialAssignment
85+
{
86+
ChunkTable notAssigned;
87+
ChunkTable assigned;
88+
89+
explicit PartialAssignment() = default;
90+
PartialAssignment( ChunkTable notAssigned );
91+
PartialAssignment( ChunkTable notAssigned, ChunkTable assigned );
92+
};
93+
94+
struct Strategy
95+
{
96+
virtual ChunkTable
97+
assign(
98+
PartialAssignment,
99+
RankMeta const & in,
100+
RankMeta const & out ) = 0;
101+
102+
virtual ~Strategy() = default;
103+
};
104+
105+
struct PartialStrategy
106+
{
107+
virtual PartialAssignment
108+
assign(
109+
PartialAssignment,
110+
RankMeta const & in,
111+
RankMeta const & out ) = 0;
112+
113+
virtual ~PartialStrategy() = default;
114+
};
115+
116+
ChunkTable
117+
assignChunks(
118+
ChunkTable,
119+
RankMeta const & rankMetaIn,
120+
RankMeta const & rankMetaOut,
121+
Strategy & strategy );
122+
123+
struct FromPartialStrategy : Strategy
124+
{
125+
FromPartialStrategy(
126+
std::unique_ptr< PartialStrategy > firstPass,
127+
std::unique_ptr< Strategy > secondPass );
128+
129+
virtual ChunkTable
130+
assign( PartialAssignment, RankMeta const & in, RankMeta const & out );
131+
132+
private:
133+
std::unique_ptr< PartialStrategy > m_firstPass;
134+
std::unique_ptr< Strategy > m_secondPass;
135+
};
136+
137+
struct RoundRobin : Strategy
138+
{
139+
ChunkTable
140+
assign( PartialAssignment, RankMeta const & in, RankMeta const & out );
141+
};
142+
143+
struct ByHostname : PartialStrategy
144+
{
145+
ByHostname( std::unique_ptr< Strategy > withinNode );
146+
147+
PartialAssignment
148+
assign( PartialAssignment, RankMeta const & in, RankMeta const & out )
149+
override;
150+
151+
private:
152+
std::unique_ptr< Strategy > m_withinNode;
153+
};
154+
155+
struct ByCuboidSlice : Strategy
156+
{
157+
ByCuboidSlice(
158+
std::unique_ptr< BlockSlicer > blockSlicer,
159+
Extent totalExtent,
160+
unsigned int mpi_rank,
161+
unsigned int mpi_size );
162+
163+
ChunkTable
164+
assign( PartialAssignment, RankMeta const & in, RankMeta const & out )
165+
override;
166+
167+
private:
168+
std::unique_ptr< BlockSlicer > blockSlicer;
169+
Extent totalExtent;
170+
unsigned int mpi_rank, mpi_size;
171+
};
172+
173+
struct BinPacking : Strategy
174+
{
175+
ChunkTable
176+
assign( PartialAssignment, RankMeta const & in, RankMeta const & out )
177+
override;
178+
};
179+
} // namespace chunk_assignment
180+
181+
namespace host_info
182+
{
183+
enum class Method
184+
{
185+
HOSTNAME
186+
};
187+
188+
std::string byMethod( Method );
189+
190+
std::string
191+
hostname();
192+
} // namespace host_info
76193
} // namespace openPMD

include/openPMD/auxiliary/MPI.hpp

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

0 commit comments

Comments
 (0)