From 447ef866f3dab2455084ec7b60cc61fe01476079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 29 Oct 2024 10:45:56 +0100 Subject: [PATCH] Better document reopening options --- include/openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp | 2 +- include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp | 5 ++-- include/openPMD/IO/IOTask.hpp | 16 ++++++++++-- include/openPMD/Series.hpp | 3 +++ src/IO/ADIOS/ADIOS2IOHandler.cpp | 26 ++++++++++++++------ src/Series.cpp | 16 ++++++++++-- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/include/openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp b/include/openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp index 1b350feee1..e741b029df 100644 --- a/include/openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp +++ b/include/openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp @@ -79,7 +79,7 @@ namespace adios_defs { Create, Open, - Reopen + ReopenFileThatWeCreated }; } // namespace adios_defs diff --git a/include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp b/include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp index c4e840a8b8..fa300da472 100644 --- a/include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp +++ b/include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp @@ -406,10 +406,11 @@ class ADIOS2IOHandlerImpl enum class IfFileNotOpen : char { - ReopenImplicitly, OpenImplicitly, CreateImplicitly, - ThrowError + ThrowError, + ReopenFileThatWeCreated, + ReopenFileFoundOnDisk = OpenImplicitly, }; detail::ADIOS2File & diff --git a/include/openPMD/IO/IOTask.hpp b/include/openPMD/IO/IOTask.hpp index cc3277e15b..5589db6923 100644 --- a/include/openPMD/IO/IOTask.hpp +++ b/include/openPMD/IO/IOTask.hpp @@ -187,9 +187,21 @@ struct OPENPMDAPI_EXPORT Parameter new Parameter(std::move(*this))); } + // Needed for reopening files in file-based Iteration encoding when using + // R/W-mode in ADIOS2. Files can only be opened for reading XOR writing, + // so R/W mode in file-based encoding can only operate at the granularity + // of files in ADIOS2. The frontend needs to tell us if we should reopen + // a file for continued reading (WasFoundOnDisk) or for continued writing + // (WasCreatedByUs). + enum class Reopen + { + WasCreatedByUs, + WasFoundOnDisk, + NoReopen + }; + std::string name = ""; - // true <-> file was previously created and is now opened again - bool reopen = false; + Reopen reopen = Reopen::NoReopen; using ParsePreference = internal::ParsePreference; std::shared_ptr out_parsePreference = std::make_shared(ParsePreference::UpFront); diff --git a/include/openPMD/Series.hpp b/include/openPMD/Series.hpp index d7b859b8ec..176b8cbe4f 100644 --- a/include/openPMD/Series.hpp +++ b/include/openPMD/Series.hpp @@ -130,6 +130,9 @@ namespace internal * READ_WRITE mode when re-opening a closed file in file-based encoding: * A file that existed previously is re-opened in Read mode and will * not support updating its contents. + * (Note that this is NOT a restriction of re-opening, this is + * fundamentally a restriction of R/W in ADIOS2. Files can be + * written XOR read.) * A file that we created anew is re-opened in Append mode to continue * writing data to it. Using `adios2.engine.parameters.FlattenSteps = * "ON"` is recommended in this case. diff --git a/src/IO/ADIOS/ADIOS2IOHandler.cpp b/src/IO/ADIOS/ADIOS2IOHandler.cpp index 5abb9bb5da..4297cbe97a 100644 --- a/src/IO/ADIOS/ADIOS2IOHandler.cpp +++ b/src/IO/ADIOS/ADIOS2IOHandler.cpp @@ -931,12 +931,22 @@ void ADIOS2IOHandlerImpl::openFile( writable->written = true; writable->abstractFilePosition = std::make_shared(); + auto how_to_open = [&]() { + switch (parameters.reopen) + { + case Parameter::Reopen::WasCreatedByUs: + return IfFileNotOpen::ReopenFileThatWeCreated; + case Parameter::Reopen::WasFoundOnDisk: + return IfFileNotOpen::ReopenFileFoundOnDisk; + case Parameter::Reopen::NoReopen: + return IfFileNotOpen::OpenImplicitly; + } + return IfFileNotOpen::ThrowError; // Unreachable + }(); + // enforce opening the file // lazy opening is deathly in parallel situations - auto &fileData = getFileData( - file, - parameters.reopen ? IfFileNotOpen::ReopenImplicitly - : IfFileNotOpen::OpenImplicitly); + auto &fileData = getFileData(file, how_to_open); *parameters.out_parsePreference = fileData.parsePreference; m_dirty.emplace(std::move(file)); } @@ -1567,7 +1577,7 @@ adios2::Mode ADIOS2IOHandlerImpl::adios2AccessMode( case adios_defs::OpenFileAs::Create: return adios2::Mode::Write; case adios_defs::OpenFileAs::Open: - case adios_defs::OpenFileAs::Reopen: + case adios_defs::OpenFileAs::ReopenFileThatWeCreated: return adios2::Mode::Append; } break; @@ -1609,7 +1619,7 @@ adios2::Mode ADIOS2IOHandlerImpl::adios2AccessMode( #else return adios2::Mode::Read; #endif - case adios_defs::OpenFileAs::Reopen: + case adios_defs::OpenFileAs::ReopenFileThatWeCreated: /* In order to write new data to an Iteration that was * created and closed previously, the only applicable access * mode is Append mode, ideally in conjunction with @@ -1726,8 +1736,8 @@ detail::ADIOS2File &ADIOS2IOHandlerImpl::getFileData( using OF = adios_defs::OpenFileAs; switch (flag) { - case IfFileNotOpen::ReopenImplicitly: - return OF::Reopen; + case IfFileNotOpen::ReopenFileThatWeCreated: + return OF::ReopenFileThatWeCreated; case IfFileNotOpen::OpenImplicitly: return OF::Open; case IfFileNotOpen::CreateImplicitly: diff --git a/src/Series.cpp b/src/Series.cpp index 9bccfde466..4f34da302f 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -2741,14 +2741,26 @@ void Series::openIteration(IterationIndex_t index, Iteration &iteration) // open the iteration's file again Parameter fOpen; fOpen.name = iterationFilename(index); - fOpen.reopen = oldStatus == CL::Closed && + using R = Parameter::Reopen; + if (oldStatus != CL::Closed) + { + fOpen.reopen = R::NoReopen; + } + else if ( // The filename only gets emplaced in there if we found it on the // file system, otherwise it's generated by iterationFilename(). // This helps us distinguish which iterations were created by us and // which ones existed already. This is important for ADIOS2 which // can open an iteration for Appending XOR for reading. series.m_iterationFilenames.find(index) == - series.m_iterationFilenames.end(); + series.m_iterationFilenames.end()) + { + fOpen.reopen = R::WasCreatedByUs; + } + else + { + fOpen.reopen = R::WasFoundOnDisk; + } IOHandler()->enqueue(IOTask(this, fOpen)); /* open base path */