Skip to content

Commit b821361

Browse files
committed
Write rank table as parallel dataset
1 parent 8aaf030 commit b821361

4 files changed

Lines changed: 82 additions & 19 deletions

File tree

include/openPMD/Series.hpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ class SeriesData : public AttributableData
108108
*/
109109
MPI_Comm m_communicator;
110110
#endif
111+
internal::AttributableInternal m_rankTable;
112+
Parameter< Operation::CREATE_DATASET > m_createRankTable;
113+
std::vector< Parameter< Operation::WRITE_DATASET > > m_chunks;
111114
}; // SeriesData
112115

113116
class SeriesInternal;
@@ -188,15 +191,6 @@ class SeriesInterface : public AttributableInterface
188191
chunk_assignment::RankMeta
189192
mpiRanksMetaInfo() const;
190193

191-
/**
192-
* @brief Set the Mpi Ranks Meta Info attribute, i.e. a Vector with
193-
* a String per (writing) MPI rank, indicating user-
194-
* defined meta information per rank. Example: host name.
195-
*
196-
* @return Reference to modified series.
197-
*/
198-
SeriesInterface & setMpiRanksMetaInfo( chunk_assignment::RankMeta );
199-
200194
/**
201195
* @brief Set the Mpi Ranks Meta Info attribute, i.e. a Vector with
202196
* a String per (writing) MPI rank, indicating user-
@@ -414,7 +408,8 @@ class SeriesInterface : public AttributableInterface
414408
void flushGorVBased( iterations_iterator begin, iterations_iterator end );
415409
void flushMeshesPath();
416410
void flushParticlesPath();
417-
void readFileBased( );
411+
void flushRankTable();
412+
void readFileBased();
418413
void readOneIterationFileBased( std::string const & filePath );
419414
/**
420415
* Note on re-parsing of a Series:

include/openPMD/backend/Attributable.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class AttributableInterface
130130
friend class Iteration;
131131
friend class Series;
132132
friend class SeriesInterface;
133+
friend class internal::SeriesInternal;
133134
friend class Writable;
134135
friend class WriteIterations;
135136

@@ -394,6 +395,20 @@ class AttributableInterface
394395
virtual void linkHierarchy(Writable& w);
395396
}; // AttributableInterface
396397

398+
namespace internal
399+
{
400+
class AttributableInternal :
401+
public AttributableData,
402+
public AttributableInterface
403+
{
404+
public:
405+
AttributableInternal() : AttributableInterface{ this }
406+
{
407+
}
408+
virtual ~AttributableInternal() = default;
409+
};
410+
}
411+
397412
// Alias this as Attributable since this is a public abstract parent class
398413
// for most of the classes in our object model of the openPMD hierarchy
399414
using Attributable = AttributableInterface;

src/Iteration.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ Iteration::flushFileBased(std::string const& filename, uint64_t i)
212212
fCreate.name = filename;
213213
IOHandler()->enqueue(IOTask(s, fCreate));
214214

215+
s->flushRankTable();
216+
215217
/* create basePath */
216218
Parameter< Operation::CREATE_PATH > pCreate;
217219
pCreate.path = auxiliary::replace_first(s->basePath(), "%T/", "");

src/Series.cpp

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "openPMD/Series.hpp"
3232
#include "openPMD/version.hpp"
3333

34+
#include <algorithm>
3435
#include <exception>
3536
#include <iomanip>
3637
#include <iostream>
@@ -187,6 +188,7 @@ SeriesInterface::mpiRanksMetaInfo() const
187188
return res;
188189
}
189190

191+
#if 0
190192
SeriesInterface &
191193
SeriesInterface::setMpiRanksMetaInfo( chunk_assignment::RankMeta rankMeta )
192194
{
@@ -208,10 +210,12 @@ SeriesInterface::setMpiRanksMetaInfo( chunk_assignment::RankMeta rankMeta )
208210
setAttribute( "rankMetaInfo", std::move( asContiguousVector ) );
209211
return *this;
210212
}
213+
#endif
211214

