From 8d310f2c4bee4bf3269e7a097b149c3053c931f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 17 Dec 2024 16:41:22 +0100 Subject: [PATCH 01/14] Introduce frontend_parent --- include/openPMD/Iteration.hpp | 3 ++- include/openPMD/ParticleSpecies.hpp | 2 +- include/openPMD/backend/Attributable.hpp | 3 ++- include/openPMD/backend/Container.hpp | 4 ++-- include/openPMD/backend/Writable.hpp | 1 + src/Iteration.cpp | 8 ++++---- src/Series.cpp | 8 ++++---- src/backend/Attributable.cpp | 9 ++++++++- 8 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index 8c39c0a518..7fb1ca77f4 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -394,7 +394,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 diff --git a/include/openPMD/ParticleSpecies.hpp b/include/openPMD/ParticleSpecies.hpp index af7aa50375..869d3301f1 100644 --- a/include/openPMD/ParticleSpecies.hpp +++ b/include/openPMD/ParticleSpecies.hpp @@ -64,7 +64,7 @@ namespace traits template void operator()(T &ret) { - ret.particlePatches.linkHierarchy(ret.writable()); + ret.particlePatches.linkHierarchy(ret); } }; } // namespace traits diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index a77d8fe524..7d806043d0 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -576,7 +576,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 diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index 8dda5b992b..f3a74cdc07 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -297,7 +297,7 @@ 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) { @@ -338,7 +338,7 @@ 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) { diff --git a/include/openPMD/backend/Writable.hpp b/include/openPMD/backend/Writable.hpp index be36f47758..c97d865844 100644 --- a/include/openPMD/backend/Writable.hpp +++ b/include/openPMD/backend/Writable.hpp @@ -151,6 +151,7 @@ OPENPMD_private */ internal::AttributableData *attributable = nullptr; Writable *parent = nullptr; + internal::AttributableData *frontend_parent = nullptr; /** Tracks if there are unwritten changes for this specific Writable. * diff --git a/src/Iteration.cpp b/src/Iteration.cpp index 931a1f9e3d..ed46e83999 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -889,11 +889,11 @@ void Iteration::setStepStatus(StepStatus status) } } -void Iteration::linkHierarchy(Writable &w) +void Iteration::linkHierarchy(internal::AttributableData &parent) { - Attributable::linkHierarchy(w); - meshes.linkHierarchy(this->writable()); - particles.linkHierarchy(this->writable()); + Attributable::linkHierarchy(parent); + meshes.linkHierarchy(*this); + particles.linkHierarchy(*this); } void Iteration::runDeferredParseAccess() diff --git a/src/Series.cpp b/src/Series.cpp index 792be0555f..b1c7339435 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -888,8 +888,8 @@ void Series::init( std::make_shared>>( std::make_unique(parsed_directory, at)); auto &series = get(); - series.iterations.linkHierarchy(writable()); - series.m_rankTable.m_attributable.linkHierarchy(writable()); + series.iterations.linkHierarchy(*this); + series.m_rankTable.m_attributable.linkHierarchy(*this); series.m_deferred_initialization = [called_this_already = false, filepath, options, at, comm...]( Series &s) mutable { @@ -1108,9 +1108,9 @@ void Series::initSeries( std::move(ioHandler)); } - series.iterations.linkHierarchy(writable); + series.iterations.linkHierarchy(*this); series.iterations.writable().ownKeyWithinParent = "iterations"; - series.m_rankTable.m_attributable.linkHierarchy(writable); + series.m_rankTable.m_attributable.linkHierarchy(*this); series.m_name = input->name; diff --git a/src/backend/Attributable.cpp b/src/backend/Attributable.cpp index da9e09e2e0..ab24409f19 100644 --- a/src/backend/Attributable.cpp +++ b/src/backend/Attributable.cpp @@ -531,11 +531,18 @@ void Attributable::setWritten(bool val, EnqueueAsynchronously ea) writable().written = val; } -void Attributable::linkHierarchy(Writable &w) +void Attributable::linkHierarchy(Attributable &parent) { + this->linkHierarchy(*parent.m_attri); +} + +void Attributable::linkHierarchy(internal::AttributableData &a) +{ + Writable &w = a->m_writable; auto handler = w.IOHandler; writable().IOHandler = handler; writable().parent = &w; + writable().frontend_parent = &a; setDirty(true); } From a231ea7fcce2068638f14e669297a887d7c08359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 17 Dec 2024 16:42:57 +0100 Subject: [PATCH 02/14] Use same writable for iterations and container in var encoding --- include/openPMD/Iteration.hpp | 38 +++++++++++++++++++++++++++ include/openPMD/ParticleSpecies.hpp | 4 +-- include/openPMD/backend/Container.hpp | 8 +++--- include/openPMD/backend/Writable.hpp | 11 ++++++++ src/Series.cpp | 25 +++++++++++++----- 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index 7fb1ca77f4..eb11ee0e9a 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -110,6 +110,13 @@ namespace internal std::optional m_deferredParseAccess{}; }; } // namespace internal + +namespace traits +{ + template <> + struct GenerationPolicy; +} + /** @brief Logical compilation of data from one snapshot (e.g. a single * simulation cycle). * @@ -127,6 +134,7 @@ class Iteration : public Attributable friend class Writable; friend class StatefulIterator; friend class StatefulSnapshotsContainer; + friend struct traits::GenerationPolicy; public: Iteration(Iteration const &) = default; @@ -452,4 +460,34 @@ class IndexedIteration : public Iteration : Iteration(std::forward(it)), iterationIndex(index) {} }; + +inline void breakpoint() +{} + +namespace traits +{ + template <> + struct GenerationPolicy + { + constexpr static bool is_noop = false; + template + void operator()(T &ret, Container *c) + { + breakpoint(); + if (ret.IOHandler()->m_encoding == IterationEncoding::variableBased) + { + static_cast< + std::shared_ptr &>( + *ret.m_attri) = + static_cast< + std::shared_ptr &>( + *c->m_attri); + Writable *writable_of_container = &c->writable(); + internal::AttributableData *attr_of_shared_parent = + writable_of_container->frontend_parent; + ret.linkHierarchy(*attr_of_shared_parent); + } + } + }; +} // namespace traits } // namespace openPMD diff --git a/include/openPMD/ParticleSpecies.hpp b/include/openPMD/ParticleSpecies.hpp index 869d3301f1..4f9d502eba 100644 --- a/include/openPMD/ParticleSpecies.hpp +++ b/include/openPMD/ParticleSpecies.hpp @@ -61,8 +61,8 @@ namespace traits struct GenerationPolicy { constexpr static bool is_noop = false; - template - void operator()(T &ret) + template + void operator()(T &ret, C const *) { ret.particlePatches.linkHierarchy(ret); } diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index f3a74cdc07..1b2175d318 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -51,8 +51,8 @@ namespace traits struct GenerationPolicy { constexpr static bool is_noop = true; - template - void operator()(T &) + template + void operator()(Args &&...) {} }; } // namespace traits @@ -308,7 +308,7 @@ class Container : virtual public Attributable ret.writable().ownKeyWithinParent = std::to_string(key); } traits::GenerationPolicy gen; - gen(ret); + gen(ret, this); return ret; } } @@ -350,7 +350,7 @@ class Container : virtual public Attributable std::to_string(std::move(key)); } traits::GenerationPolicy gen; - gen(ret); + gen(ret, this); return ret; } } diff --git a/include/openPMD/backend/Writable.hpp b/include/openPMD/backend/Writable.hpp index c97d865844..10fc3dcc0d 100644 --- a/include/openPMD/backend/Writable.hpp +++ b/include/openPMD/backend/Writable.hpp @@ -62,6 +62,16 @@ namespace debug void printDirty(Series const &); } +class Iteration; + +namespace traits +{ + template + struct GenerationPolicy; + template <> + struct GenerationPolicy; +} // namespace traits + /** @brief Layer to mirror structure of logical data and persistent data in * file. * @@ -103,6 +113,7 @@ class Writable final template friend class Span; friend void debug::printDirty(Series const &); + friend struct traits::GenerationPolicy; private: Writable(internal::AttributableData *); diff --git a/src/Series.cpp b/src/Series.cpp index b1c7339435..c29611f377 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -1507,7 +1507,18 @@ void Series::flushGorVBased( case IO::HasBeenOpened: if (!it->second.written()) { - it->second.parent() = getWritable(&series.iterations); + if (iterationEncoding() != IterationEncoding::variableBased) + { + it->second.parent() = getWritable(&series.iterations); + } + else if ( + &it->second.writable() != &series.iterations.writable()) + { + throw error::Internal( + "In variable-based encoding, the container of " + "Iterations must be the same backend object as the " + "Iterations themselves."); + } series.m_currentlyActiveIterations.emplace(it->first); } switch (iterationEncoding()) @@ -2791,11 +2802,13 @@ void Series::openIteration(IterationIndex_t index, Iteration &iteration) Parameter pOpen; pOpen.path = auxiliary::replace_first(basePath(), "%T/", ""); IOHandler()->enqueue(IOTask(&series.iterations, pOpen)); - /* open iteration path */ - pOpen.path = iterationEncoding() == IterationEncoding::variableBased - ? "" - : std::to_string(index); - IOHandler()->enqueue(IOTask(&iteration, pOpen)); + if (iterationEncoding() != IterationEncoding::variableBased) + { + /* open iteration path */ + pOpen.path = std::to_string(index); + IOHandler()->enqueue(IOTask(&iteration, pOpen)); + } + break; } case IE::groupBased: From a2200d9174547066e08c773094922bf2b2c9e674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 17 Dec 2024 17:46:00 +0100 Subject: [PATCH 03/14] Put dirty, dirtyRecursive and frontend_parent in the right place --- include/openPMD/Iteration.hpp | 3 +- include/openPMD/backend/Attributable.hpp | 36 ++++++++++++++++++------ include/openPMD/backend/Writable.hpp | 19 ------------- src/Series.cpp | 1 + src/backend/Attributable.cpp | 2 +- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index eb11ee0e9a..1e3409eaaa 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -482,9 +482,8 @@ namespace traits static_cast< std::shared_ptr &>( *c->m_attri); - Writable *writable_of_container = &c->writable(); internal::AttributableData *attr_of_shared_parent = - writable_of_container->frontend_parent; + c->m_attri->frontend_parent; ret.linkHierarchy(*attr_of_shared_parent); } } diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 7d806043d0..1fc62463d3 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -152,6 +152,27 @@ namespace internal std::shared_ptr(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; }; template @@ -505,18 +526,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). @@ -537,15 +557,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; } } } diff --git a/include/openPMD/backend/Writable.hpp b/include/openPMD/backend/Writable.hpp index 10fc3dcc0d..01cdc545dd 100644 --- a/include/openPMD/backend/Writable.hpp +++ b/include/openPMD/backend/Writable.hpp @@ -162,26 +162,7 @@ OPENPMD_private */ internal::AttributableData *attributable = nullptr; Writable *parent = nullptr; - 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 parent is not null, then this is a key such that: * &(*parent)[key] == this diff --git a/src/Series.cpp b/src/Series.cpp index c29611f377..926e82b995 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -38,6 +38,7 @@ #include "openPMD/auxiliary/StringManip.hpp" #include "openPMD/auxiliary/Variant.hpp" #include "openPMD/backend/Attributable.hpp" +#include "openPMD/backend/Writable.hpp" #include "openPMD/snapshots/ContainerImpls.hpp" #include "openPMD/snapshots/IteratorTraits.hpp" #include "openPMD/snapshots/RandomAccessIterator.hpp" diff --git a/src/backend/Attributable.cpp b/src/backend/Attributable.cpp index ab24409f19..381e03856b 100644 --- a/src/backend/Attributable.cpp +++ b/src/backend/Attributable.cpp @@ -542,7 +542,7 @@ void Attributable::linkHierarchy(internal::AttributableData &a) auto handler = w.IOHandler; writable().IOHandler = handler; writable().parent = &w; - writable().frontend_parent = &a; + m_attri->frontend_parent = &a; setDirty(true); } From 0dad27debcdb8640d251d385c71cdca42abca5c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 17 Dec 2024 17:46:38 +0100 Subject: [PATCH 04/14] Graphviz debug output --- src/Series.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/Series.cpp b/src/Series.cpp index 926e82b995..edf9da2e24 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -1499,6 +1500,8 @@ void Series::flushGorVBased( series.iterations.flush( auxiliary::replace_first(basePath(), "%T/", ""), flushParams); + debug::printDirty(*this); + for (auto it = begin; it != end; ++it) { // Phase 1 @@ -2098,6 +2101,16 @@ creating new iterations. { // parse for the first time, resp. delay the parsing process Iteration &i = series.iterations[index]; + // if (iterationEncoding() == IterationEncoding::variableBased) + // { + // static_cast< + // std::shared_ptr &>( + // *i.m_attri) = + // static_cast< + // std::shared_ptr &>( + // *series.iterations.m_attri); + // i.linkHierarchy(writable()); + // } i.deferParseAccess({path, index, false, beginStep}); if (!series.m_parseLazily) { @@ -3410,7 +3423,9 @@ namespace debug { void printDirty(Series const &series) { - auto print = [](Attributable const &attr) { + std::stringstream graph; + graph << "digraph\n{node [shape=\"box\"];\n"; + auto print = [&graph](Attributable const &attr) { size_t indent = 0; { auto current = attr.parent(); @@ -3430,9 +3445,21 @@ namespace debug auto const &w = attr.writable(); std::cout << w.ownKeyWithinParent << '\n'; make_indent(); - std::cout << "Self: " << w.dirtySelf - << "\tRec: " << w.dirtyRecursive << '\n'; - std::cout << std::endl; + std::cout << "Self: " << attr.m_attri->dirtySelf + << "\tRec: " << attr.m_attri->dirtyRecursive << '\n'; + std::cout << '\n'; + graph << "{rank = same; "; + graph << "_" << attr.m_attri.get() << "[color=green, label = \"A " + << attr.m_attri.get() << " '" << w.ownKeyWithinParent + << "'\"]; "; + graph << "_" << &w << "[color=blue, label = \"W " << &w << " '" + << w.ownKeyWithinParent << "'\"]; "; + graph << "}\n"; + graph << "_" << &w << " -> _" << attr.m_attri.get() + << "[dir=none];\n"; + graph << "_" << w.parent << " -> _" << &w << ";\n"; + graph << "_" << attr.m_attri->frontend_parent << " -> _" + << attr.m_attri.get() << '\n'; }; print(series); print(series.iterations); @@ -3488,6 +3515,9 @@ namespace debug } } } + graph << "}"; + std::cout << graph.str(); + std::cout.flush(); } } // namespace debug } // namespace openPMD From b2f0b02e161f442a2b6e51454a3796fd80aac0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 17 Dec 2024 18:29:11 +0100 Subject: [PATCH 05/14] Fix indexOf --- src/Series.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Series.cpp b/src/Series.cpp index edf9da2e24..d1d9801c0c 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -2417,7 +2417,7 @@ Series::iterations_iterator Series::indexOf(Iteration const &iteration) for (auto it = series.iterations.begin(); it != series.iterations.end(); ++it) { - if (&it->second.Attributable::get() == &iteration.Attributable::get()) + if (it->second.m_attri->get() == iteration.m_attri->get()) { return it; } From f94f4b63dd6d0ee807702beb160ebdf6e6f1c69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 11:09:51 +0100 Subject: [PATCH 06/14] graphviz --- src/Series.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Series.cpp b/src/Series.cpp index d1d9801c0c..e9d0d95713 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -3443,9 +3443,10 @@ namespace debug }; make_indent(); auto const &w = attr.writable(); - std::cout << w.ownKeyWithinParent << '\n'; + std::cout << w.ownKeyWithinParent << '\t' << attr.m_attri.get() + << " -> " << &attr.writable() << '\n'; make_indent(); - std::cout << "Self: " << attr.m_attri->dirtySelf + std::cout << "Self:\t" << attr.m_attri->dirtySelf << "\tRec: " << attr.m_attri->dirtyRecursive << '\n'; std::cout << '\n'; graph << "{rank = same; "; From eac55c65ea911176ceab1d5cf4c2aa0b9f71385e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 12:11:14 +0100 Subject: [PATCH 07/14] Further fixes --- include/openPMD/Iteration.hpp | 10 ++++++---- src/Iteration.cpp | 14 ++------------ src/Series.cpp | 4 +--- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index 1e3409eaaa..e5d3242dbc 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -461,9 +461,6 @@ class IndexedIteration : public Iteration {} }; -inline void breakpoint() -{} - namespace traits { template <> @@ -473,9 +470,14 @@ namespace traits template void operator()(T &ret, Container *c) { - breakpoint(); if (ret.IOHandler()->m_encoding == IterationEncoding::variableBased) { + for (auto &pair : + static_cast(ret).get().m_attributes) + { + static_cast(*c).get().m_attributes.emplace( + std::move(pair)); + } static_cast< std::shared_ptr &>( *ret.m_attri) = diff --git a/src/Iteration.cpp b/src/Iteration.cpp index ed46e83999..b51fadd741 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -293,13 +293,7 @@ void Iteration::flushGroupBased( void Iteration::flushVariableBased( IterationIndex_t i, internal::FlushParams const &flushParams) { - if (!written()) - { - /* create iteration path */ - Parameter pOpen; - pOpen.path = ""; - IOHandler()->enqueue(IOTask(this, pOpen)); - } + setDirty(true); switch (flushParams.flushLevel) { @@ -312,12 +306,8 @@ void Iteration::flushVariableBased( break; } - if (!written()) + // @todo maybe dont repeat this upon each invocation { - /* create iteration path */ - Parameter pOpen; - pOpen.path = ""; - IOHandler()->enqueue(IOTask(this, pOpen)); /* * In v-based encoding, the snapshot attribute must always be written. * Reason: Even in backends that don't support changing attributes, diff --git a/src/Series.cpp b/src/Series.cpp index e9d0d95713..92bd973021 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -1500,8 +1500,6 @@ void Series::flushGorVBased( series.iterations.flush( auxiliary::replace_first(basePath(), "%T/", ""), flushParams); - debug::printDirty(*this); - for (auto it = begin; it != end; ++it) { // Phase 1 @@ -2417,7 +2415,7 @@ Series::iterations_iterator Series::indexOf(Iteration const &iteration) for (auto it = series.iterations.begin(); it != series.iterations.end(); ++it) { - if (it->second.m_attri->get() == iteration.m_attri->get()) + if (it->second.m_attri.get() == iteration.m_attri.get()) { return it; } From c600222ed800fd51399bee46c0893c415d49df62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 12:27:56 +0100 Subject: [PATCH 08/14] Fix Attributable::containingIteration() --- include/openPMD/backend/Attributable.hpp | 10 ++++++---- src/backend/Attributable.cpp | 25 +++++++++++++++--------- src/backend/BaseRecordComponent.cpp | 3 ++- src/backend/Writable.cpp | 3 ++- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 1fc62463d3..203fd64a0c 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/IO/AbstractIOHandler.hpp" +#include "openPMD/IterationEncoding.hpp" #include "openPMD/ThrowError.hpp" #include "openPMD/auxiliary/OutOfRangeMsg.hpp" #include "openPMD/backend/Attribute.hpp" @@ -398,10 +399,11 @@ OPENPMD_protected * Throws an error otherwise, e.g., for Series objects. * @{ */ - [[nodiscard]] auto containingIteration() const -> std::pair< - std::optional, - internal::SeriesData const *>; - auto containingIteration() -> std:: + [[nodiscard]] auto containingIteration(IterationEncoding ie) const + -> std::pair< + std::optional, + internal::SeriesData const *>; + auto containingIteration(IterationEncoding ie) -> std:: pair, internal::SeriesData *>; /** @} */ diff --git a/src/backend/Attributable.cpp b/src/backend/Attributable.cpp index 381e03856b..ddb0b7a656 100644 --- a/src/backend/Attributable.cpp +++ b/src/backend/Attributable.cpp @@ -21,6 +21,7 @@ #include "openPMD/backend/Attributable.hpp" #include "openPMD/IO/AbstractIOHandler.hpp" #include "openPMD/Iteration.hpp" +#include "openPMD/IterationEncoding.hpp" #include "openPMD/ParticleSpecies.hpp" #include "openPMD/RecordComponent.hpp" #include "openPMD/Series.hpp" @@ -150,19 +151,19 @@ Series Attributable::retrieveSeries() const return findSeries->attributable->asInternalCopyOf(); } -auto Attributable::containingIteration() const -> std::pair< +auto Attributable::containingIteration(IterationEncoding ie) const -> std::pair< std::optional, internal::SeriesData const *> { constexpr size_t search_queue_size = 3; - Writable const *search_queue[search_queue_size]{nullptr}; + internal::AttributableData const *search_queue[search_queue_size]{nullptr}; size_t search_queue_idx = 0; - Writable const *findSeries = &writable(); + internal::AttributableData const *findSeries = m_attri.get(); while (true) { search_queue[search_queue_idx] = findSeries; // we don't need to push the last Writable since it's the Series anyway - findSeries = findSeries->parent; + findSeries = findSeries->frontend_parent; if (!findSeries) { break; @@ -174,15 +175,21 @@ auto Attributable::containingIteration() const -> std::pair< } // End of the queue: // Iteration -> Series.iterations -> Series + // in variable-based encoding, Iteration and Series.iterations is the same + // thing, hence: + // Iteration -> Series + size_t distance_to_iteration = + ie == IterationEncoding::variableBased ? 1 : 2; auto *series = &auxiliary::deref_dynamic_cast( - search_queue[search_queue_idx]->attributable); + search_queue[search_queue_idx]); auto maybe_iteration = search_queue - [(search_queue_idx + (search_queue_size - 2)) % search_queue_size]; + [(search_queue_idx + (search_queue_size - distance_to_iteration)) % + search_queue_size]; if (maybe_iteration) { auto *iteration = &auxiliary::deref_dynamic_cast( - maybe_iteration->attributable); + maybe_iteration); return std::make_pair(std::make_optional(iteration), series); } else @@ -191,11 +198,11 @@ auto Attributable::containingIteration() const -> std::pair< } } -auto Attributable::containingIteration() -> std:: +auto Attributable::containingIteration(IterationEncoding ie) -> std:: pair, internal::SeriesData *> { auto const_res = - static_cast(this)->containingIteration(); + static_cast(this)->containingIteration(ie); return std::make_pair( const_res.first.has_value() ? std::make_optional( diff --git a/src/backend/BaseRecordComponent.cpp b/src/backend/BaseRecordComponent.cpp index 3f0f1b35c0..d3a13f189c 100644 --- a/src/backend/BaseRecordComponent.cpp +++ b/src/backend/BaseRecordComponent.cpp @@ -91,7 +91,8 @@ ChunkTable BaseRecordComponent::availableChunks() Offset offset(rc.m_dataset.value().extent.size(), 0); return ChunkTable{{std::move(offset), rc.m_dataset.value().extent}}; } - if (auto iteration_data = containingIteration().first; + if (auto iteration_data = + containingIteration(IOHandler()->m_encoding).first; iteration_data.has_value()) { (*iteration_data)->asInternalCopyOf().open(); diff --git a/src/backend/Writable.cpp b/src/backend/Writable.cpp index 948ff71580..27dca60d2a 100644 --- a/src/backend/Writable.cpp +++ b/src/backend/Writable.cpp @@ -60,7 +60,8 @@ void Writable::seriesFlush(internal::FlushParams const &flushParams) { Attributable impl; impl.setData({attributable, [](auto const *) {}}); - auto [iteration_internal, series_internal] = impl.containingIteration(); + auto [iteration_internal, series_internal] = + impl.containingIteration(impl.IOHandler()->m_encoding); if (iteration_internal) { (*iteration_internal)->asInternalCopyOf().touch(); From e15e4ec6d1c1e59406162e6f8d7bcd49d698ac31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 14:15:26 +0100 Subject: [PATCH 09/14] Fix flushStep() logic --- include/openPMD/Iteration.hpp | 2 +- src/IO/AbstractIOHandlerImpl.cpp | 24 +++++++++++++++++++++++- src/Iteration.cpp | 20 +------------------- src/Series.cpp | 14 +++++++++++--- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index e5d3242dbc..e33c0964b5 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -285,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); /* diff --git a/src/IO/AbstractIOHandlerImpl.cpp b/src/IO/AbstractIOHandlerImpl.cpp index 7675cc3e07..dbb8839f76 100644 --- a/src/IO/AbstractIOHandlerImpl.cpp +++ b/src/IO/AbstractIOHandlerImpl.cpp @@ -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 @@ -301,7 +302,28 @@ std::future 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>; + if constexpr ( + auxiliary::IsArray_v || + auxiliary::IsVector_v) + { + return vec_as_string(val); + } + else + { + std::stringstream res; + res << val; + return res.str(); + } + }, + parameter.resource); + }); writeAttribute(i.writable, parameter); break; } diff --git a/src/Iteration.cpp b/src/Iteration.cpp index b51fadd741..53abad548b 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -290,8 +290,7 @@ void Iteration::flushGroupBased( } } -void Iteration::flushVariableBased( - IterationIndex_t i, internal::FlushParams const &flushParams) +void Iteration::flushVariableBased(internal::FlushParams const &flushParams) { setDirty(true); @@ -305,23 +304,6 @@ void Iteration::flushVariableBased( flush(flushParams); break; } - - // @todo maybe dont repeat this upon each invocation - { - /* - * In v-based encoding, the snapshot attribute must always be written. - * Reason: Even in backends that don't support changing attributes, - * variable-based iteration encoding can be used to write one single - * iteration. Then, this attribute determines which iteration it is. - */ - Parameter wAttr; - wAttr.changesOverSteps = - Parameter::ChangesOverSteps::IfPossible; - wAttr.name = "snapshot"; - wAttr.resource = (unsigned long long)i; - wAttr.dtype = Datatype::ULONGLONG; - IOHandler()->enqueue(IOTask(this, wAttr)); - } } void Iteration::flush(internal::FlushParams const &flushParams) diff --git a/src/Series.cpp b/src/Series.cpp index 92bd973021..a99c7f92ff 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -1521,8 +1521,8 @@ void Series::flushGorVBased( "Iterations must be the same backend object as the " "Iterations themselves."); } - series.m_currentlyActiveIterations.emplace(it->first); } + series.m_currentlyActiveIterations.emplace(it->first); switch (iterationEncoding()) { using IE = IterationEncoding; @@ -1530,7 +1530,7 @@ void Series::flushGorVBased( it->second.flushGroupBased(it->first, flushParams); break; case IE::variableBased: - it->second.flushVariableBased(it->first, flushParams); + it->second.flushVariableBased(flushParams); break; default: throw std::runtime_error( @@ -2636,8 +2636,16 @@ void Series::flushStep(bool doFlush) * one IO step. */ Parameter wAttr; + /* + * In v-based encoding, the snapshot attribute must always be written. + * Reason: Even in backends that don't support changing attributes, + * variable-based iteration encoding can be used to write one single + * iteration. Then, this attribute determines which iteration it is. + */ wAttr.changesOverSteps = - Parameter::ChangesOverSteps::Yes; + iterationEncoding() == IterationEncoding::variableBased + ? Parameter::ChangesOverSteps::IfPossible + : Parameter::ChangesOverSteps::Yes; wAttr.name = "snapshot"; wAttr.resource = std::vector{ series.m_currentlyActiveIterations.begin(), From 6ce3bd764950e4e29fd8ffa84675ed5cfd7d2dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 14:26:06 +0100 Subject: [PATCH 10/14] Link frontend_parent of Iterations to Iterations container --- include/openPMD/Iteration.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index e33c0964b5..84af9d35e2 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -487,6 +487,7 @@ namespace traits 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(); } } }; From cbdde4d23a01c82d7527ed9fbfee791c9172e0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 14:26:18 +0100 Subject: [PATCH 11/14] Revert "Fix Attributable::containingIteration()" This reverts commit 41d950a2d12f6a66b828050c13f045a49b1e808b. --- include/openPMD/backend/Attributable.hpp | 10 ++++------ src/backend/Attributable.cpp | 15 ++++----------- src/backend/BaseRecordComponent.cpp | 3 +-- src/backend/Writable.cpp | 3 +-- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 203fd64a0c..1fc62463d3 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -21,7 +21,6 @@ #pragma once #include "openPMD/IO/AbstractIOHandler.hpp" -#include "openPMD/IterationEncoding.hpp" #include "openPMD/ThrowError.hpp" #include "openPMD/auxiliary/OutOfRangeMsg.hpp" #include "openPMD/backend/Attribute.hpp" @@ -399,11 +398,10 @@ OPENPMD_protected * Throws an error otherwise, e.g., for Series objects. * @{ */ - [[nodiscard]] auto containingIteration(IterationEncoding ie) const - -> std::pair< - std::optional, - internal::SeriesData const *>; - auto containingIteration(IterationEncoding ie) -> std:: + [[nodiscard]] auto containingIteration() const -> std::pair< + std::optional, + internal::SeriesData const *>; + auto containingIteration() -> std:: pair, internal::SeriesData *>; /** @} */ diff --git a/src/backend/Attributable.cpp b/src/backend/Attributable.cpp index ddb0b7a656..608eeccc07 100644 --- a/src/backend/Attributable.cpp +++ b/src/backend/Attributable.cpp @@ -21,7 +21,6 @@ #include "openPMD/backend/Attributable.hpp" #include "openPMD/IO/AbstractIOHandler.hpp" #include "openPMD/Iteration.hpp" -#include "openPMD/IterationEncoding.hpp" #include "openPMD/ParticleSpecies.hpp" #include "openPMD/RecordComponent.hpp" #include "openPMD/Series.hpp" @@ -151,7 +150,7 @@ Series Attributable::retrieveSeries() const return findSeries->attributable->asInternalCopyOf(); } -auto Attributable::containingIteration(IterationEncoding ie) const -> std::pair< +auto Attributable::containingIteration() const -> std::pair< std::optional, internal::SeriesData const *> { @@ -175,16 +174,10 @@ auto Attributable::containingIteration(IterationEncoding ie) const -> std::pair< } // End of the queue: // Iteration -> Series.iterations -> Series - // in variable-based encoding, Iteration and Series.iterations is the same - // thing, hence: - // Iteration -> Series - size_t distance_to_iteration = - ie == IterationEncoding::variableBased ? 1 : 2; auto *series = &auxiliary::deref_dynamic_cast( search_queue[search_queue_idx]); auto maybe_iteration = search_queue - [(search_queue_idx + (search_queue_size - distance_to_iteration)) % - search_queue_size]; + [(search_queue_idx + (search_queue_size - 2)) % search_queue_size]; if (maybe_iteration) { auto *iteration = @@ -198,11 +191,11 @@ auto Attributable::containingIteration(IterationEncoding ie) const -> std::pair< } } -auto Attributable::containingIteration(IterationEncoding ie) -> std:: +auto Attributable::containingIteration() -> std:: pair, internal::SeriesData *> { auto const_res = - static_cast(this)->containingIteration(ie); + static_cast(this)->containingIteration(); return std::make_pair( const_res.first.has_value() ? std::make_optional( diff --git a/src/backend/BaseRecordComponent.cpp b/src/backend/BaseRecordComponent.cpp index d3a13f189c..3f0f1b35c0 100644 --- a/src/backend/BaseRecordComponent.cpp +++ b/src/backend/BaseRecordComponent.cpp @@ -91,8 +91,7 @@ ChunkTable BaseRecordComponent::availableChunks() Offset offset(rc.m_dataset.value().extent.size(), 0); return ChunkTable{{std::move(offset), rc.m_dataset.value().extent}}; } - if (auto iteration_data = - containingIteration(IOHandler()->m_encoding).first; + if (auto iteration_data = containingIteration().first; iteration_data.has_value()) { (*iteration_data)->asInternalCopyOf().open(); diff --git a/src/backend/Writable.cpp b/src/backend/Writable.cpp index 27dca60d2a..948ff71580 100644 --- a/src/backend/Writable.cpp +++ b/src/backend/Writable.cpp @@ -60,8 +60,7 @@ void Writable::seriesFlush(internal::FlushParams const &flushParams) { Attributable impl; impl.setData({attributable, [](auto const *) {}}); - auto [iteration_internal, series_internal] = - impl.containingIteration(impl.IOHandler()->m_encoding); + auto [iteration_internal, series_internal] = impl.containingIteration(); if (iteration_internal) { (*iteration_internal)->asInternalCopyOf().touch(); From c90448a3218421a173d5894137a4768f0606a7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 15:03:00 +0100 Subject: [PATCH 12/14] Add failing test --- test/CoreTest.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test/CoreTest.cpp b/test/CoreTest.cpp index 2c4a0b1680..d23dd92006 100644 --- a/test/CoreTest.cpp +++ b/test/CoreTest.cpp @@ -185,11 +185,12 @@ TEST_CASE("attribute_dtype_test", "[core]") } } -TEST_CASE("myPath", "[core]") +void myPath(std::string const &filename, IterationEncoding ie) { + auto filepath = "../samples/" + filename + ".json"; #if openPMD_USE_INVASIVE_TESTS using vec_t = std::vector; - auto pathOf = [](Attributable &attr) { + auto pathOf = [&](Attributable &attr) { auto res = attr.myPath(); #if false std::cout << "Directory:\t" << res.directory << "\nSeries name:\t" @@ -197,13 +198,14 @@ TEST_CASE("myPath", "[core]") << std::endl; #endif REQUIRE(res.directory == "../samples/"); - REQUIRE(res.seriesName == "myPath"); + REQUIRE(res.seriesName == filename); REQUIRE(res.seriesExtension == ".json"); - REQUIRE(res.filePath() == "../samples/myPath.json"); + REQUIRE(res.filePath() == filepath); return res.group; }; - Series series("../samples/myPath.json", Access::CREATE); + Series series(filepath, Access::CREATE); + series.setIterationEncoding(ie); REQUIRE(pathOf(series) == vec_t{}); auto iteration = series.iterations[1234]; REQUIRE(pathOf(iteration) == vec_t{"iterations", "1234"}); @@ -313,6 +315,13 @@ TEST_CASE("myPath", "[core]") #endif } +TEST_CASE("myPath", "[core]") +{ + myPath("myPath_g", IterationEncoding::groupBased); + myPath("myPath_%T", IterationEncoding::fileBased); + myPath("myPath_v", IterationEncoding::variableBased); +} + TEST_CASE("output_default_test", "[core]") { using IE = IterationEncoding; From bd517763b6956264d12459c161bc91f373ea97ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Wed, 18 Dec 2024 15:08:52 +0100 Subject: [PATCH 13/14] Fix this.. --- include/openPMD/backend/Attributable.hpp | 6 ++++++ include/openPMD/backend/Container.hpp | 8 ++++---- include/openPMD/backend/Writable.hpp | 5 ----- src/Iteration.cpp | 4 ++-- src/ParticleSpecies.cpp | 2 +- src/Series.cpp | 13 +++++++------ src/backend/Attributable.cpp | 10 +++++----- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 1fc62463d3..3b9cbb283e 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -173,6 +173,12 @@ namespace internal * 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 diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index 1b2175d318..4e683fc57d 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -301,11 +301,11 @@ class Container : virtual public Attributable auto &ret = container().insert({key, std::move(t)}).first->second; if constexpr (std::is_same_v) { - 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 gen; gen(ret, this); @@ -342,11 +342,11 @@ class Container : virtual public Attributable auto &ret = container().insert({key, std::move(t)}).first->second; if constexpr (std::is_same_v) { - 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 gen; diff --git a/include/openPMD/backend/Writable.hpp b/include/openPMD/backend/Writable.hpp index 01cdc545dd..bef03a5e7a 100644 --- a/include/openPMD/backend/Writable.hpp +++ b/include/openPMD/backend/Writable.hpp @@ -163,11 +163,6 @@ OPENPMD_private internal::AttributableData *attributable = nullptr; Writable *parent = nullptr; - /** - * 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. * diff --git a/src/Iteration.cpp b/src/Iteration.cpp index 53abad548b..25b6170b69 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -51,8 +51,8 @@ Iteration::Iteration() : Attributable(NoInit()) setTime(static_cast(0)); setDt(static_cast(1)); setTimeUnitSI(1); - meshes.writable().ownKeyWithinParent = "meshes"; - particles.writable().ownKeyWithinParent = "particles"; + meshes.m_attri->ownKeyWithinParent = "meshes"; + particles.m_attri->ownKeyWithinParent = "particles"; } template diff --git a/src/ParticleSpecies.cpp b/src/ParticleSpecies.cpp index 4006cc82ba..fcd97e71a3 100644 --- a/src/ParticleSpecies.cpp +++ b/src/ParticleSpecies.cpp @@ -30,7 +30,7 @@ namespace openPMD { ParticleSpecies::ParticleSpecies() { - particlePatches.writable().ownKeyWithinParent = "particlePatches"; + particlePatches.m_attri->ownKeyWithinParent = "particlePatches"; } void ParticleSpecies::read() diff --git a/src/Series.cpp b/src/Series.cpp index a99c7f92ff..4348c7bb59 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -1111,7 +1111,7 @@ void Series::initSeries( } series.iterations.linkHierarchy(*this); - series.iterations.writable().ownKeyWithinParent = "iterations"; + series.iterations.m_attri->ownKeyWithinParent = "iterations"; series.m_rankTable.m_attributable.linkHierarchy(*this); series.m_name = input->name; @@ -3449,18 +3449,19 @@ namespace debug }; make_indent(); auto const &w = attr.writable(); - std::cout << w.ownKeyWithinParent << '\t' << attr.m_attri.get() - << " -> " << &attr.writable() << '\n'; + std::cout << attr.m_attri->ownKeyWithinParent << '\t' + << attr.m_attri.get() << " -> " << &attr.writable() + << '\n'; make_indent(); std::cout << "Self:\t" << attr.m_attri->dirtySelf << "\tRec: " << attr.m_attri->dirtyRecursive << '\n'; std::cout << '\n'; graph << "{rank = same; "; graph << "_" << attr.m_attri.get() << "[color=green, label = \"A " - << attr.m_attri.get() << " '" << w.ownKeyWithinParent - << "'\"]; "; + << attr.m_attri.get() << " '" + << attr.m_attri->ownKeyWithinParent << "'\"]; "; graph << "_" << &w << "[color=blue, label = \"W " << &w << " '" - << w.ownKeyWithinParent << "'\"]; "; + << attr.m_attri->ownKeyWithinParent << "'\"]; "; graph << "}\n"; graph << "_" << &w << " -> _" << attr.m_attri.get() << "[dir=none];\n"; diff --git a/src/backend/Attributable.cpp b/src/backend/Attributable.cpp index 608eeccc07..a4ae4d3ea0 100644 --- a/src/backend/Attributable.cpp +++ b/src/backend/Attributable.cpp @@ -232,19 +232,19 @@ std::string Attributable::MyPath::openPMDPath() const auto Attributable::myPath() const -> MyPath { MyPath res; - Writable const *findSeries = &writable(); - while (findSeries->parent) + internal::AttributableData *findSeries = m_attri.get(); + while (findSeries->frontend_parent) { // we don't need to push_back the ownKeyWithinParent of the Series class // so it's alright that this loop doesn't ask the key of the last found // Writable res.group.push_back(findSeries->ownKeyWithinParent); - findSeries = findSeries->parent; + findSeries = findSeries->frontend_parent; } std::reverse(res.group.begin(), res.group.end()); - auto &seriesData = auxiliary::deref_dynamic_cast( - findSeries->attributable); + auto &seriesData = + auxiliary::deref_dynamic_cast(findSeries); Series series; series.setData(std::shared_ptr{ &seriesData, [](auto const *) {}}); From 50fded4c212d72716c5f694955d197ff8e4e2617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Thu, 19 Dec 2024 15:26:31 +0100 Subject: [PATCH 14/14] CI fixes --- include/openPMD/Iteration.hpp | 2 +- include/openPMD/backend/Attributable.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index 84af9d35e2..542f0767bb 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -400,7 +400,7 @@ class Iteration : public Attributable /** * @brief Link with parent. * - * @param w The Writable representing the parent. + * @param parent The Writable representing the parent. */ void linkHierarchy(internal::AttributableData &parent) override; using Attributable::linkHierarchy; diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 3b9cbb283e..e89506fc6a 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -600,7 +600,7 @@ OPENPMD_protected /** * @brief Link with parent. * - * @param w The Writable representing the parent. + * @param parent The Writable representing the parent. */ void linkHierarchy(Attributable &parent); virtual void linkHierarchy(internal::AttributableData &parent);