Skip to content

Commit ca73852

Browse files
committed
Backend implementation
1) Make backends aware of Append mode 2) In ADIOS1, fix use of namespaces, only use #include statements outside of namespaces
1 parent 15d3074 commit ca73852

6 files changed

Lines changed: 106 additions & 35 deletions

File tree

src/IO/ADIOS/ADIOS1IOHandler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,17 @@ ADIOS1IOHandlerImpl::initialize_group(std::string const &name)
319319
return group;
320320
}
321321

322+
} // namespace openPMD
323+
322324
#ifndef DOXYGEN_SHOULD_SKIP_THIS
323325
#define CommonADIOS1IOHandlerImpl ADIOS1IOHandlerImpl
324326
#include "CommonADIOS1IOHandler.cpp"
325327
#undef CommonADIOS1IOHandlerImpl
326328
#endif
327329

330+
namespace openPMD
331+
{
332+
328333
#else
329334
ADIOS1IOHandler::ADIOS1IOHandler(std::string path, Access at)
330335
: AbstractIOHandler(std::move(path), at)

src/IO/ADIOS/ADIOS2IOHandler.cpp

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "openPMD/IO/ADIOS/ADIOS2IOHandler.hpp"
2323

2424
#include "openPMD/Datatype.hpp"
25+
#include "openPMD/Error.hpp"
2526
#include "openPMD/IO/ADIOS/ADIOS2FilePosition.hpp"
2627
#include "openPMD/IO/ADIOS/ADIOS2IOHandler.hpp"
2728
#include "openPMD/auxiliary/Environment.hpp"
@@ -292,9 +293,6 @@ void ADIOS2IOHandlerImpl::createFile(
292293
m_iterationEncoding = parameters.encoding;
293294
associateWithFile( writable, shared_name );
294295
this->m_dirty.emplace( shared_name );
295-
getFileData( shared_name, IfFileNotOpen::OpenImplicitly ).m_mode =
296-
adios2::Mode::Write; // WORKAROUND
297-
// ADIOS2 does not yet implement ReadWrite Mode
298296

299297
writable->written = true;
300298
writable->abstractFilePosition =
@@ -1061,7 +1059,8 @@ void ADIOS2IOHandlerImpl::availableChunks(
10611059
adios2::Mode
10621060
ADIOS2IOHandlerImpl::adios2AccessMode( std::string const & fullPath )
10631061
{
1064-
switch ( m_handler->m_backendAccess )
1062+
( void )fullPath;
1063+
switch( m_handler->m_backendAccess )
10651064
{
10661065
case Access::CREATE:
10671066
return adios2::Mode::Write;
@@ -1071,21 +1070,16 @@ ADIOS2IOHandlerImpl::adios2AccessMode( std::string const & fullPath )
10711070
if( auxiliary::directory_exists( fullPath ) ||
10721071
auxiliary::file_exists( fullPath ) )
10731072
{
1074-
std::cerr << "ADIOS2 does currently not yet implement ReadWrite "
1075-
"(Append) mode. "
1076-
<< "Replacing with Read mode." << std::endl;
10771073
return adios2::Mode::Read;
10781074
}
10791075
else
10801076
{
1081-
std::cerr << "ADIOS2 does currently not yet implement ReadWrite "
1082-
"(Append) mode. "
1083-
<< "Replacing with Write mode." << std::endl;
10841077
return adios2::Mode::Write;
10851078
}
1086-
default:
1087-
return adios2::Mode::Undefined;
1079+
case Access::APPEND:
1080+
return adios2::Mode::Append;
10881081
}
1082+
throw std::runtime_error( "Unreachable!" );
10891083
}
10901084

10911085
auxiliary::TracingJSON ADIOS2IOHandlerImpl::nullvalue = nlohmann::json();
@@ -2304,6 +2298,7 @@ namespace detail
23042298
delayOpeningTheFirstStep = true;
23052299
break;
23062300
case adios2::Mode::Write:
2301+
case adios2::Mode::Append:
23072302
/*
23082303
* File engines, write mode:
23092304
* Default for old layout is no steps.
@@ -2463,6 +2458,7 @@ namespace detail
24632458
{
24642459
switch( m_mode )
24652460
{
2461+
case adios2::Mode::Append:
24662462
case adios2::Mode::Write: {
24672463
// usesSteps attribute only written upon ::advance()
24682464
// this makes sure that the attribute is only put in case
@@ -2695,19 +2691,17 @@ namespace detail
26952691
[]( BufferedActions & ba, adios2::Engine & eng ) {
26962692
switch( ba.m_mode )
26972693
{
2698-
case adios2::Mode::Write:
2699-
eng.PerformPuts();
2700-
break;
2701-
case adios2::Mode::Read:
2702-
eng.PerformGets();
2703-
break;
2704-
case adios2::Mode::Append:
2705-
// TODO order?
2706-
eng.PerformGets();
2707-
eng.PerformPuts();
2708-
break;
2709-
default:
2710-
break;
2694+
case adios2::Mode::Write:
2695+
case adios2::Mode::Append:
2696+
eng.PerformPuts();
2697+
break;
2698+
case adios2::Mode::Read:
2699+
eng.PerformGets();
2700+
break;
2701+
default:
2702+
throw std::runtime_error(
2703+
"[ADIOS2] Unexpected access mode." );
2704+
break;
27112705
}
27122706
},
27132707
writeAttributes,

src/IO/ADIOS/CommonADIOS1IOHandler.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@
1818
* and the GNU Lesser General Public License along with openPMD-api.
1919
* If not, see <http://www.gnu.org/licenses/>.
2020
*/
21+
#include "openPMD/auxiliary/Filesystem.hpp"
22+
#include "openPMD/Error.hpp"
23+
2124
#include <algorithm>
2225
#include <complex>
23-
#include <tuple>
2426
#include <string>
27+
#include <tuple>
2528

29+
namespace openPMD
30+
{
2631

2732
void
2833
CommonADIOS1IOHandlerImpl::close(int64_t fd)
@@ -393,6 +398,15 @@ CommonADIOS1IOHandlerImpl::createFile(Writable* writable,
393398
if( !auxiliary::ends_with(name, ".bp") )
394399
name += ".bp";
395400

401+
if( m_handler->m_backendAccess == Access::APPEND &&
402+
auxiliary::file_exists( name ) )
403+
{
404+
throw error::OperationUnsupportedInBackend(
405+
"ADIOS1",
406+
"Appending to existing file on disk (use Access::CREATE to "
407+
"overwrite)" );
408+
}
409+
396410
writable->written = true;
397411
writable->abstractFilePosition = std::make_shared< ADIOS1FilePosition >("/");
398412

@@ -1653,3 +1667,5 @@ CommonADIOS1IOHandlerImpl::listAttributes(Writable* writable,
16531667
*parameters.attributes = std::vector< std::string >(attributes.begin(), attributes.end());
16541668
}
16551669
}
1670+
1671+
} // namespace openPMD

src/IO/ADIOS/ParallelADIOS1IOHandler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,17 @@ ParallelADIOS1IOHandlerImpl::initialize_group(std::string const &name)
348348
return group;
349349
}
350350

351+
} // namespace openPMD
352+
351353
#ifndef DOXYGEN_SHOULD_SKIP_THIS
352354
#define CommonADIOS1IOHandlerImpl ParallelADIOS1IOHandlerImpl
353355
#include "CommonADIOS1IOHandler.cpp"
354356
#undef CommonADIOS1IOHandlerImpl
355357
#endif
356358

359+
namespace openPMD
360+
{
361+
357362
#else
358363
# if openPMD_HAVE_MPI
359364
ParallelADIOS1IOHandler::ParallelADIOS1IOHandler(std::string path,

src/IO/HDF5/HDF5IOHandler.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,42 @@ HDF5IOHandlerImpl::createFile(Writable* writable,
175175
std::string name = m_handler->directory + parameters.name;
176176
if( !auxiliary::ends_with(name, ".h5") )
177177
name += ".h5";
178-
unsigned flags;
179-
if( m_handler->m_backendAccess == Access::CREATE )
178+
unsigned flags{};
179+
switch( m_handler->m_backendAccess )
180+
{
181+
case Access::CREATE:
180182
flags = H5F_ACC_TRUNC;
181-
else
183+
break;
184+
case Access::APPEND:
185+
if( auxiliary::file_exists( name ) )
186+
{
187+
flags = H5F_ACC_RDWR;
188+
}
189+
else
190+
{
191+
flags = H5F_ACC_TRUNC;
192+
}
193+
break;
194+
case Access::READ_WRITE:
182195
flags = H5F_ACC_EXCL;
183-
hid_t id = H5Fcreate(name.c_str(),
184-
flags,
185-
H5P_DEFAULT,
186-
m_fileAccessProperty);
196+
break;
197+
case Access::READ_ONLY:
198+
// condition has been checked above
199+
throw std::runtime_error( "Control flow error" );
200+
}
201+
202+
hid_t id{};
203+
if( flags == H5F_ACC_RDWR )
204+
{
205+
id = H5Fopen( name.c_str(), flags, m_fileAccessProperty);
206+
}
207+
else
208+
{
209+
id = H5Fcreate(name.c_str(),
210+
flags,
211+
H5P_DEFAULT,
212+
m_fileAccessProperty);
213+
}
187214
VERIFY(id >= 0, "[HDF5] Internal error: Failed to create HDF5 file");
188215

189216
writable->written = true;
@@ -554,7 +581,14 @@ HDF5IOHandlerImpl::openFile(
554581
Access at = m_handler->m_backendAccess;
555582
if( at == Access::READ_ONLY )
556583
flags = H5F_ACC_RDONLY;
557-
else if( at == Access::READ_WRITE || at == Access::CREATE )
584+
/*
585+
* Within the HDF5 backend, APPEND and READ_WRITE mode are
586+
* equivalent, but the openPMD frontend exposes no reading
587+
* functionality in APPEND mode.
588+
*/
589+
else if(
590+
at == Access::READ_WRITE || at == Access::CREATE ||
591+
at == Access::APPEND )
558592
flags = H5F_ACC_RDWR;
559593
else
560594
throw std::runtime_error("[HDF5] Unknown file Access");

src/IO/JSON/JSONIOHandlerImpl.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ namespace openPMD
115115
file.invalidate( );
116116
}
117117

118-
std::string const dir( m_handler->directory );
118+
std::string const & dir( m_handler->directory );
119119
if( !auxiliary::directory_exists( dir ) )
120120
{
121121
auto success = auxiliary::create_directories( dir );
@@ -133,6 +133,15 @@ namespace openPMD
133133
this->m_jsonVals[shared_name] =
134134
std::make_shared< nlohmann::json >( );
135135

136+
// start off with already written contents if available
137+
// @todo Do the same in READ_WRITE mode in ::openFile()?
138+
auto const & fullName = fullPath(name);
139+
if( m_handler->m_backendAccess == Access::APPEND
140+
&& auxiliary::file_exists(fullName))
141+
{
142+
std::ifstream handle(fullName);
143+
handle >> *this->m_jsonVals[shared_name];
144+
}
136145

137146
writable->written = true;
138147
writable->abstractFilePosition =
@@ -1099,6 +1108,14 @@ namespace openPMD
10991108
{
11001109
case Access::CREATE:
11011110
case Access::READ_WRITE:
1111+
case Access::APPEND:
1112+
/*
1113+
* Always truncate when writing, we alway write entire JSON
1114+
* datasets, never partial ones.
1115+
* Within the JSON backend, APPEND and READ_WRITE mode are
1116+
* equivalent, but the openPMD frontend exposes no reading
1117+
* functionality in APPEND mode.
1118+
*/
11021119
fs->open(
11031120
path,
11041121
std::ios_base::out | std::ios_base::trunc

0 commit comments

Comments
 (0)