Skip to content

Commit 82a1f7b

Browse files
Snapshots API: Fill missing bits, harmonize API (#1768)
* Basic untested binding for ::snapshots() * Add Python bindings for Snapshots deletion missing * Implement deletion * Implement emplace() could be added for stateful iterator too probably * Fix Python GIL evasion * Add new access types, no implementation yet * Add aliases * Harmonize write- and read-side API * Remove IteratorHelpers from CMake * Move iterator convertors back to helper file * CI fixes * Update examples * Documentation, cleanup * CI fixes * Replace .writeIteration() with CREATE_LINEAR + snapshots() * Same for readIterations * Replace writeIterations() with snapshots() in parallel tests * Same for readIterations() * Same for test subfiles * Explicitly open Iterations in READ_ONLY with deferred parsing
1 parent a985bd2 commit 82a1f7b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1141
-974
lines changed

examples/10_streaming_read.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ int main()
5757

5858
// The iteration can be closed in order to help free up resources.
5959
// The iteration's content will be flushed automatically.
60-
// An iteration once closed cannot (yet) be reopened.
6160
iteration.close();
6261

6362
for (size_t i = 0; i < 3; ++i)

examples/10_streaming_read.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,8 @@
2020
series = io.Series("simData.sst", io.Access_Type.read_linear, config)
2121

2222
# Read all available iterations and print electron position data.
23-
# Direct access to iterations is possible via `series.iterations`.
24-
# For streaming support, `series.read_iterations()` needs to be used
25-
# instead of `series.iterations`.
26-
# `Series.write_iterations()` and `Series.read_iterations()` are
27-
# intentionally restricted APIs that ensure a workflow which also works
28-
# in streaming setups, e.g. an iteration cannot be opened again once
29-
# it has been closed.
30-
for iteration in series.read_iterations():
31-
print("Current iteration {}".format(iteration.iteration_index))
23+
for index, iteration in series.snapshots().items():
24+
print("Current iteration {}".format(index))
3225
electronPositions = iteration.particles["e"]["position"]
3326
loadedChunks = []
3427
shapes = []

examples/10_streaming_write.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ int main()
2525
// use QueueFullPolicy = Discard in order to create a situation where from
2626
// the reader's perspective steps are skipped. This tests the bug reported
2727
// in https://github.com/openPMD/openPMD-api/issues/1747.
28-
Series series = Series("electrons.sst", Access::CREATE, R"(
28+
// Create the Series with linear write access, i.e. one Iteration after
29+
// the other. The alternative would be random-access where multiple
30+
// Iterations can be accessed independently from one another. This more
31+
// restricted mode enables performance optimizations in the backends, and
32+
// more importantly is compatible with streaming I/O.
33+
Series series = Series("electrons.sst", Access::CREATE_LINEAR, R"(
2934
{
3035
"adios2": {
3136
"engine": {
@@ -44,12 +49,7 @@ int main()
4449
std::shared_ptr<position_t> local_data(
4550
new position_t[length], [](position_t const *ptr) { delete[] ptr; });
4651

47-
// Create the Series with synchronous snapshots, i.e. one Iteration after
48-
// the other. The alternative would be random-access where multiple
49-
// Iterations can be accessed independently from one another. This more
50-
// restricted mode enables performance optimizations in the backends, and
51-
// more importantly is compatible with streaming I/O.
52-
auto iterations = series.snapshots(SnapshotWorkflow::Synchronous);
52+
auto iterations = series.snapshots();
5353
for (size_t i = 0; i < 100; ++i)
5454
{
5555
Iteration iteration = iterations[i];

examples/10_streaming_write.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,13 @@
2020

2121
# create a series and specify some global metadata
2222
# change the file extension to .json, .h5 or .bp for regular file writing
23-
series = io.Series("simData.sst", io.Access_Type.create, config)
23+
series = io.Series("simData.sst", io.Access_Type.create_linear, config)
2424
series.set_author("Franz Poeschel <f.poeschel@hzdr.de>")
2525
series.set_software("openPMD-api-python-examples")
2626

2727
# now, write a number of iterations (or: snapshots, time steps)
2828
for i in range(10):
29-
# Direct access to iterations is possible via `series.iterations`.
30-
# For streaming support, `series.write_iterations()` needs to be used
31-
# instead of `series.iterations`.
32-
# `Series.write_iterations()` and `Series.read_iterations()` are
33-
# intentionally restricted APIs that ensure a workflow which also works
34-
# in streaming setups, e.g. an iteration cannot be opened again once
35-
# it has been closed.
36-
iteration = series.write_iterations()[i]
29+
iteration = series.snapshots()[i]
3730

3831
#######################
3932
# write electron data #

examples/11_particle_dataframe.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
# This "if" is important for distributed dask runs
3737
if __name__ == "__main__":
3838
s = io.Series("../samples/git-sample/data%T.h5", io.Access.read_only)
39-
electrons = s.iterations[400].particles["electrons"]
39+
electrons = s.snapshots()[400].particles["electrons"]
4040

4141
# all particles
4242
df = electrons.to_df()
@@ -101,7 +101,7 @@
101101

102102
# Meshes
103103
if found_dask:
104-
E = s.iterations[400].meshes["E"]
104+
E = s.snapshots()[400].meshes["E"]
105105
E_x = E["x"]
106106
E_y = E["y"]
107107
E_z = E["z"]

examples/12_span_write.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void span_write(std::string const &filename)
1010
using namespace openPMD;
1111
using position_t = double;
1212
// open file for writing
13-
Series series = Series(filename, Access::CREATE);
13+
Series series = Series(filename, Access::CREATE_LINEAR);
1414

1515
Datatype datatype = determineDatatype<position_t>();
1616
constexpr unsigned long length = 10ul;
@@ -19,12 +19,7 @@ void span_write(std::string const &filename)
1919

2020
std::vector<position_t> fallbackBuffer;
2121

22-
// `Series::writeIterations()` and `Series::readIterations()` are
23-
// intentionally restricted APIs that ensure a workflow which also works
24-
// in streaming setups, e.g. an iteration cannot be opened again once
25-
// it has been closed.
26-
// `Series::iterations` can be directly accessed in random-access workflows.
27-
WriteIterations iterations = series.writeIterations();
22+
Snapshots iterations = series.snapshots();
2823
for (size_t i = 0; i < 10; ++i)
2924
{
3025
Iteration iteration = iterations[i];

examples/12_span_write.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,14 @@
33

44

55
def span_write(filename):
6-
series = io.Series(filename, io.Access_Type.create)
6+
series = io.Series(filename, io.Access_Type.create_linear)
77

88
datatype = np.dtype("double")
99
length = 10
1010
extent = [length]
1111
dataset = io.Dataset(datatype, extent)
1212

13-
# `Series.write_iterations()` and `Series.read_iterations()` are
14-
# intentionally restricted APIs that ensure a workflow which also works
15-
# in streaming setups, e.g. an iteration cannot be opened again once
16-
# it has been closed.
17-
# `Series.iterations` can be directly accessed in random-access workflows.
18-
iterations = series.write_iterations()
13+
iterations = series.snapshots()
1914
for i in range(12):
2015
iteration = iterations[i]
2116
electronPositions = iteration.particles["e"]["position"]

examples/13_write_dynamic_configuration.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ CFG.CHUNKS = [10]
157157

158158
// open file for writing
159159
Series series =
160-
Series("../samples/dynamicConfig.h5", Access::CREATE, defaults);
160+
Series("../samples/dynamicConfig.h5", Access::CREATE_LINEAR, defaults);
161161

162162
Datatype datatype = determineDatatype<position_t>();
163163
constexpr unsigned long length = 10ul;
@@ -166,12 +166,7 @@ CFG.CHUNKS = [10]
166166
std::shared_ptr<position_t> local_data(
167167
new position_t[length], [](position_t const *ptr) { delete[] ptr; });
168168

169-
// `Series::writeIterations()` and `Series::readIterations()` are
170-
// intentionally restricted APIs that ensure a workflow which also works
171-
// in streaming setups, e.g. an iteration cannot be opened again once
172-
// it has been closed.
173-
// `Series::iterations` can be directly accessed in random-access workflows.
174-
WriteIterations iterations = series.writeIterations();
169+
Snapshots iterations = series.snapshots();
175170
for (size_t i = 0; i < 100; ++i)
176171
{
177172
Iteration iteration = iterations[i];

examples/13_write_dynamic_configuration.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,16 @@ def main():
5656

5757
# create a series and specify some global metadata
5858
# change the file extension to .json, .h5 or .bp for regular file writing
59-
series = io.Series("../samples/dynamicConfig.bp", io.Access_Type.create,
60-
defaults)
59+
series = io.Series("../samples/dynamicConfig.bp",
60+
io.Access_Type.create_linear, defaults)
6161

6262
# now, write a number of iterations (or: snapshots, time steps)
6363
for i in range(10):
64-
# Direct access to iterations is possible via `series.iterations`.
65-
# For streaming support, `series.write_iterations()` needs to be used
66-
# instead of `series.iterations`.
67-
# `Series.write_iterations()` and `Series.read_iterations()` are
68-
# intentionally restricted APIs that ensure a workflow which also works
69-
# in streaming setups, e.g. an iteration cannot be opened again once
70-
# it has been closed.
71-
iteration = series.write_iterations()[i]
64+
# Direct access to iterations is possible via `series.snapshots()`.
65+
# Access.create_linear ensures that at most one
66+
# Iteration/Snapshot is active at any given time, which is necessary
67+
# supporting ADIOS2 steps, and also enables further optimizations.
68+
iteration = series.snapshots()[i]
7269

7370
#######################
7471
# write electron data #
@@ -134,7 +131,7 @@ def main():
134131
# After closing the iteration, the readers can see the iteration.
135132
# It can no longer be modified.
136133
# If not closing an iteration explicitly, it will be implicitly closed
137-
# upon creating the next iteration.
134+
# upon creating the next iteration due to the use of create_linear.
138135
iteration.close()
139136

140137
# The files in 'series' are still open until the object is destroyed, on

examples/14_toml_template.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ void write()
3333

3434
openPMD::Series writeTemplate(
3535
"../samples/tomlTemplate." + backendEnding(),
36-
openPMD::Access::CREATE,
36+
openPMD::Access::CREATE_LINEAR,
3737
config);
38-
auto iteration = writeTemplate.writeIterations()[0];
38+
auto iteration = writeTemplate.snapshots()[0];
3939

4040
openPMD::Dataset ds{openPMD::Datatype::FLOAT, {5, 5}};
4141

0 commit comments

Comments
 (0)