Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring for variable-based encoding: Use same backend object for Iterations container and the Iterations themselves #1707

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
Open
45 changes: 43 additions & 2 deletions include/openPMD/Iteration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ namespace internal
std::optional<DeferredParseAccess> m_deferredParseAccess{};
};
} // namespace internal

namespace traits
{
template <>
struct GenerationPolicy<Iteration>;
}

/** @brief Logical compilation of data from one snapshot (e.g. a single
* simulation cycle).
*
Expand All @@ -127,6 +134,7 @@ class Iteration : public Attributable
friend class Writable;
friend class StatefulIterator;
friend class StatefulSnapshotsContainer;
friend struct traits::GenerationPolicy<Iteration>;

public:
Iteration(Iteration const &) = default;
Expand Down Expand Up @@ -277,7 +285,7 @@ class Iteration : public Attributable
void flushFileBased(
std::string const &, IterationIndex_t, internal::FlushParams const &);
void flushGroupBased(IterationIndex_t, internal::FlushParams const &);
void flushVariableBased(IterationIndex_t, internal::FlushParams const &);
void flushVariableBased(internal::FlushParams const &);
void flush(internal::FlushParams const &);
void deferParseAccess(internal::DeferredParseAccess);
/*
Expand Down Expand Up @@ -394,7 +402,8 @@ class Iteration : public Attributable
*
* @param w The Writable representing the parent.
*/
virtual void linkHierarchy(Writable &w);
void linkHierarchy(internal::AttributableData &parent) override;
using Attributable::linkHierarchy;

/**
* @brief Access an iteration in read mode that has potentially not been
Expand Down Expand Up @@ -451,4 +460,36 @@ class IndexedIteration : public Iteration
: Iteration(std::forward<Iteration_t>(it)), iterationIndex(index)
{}
};

namespace traits
{
template <>
struct GenerationPolicy<Iteration>
{
constexpr static bool is_noop = false;
template <typename T, typename Container>
void operator()(T &ret, Container *c)
{
if (ret.IOHandler()->m_encoding == IterationEncoding::variableBased)
{
for (auto &pair :
static_cast<Attributable &>(ret).get().m_attributes)
{
static_cast<Attributable &>(*c).get().m_attributes.emplace(
std::move(pair));
}
static_cast<
std::shared_ptr<internal::SharedAttributableData> &>(
*ret.m_attri) =
static_cast<
std::shared_ptr<internal::SharedAttributableData> &>(
*c->m_attri);
internal::AttributableData *attr_of_shared_parent =
c->m_attri->frontend_parent;
ret.linkHierarchy(*attr_of_shared_parent);
ret.m_attri->frontend_parent = c->m_attri.get();
}
}
};
} // namespace traits
} // namespace openPMD
6 changes: 3 additions & 3 deletions include/openPMD/ParticleSpecies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ namespace traits
struct GenerationPolicy<ParticleSpecies>
{
constexpr static bool is_noop = false;
template <typename T>
void operator()(T &ret)
template <typename T, typename C>
void operator()(T &ret, C const *)
{
ret.particlePatches.linkHierarchy(ret.writable());
ret.particlePatches.linkHierarchy(ret);
}
};
} // namespace traits
Expand Down
45 changes: 36 additions & 9 deletions include/openPMD/backend/Attributable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,33 @@ namespace internal
std::shared_ptr<typename T::Data_t>(self, [](auto const *) {}));
return res;
}

internal::AttributableData *frontend_parent = nullptr;

/** Tracks if there are unwritten changes for this specific Writable.
*
* Manipulate via Attributable::dirty() and Attributable::setDirty().
*/
bool dirtySelf = true;
/**
* Tracks if there are unwritten changes anywhere in the
* tree whose ancestor this Writable is.
*
* Invariant: this->dirtyRecursive implies parent->dirtyRecursive.
*
* dirtySelf and dirtyRecursive are separated since that allows
* specifying that `this` is not dirty, but some child is.
*
* Manipulate via Attributable::dirtyRecursive() and
* Attributable::setDirtyRecursive().
*/
bool dirtyRecursive = true;

/**
* If frontend_parent is not null, then this is a key such that:
* &(*frontend_parent)[key] == this
*/
std::string ownKeyWithinParent;
};

template <typename, typename>
Expand Down Expand Up @@ -505,18 +532,17 @@ OPENPMD_protected

bool dirty() const
{
return writable().dirtySelf;
return m_attri->dirtySelf;
}
/** O(1).
*/
bool dirtyRecursive() const
{
return writable().dirtyRecursive;
return m_attri->dirtyRecursive;
}
void setDirty(bool dirty_in)
{
auto &w = writable();
w.dirtySelf = dirty_in;
m_attri->dirtySelf = dirty_in;
setDirtyRecursive(dirty_in);
}
/* Amortized O(1) if dirty_in is true, else O(1).
Expand All @@ -537,15 +563,15 @@ OPENPMD_protected
*/
void setDirtyRecursive(bool dirty_in)
{
auto &w = writable();
w.dirtyRecursive = dirty_in;
auto &a = *m_attri;
a.dirtyRecursive = dirty_in;
if (dirty_in)
{
auto current = w.parent;
auto current = a.frontend_parent;
while (current && !current->dirtyRecursive)
{
current->dirtyRecursive = true;
current = current->parent;
current = current->frontend_parent;
}
}
}
Expand Down Expand Up @@ -576,7 +602,8 @@ OPENPMD_protected
*
* @param w The Writable representing the parent.
*/
virtual void linkHierarchy(Writable &w);
void linkHierarchy(Attributable &parent);
virtual void linkHierarchy(internal::AttributableData &parent);
}; // Attributable

