From ad9cd983268d3bf4c725a42a1eaa5e2016b4efc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Thu, 20 Oct 2022 15:14:13 +0200 Subject: [PATCH] Tentatively working version --- include/openPMD/RecordComponent.hpp | 1 + include/openPMD/backend/Attributable.hpp | 2 +- include/openPMD/backend/BaseRecord.hpp | 57 +++++++++++++++---- .../openPMD/backend/BaseRecordComponent.hpp | 2 + .../openPMD/backend/MeshRecordComponent.hpp | 5 ++ .../openPMD/backend/PatchRecordComponent.hpp | 14 ++--- src/RecordComponent.cpp | 3 + src/backend/BaseRecordComponent.cpp | 4 ++ src/backend/MeshRecordComponent.cpp | 14 ++++- src/backend/PatchRecordComponent.cpp | 3 +- test/CoreTest.cpp | 2 + 11 files changed, 83 insertions(+), 24 deletions(-) diff --git a/include/openPMD/RecordComponent.hpp b/include/openPMD/RecordComponent.hpp index d3278dd78a..0e57798876 100644 --- a/include/openPMD/RecordComponent.hpp +++ b/include/openPMD/RecordComponent.hpp @@ -329,6 +329,7 @@ OPENPMD_protected inline internal::RecordComponentData &get() { + datasetDefined(); return *m_recordComponentData; } diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 1b72d206ab..45206790be 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -141,7 +141,7 @@ class Attributable friend class BaseRecord; template friend class BaseRecordInterface; - template + template friend class internal::BaseRecordData; template friend class Container; diff --git a/include/openPMD/backend/BaseRecord.hpp b/include/openPMD/backend/BaseRecord.hpp index 4c6feb2b71..584e34588b 100644 --- a/include/openPMD/backend/BaseRecord.hpp +++ b/include/openPMD/backend/BaseRecord.hpp @@ -71,7 +71,7 @@ namespace internal */ template < typename T_elem_maybe_void, - typename T_RecordComponent = RecordComponent> + typename T_RecordComponent = T_elem_maybe_void> class BaseRecord : public Container< typename auxiliary::OkOr >::type> @@ -91,18 +91,25 @@ class BaseRecord std::shared_ptr > m_baseRecordData{ new internal::BaseRecordData()}; + using Data_t = internal::BaseRecordData; - inline internal::BaseRecordData &get() + inline Data_t &get() { return *m_baseRecordData; } - inline internal::BaseRecordData const & - get() const + inline Data_t const &get() const { return *m_baseRecordData; } + inline void setData(std::shared_ptr data) + { + m_baseRecordData = std::move(data); + T_Container::setData(m_baseRecordData); + T_RecordComponent::setData(m_baseRecordData); + } + BaseRecord(); public: @@ -119,6 +126,14 @@ class BaseRecord using iterator = typename Container::iterator; using const_iterator = typename Container::const_iterator; + // this avoids object slicing + operator T_RecordComponent() const + { + T_RecordComponent res; + res.setData(m_baseRecordData); + return res; + } + virtual ~BaseRecord() = default; mapped_type &operator[](key_type const &key) override; @@ -160,11 +175,13 @@ class BaseRecord // BaseRecord(internal::BaseRecordData *); void readBase(); + void datasetDefined() override; + private: void flush(std::string const &, internal::FlushParams const &) final; virtual void flush_impl(std::string const &, internal::FlushParams const &) = 0; - virtual void read() = 0; + // virtual void read() = 0; /** * @brief Check recursively whether this BaseRecord is dirty. @@ -195,7 +212,8 @@ namespace internal template BaseRecord::BaseRecord() { - Container::setData(m_baseRecordData); + T_Container::setData(m_baseRecordData); + T_RecordComponent::setData(m_baseRecordData); } template @@ -214,12 +232,12 @@ BaseRecord::operator[](key_type const &key) "A scalar component can not be contained at " "the same time as one or more regular components."); - mapped_type &ret = Container::operator[](key); if (keyScalar) { - get().m_containsScalar = true; - ret.parent() = this->parent(); + datasetDefined(); } + mapped_type &ret = keyScalar ? static_cast(*this) + : T_Container::operator[](key); return ret; } } @@ -240,12 +258,15 @@ BaseRecord::operator[](key_type &&key) "A scalar component can not be contained at " "the same time as one or more regular components."); - mapped_type &ret = Container::operator[](std::move(key)); if (keyScalar) { - get().m_containsScalar = true; - ret.parent() = this->parent(); + datasetDefined(); } + /* + * datasetDefined() inits the container entry + */ + mapped_type &ret = keyScalar ? T_Container::at(std::move(key)) + : T_Container::operator[](std::move(key)); return ret; } } @@ -406,4 +427,16 @@ inline bool BaseRecord::dirtyRecursive() const } return false; } + +template +void BaseRecord::datasetDefined() +{ + // If the RecordComponent API of this object has been used, then the record + // is a scalar one + T_RecordComponent copy; + copy.setData(m_baseRecordData); + T_Container::emplace(RecordComponent::SCALAR, std::move(copy)); + get().m_containsScalar = true; + T_RecordComponent::datasetDefined(); +} } // namespace openPMD diff --git a/include/openPMD/backend/BaseRecordComponent.hpp b/include/openPMD/backend/BaseRecordComponent.hpp index c1776604c0..be93c1545c 100644 --- a/include/openPMD/backend/BaseRecordComponent.hpp +++ b/include/openPMD/backend/BaseRecordComponent.hpp @@ -119,6 +119,8 @@ class BaseRecordComponent : virtual public Attributable Attributable::setData(m_baseRecordComponentData); } + virtual void datasetDefined(); + BaseRecordComponent(); }; // BaseRecordComponent diff --git a/include/openPMD/backend/MeshRecordComponent.hpp b/include/openPMD/backend/MeshRecordComponent.hpp index 20f5a9b42a..9cf3e973d8 100644 --- a/include/openPMD/backend/MeshRecordComponent.hpp +++ b/include/openPMD/backend/MeshRecordComponent.hpp @@ -30,6 +30,8 @@ class MeshRecordComponent : public RecordComponent { template friend class Container; + template + friend class BaseRecord; friend class Mesh; @@ -70,6 +72,9 @@ class MeshRecordComponent : public RecordComponent */ template MeshRecordComponent &makeConstant(T); + +protected: + void datasetDefined() override; }; template diff --git a/include/openPMD/backend/PatchRecordComponent.hpp b/include/openPMD/backend/PatchRecordComponent.hpp index 7abfaf9a6e..d4be13fb96 100644 --- a/include/openPMD/backend/PatchRecordComponent.hpp +++ b/include/openPMD/backend/PatchRecordComponent.hpp @@ -92,7 +92,7 @@ OPENPMD_private // clang-format on void flush(std::string const &, internal::FlushParams const &); - void read(); + virtual void read(); /** * @brief Check recursively whether this RecordComponent is dirty. @@ -104,8 +104,8 @@ OPENPMD_private */ bool dirtyRecursive() const; - std::shared_ptr - m_patchRecordComponentData{new internal::PatchRecordComponentData()}; + std::shared_ptr m_recordComponentData{ + new internal::PatchRecordComponentData()}; PatchRecordComponent(); @@ -115,19 +115,19 @@ OPENPMD_protected inline internal::PatchRecordComponentData const &get() const { - return *m_patchRecordComponentData; + return *m_recordComponentData; } inline internal::PatchRecordComponentData &get() { - return *m_patchRecordComponentData; + return *m_recordComponentData; } inline void setData(std::shared_ptr data) { - m_patchRecordComponentData = std::move(data); - BaseRecordComponent::setData(m_patchRecordComponentData); + m_recordComponentData = std::move(data); + BaseRecordComponent::setData(m_recordComponentData); } }; // PatchRecordComponent diff --git a/src/RecordComponent.cpp b/src/RecordComponent.cpp index e24f8f5f23..811d6c295b 100644 --- a/src/RecordComponent.cpp +++ b/src/RecordComponent.cpp @@ -79,6 +79,8 @@ RecordComponent &RecordComponent::resetDataset(Dataset d) throw error::WrongAPIUsage( "[RecordComponent] Must set specific datatype."); } + + datasetDefined(); // if( d.extent.empty() ) // throw std::runtime_error("Dataset extent must be at least 1D."); if (std::any_of( @@ -167,6 +169,7 @@ RecordComponent &RecordComponent::makeEmpty(Dataset d) if (rc.m_dataset.extent.size() == 0) throw std::runtime_error("Dataset extent must be at least 1D."); + datasetDefined(); rc.m_isEmpty = true; dirty() = true; if (!written()) diff --git a/src/backend/BaseRecordComponent.cpp b/src/backend/BaseRecordComponent.cpp index 3f0e5a10de..9a2e94b470 100644 --- a/src/backend/BaseRecordComponent.cpp +++ b/src/backend/BaseRecordComponent.cpp @@ -35,6 +35,7 @@ BaseRecordComponent &BaseRecordComponent::resetDatatype(Datatype d) "A Records Datatype can not (yet) be changed after it has been " "written."); + datasetDefined(); get().m_dataset.dtype = d; return *this; } @@ -69,4 +70,7 @@ BaseRecordComponent::BaseRecordComponent() { Attributable::setData(m_baseRecordComponentData); } + +void BaseRecordComponent::datasetDefined() +{} } // namespace openPMD diff --git a/src/backend/MeshRecordComponent.cpp b/src/backend/MeshRecordComponent.cpp index a3b29a705f..c4600385f4 100644 --- a/src/backend/MeshRecordComponent.cpp +++ b/src/backend/MeshRecordComponent.cpp @@ -23,9 +23,7 @@ namespace openPMD { MeshRecordComponent::MeshRecordComponent() : RecordComponent() -{ - setPosition(std::vector{0}); -} +{} void MeshRecordComponent::read() { @@ -64,6 +62,16 @@ MeshRecordComponent &MeshRecordComponent::setPosition(std::vector pos) return *this; } +void MeshRecordComponent::datasetDefined() +{ + if (access::write(IOHandler()->m_frontendAccess) && + !containsAttribute("position")) + { + setPosition(std::vector{0}); + } + RecordComponent::datasetDefined(); +} + template MeshRecordComponent & MeshRecordComponent::setPosition(std::vector pos); template MeshRecordComponent & diff --git a/src/backend/PatchRecordComponent.cpp b/src/backend/PatchRecordComponent.cpp index 874bb7b180..b50e009dfe 100644 --- a/src/backend/PatchRecordComponent.cpp +++ b/src/backend/PatchRecordComponent.cpp @@ -51,6 +51,7 @@ PatchRecordComponent &PatchRecordComponent::resetDataset(Dataset d) throw std::runtime_error( "Dataset extent must not be zero in any dimension."); + datasetDefined(); get().m_dataset = d; dirty() = true; return *this; @@ -68,7 +69,7 @@ Extent PatchRecordComponent::getExtent() const PatchRecordComponent::PatchRecordComponent() { - BaseRecordComponent::setData(m_patchRecordComponentData); + BaseRecordComponent::setData(m_recordComponentData); setUnitSI(1); } diff --git a/test/CoreTest.cpp b/test/CoreTest.cpp index fa2a1cad42..bc01ebe9da 100644 --- a/test/CoreTest.cpp +++ b/test/CoreTest.cpp @@ -1008,6 +1008,8 @@ TEST_CASE("empty_record_test", "[core]") "RecordComponents: E")); o.iterations[1].meshes["E"][RecordComponent::SCALAR].resetDataset( Dataset(Datatype::DOUBLE, {1})); + auto B = o.iterations[1].meshes["B"]; + B.resetDataset(Dataset(Datatype::DOUBLE, {1})); o.flush(); }