Skip to content

Commit 4df9ed3

Browse files
committed
Reading changes: Use snapshot attribute
This means that the snapshot attribute, if present, is used for accessing iterations inside `series.readIterations()`. Fallback to the old behavior (linear progression through iterations) if the attribute is not found. Variable-b. encoding: Allow several (equivalent) iterations per step This means that a single step can be marked by /data/snapshot to represent iterations 0,10,20,30 at the same time. The underlying data is the same, but the API will treat it as 4 times a different iteration with equivalent content. Use RW-mode in some places when re-parsing Skip repeated iterations that occur in Append mode Before the explicit iteration-step mapping, these were not seen by reading procedures at all. Now they are, so we skip the second instance. Better error message when calling readIterations() too late
1 parent 1e196d0 commit 4df9ed3

7 files changed

Lines changed: 323 additions & 72 deletions

File tree

include/openPMD/Iteration.hpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
#include "openPMD/backend/Attributable.hpp"
2929
#include "openPMD/backend/Container.hpp"
3030

31+
#include <cstdint>
32+
#include <deque>
3133
#include <optional>
34+
#include <tuple>
3235

3336
namespace openPMD
3437
{
@@ -282,14 +285,49 @@ class Iteration : public Attributable
282285
void readGorVBased(std::string const &groupPath, bool beginStep);
283286
void read_impl(std::string const &groupPath);
284287

288+
/**
289+
* Status after beginning an IO step. Currently includes:
290+
* * The advance status (OK, OVER, RANDOMACCESS)
291+
* * The opened iterations, in case the snapshot attribute is found
292+
*/
293+
struct BeginStepStatus
294+
{
295+
using AvailableIterations_t = std::optional<std::deque<uint64_t> >;
296+
297+
AdvanceStatus stepStatus{};
298+
/*
299+
* If the iteration attribute `snapshot` is present, the value of that
300+
* attribute. Otherwise empty.
301+
*/
302+
AvailableIterations_t iterationsInOpenedStep;
303+
304+
/*
305+
* Most of the time, the AdvanceStatus part of this struct is what we
306+
* need, so let's make it easy to access.
307+
*/
308+
inline operator AdvanceStatus() const
309+
{
310+
return stepStatus;
311+
}
312+
313+
/*
314+
* Support for std::tie()
315+
*/
316+
inline operator std::tuple<AdvanceStatus &, AvailableIterations_t &>()
317+
{
318+
return std::tuple<AdvanceStatus &, AvailableIterations_t &>{
319+
stepStatus, iterationsInOpenedStep};
320+
}
321+
};
322+
285323
/**
286324
* @brief Begin an IO step on the IO file (or file-like object)
287325
* containing this iteration. In case of group-based iteration
288326
* layout, this will be the complete Series.
289327
*
290-
* @return AdvanceStatus
328+
* @return BeginStepStatus
291329
*/
292-
AdvanceStatus beginStep(bool reread);
330+
BeginStepStatus beginStep(bool reread);
293331

294332
/**
295333
* @brief End an IO step on the IO file (or file-like object)

include/openPMD/ReadIterations.hpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "openPMD/Iteration.hpp"
2424
#include "openPMD/Series.hpp"
2525

26+
#include <deque>
27+
#include <iostream>
2628
#include <optional>
2729

2830
namespace openPMD
@@ -54,7 +56,8 @@ class SeriesIterator
5456
using maybe_series_t = std::optional<Series>;
5557

5658
maybe_series_t m_series;
57-
iteration_index_t m_currentIteration = 0;
59+
std::deque<iteration_index_t> m_iterationsInCurrentStep;
60+
uint64_t m_currentIteration{};
5861

5962
public:
6063
//! construct the end() iterator
@@ -71,6 +74,21 @@ class SeriesIterator
7174
bool operator!=(SeriesIterator const &other) const;
7275

7376
static SeriesIterator end();
77+
78+
private:
79+
inline bool setCurrentIteration()
80+
{
81+
if (m_iterationsInCurrentStep.empty())
82+
{
83+
std::cerr << "[ReadIterations] Encountered a step without "
84+
"iterations. Closing the Series."
85+
<< std::endl;
86+
*this = end();
87+
return false;
88+
}
89+
m_currentIteration = *m_iterationsInCurrentStep.begin();
90+
return true;
91+
}
7492
};
7593

7694
/**

include/openPMD/Series.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <mpi.h>
3838
#endif
3939

40+
#include <deque>
4041
#include <map>
4142
#include <optional>
4243
#include <set>
@@ -585,8 +586,10 @@ OPENPMD_private
585586
* Note on re-parsing of a Series:
586587
* If init == false, the parsing process will seek for new
587588
* Iterations/Records/Record Components etc.
589+
* If series.iterations contains the attribute `snapshot`, returns its
590+
* value.
588591
*/
589-
void readGorVBased(bool init = true);
592+
std::optional<std::deque<uint64_t> > readGorVBased(bool init = true);
590593
void readBase();
591594
std::string iterationFilename(uint64_t i);
592595

src/Iteration.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,9 @@ void Iteration::read_impl(std::string const &groupPath)
566566
readAttributes(ReadMode::FullyReread);
567567
}
568568

569-
AdvanceStatus Iteration::beginStep(bool reread)
569+
auto Iteration::beginStep(bool reread) -> BeginStepStatus
570570
{
571+
BeginStepStatus res;
571572
using IE = IterationEncoding;
572573
auto series = retrieveSeries();
573574
// Initialize file with this to quiet warnings
@@ -583,11 +584,17 @@ AdvanceStatus Iteration::beginStep(bool reread)
583584
file = &series.get();
584585
break;
585586
}
587+
586588
AdvanceStatus status = series.advance(
587589
AdvanceMode::BEGINSTEP, *file, series.indexOf(*this), *this);
588-
if (status != AdvanceStatus::OK)
590+
switch (status)
589591
{
590-
return status;
592+
case AdvanceStatus::OVER:
593+
res.stepStatus = status;
594+
return res;
595+
case AdvanceStatus::OK:
596+
case AdvanceStatus::RANDOMACCESS:
597+
break;
591598
}
592599

593600
// re-read -> new datasets might be available
@@ -606,6 +613,7 @@ AdvanceStatus Iteration::beginStep(bool reread)
606613
auto oldType = this->IOHandler()->m_frontendAccess;
607614
auto newType =
608615
const_cast<Access *>(&this->IOHandler()->m_frontendAccess);
616+
res.iterationsInOpenedStep = series.readGorVBased(false);
609617
*newType = Access::READ_WRITE;
610618
series.readGorVBased(false);
611619
*newType = oldType;
@@ -619,7 +627,8 @@ AdvanceStatus Iteration::beginStep(bool reread)
619627
}
620628
}
621629

622-
return status;
630+
res.stepStatus = status;
631+
return res;
623632
}
624633

625634
void Iteration::endStep()
@@ -641,6 +650,7 @@ void Iteration::endStep()
641650
}
642651
// @todo filebased check
643652
series.advance(AdvanceMode::ENDSTEP, *file, series.indexOf(*this), *this);
653+
series.get().m_currentlyActiveIterations.clear();
644654
}
645655

646656
StepStatus Iteration::getStepStatus()

0 commit comments

Comments
 (0)