// note: we explicitly instantiate Attributable::setAttributeImpl for all T in
Expand Down
20 changes: 10 additions & 10 deletions include/openPMD/backend/Container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ namespace traits
struct GenerationPolicy
{
constexpr static bool is_noop = true;
template <typename T>
void operator()(T &)
template <typename... Args>
void operator()(Args &&...)
{}
};
} // namespace traits
Expand Down Expand Up @@ -297,18 +297,18 @@ class Container : virtual public Attributable
}

T t = T();
t.linkHierarchy(writable());
t.linkHierarchy(*this);
auto &ret = container().insert({key, std::move(t)}).first->second;
if constexpr (std::is_same_v<T_key, std::string>)
{
ret.writable().ownKeyWithinParent = key;
ret.m_attri->ownKeyWithinParent = key;
}
else
{
ret.writable().ownKeyWithinParent = std::to_string(key);
ret.m_attri->ownKeyWithinParent = std::to_string(key);
}
traits::GenerationPolicy<T> gen;
gen(ret);
gen(ret, this);
return ret;
}
}
Expand Down Expand Up @@ -338,19 +338,19 @@ class Container : virtual public Attributable
}

T t = T();
t.linkHierarchy(writable());
t.linkHierarchy(*this);
auto &ret = container().insert({key, std::move(t)}).first->second;
if constexpr (std::is_same_v<T_key, std::string>)
{
ret.writable().ownKeyWithinParent = std::move(key);
ret.m_attri->ownKeyWithinParent = std::move(key);
}
else
{
ret.writable().ownKeyWithinParent =
ret.m_attri->ownKeyWithinParent =
std::to_string(std::move(key));
}
traits::GenerationPolicy<T> gen;
gen(ret);
gen(ret, this);
return ret;
}
}
Expand Down
34 changes: 11 additions & 23 deletions include/openPMD/backend/Writable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ namespace debug
void printDirty(Series const &);
}

class Iteration;

namespace traits
{
template <typename>
struct GenerationPolicy;
template <>
struct GenerationPolicy<Iteration>;
} // namespace traits

/** @brief Layer to mirror structure of logical data and persistent data in
* file.
*
Expand Down Expand Up @@ -103,6 +113,7 @@ class Writable final
template <typename>
friend class Span;
friend void debug::printDirty(Series const &);
friend struct traits::GenerationPolicy<Iteration>;

private:
Writable(internal::AttributableData *);
Expand Down Expand Up @@ -152,29 +163,6 @@ OPENPMD_private
internal::AttributableData *attributable = nullptr;
Writable *parent = nullptr;

/** Tracks if there are unwritten changes for this specific Writable.
*
* Manipulate via Attributable::dirty() and Attributable::setDirty().
*/
bool dirtySelf = true;
/**
* Tracks if there are unwritten changes anywhere in the
* tree whose ancestor this Writable is.
*
* Invariant: this->dirtyRecursive implies parent->dirtyRecursive.
*
* dirtySelf and dirtyRecursive are separated since that allows specifying
* that `this` is not dirty, but some child is.
*
* Manipulate via Attributable::dirtyRecursive() and
* Attributable::setDirtyRecursive().
*/
bool dirtyRecursive = true;
/**
* If parent is not null, then this is a key such that:
* &(*parent)[key] == this
*/
std::string ownKeyWithinParent;
/**
* @brief Whether a Writable has been written to the backend.
*
Expand Down
24 changes: 23 additions & 1 deletion src/IO/AbstractIOHandlerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "openPMD/IO/AbstractIOHandlerImpl.hpp"

#include "openPMD/auxiliary/Environment.hpp"
#include "openPMD/auxiliary/TypeTraits.hpp"
#include "openPMD/backend/Writable.hpp"

#include <iostream>
Expand Down Expand Up @@ -301,7 +302,28 @@ std::future<void> AbstractIOHandlerImpl::flush()
"] WRITE_ATT: (",
parameter.dtype,
") ",
parameter.name);
parameter.name,
"=",
[&]() {
return std::visit(
[&](auto const &val) {
using dtype = std::remove_cv_t<
std::remove_reference_t<decltype(val)>>;
if constexpr (
auxiliary::IsArray_v<dtype> ||
auxiliary::IsVector_v<dtype>)
{
return vec_as_string(val);
}
else
{
std::stringstream res;
res << val;
return res.str();
}
},
parameter.resource);
});
writeAttribute(i.writable, parameter);
break;
}
Expand Down
Loading
Loading