Skip to content

Commit f85d53a

Browse files
authored
Merge pull request #364 from ax3l/topic-particlePatchesLoad
ParticlePatches: load() at once
2 parents b3478b1 + 0e8a678 commit f85d53a

File tree

3 files changed

+126
-20
lines changed

3 files changed

+126
-20
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Features
2323
- better check for (unsupported) numpy array strides #353
2424
- implement ``Record_Component.make_constant`` #354
2525
- comply with runtime constraints w.r.t. ``written`` status #352
26+
- load at once ``ParticlePatches.load()`` #364
2627

2728
Bug Fixes
2829
"""""""""

include/openPMD/backend/PatchRecordComponent.hpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ class PatchRecordComponent : public BaseRecordComponent
5757
Extent getExtent() const;
5858

5959
template< typename T >
60-
std::shared_ptr< T > load(uint64_t idx);
60+
std::shared_ptr< T > load();
6161
template< typename T >
62-
void load(uint64_t idx, std::shared_ptr< T >);
62+
void load(std::shared_ptr< T >);
6363
template< typename T >
6464
void store(uint64_t idx, T);
6565
//! @todo add support for constant patch record components
@@ -75,34 +75,32 @@ class PatchRecordComponent : public BaseRecordComponent
7575

7676
template< typename T >
7777
inline std::shared_ptr< T >
78-
PatchRecordComponent::load(uint64_t idx)
78+
PatchRecordComponent::load()
7979
{
80-
auto newData = std::make_shared< T >();
81-
loadChunk(idx, newData);
80+
uint64_t numPoints = getExtent()[0];
81+
auto newData = std::shared_ptr< T >(new T[numPoints], []( T *p ){ delete [] p; });
82+
load(newData);
8283
return newData;
8384
}
8485

8586
template< typename T >
8687
inline void
87-
PatchRecordComponent::load(uint64_t idx, std::shared_ptr< T > data)
88+
PatchRecordComponent::load(std::shared_ptr< T > data)
8889
{
8990
Datatype dtype = determineDatatype< T >();
9091
if( dtype != getDatatype() )
9192
throw std::runtime_error("Type conversion during particle patch loading not yet implemented");
9293

93-
Extent dse = getExtent();
94-
if( dse[0] - 1u < idx )
95-
throw std::runtime_error("Index does not reside inside patch (no. patches: " + std::to_string(dse[0])
96-
+ " - index: " + std::to_string(idx) + ")");
97-
9894
if( !data )
9995
throw std::runtime_error("Unallocated pointer passed during ParticlePatch loading.");
10096

97+
uint64_t numPoints = getExtent()[0];
98+
10199
//! @todo add support for constant patch record components
102100

103101
Parameter< Operation::READ_DATASET > dRead;
104-
dRead.offset = {idx};
105-
dRead.extent = {1};
102+
dRead.offset = {0};
103+
dRead.extent = {numPoints};
106104
dRead.dtype = getDatatype();
107105
dRead.data = std::static_pointer_cast< void >(data);
108106
m_chunks->push(IOTask(this, dRead));

test/SerialIOTest.cpp

Lines changed: 114 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <array>
1818
#include <memory>
1919
#include <limits>
20+
#include <numeric>
2021

2122
using namespace openPMD;
2223

@@ -111,6 +112,88 @@ void constant_scalar(std::string file_ending)
111112
}
112113
}
113114

115+
inline
116+
void particle_patches( std::string file_ending )
117+
{
118+
constexpr auto SCALAR = openPMD::RecordComponent::SCALAR;
119+
120+
uint64_t const extent = 123u;
121+
uint64_t const num_patches = 2u;
122+
{
123+
// constant scalar
124+
Series s = Series("../samples/particle_patches." + file_ending, AccessType::CREATE);
125+
126+
auto e = s.iterations[42].particles["electrons"];
127+
128+
for( auto r : {"x", "y"} )
129+
{
130+
auto x = e["position"][r];
131+
x.resetDataset(Dataset(determineDatatype<float>(), {extent}));
132+
std::vector<float> xd( extent );
133+
std::iota(xd.begin(), xd.end(), 0);
134+
x.storeChunk({0}, {extent}, shareRaw(xd.data()));
135+
auto o = e["positionOffset"][r];
136+
o.resetDataset(Dataset(determineDatatype<uint64_t>(), {extent}));
137+
std::vector<uint64_t> od( extent );
138+
std::iota(od.begin(), od.end(), 0);
139+
o.storeChunk({0}, {extent}, shareRaw(od.data()));
140+
}
141+
142+
auto const dset_n = Dataset(determineDatatype<uint64_t>(), {num_patches, });
143+
e.particlePatches["numParticles"][SCALAR].resetDataset(dset_n);
144+
e.particlePatches["numParticlesOffset"][SCALAR].resetDataset(dset_n);
145+
146+
auto const dset_f = Dataset(determineDatatype<float>(), {num_patches, });
147+
e.particlePatches["offset"]["x"].resetDataset(dset_f);
148+
e.particlePatches["offset"]["y"].resetDataset(dset_f);
149+
e.particlePatches["extent"]["x"].resetDataset(dset_f);
150+
e.particlePatches["extent"]["y"].resetDataset(dset_f);
151+
152+
// patch 0 (decomposed in x)
153+
e.particlePatches["numParticles"][SCALAR].store(0, uint64_t(10u));
154+
e.particlePatches["numParticlesOffset"][SCALAR].store(0, uint64_t(0u));
155+
e.particlePatches["offset"]["x"].store(0, float(0.));
156+
e.particlePatches["offset"]["y"].store(0, float(0.));
157+
e.particlePatches["extent"]["x"].store(0, float(10.));
158+
e.particlePatches["extent"]["y"].store(0, float(123.));
159+
160+
// patch 1 (decomposed in x)
161+
e.particlePatches["numParticles"][SCALAR].store(1, uint64_t(113u));
162+
e.particlePatches["numParticlesOffset"][SCALAR].store(1, uint64_t(10u));
163+
e.particlePatches["offset"]["x"].store(1, float(10.));
164+
e.particlePatches["offset"]["y"].store(1, float(0.));
165+
e.particlePatches["extent"]["x"].store(1, float(113));
166+
e.particlePatches["extent"]["y"].store(1, float(123.));
167+
}
168+
{
169+
Series s = Series("../samples/particle_patches." + file_ending, AccessType::READ_ONLY);
170+
171+
auto e = s.iterations[42].particles["electrons"];
172+
173+
auto numParticles = e.particlePatches["numParticles"][SCALAR].template load< uint64_t >();
174+
auto numParticlesOffset = e.particlePatches["numParticlesOffset"][SCALAR].template load< uint64_t >();
175+
auto extent_x = e.particlePatches["extent"]["x"].template load< float >();
176+
auto extent_y = e.particlePatches["extent"]["y"].template load< float >();
177+
auto offset_x = e.particlePatches["offset"]["x"].template load< float >();
178+
auto offset_y = e.particlePatches["offset"]["y"].template load< float >();
179+
180+
s.flush();
181+
182+
REQUIRE(numParticles.get()[0] == 10);
183+
REQUIRE(numParticles.get()[1] == 113);
184+
REQUIRE(numParticlesOffset.get()[0] == 0);
185+
REQUIRE(numParticlesOffset.get()[1] == 10);
186+
REQUIRE(extent_x.get()[0] == 10.);
187+
REQUIRE(extent_x.get()[1] == 113.);
188+
REQUIRE(extent_y.get()[0] == 123.);
189+
REQUIRE(extent_y.get()[1] == 123.);
190+
REQUIRE(offset_x.get()[0] == 0.);
191+
REQUIRE(offset_x.get()[1] == 10.);
192+
REQUIRE(offset_y.get()[0] == 0.);
193+
REQUIRE(offset_y.get()[1] == 0.);
194+
}
195+
}
196+
114197
#if openPMD_HAVE_HDF5
115198
TEST_CASE( "git_hdf5_sample_structure_test", "[serial][hdf5]" )
116199
{
@@ -554,7 +637,8 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
554637
// since this file might not be publicly available, gracefully handle errors
555638
try
556639
{
557-
/* development/huebl/lwfa-openPMD-062-smallLWFA-h5 */
640+
/* HZDR: /bigdata/hplsim/development/huebl/lwfa-openPMD-062-smallLWFA-h5
641+
* DOI:10.14278/rodare.57 */
558642
Series o = Series("../samples/hzdr-sample/h5/simData_%T.h5", AccessType::READ_ONLY);
559643

560644
REQUIRE(o.openPMD() == "1.0.0");
@@ -907,10 +991,13 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
907991
#endif
908992
REQUIRE(isSame(e_extent_z.getDatatype(), determineDatatype< uint64_t >()));
909993

910-
std::shared_ptr< uint64_t > data;
911-
e_extent_z.load(0, data);
994+
std::vector< uint64_t > data( e_patches.size() );
995+
e_extent_z.load(shareRaw(data.data()));
912996
o.flush();
913-
REQUIRE(*data == static_cast< uint64_t >(80));
997+
REQUIRE(data.at(0) == static_cast< uint64_t >(80));
998+
REQUIRE(data.at(1) == static_cast< uint64_t >(80));
999+
REQUIRE(data.at(2) == static_cast< uint64_t >(80));
1000+
REQUIRE(data.at(3) == static_cast< uint64_t >(80));
9141001

9151002
PatchRecord& e_numParticles = e_patches["numParticles"];
9161003
REQUIRE(e_numParticles.size() == 1);
@@ -922,9 +1009,12 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
9221009
#endif
9231010
REQUIRE(isSame(e_numParticles_scalar.getDatatype(), determineDatatype< uint64_t >()));
9241011

925-
e_numParticles_scalar.load(0, data);
1012+
e_numParticles_scalar.load(shareRaw(data.data()));
9261013
o.flush();
927-
REQUIRE(*data == static_cast< uint64_t >(512000));
1014+
REQUIRE(data.at(0) == static_cast< uint64_t >(512000));
1015+
REQUIRE(data.at(1) == static_cast< uint64_t >(819200));
1016+
REQUIRE(data.at(2) == static_cast< uint64_t >(819200));
1017+
REQUIRE(data.at(3) == static_cast< uint64_t >(0));
9281018

9291019
PatchRecord& e_numParticlesOffset = e_patches["numParticlesOffset"];
9301020
REQUIRE(e_numParticlesOffset.size() == 1);
@@ -958,6 +1048,13 @@ TEST_CASE( "hzdr_hdf5_sample_content_test", "[serial][hdf5]" )
9581048
#endif
9591049
REQUIRE(isSame(e_offset_y.getDatatype(), determineDatatype< uint64_t >()));
9601050

1051+
e_offset_y.load(shareRaw(data.data()));
1052+
o.flush();
1053+
REQUIRE(data.at(0) == static_cast< uint64_t >(0));
1054+
REQUIRE(data.at(1) == static_cast< uint64_t >(128));
1055+
REQUIRE(data.at(2) == static_cast< uint64_t >(256));
1056+
REQUIRE(data.at(3) == static_cast< uint64_t >(384));
1057+
9611058
PatchRecordComponent& e_offset_z = e_offset["z"];
9621059
REQUIRE(e_offset_z.unitSI() == 2.599999993753294e-07);
9631060
#if !defined(_MSC_VER)
@@ -1540,6 +1637,11 @@ TEST_CASE( "hdf5_constant_scalar", "[serial][hdf5]" )
15401637
{
15411638
constant_scalar("h5");
15421639
}
1640+
1641+
TEST_CASE( "hdf5_particle_patches", "[serial][hdf5]" )
1642+
{
1643+
particle_patches("h5");
1644+
}
15431645
#else
15441646
TEST_CASE( "no_serial_hdf5", "[serial][hdf5]" )
15451647
{
@@ -1999,7 +2101,8 @@ TEST_CASE( "hzdr_adios1_sample_content_test", "[serial][adios1]" )
19992101
/** @todo add bp example files to https://github.com/openPMD/openPMD-example-datasets */
20002102
try
20012103
{
2002-
/* development/huebl/lwfa-bgfield-001 */
2104+
/* HZDR: /bigdata/hplsim/development/huebl/lwfa-bgfield-001
2105+
* DOI:10.14278/rodare.57 */
20032106
Series o = Series("../samples/hzdr-sample/bp/checkpoint_%T.bp", AccessType::READ_ONLY);
20042107

20052108
REQUIRE(o.openPMD() == "1.0.0");
@@ -2156,6 +2259,10 @@ TEST_CASE( "adios1_constant_scalar", "[serial][adios1]" )
21562259
{
21572260
constant_scalar("bp");
21582261
}
2262+
TEST_CASE( "adios1_particle_patches", "[serial][adios1]" )
2263+
{
2264+
particle_patches("bp");
2265+
}
21592266
#else
21602267
TEST_CASE( "no_serial_adios1", "[serial][adios]")
21612268
{

0 commit comments

Comments
 (0)