Skip to content

Commit 8c7fc78

Browse files
committed
Testing (only printf testing for now)
1 parent b4fbfc1 commit 8c7fc78

2 files changed

Lines changed: 218 additions & 1 deletion

File tree

test/CoreTest.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# define OPENPMD_private public
44
# define OPENPMD_protected public
55
#endif
6+
7+
#include "openPMD/ChunkInfo.hpp"
68
#include "openPMD/openPMD.hpp"
79

810
#include <catch2/catch.hpp>
@@ -19,11 +21,78 @@
1921

2022
using namespace openPMD;
2123

24+
namespace test_chunk_assignment
25+
{
26+
using namespace openPMD::chunk_assignment;
27+
struct Params
28+
{
29+
ChunkTable table;
30+
RankMeta metaSource;
31+
RankMeta metaSink;
32+
33+
void
34+
init(
35+
size_t sourceRanks,
36+
size_t sinkRanks,
37+
size_t in_per_host,
38+
size_t out_per_host )
39+
{
40+
for( size_t rank = 0; rank < sourceRanks; ++rank )
41+
{
42+
table.emplace_back(
43+
Offset{ rank, rank }, Extent{ rank, rank }, rank );
44+
table.emplace_back(
45+
Offset{ rank, 100 * rank }, Extent{ rank, 100 * rank }, rank );
46+
metaSource.emplace( rank, std::to_string( rank / in_per_host ) );
47+
}
48+
for( size_t rank = 0; rank < sinkRanks; ++rank )
49+
{
50+
metaSink.emplace( rank, std::to_string( rank / out_per_host ) );
51+
}
52+
}
53+
};
54+
void print( RankMeta const & meta, ChunkTable const & table )
55+
{
56+
for( auto const & chunk : table )
57+
{
58+
std::cout << "[HOST: " << meta.at( chunk.sourceID )
59+
<< ",\tRank: " << chunk.sourceID << ",\tOffset: ";
60+
for( auto offset : chunk.offset )
61+
{
62+
std::cout << offset << ", ";
63+
}
64+
std::cout << "\tExtent: ";
65+
for( auto extent : chunk.extent )
66+
{
67+
std::cout << extent << ", ";
68+
}
69+
std::cout << "]" << std::endl;
70+
}
71+
}
72+
} // namespace test_chunk_assignment
73+
74+
TEST_CASE( "chunk_assignment", "[core]" )
75+
{
76+
using namespace chunk_assignment;
77+
test_chunk_assignment::Params params;
78+
params.init( 6, 2, 2, 1 );
79+
test_chunk_assignment::print( params.metaSource, params.table );
80+
ByHostname byHostname( make_unique< RoundRobin >() );
81+
FromPartialStrategy fullStrategy(
82+
make_unique< ByHostname >( std::move( byHostname ) ),
83+
make_unique< BinPacking >() );
84+
ChunkTable res = assignChunks(
85+
params.table, params.metaSource, params.metaSink, fullStrategy );
86+
std::cout << "\nRESULTS:" << std::endl;
87+
test_chunk_assignment::print( params.metaSink, res );
88+
}
89+
2290
TEST_CASE( "versions_test", "[core]" )
2391
{
2492
auto const apiVersion = getVersion( );
2593
REQUIRE(2u == std::count_if(apiVersion.begin(), apiVersion.end(), []( char const c ){ return c == '.';}));
2694

95+
2796
auto const standard = getStandard( );
2897
REQUIRE(standard == "1.1.0");
2998

test/ParallelIOTest.cpp

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "openPMD/auxiliary/Environment.hpp"
55
#include "openPMD/auxiliary/Filesystem.hpp"
66
#include "openPMD/openPMD.hpp"
7+
// @todo change includes
8+
#include "openPMD/benchmark/mpi/OneDimensionalBlockSlicer.hpp"
79
#include <catch2/catch.hpp>
810

911
#if openPMD_HAVE_MPI
@@ -1108,4 +1110,150 @@ TEST_CASE( "adios2_ssc", "[parallel][adios2]" )
11081110
{
11091111
adios2_ssc();
11101112
}
1111-
#endif
1113+
1114+
void adios2_chunk_distribution()
1115+
{
1116+
int mpi_size{ -1 };
1117+
int mpi_rank{ -1 };
1118+
MPI_Comm_size( MPI_COMM_WORLD, &mpi_size );
1119+
MPI_Comm_rank( MPI_COMM_WORLD, &mpi_rank );
1120+
1121+
chunk_assignment::RankMeta writingRanksHostnames, readingRanksHostnames;
1122+
for( int i = 0; i < mpi_size; ++i )
1123+
{
1124+
// 0, 0, 1, 1, 2, 2, 3, 3 ...
1125+
writingRanksHostnames[ i ] = "node" + std::to_string( i / 2 );
1126+
// 0, 0, 0, 0, 2, 2, 2, 2 ...
1127+
readingRanksHostnames[ i ] = "node" + std::to_string( i / 4 * 2 );
1128+
}
1129+
1130+
std::string filename = "../samples/adios2_chunk_distribution.bp";
1131+
// simulate a stream
1132+
std::stringstream parameters;
1133+
parameters << R"END(
1134+
{
1135+
"adios2":
1136+
{
1137+
"engine":
1138+
{
1139+
"type": "bp4",
1140+
"parameters":
1141+
{
1142+
"NumAggregators":)END"
1143+
<< "\"" << std::to_string( mpi_size ) << "\""
1144+
<< R"END(
1145+
}
1146+
}
1147+
}
1148+
}
1149+
)END";
1150+
1151+
auto printAssignment = [ mpi_rank ](
1152+
std::string const & strategyName,
1153+
ChunkTable const & table,
1154+
chunk_assignment::RankMeta const & meta )
1155+
{
1156+
if( mpi_rank != 0 )
1157+
{
1158+
return;
1159+
}
1160+
std::cout << "WITH STRATEGY '" << strategyName << "':\n";
1161+
for( auto const & chunk : table )
1162+
{
1163+
std::cout << "[HOST: " << meta.at( chunk.sourceID )
1164+
<< ",\tRank: " << chunk.sourceID << ",\tOffset: ";
1165+
for( auto offset : chunk.offset )
1166+
{
1167+
std::cout << offset << ", ";
1168+
}
1169+
std::cout << "\tExtent: ";
1170+
for( auto extent : chunk.extent )
1171+
{
1172+
std::cout << extent << ", ";
1173+
}
1174+
std::cout << "]" << std::endl;
1175+
}
1176+
};
1177+
1178+
{
1179+
Series series(
1180+
filename,
1181+
openPMD::Access::CREATE,
1182+
MPI_COMM_WORLD,
1183+
parameters.str() );
1184+
series.setMpiRanksMetaInfo( writingRanksHostnames.at( mpi_rank ) );
1185+
1186+
auto E_x = series.iterations[ 0 ].meshes[ "E" ][ "x" ];
1187+
openPMD::Dataset ds(
1188+
openPMD::Datatype::INT, { unsigned( mpi_size ), 10 } );
1189+
E_x.resetDataset( ds );
1190+
std::vector< int > data( 10, 0 );
1191+
std::iota( data.begin(), data.end(), 0 );
1192+
E_x.storeChunk( data, { unsigned( mpi_rank ), 0 }, { 1, 10 } );
1193+
series.flush();
1194+
}
1195+
1196+
{
1197+
Series series( filename, openPMD::Access::READ_ONLY, MPI_COMM_WORLD );
1198+
auto rankMetaIn = series.mpiRanksMetaInfo();
1199+
REQUIRE( rankMetaIn == writingRanksHostnames );
1200+
1201+
auto E_x = series.iterations[ 0 ].meshes[ "E" ][ "x" ];
1202+
auto const chunkTable = E_x.availableChunks();
1203+
1204+
printAssignment( "INPUT", chunkTable, rankMetaIn );
1205+
1206+
using namespace chunk_assignment;
1207+
1208+
RoundRobin roundRobinStrategy;
1209+
auto roundRobinAssignment = assignChunks(
1210+
chunkTable, rankMetaIn, readingRanksHostnames, roundRobinStrategy );
1211+
printAssignment(
1212+
"ROUND ROBIN", roundRobinAssignment, readingRanksHostnames );
1213+
1214+
ByHostname byHostname(
1215+
std::make_unique< BinPacking >( /* splitAlongDimension = */ 1 ) );
1216+
auto byHostnamePartialAssignment = assignChunks(
1217+
chunkTable, rankMetaIn, readingRanksHostnames, byHostname );
1218+
printAssignment(
1219+
"HOSTNAME, ASSIGNED",
1220+
byHostnamePartialAssignment.assigned,
1221+
readingRanksHostnames );
1222+
printAssignment(
1223+
"HOSTNAME, LEFTOVER",
1224+
byHostnamePartialAssignment.notAssigned,
1225+
rankMetaIn );
1226+
1227+
FromPartialStrategy fromPartialStrategy(
1228+
std::make_unique< ByHostname >( std::move( byHostname ) ),
1229+
std::make_unique< BinPacking >( /* splitAlongDimension = */ 1 ) );
1230+
auto fromPartialAssignment = assignChunks(
1231+
chunkTable,
1232+
rankMetaIn,
1233+
readingRanksHostnames,
1234+
fromPartialStrategy );
1235+
printAssignment(
1236+
"HOSTNAME WITH SECOND PASS",
1237+
fromPartialAssignment,
1238+
readingRanksHostnames );
1239+
1240+
ByCuboidSlice cuboidSliceStrategy(
1241+
std::make_unique< OneDimensionalBlockSlicer >( 1 ),
1242+
E_x.getExtent(),
1243+
mpi_rank,
1244+
mpi_size );
1245+
auto cuboidSliceAssignment = assignChunks(
1246+
chunkTable,
1247+
rankMetaIn,
1248+
readingRanksHostnames,
1249+
cuboidSliceStrategy );
1250+
printAssignment(
1251+
"CUBOID SLICE", cuboidSliceAssignment, readingRanksHostnames );
1252+
}
1253+
}
1254+
1255+
TEST_CASE( "adios2_chunk_distribution", "[parallel][adios2]" )
1256+
{
1257+
adios2_chunk_distribution();
1258+
}
1259+
#endif // openPMD_HAVE_ADIOS2 && openPMD_HAVE_MPI

0 commit comments

Comments
 (0)