Skip to content

Commit db7f2db

Browse files
committed
Allow setting and retrieving meta info on Series
1 parent 4f925f2 commit db7f2db

5 files changed

Lines changed: 151 additions & 0 deletions

File tree

include/openPMD/Series.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,33 @@ class Series : public Attributable
116116
*/
117117
Series& setMeshesPath(std::string const& meshesPath);
118118

119+
/**
120+
* @throw no_such_attribute_error If optional attribute is not present.
121+
* @return Vector with a String per (writing) MPI rank, indicating user-
122+
* defined meta information per rank. Example: host name.
123+
*/
124+
chunk_assignment::RankMeta
125+
mpiRanksMetaInfo() const;
126+
127+
/**
128+
* @brief Set the Mpi Ranks Meta Info attribute, i.e. a Vector with
129+
* a String per (writing) MPI rank, indicating user-
130+
* defined meta information per rank. Example: host name.
131+
*
132+
* @return Reference to modified series.
133+
*/
134+
Series & setMpiRanksMetaInfo( chunk_assignment::RankMeta );
135+
136+
/**
137+
* @brief Set the Mpi Ranks Meta Info attribute, i.e. a Vector with
138+
* a String per (writing) MPI rank, indicating user-
139+
* defined meta information per rank. Example: host name.
140+
*
141+
* @return Reference to modified series.
142+
*/
143+
Series &
144+
setMpiRanksMetaInfo( std::string const & myRankInfo );
145+
119146
/**
120147
* @throw no_such_attribute_error If optional attribute is not present.
121148
* @return String representing the path to particle species, relative(!) to <CODE>basePath</CODE>.
@@ -282,5 +309,8 @@ class Series : public Attributable
282309
std::shared_ptr< std::string > m_filenamePrefix;
283310
std::shared_ptr< std::string > m_filenamePostfix;
284311
std::shared_ptr< int > m_filenamePadding;
312+
#if openPMD_HAVE_MPI
313+
MPI_Comm m_communicator;
314+
#endif
285315
}; // Series
286316
} // namespace openPMD

include/openPMD/auxiliary/Filesystem.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,19 @@ remove_directory(std::string const& path);
8787
*/
8888
bool
8989
remove_file(std::string const& path);
90+
struct no_such_file_error
91+
{
92+
};
93+
94+
/**
95+
* @brief Read a file line by line.
96+
*
97+
* @param path Path to the file.
98+
* @return Lines of the read file, excluding newline characters.
99+
*
100+
* @throws no_such_file_error
101+
*/
102+
std::vector< std::string >
103+
read_file_by_lines( std::string const & path );
90104
} // auxiliary
91105
} // openPMD

include/openPMD/auxiliary/MPI.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include "openPMD/config.hpp"
4+
35
#if openPMD_HAVE_MPI
46

57
# include <mpi.h>

src/Series.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
#include "openPMD/auxiliary/Date.hpp"
2222
#include "openPMD/auxiliary/Filesystem.hpp"
23+
#include "openPMD/auxiliary/MPI.hpp"
2324
#include "openPMD/auxiliary/StringManip.hpp"
2425
#include "openPMD/IO/AbstractIOHandler.hpp"
2526
#include "openPMD/IO/AbstractIOHandlerHelper.hpp"
@@ -92,6 +93,7 @@ Series::Series(
9293
std::string const & options )
9394
: iterations{ Container< Iteration, uint64_t >() }
9495
, m_iterationEncoding{ std::make_shared< IterationEncoding >() }
96+
, m_communicator{ comm }
9597
{
9698
auto input = parseInput( filepath );
9799
auto handler =
@@ -193,6 +195,90 @@ Series::setMeshesPath(std::string const& mp)
193195
return *this;
194196
}
195197

198+
chunk_assignment::RankMeta
199+
Series::mpiRanksMetaInfo() const
200+
{
201+
std::vector< std::string > asContiguousVector;
202+
try
203+
{
204+
asContiguousVector =
205+
getAttribute( "rankMetaInfo" ).get< std::vector< std::string > >();
206+
}
207+
catch( std::runtime_error const & )
208+
{
209+
// workaround: if vector has length 1, some backends may report a
210+
// single value instead of a vector
211+
asContiguousVector = {
212+
getAttribute( "rankMetaInfo" ).get< std::string >()
213+
};
214+
}
215+
chunk_assignment::RankMeta res;
216+
for( size_t i = 0; i < asContiguousVector.size(); ++i )
217+
{
218+
res[ i ] = std::move( asContiguousVector[ i ] );
219+
}
220+
return res;
221+
}
222+
223+
Series &
224+
Series::setMpiRanksMetaInfo( chunk_assignment::RankMeta rankMeta )
225+
{
226+
std::vector< std::string > asContiguousVector;
227+
asContiguousVector.reserve( rankMeta.size() );
228+
try
229+
{
230+
for( size_t i = 0; i < rankMeta.size(); ++i )
231+
{
232+
asContiguousVector.emplace_back( std::move( rankMeta.at( i ) ) );
233+
}
234+
}
235+
catch( std::out_of_range )
236+
{
237+
throw std::runtime_error( "[setMpiRanksMetaInfo] Can only set meta "
238+
"info for contiguous ranks 0 to n." );
239+
}
240+
241+
setAttribute( "rankMetaInfo", std::move( asContiguousVector ) );
242+
return *this;
243+
}
244+
245+
Series &
246+
Series::setMpiRanksMetaInfo( std::string const & myRankInfo )
247+
{
248+
if( auxiliary::starts_with( myRankInfo, '@' ) )
249+
{
250+
// read from file
251+
std::string fileName = auxiliary::replace_first( myRankInfo, "@", "" );
252+
std::vector< std::string > rankMeta;
253+
try
254+
{
255+
rankMeta = auxiliary::read_file_by_lines( fileName );
256+
}
257+
catch( auxiliary::no_such_file_error const & )
258+
{
259+
std::cerr << "Not setting rank meta information, because file has "
260+
"not been found: "
261+
<< fileName << std::endl;
262+
return *this;
263+
}
264+
setAttribute( "rankMetaInfo", rankMeta );
265+
return *this;
266+
}
267+
#if openPMD_HAVE_MPI
268+
int rank;
269+
MPI_Comm_rank( m_communicator, &rank );
270+
std::vector< std::string > rankMeta =
271+
auxiliary::collectStringsTo( m_communicator, 0, myRankInfo );
272+
if( rank == 0 )
273+
{
274+
setAttribute( "rankMetaInfo", std::move( rankMeta ) );
275+
}
276+
return *this;
277+
#else
278+
setAttribute( "rankMetaInfo", std::vector< std::string >{ myRankInfo } );
279+
#endif
280+
}
281+
196282
std::string
197283
Series::particlesPath() const
198284
{

src/auxiliary/Filesystem.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
#include <stdexcept>
3434
#include <system_error>
35+
#include <fstream>
36+
#include <sstream>
3537

3638

3739
namespace openPMD
@@ -168,5 +170,22 @@ remove_file( std::string const& path )
168170
#endif
169171
}
170172

173+
std::vector< std::string >
174+
read_file_by_lines( std::string const & path )
175+
{
176+
std::vector< std::string > res;
177+
std::ifstream file( path, std::ios_base::in );
178+
if ( file.fail( ) )
179+
{
180+
throw no_such_file_error( );
181+
}
182+
std::string line;
183+
while( std::getline( file, line ) )
184+
{
185+
res.push_back( std::move( line ) );
186+
line = std::string( );
187+
}
188+
return res;
189+
}
171190
} // auxiliary
172191
} // openPMD

0 commit comments

Comments
 (0)