212215
SeriesInterface &
213216
SeriesInterface::setMpiRanksMetaInfo( std::string const & myRankInfo )
214217
{
218+
#if 0
215219
if( auxiliary::starts_with( myRankInfo, '@' ) )
216220
{
217221
// read from file
@@ -231,22 +235,66 @@ SeriesInterface::setMpiRanksMetaInfo( std::string const & myRankInfo )
231235
setAttribute( "rankMetaInfo", rankMeta );
232236
return *this;
233237
}
234-
#if openPMD_HAVE_MPI
238+
#endif
235239
auto & series = get();
236-
int rank;
240+
unsigned long long mySize = myRankInfo.size() + 1; // null character
241+
#if openPMD_HAVE_MPI
242+
int rank, size;
237243
MPI_Comm_rank( series.m_communicator, &rank );
238-
std::vector< std::string > rankMeta =
239-
auxiliary::collectStringsTo( series.m_communicator, 0, myRankInfo );
240-
if( rank == 0 )
241-
{
242-
setAttribute( "rankMetaInfo", std::move( rankMeta ) );
243-
}
244+
MPI_Comm_size( series.m_communicator, &size );
245+
// todo char portability
246+
unsigned long long maxSize = 0;
247+
MPI_Allreduce(
248+
&mySize,
249+
&maxSize,
250+
1,
251+
MPI_UNSIGNED_LONG_LONG,
252+
MPI_MAX,
253+
series.m_communicator );
244254
#else
245-
setAttribute( "rankMetaInfo", std::vector< std::string >{ myRankInfo } );
255+
int rank{ 0 }, size{ 1 };
256+
unsigned long long maxSize = mySize;
246257
#endif
258+
259+
series.m_createRankTable.name = "hostTable";
260+
series.m_createRankTable.dtype = Datatype::CHAR;
261+
series.m_createRankTable.extent = { uint64_t( size ), uint64_t( maxSize ) };
262+
263+
std::shared_ptr< char > put{
264+
new char[ maxSize ]{}, []( char const * ptr ) { delete[] ptr; } };
265+
std::copy_n( myRankInfo.c_str(), mySize, put.get() );
266+
267+
Parameter< Operation::WRITE_DATASET > writeDataset;
268+
writeDataset.dtype = Datatype::CHAR;
269+
writeDataset.offset = { uint64_t( rank ), 0 };
270+
writeDataset.extent = { 1, maxSize };
271+
writeDataset.data = std::move( put );
272+
series.m_chunks.push_back( std::move( writeDataset ) );
273+
247274
return *this;
248275
}
249276

277+
void SeriesInterface::flushRankTable()
278+
{
279+
auto & series = get();
280+
if( series.m_chunks.empty() )
281+
{
282+
return;
283+
}
284+
285+
if( !series.m_rankTable.written() )
286+
{
287+
IOHandler()->enqueue(
288+
IOTask( &series.m_rankTable, series.m_createRankTable ) );
289+
}
290+
for( auto & writeDataset : series.m_chunks )
291+
{
292+
IOHandler()->enqueue(
293+
IOTask( &series.m_rankTable, std::move( writeDataset ) ) );
294+
}
295+
series.m_chunks.clear();
296+
}
297+
250298
std::string
251299
SeriesInterface::particlesPath() const
252300
{
@@ -797,6 +845,8 @@ SeriesInterface::flushGorVBased( iterations_iterator begin, iterations_iterator
797845
fCreate.name = series.m_name;
798846
fCreate.encoding = iterationEncoding();
799847
IOHandler()->enqueue(IOTask(this, fCreate));
848+
849+
flushRankTable();
800850
}
801851

802852
series.iterations.flush(
@@ -1564,6 +1614,7 @@ SeriesInternal::SeriesInternal(
15641614
auto handler = createIOHandler(
15651615
input->path, at, input->format, comm, std::move( optionsJson ) );
15661616
init( handler, std::move( input ) );
1617+
m_rankTable.linkHierarchy( writable() );
15671618
}
15681619
#endif
15691620

0 commit comments

Comments
 (0)