2424#include " openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp"
2525#include " openPMD/IO/ADIOS/ADIOS2FilePosition.hpp"
2626#include " openPMD/IO/ADIOS/ADIOS2PreloadAttributes.hpp"
27+ #include " openPMD/IO/ADIOS/ADIOS2PreloadVariables.hpp"
2728#include " openPMD/IO/ADIOS/macros.hpp"
2829#include " openPMD/IO/AbstractIOHandler.hpp"
2930#include " openPMD/IO/AbstractIOHandlerImpl.hpp"
@@ -426,6 +427,74 @@ class ADIOS2IOHandlerImpl
426427
427428 void dropFileData (InvalidatableFile const &file);
428429
430+ template <typename T>
431+ static void setStepSelectionForVariable (
432+ adios2::Variable<T> var,
433+ std::string const &varName,
434+ size_t step_selection,
435+ size_t file_steps,
436+ detail::AdiosVariables const &av)
437+ {
438+ auto var_steps = var.Steps ();
439+ if (var_steps == 1 && step_selection == 0 )
440+ {
441+ // variable has no steps
442+ return ;
443+ }
444+ if (file_steps != var_steps)
445+ {
446+ if (!av.m_preparsed .has_value ())
447+ {
448+ throw error::ReadError (
449+ error::AffectedObject::Dataset,
450+ error::Reason::UnexpectedContent,
451+ " ADIOS2" ,
452+ " The opened file contains different data per step, but "
453+ " variable data was not preparsed. ERROR: Variable " +
454+ varName + " ' has " + std::to_string (var_steps) +
455+ " step(s), but the file has " +
456+ std::to_string (file_steps) + " step(s)." );
457+ }
458+ auto preparsed = av.m_preparsed ->m_partialVariables .find (varName);
459+ if (preparsed == av.m_preparsed ->m_partialVariables .end ())
460+ {
461+ throw error::ReadError (
462+ error::AffectedObject::Dataset,
463+ error::Reason::UnexpectedContent,
464+ " ADIOS2" ,
465+ " The opened file contains different data per step, but "
466+ " variable data contains no preparsing info on '" +
467+ varName + " '. Has " + std::to_string (var_steps) +
468+ " step(s), but the file has " +
469+ std::to_string (file_steps) + " step(s)." );
470+ }
471+ auto step_index = std::find (
472+ preparsed->second .begin (),
473+ preparsed->second .end (),
474+ step_selection);
475+ if (step_index == preparsed->second .end ())
476+ {
477+ throw error::ReadError (
478+ error::AffectedObject::Dataset,
479+ error::Reason::UnexpectedContent,
480+ " ADIOS2" ,
481+ " Tried selecting global step " +
482+ std::to_string (step_selection) + " for variable '" +
483+ varName +
484+ " ', but variable is not defined for that step (only "
485+ " for steps " +
486+ auxiliary::vec_as_string (preparsed->second ) +
487+ " ). Has " + std::to_string (var_steps) +
488+ " step(s), but the file has " +
489+ std::to_string (file_steps) + " step(s)." );
490+ }
491+ // We need to replace the (global) step selection with the
492+ // (local) step index
493+ step_selection = step_index - preparsed->second .begin ();
494+ }
495+ var.SetStepSelection ({step_selection, 1 });
496+ }
497+
429498 /*
430499 * Prepare a variable that already exists for an IO
431500 * operation, including:
@@ -439,8 +508,10 @@ class ADIOS2IOHandlerImpl
439508 Offset const &offset,
440509 Extent const &extent,
441510 adios2::IO &IO,
511+ adios2::Engine &engine,
442512 std::string const &varName,
443- std::optional<size_t > stepSelection)
513+ std::optional<size_t > stepSelection,
514+ detail::AdiosVariables const &av)
444515 {
445516 {
446517 auto requiredType = adios2::GetType<T>();
@@ -469,7 +540,9 @@ class ADIOS2IOHandlerImpl
469540 }
470541 if (stepSelection.has_value ())
471542 {
472- var.SetStepSelection ({*stepSelection, 1 });
543+ auto file_steps = engine.Steps ();
544+ setStepSelectionForVariable (
545+ var, varName, *stepSelection, file_steps, av);
473546 }
474547 // TODO leave this check to ADIOS?
475548 adios2::Dims shape = var.Shape ();
@@ -615,7 +688,8 @@ namespace detail
615688 Parameter<Operation::OPEN_DATASET> ¶meters,
616689 std::optional<size_t > stepSelection,
617690 std::vector<ADIOS2IOHandlerImpl::ParameterizedOperator> const
618- &operators);
691+ &operators,
692+ detail::AdiosVariables const &);
619693
620694 static constexpr char const *errorMsg = " ADIOS2: openDataset()" ;
621695 };
0 commit comments