Skip to content

Commit 21adf5a

Browse files
Performance optimizations for interacting with many meshes / species types (#1741)
* Emplace scalar tuple only when needed * Flush only dirty meshes/species TODO: Maybe do this in more places, and also when reading * Improved specification of standards * Don't forward empty Span operations to backend * Verify that Iterations are not reparsed * Check for dirtyRecursive more fine-grained * Update include/openPMD/backend/BaseRecord.hpp
1 parent 52cc164 commit 21adf5a

File tree

10 files changed

+74
-15
lines changed

10 files changed

+74
-15
lines changed

include/openPMD/RecordComponent.tpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ RecordComponent::storeChunk(Offset o, Extent e, F &&createBuffer)
114114
dCreate.name = rc.m_name;
115115
IOHandler()->enqueue(IOTask(this, dCreate));
116116
}
117+
118+
if (size == 0)
119+
{
120+
// Don't forward this operation to the backend as it might create ugly
121+
// zero-blocks in ADIOS2
122+
setDirtyRecursive(true);
123+
return DynamicMemoryView<T>();
124+
}
125+
117126
Parameter<Operation::GET_BUFFER_VIEW> getBufferView;
118127
getBufferView.offset = o;
119128
getBufferView.extent = e;

include/openPMD/Span.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ class DynamicMemoryView
113113
}
114114

115115
public:
116-
explicit DynamicMemoryView() = default;
116+
explicit DynamicMemoryView()
117+
{
118+
m_param.out->backendManagedBuffer = false;
119+
}
117120

118121
/**
119122
* @brief Acquire the underlying buffer at its current position in memory.

src/Iteration.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,14 @@ void Iteration::flush(internal::FlushParams const &flushParams)
362362
s.setMeshesPath("meshes/");
363363
s.flushMeshesPath();
364364
}
365-
meshes.flush(s.meshesPath(), flushParams);
366-
for (auto &m : meshes)
367-
m.second.flush(m.first, flushParams);
365+
if (meshes.dirtyRecursive())
366+
{
367+
meshes.flush(s.meshesPath(), flushParams);
368+
for (auto &m : meshes)
369+
{
370+
m.second.flush(m.first, flushParams);
371+
}
372+
}
368373
}
369374
else
370375
{
@@ -378,9 +383,14 @@ void Iteration::flush(internal::FlushParams const &flushParams)
378383
s.setParticlesPath("particles/");
379384
s.flushParticlesPath();
380385
}
381-
particles.flush(s.particlesPath(), flushParams);
382-
for (auto &species : particles)
383-
species.second.flush(species.first, flushParams);
386+
if (particles.dirtyRecursive())
387+
{
388+
particles.flush(s.particlesPath(), flushParams);
389+
for (auto &species : particles)
390+
{
391+
species.second.flush(species.first, flushParams);
392+
}
393+
}
384394
}
385395
else
386396
{
@@ -470,6 +480,11 @@ void Iteration::readGorVBased(
470480

471481
void Iteration::read_impl(std::string const &groupPath)
472482
{
483+
if (!get().m_deferredParseAccess.has_value())
484+
{
485+
throw error::Internal(
486+
"Attempted reparsing an Iteration that is already parsed.");
487+
}
473488
Parameter<Operation::OPEN_PATH> pOpen;
474489
pOpen.path = groupPath;
475490
IOHandler()->enqueue(IOTask(this, pOpen));

src/Mesh.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ template Mesh &Mesh::setTimeOffset(float);
366366
void Mesh::flush_impl(
367367
std::string const &name, internal::FlushParams const &flushParams)
368368
{
369+
if (!dirtyRecursive())
370+
{
371+
return;
372+
}
369373
if (access::readOnly(IOHandler()->m_frontendAccess))
370374
{
371375
auto &m = get();

src/ParticleSpecies.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ namespace
155155
void ParticleSpecies::flush(
156156
std::string const &path, internal::FlushParams const &flushParams)
157157
{
158+
if (!dirtyRecursive())
159+
{
160+
return;
161+
}
158162
if (access::readOnly(IOHandler()->m_frontendAccess))
159163
{
160164
for (auto &record : *this)
@@ -168,12 +172,15 @@ void ParticleSpecies::flush(
168172
}
169173
else
170174
{
171-
auto it = find("position");
172-
if (it != end())
173-
it->second.setUnitDimension({{UnitDimension::L, 1}});
174-
it = find("positionOffset");
175-
if (it != end())
176-
it->second.setUnitDimension({{UnitDimension::L, 1}});
175+
if (flushParams.flushLevel != FlushLevel::SkeletonOnly)
176+
{
177+
auto it = find("position");
178+
if (it != end())
179+
it->second.setUnitDimension({{UnitDimension::L, 1}});
180+
it = find("positionOffset");
181+
if (it != end())
182+
it->second.setUnitDimension({{UnitDimension::L, 1}});
183+
}
177184

178185
Container<Record>::flush(path, flushParams);
179186

src/Record.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ Record &Record::setUnitDimension(unit_representations::AsMap const &udim)
4545
}
4646
Record &Record::setUnitDimension(unit_representations::AsArray const &udim)
4747
{
48-
return setUnitDimension(
49-
unit_representations::asMap(udim, /* skip_zeros = */ false));
48+
setAttribute("unitDimension", udim);
49+
return *this;
5050
}
5151

5252
void Record::flush_impl(
5353
std::string const &name, internal::FlushParams const &flushParams)
5454
{
55+
if (!dirtyRecursive())
56+
{
57+
return;
58+
}
5559
if (access::readOnly(IOHandler()->m_frontendAccess))
5660
{
5761
if (scalar())

src/RecordComponent.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ bool RecordComponent::empty() const
255255
void RecordComponent::flush(
256256
std::string const &name, internal::FlushParams const &flushParams)
257257
{
258+
if (!dirtyRecursive())
259+
{
260+
return;
261+
}
258262
auto &rc = get();
259263
if (flushParams.flushLevel == FlushLevel::SkeletonOnly)
260264
{

src/backend/BaseRecord.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,11 @@ template <typename T_elem>
819819
inline void BaseRecord<T_elem>::flush(
820820
std::string const &name, internal::FlushParams const &flushParams)
821821
{
822+
if (!this->dirtyRecursive())
823+
{
824+
return;
825+
}
826+
822827
if (!this->written() && this->empty() && !this->datasetDefined())
823828
throw std::runtime_error(
824829
"A Record can not be written without any contained "

src/backend/MeshRecordComponent.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ void MeshRecordComponent::read()
7272
void MeshRecordComponent::flush(
7373
std::string const &name, internal::FlushParams const &params)
7474
{
75+
if (!dirtyRecursive())
76+
{
77+
return;
78+
}
7579
if (access::write(IOHandler()->m_frontendAccess) &&
7680
!containsAttribute("position"))
7781
{

src/backend/PatchRecord.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ PatchRecord::setUnitDimension(std::map<UnitDimension, double> const &udim)
4141
void PatchRecord::flush_impl(
4242
std::string const &path, internal::FlushParams const &flushParams)
4343
{
44+
if (!dirtyRecursive())
45+
{
46+
return;
47+
}
4448
if (!this->datasetDefined())
4549
{
4650
if (IOHandler()->m_frontendAccess != Access::READ_ONLY)

0 commit comments

Comments
 (0)