4040#include " openPMD/backend/Attributable.hpp"
4141#include " openPMD/backend/Attribute.hpp"
4242#include " openPMD/snapshots/ContainerImpls.hpp"
43- #include " openPMD/snapshots/IteratorTraits.hpp"
44- #include " openPMD/snapshots/RandomAccessIterator.hpp"
43+ #include " openPMD/snapshots/ContainerTraits.hpp"
4544#include " openPMD/snapshots/Snapshots.hpp"
4645#include " openPMD/snapshots/StatefulIterator.hpp"
4746#include " openPMD/version.hpp"
@@ -3186,135 +3185,92 @@ namespace
31863185 }
31873186} // namespace
31883187
3189- Snapshots
3190- Series::snapshots (std::optional<SnapshotWorkflow> const snapshot_workflow)
3188+ Snapshots Series::snapshots ()
31913189{
31923190 auto &series = get ();
31933191 if (series.m_deferred_initialization .has_value ())
31943192 {
31953193 runDeferredInitialization ();
31963194 }
31973195 auto access = IOHandler ()->m_frontendAccess ;
3198- auto guard_wrong_access_specification =
3199- [&](SnapshotWorkflow required_access) {
3200- if (!snapshot_workflow.has_value ())
3201- {
3202- return required_access;
3203- }
3204- if (required_access != *snapshot_workflow)
3205- {
3206- std::stringstream error;
3207- error << " [Series::snapshots()] Specified "
3208- << (*snapshot_workflow == SnapshotWorkflow::Synchronous
3209- ? " linear"
3210- : " random-access" )
3211- << " iteration in method parameter "
3212- " `snapshot_workflow`, but access type "
3213- << access << " requires "
3214- << (required_access == SnapshotWorkflow::Synchronous
3215- ? " linear"
3216- : " random-access" )
3217- << " iteration. Please remove the parameter, there is no "
3218- " need to specify it under "
3219- << access << " mode." << std::endl;
3220- throw error::WrongAPIUsage (error.str ());
3221- }
3222- else
3223- {
3224- std::cerr
3225- << " [Series::snapshots()] No need to explicitly specify "
3226- " synchronous or non-synchronous access via method "
3227- " parameter `snapshot_workflow` in mode '"
3228- << access << " . Will ignore." << std::endl;
3229- }
3230- return required_access;
3231- };
3232- SnapshotWorkflow usedSnapshotWorkflow{};
3196+ SnapshotWorkflow usedSnapshotWorkflow = access::random_access (access)
3197+ ? SnapshotWorkflow::RandomAccess
3198+ : SnapshotWorkflow::Synchronous;
3199+ if (access == Access::READ_RANDOM_ACCESS)
32333200 {
3234- switch (access)
3201+ // Some error checks
3202+ if (series.m_parsePreference .has_value ())
32353203 {
3236- case Access::READ_LINEAR:
3237- usedSnapshotWorkflow =
3238- guard_wrong_access_specification (SnapshotWorkflow::Synchronous);
3239- break ;
3240- case Access::READ_ONLY:
3241- usedSnapshotWorkflow = guard_wrong_access_specification (
3242- SnapshotWorkflow::RandomAccess);
3243-
3244- // Some error checks
3245- if (series.m_parsePreference .has_value ())
3204+ switch (series.m_parsePreference .value ())
32463205 {
3247- switch (series.m_parsePreference .value ())
3248- {
3249- case internal::ParsePreference::UpFront:
3250- break ;
3251- case internal::ParsePreference::PerStep:
3252- throw error::ReadError (
3253- error::AffectedObject::File,
3254- error::Reason::UnexpectedContent,
3255- std::nullopt ,
3256- " [Series::snapshots()] Series requires collective "
3257- " processing with READ_LINEAR access mode." );
3258- }
3259- }
3260- else if (iterationEncoding () != IterationEncoding::fileBased)
3261- {
3262- throw error::Internal (
3263- " READ_ONLY mode and non-fileBased iteration encoding, but "
3264- " the backend did not set a parse preference." );
3206+ case internal::ParsePreference::UpFront:
3207+ break ;
3208+ case internal::ParsePreference::PerStep:
3209+ throw error::ReadError (
3210+ error::AffectedObject::File,
3211+ error::Reason::UnexpectedContent,
3212+ std::nullopt ,
3213+ " [Series::snapshots()] Series requires collective "
3214+ " processing with READ_LINEAR access mode." );
32653215 }
3266- break ;
3267- case Access::READ_WRITE:
3268- // Our Read-Write workflows are entirely random-access based (so
3269- // far).
3270- // (Might be possible to allow stateful access actually, but there's
3271- // no real use, so keep it simple.)
3272- usedSnapshotWorkflow = guard_wrong_access_specification (
3273- SnapshotWorkflow::RandomAccess);
3274- break ;
3275-
3276- // TODO: Remove parameter
3277- case Access::CREATE_RANDOM_ACCESS:
3278- case Access::APPEND_RANDOM_ACCESS:
3279- // Users can select.
3280- usedSnapshotWorkflow = snapshot_workflow.value_or (
3281- /* random-access logic by default */
3282- SnapshotWorkflow::RandomAccess);
3283- break ;
3284- case Access::CREATE_LINEAR:
3285- case Access::APPEND_LINEAR:
3286- // Users can select.
3287- usedSnapshotWorkflow = snapshot_workflow.value_or (
3288- /* random-access logic by default */
3289- SnapshotWorkflow::Synchronous);
3290- break ;
3216+ }
3217+ else if (iterationEncoding () != IterationEncoding::fileBased)
3218+ {
3219+ throw error::Internal (
3220+ " READ_ONLY mode and non-fileBased iteration encoding, but "
3221+ " the backend did not set a parse preference." );
32913222 }
32923223 }
32933224
3225+ switch (usedSnapshotWorkflow)
3226+ {
3227+ case SnapshotWorkflow::RandomAccess: {
3228+ return makeRandomAccessSnapshots ();
3229+ }
3230+ case SnapshotWorkflow::Synchronous: {
3231+ return makeSynchronousSnapshots ();
3232+ }
3233+ }
3234+ throw std::runtime_error (" unreachable!" );
3235+ }
3236+
3237+ Snapshots Series::makeRandomAccessSnapshots ()
3238+ {
3239+ auto &series = get ();
3240+ return Snapshots (
3241+ std::shared_ptr<RandomAccessIteratorContainer>{
3242+ new RandomAccessIteratorContainer (series.iterations )},
3243+ series.iterations );
3244+ }
3245+ Snapshots Series::makeSynchronousSnapshots ()
3246+ {
3247+ auto &series = get ();
32943248 /*
3295- * ADIOS2 should use variable-based encoding as a default when applicable,
3296- * since group-based encoding has severe limitations in ADIOS2.
3297- * The below logic checks if variable-based encoding should be used.
3249+ * ADIOS2 should use variable-based encoding as a default when
3250+ * applicable, since group-based encoding has severe limitations
3251+ * in ADIOS2. The below logic checks if variable-based encoding
3252+ * should be used.
32983253 */
32993254
33003255 if (
33013256 // 1. No encoding has been explicitly selected by the user.
33023257 // Flag set by Series::setIterationEncoding().
33033258 series.m_iterationEncodingSetExplicitly ==
33043259 internal::default_or_explicit::default_ &&
3305- // 2. Iteration encoding was recognized as groupBased by init()
3260+ // 2. Iteration encoding was recognized as groupBased by
3261+ // init()
33063262 // procedures (and not file-based).
33073263 series.m_iterationEncoding == IterationEncoding::groupBased &&
3308- // 3. The IO workflow will be synchronous, necessary for writing
3309- // variable-based data (but not for reading!).
3310- usedSnapshotWorkflow == SnapshotWorkflow::Synchronous &&
3311- // 4. The chosen access type is write-only, otherwise the encoding is
3264+ // 3. The chosen access type is write-only, otherwise the
3265+ // encoding is
33123266 // determined by the previous file content.
3313- access::writeOnly (access) &&
3314- // 5. The backend is ADIOS2 in a recent enough version to support
3267+ access::writeOnly (IOHandler ()->m_frontendAccess ) &&
3268+ // 4. The backend is ADIOS2 in a recent enough version to
3269+ // support
33153270 // modifiable attributes (v2.9).
33163271 IOHandler ()->fullSupportForVariableBasedEncoding () &&
3317- // 6. The Series must not yet be written, otherwise we're too late
3272+ // 5. The Series must not yet be written, otherwise we're
3273+ // too late
33183274 // for this
33193275 !this ->written ())
33203276 {
@@ -3323,32 +3279,20 @@ Series::snapshots(std::optional<SnapshotWorkflow> const snapshot_workflow)
33233279 internal::default_or_explicit::default_);
33243280 }
33253281
3326- switch (usedSnapshotWorkflow)
3327- {
3328- case SnapshotWorkflow::RandomAccess: {
3329- return Snapshots (
3330- std::shared_ptr<RandomAccessIteratorContainer>{
3331- new RandomAccessIteratorContainer (series.iterations )},
3332- series.iterations );
3333- }
3334- case SnapshotWorkflow::Synchronous: {
3335- std::function<StatefulIterator *()> begin;
3282+ std::function<StatefulIterator *()> begin;
33363283
3337- if (access::write (IOHandler ()->m_frontendAccess ))
3338- {
3339- begin = make_writing_stateful_iterator (*this , series);
3340- }
3341- else
3342- {
3343- begin = make_reading_stateful_iterator (*this , series);
3344- }
3345- return Snapshots (
3346- std::shared_ptr<StatefulSnapshotsContainer>(
3347- new StatefulSnapshotsContainer (std::move (begin))),
3348- series.iterations );
3284+ if (access::write (IOHandler ()->m_frontendAccess ))
3285+ {
3286+ begin = make_writing_stateful_iterator (*this , series);
33493287 }
3288+ else
3289+ {
3290+ begin = make_reading_stateful_iterator (*this , series);
33503291 }
3351- throw std::runtime_error (" unreachable!" );
3292+ return Snapshots (
3293+ std::shared_ptr<StatefulSnapshotsContainer>(
3294+ new StatefulSnapshotsContainer (std::move (begin))),
3295+ series.iterations );
33523296}
33533297
33543298void Series::parseBase ()
@@ -3361,14 +3305,16 @@ WriteIterations Series::writeIterations()
33613305{
33623306 auto const access = IOHandler ()->m_frontendAccess ;
33633307 if (access != Access::CREATE_RANDOM_ACCESS &&
3364- access != Access::APPEND_RANDOM_ACCESS)
3308+ access != Access::APPEND_RANDOM_ACCESS &&
3309+ access != Access::CREATE_LINEAR &&
3310+ access != Access::CREATE_RANDOM_ACCESS)
33653311 {
33663312 throw error::WrongAPIUsage (
33673313 " [Series::writeIterations()] May only be applied for access modes "
33683314 " CREATE or APPEND. Use Series::snapshots() for random-access-type "
33693315 " or for read-type workflows." );
33703316 }
3371- return snapshots (SnapshotWorkflow::Synchronous );
3317+ return makeSynchronousSnapshots ( );
33723318}
33733319
33743320void Series::close ()
0 commit comments