From e6da712482021a111e03d5793e9f1bf199fd0309 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Wed, 18 Jan 2023 00:49:11 +0100 Subject: [PATCH] ranges: extend + array: init + extend + hdf5: adapt --- src/include/array/marray.cc.h | 23 ++++++ src/include/array/marray.h | 2 + src/include/ranges/crange.h | 1 + src/include/ranges/mrange.cc.h | 13 ++++ src/include/ranges/mrange.h | 1 + src/include/ranges/range_base.h | 1 + src/include/ranges/urange.cc.h | 9 +++ src/include/ranges/urange.h | 1 + src/include/ranges/xindex.cc.h | 12 +++ src/include/ranges/xindex.h | 3 + src/include/ranges/yrange.h | 1 + src/lib/ranges/crange.cc | 6 ++ src/lib/ranges/yrange.cc | 11 +++ src/opt/hdf5/include/h5_content_base.h | 5 +- src/opt/hdf5/include/h5_file.h | 14 ++-- src/opt/hdf5/include/h5_group.h | 29 ++++--- src/opt/hdf5/lib/h5_file.cc | 88 +++++---------------- src/opt/hdf5/lib/h5_group.cc | 98 +++++++++++++++++------- src/opt/hdf5/tests/h5_basic_unit_test.cc | 16 +++- 19 files changed, 210 insertions(+), 124 deletions(-) diff --git a/src/include/array/marray.cc.h b/src/include/array/marray.cc.h index 6925645..3310586 100644 --- a/src/include/array/marray.cc.h +++ b/src/include/array/marray.cc.h @@ -25,6 +25,29 @@ namespace CNORXZ ArrayBase(range), mCont(vec) {} + template + MArray& MArray::init(const RangePtr& range) + { + AB::mRange = rangeCast(range); + mCont.resize(AB::mRange->size()); + return *this; + } + + template + MArray& MArray::extend(const RangePtr& range) + { + MArray tmp(AB::mRange->extend(range)); + auto ei = this->end(); + auto ti = tmp.begin(); + // this is not very efficient; remove by sub-index operation once available: + for(auto ii = this->begin(); ii != ei; ++ii){ + ti.at(ii.meta()); + *ti = *ii; + } + *this = std::move(tmp); + return *this; + } + template const T* MArray::data() const { diff --git a/src/include/array/marray.h b/src/include/array/marray.h index 118f80b..c272cd4 100644 --- a/src/include/array/marray.h +++ b/src/include/array/marray.h @@ -21,6 +21,8 @@ namespace CNORXZ MArray(const RangePtr& range); MArray(const RangePtr& range, const Vector& vec); MArray(const RangePtr& range, Vector&& vec); + MArray& init(const RangePtr& range); + MArray& extend(const RangePtr& range); virtual const T* data() const override; virtual T* data() override; diff --git a/src/include/ranges/crange.h b/src/include/ranges/crange.h index 1085dea..549bca6 100644 --- a/src/include/ranges/crange.h +++ b/src/include/ranges/crange.h @@ -88,6 +88,7 @@ namespace CNORXZ virtual String stringMeta(SizeT pos) const override final; virtual const TypeInfo& type() const override final; virtual const TypeInfo& metaType() const override final; + virtual RangePtr extend(const RangePtr& r) const override final; SizeT get(SizeT pos) const; SizeT getMeta(SizeT metaPos) const; diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 6e0a748..32225f3 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -594,6 +594,19 @@ namespace CNORXZ return i.at(metaPos).pos(); } + template + RangePtr MRange::extend(const RangePtr& r) const + { + CXZ_ASSERT( r->dim() == this->dim(), "cannot extend range of dimension " + << this->dim() << " by range of dimension " << r->dim()); + auto rs = iter<0,NR>( [&](auto i) { + typedef typename std::remove_reference(mRs))>::type RType; + return std::dynamic_pointer_cast( std::get(mRs)->extend(r->sub(i)) ); }, + [](const auto&... e) { return std::make_tuple(e...); } + ); + return MRangeFactory( rs ).create(); + } + /************************ * MRange (private) * ************************/ diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index da24aab..dd80c28 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -179,6 +179,7 @@ namespace CNORXZ virtual String stringMeta(SizeT pos) const override final; virtual const TypeInfo& type() const override final; virtual const TypeInfo& metaType() const override final; + virtual RangePtr extend(const RangePtr& r) const override final; decltype(auto) space() const; const MetaType get(SizeT pos) const; diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h index 15ca474..cb51dc8 100644 --- a/src/include/ranges/range_base.h +++ b/src/include/ranges/range_base.h @@ -53,6 +53,7 @@ namespace CNORXZ virtual const TypeInfo& metaType() const = 0; virtual String stringMeta(SizeT pos) const = 0; virtual DIndex index(SizeT pos = 0) const = 0; + virtual RangePtr extend(const RangePtr& r) const = 0; bool operator==(const RangeBase& in) const; bool operator!=(const RangeBase& in) const; diff --git a/src/include/ranges/urange.cc.h b/src/include/ranges/urange.cc.h index 4964586..f9d51e8 100644 --- a/src/include/ranges/urange.cc.h +++ b/src/include/ranges/urange.cc.h @@ -273,6 +273,15 @@ namespace CNORXZ return typeid(MetaType); } + template + RangePtr URange::extend(const RangePtr& r) const + { + auto rx = rangeCast>(r); + auto space = mSpace; + space.insert(space.end(), rx->mSpace.begin(), rx->mSpace.end()); + return URangeFactory( space ).create(); + } + /******************* * Range Casts * *******************/ diff --git a/src/include/ranges/urange.h b/src/include/ranges/urange.h index b6493e1..39e5471 100644 --- a/src/include/ranges/urange.h +++ b/src/include/ranges/urange.h @@ -95,6 +95,7 @@ namespace CNORXZ virtual String stringMeta(SizeT pos) const override final; virtual const TypeInfo& type() const override final; virtual const TypeInfo& metaType() const override final; + virtual RangePtr extend(const RangePtr& r) const override final; const MetaType& get(SizeT pos) const; SizeT getMeta(const MetaType& metaPos) const; diff --git a/src/include/ranges/xindex.cc.h b/src/include/ranges/xindex.cc.h index 6996244..589c3ec 100644 --- a/src/include/ranges/xindex.cc.h +++ b/src/include/ranges/xindex.cc.h @@ -216,6 +216,18 @@ namespace CNORXZ return DXpr(mI->ifor(xpr, std::forward>(f))); } + template + Index& XIndex::get() + { + return mI->THIS(); + } + + template + const Index& XIndex::get() const + { + return mI->THIS(); + } + template inline XIndexPtr xindexPtr(const Sptr& i) { diff --git a/src/include/ranges/xindex.h b/src/include/ranges/xindex.h index 663e084..02eca13 100644 --- a/src/include/ranges/xindex.h +++ b/src/include/ranges/xindex.h @@ -101,6 +101,9 @@ namespace CNORXZ virtual DXpr ifor(const DXpr& xpr, std::function&& f) const override final; + Index& get(); + const Index& get() const; + private: IndexPtr mI; diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index 371899f..a7fe749 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -123,6 +123,7 @@ namespace CNORXZ virtual String stringMeta(SizeT pos) const override final; virtual const TypeInfo& type() const override final; virtual const TypeInfo& metaType() const override final; + virtual RangePtr extend(const RangePtr& r) const override final; private: diff --git a/src/lib/ranges/crange.cc b/src/lib/ranges/crange.cc index 9f3dc03..2d4182d 100644 --- a/src/lib/ranges/crange.cc +++ b/src/lib/ranges/crange.cc @@ -172,6 +172,12 @@ namespace CNORXZ return typeid(SizeT); } + RangePtr CRange::extend(const RangePtr& r) const + { + auto rx = rangeCast(r); + return CRangeFactory( this->size() + rx->size() ).create(); + } + /******************* * Range Casts * *******************/ diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index 5ff3c45..1699712 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -484,6 +484,17 @@ namespace CNORXZ return typeid(DType); } + RangePtr YRange::extend(const RangePtr& r) const + { + CXZ_ASSERT(r->dim() == this->dim(), "cannot extend range of dimension " + << this->dim() << " by range of dimension " << r->dim()); + Vector rvec(this->dim()); + for(SizeT i = 0; i != this->dim(); ++i){ + rvec[i] = mRVec[i]->extend( r->sub(i) ); + } + return YRangeFactory( rvec ).create(); + } + YRange::YRange(const Vector& rvec) : mRVec(rvec) {} YRange::YRange(Vector&& rvec) : mRVec(std::forward>(rvec)) {} diff --git a/src/opt/hdf5/include/h5_content_base.h b/src/opt/hdf5/include/h5_content_base.h index bf18bce..3685936 100644 --- a/src/opt/hdf5/include/h5_content_base.h +++ b/src/opt/hdf5/include/h5_content_base.h @@ -27,11 +27,9 @@ namespace CNORXZ virtual ContentType type() const = 0; virtual bool ro() const = 0; - virtual ContentBase& load() = 0; + virtual ContentBase& open() = 0; virtual ContentBase& write() = 0; virtual ContentBase& close() = 0; - virtual MArray>* get() = 0; - virtual const MArray>* get() const = 0; virtual String path() const = 0; virtual String filename() const = 0; @@ -39,6 +37,7 @@ namespace CNORXZ const ContentBase* parent() const; RangePtr range() const; hid_t id() const; + inline bool isOpen() const { return mId != 0; } protected: String mName; diff --git a/src/opt/hdf5/include/h5_file.h b/src/opt/hdf5/include/h5_file.h index c312f9a..5c0a5f7 100644 --- a/src/opt/hdf5/include/h5_file.h +++ b/src/opt/hdf5/include/h5_file.h @@ -3,14 +3,15 @@ #define __cxz_h5_file_h__ #include "h5_content_base.h" -#include +#include "h5_group.h" +//#include namespace CNORXZ { namespace hdf5 { // maybe introduce abstraction layer between as base for File and Group - class File : public ContentBase + class File : public Group { public: typedef URange RangeT; @@ -21,21 +22,16 @@ namespace CNORXZ virtual ContentType type() const override final; virtual bool ro() const override final; - virtual File& load() override final; + virtual File& open() override final; virtual File& write() override final; virtual File& close() override final; - virtual MArray>* get() override final; - virtual const MArray>* get() const override final; virtual String path() const override final; virtual String filename() const override final; - Int exists() const; - File& set(const RangePtr& range); - File& append(const String& cname); + virtual Int exists() const override final; private: bool mRo = true; - MArray mCont; }; } } diff --git a/src/opt/hdf5/include/h5_group.h b/src/opt/hdf5/include/h5_group.h index e46c1cc..da870c5 100644 --- a/src/opt/hdf5/include/h5_group.h +++ b/src/opt/hdf5/include/h5_group.h @@ -15,21 +15,26 @@ namespace CNORXZ Group(const String& gname, const ContentBase* _parent); ~Group(); - virtual ContentType type() const override final; - virtual bool ro() const override final; - virtual Group& load() override final; - virtual Group& write() override final; - virtual Group& close() override final; - virtual MArray>* get() override final; - virtual const MArray>* get() const override final; - virtual String path() const override final; - virtual String filename() const override final; + virtual ContentType type() const override; + virtual bool ro() const override; + virtual Group& open() override; // load group if existing, else create new group + virtual Group& write() override; + virtual Group& close() override; + virtual String path() const override; + virtual String filename() const override; - bool exists() const; - Group& append(const ContentPtr& c); + virtual Int exists() const; + + const MArray& get() const; + Group& addGroup(const String& name); + + template + Group& addData(const String& name, const ArrayBase& data); - private: + protected: MArray mCont; + + void mkCont(); }; } diff --git a/src/opt/hdf5/lib/h5_file.cc b/src/opt/hdf5/lib/h5_file.cc index 48b389a..3f400ee 100644 --- a/src/opt/hdf5/lib/h5_file.cc +++ b/src/opt/hdf5/lib/h5_file.cc @@ -7,8 +7,26 @@ namespace CNORXZ namespace hdf5 { File::File(const String& fname, bool _ro) : - ContentBase(fname), + Group(fname, nullptr), mRo(_ro) + {} + + File::~File() + { + this->close(); + } + + ContentType File::type() const + { + return ContentType::FILE; + } + + bool File::ro() const + { + return mRo; + } + + File& File::open() { Int ex = this->exists(); const String fn = this->filename(); @@ -27,27 +45,7 @@ namespace CNORXZ } } CXZ_ASSERT( mId > 0, "error while opening file '" << fn << "'" ); - } - - File::~File() - { - this->close(); - } - - ContentType File::type() const - { - return ContentType::FILE; - } - - bool File::ro() const - { - return mRo; - } - - File& File::load() - { - // !!! - + this->mkCont(); return *this; } @@ -75,16 +73,6 @@ namespace CNORXZ return *this; } - MArray>* File::get() - { - return &mCont; - } - - const MArray>* File::get() const - { - return &mCont; - } - String File::path() const { return String("/"); @@ -111,41 +99,5 @@ namespace CNORXZ return ex; } - File& File::set(const RangePtr& range) - { - if(mCont.range() != nullptr){ - CXZ_ERROR("IMPLEMENT"); - // operator+ for RangePtr!!! - } - else { - mCont = MArray(range); - } - return *this; - } - - File& File::append(const String& cname) - { - if(mCont.range() != nullptr){ - auto oldrange = std::dynamic_pointer_cast>(mCont.range()); - Vector names(oldrange->size()); - for(auto i = oldrange->begin(); i != oldrange->end(); ++i){ - names[i.lex()] = *i; - } - names[names.size()-1] = cname; - auto range = URangeFactory( names ).create(); - MArray ncont( range ); - auto j = ncont.begin(); - for(auto i = mCont.begin(); i != mCont.end(); ++i){ - j.at( i.meta() ); - ncont[j] = mCont[i]; - } - mCont = ncont; - } - else { - auto range = URangeFactory( Vector({cname}) ).create(); - mCont = MArray( range ); - } - return *this; - } } } diff --git a/src/opt/hdf5/lib/h5_group.cc b/src/opt/hdf5/lib/h5_group.cc index 0709bd0..3a512b8 100644 --- a/src/opt/hdf5/lib/h5_group.cc +++ b/src/opt/hdf5/lib/h5_group.cc @@ -7,21 +7,11 @@ namespace CNORXZ { Group::Group(const String& gname, const ContentBase* _parent) : ContentBase(gname, _parent) - { - if(this->exists()){ - mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT ); - } - else { - mId = H5Gcreate( mParent->id(), mName.c_str(), - H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ); - } - } + {} Group::~Group() { - if(mId != 0){ - H5Gclose(mId); - } + this->close(); } ContentType Group::type() const @@ -37,9 +27,16 @@ namespace CNORXZ return false; } - Group& Group::load() + Group& Group::open() { - // load content!!! + if(this->exists()){ + mId = H5Gopen( mParent->id(), mName.c_str(), H5P_DEFAULT ); + } + else { + mId = H5Gcreate( mParent->id(), mName.c_str(), + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ); + } + this->mkCont(); return *this; } @@ -51,19 +48,12 @@ namespace CNORXZ Group& Group::close() { + if(mId != 0){ + H5Gclose(mId); + } return *this; } - MArray>* Group::get() - { - return &mCont; - } - - const MArray>* Group::get() const - { - return &mCont; - } - String Group::path() const { if(mParent){ @@ -80,15 +70,67 @@ namespace CNORXZ return String(); } - bool Group::exists() const + Int Group::exists() const { - return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) != 0; + return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) != 0 ? 1 : 0; } - Group& Group::append(const ContentPtr& c) + const MArray& Group::get() const { + return mCont; + } - return *this; + struct InitContData + { + const ContentBase* parent; + BIndex index; + }; + + static herr_t addName(hid_t id, const char* name, const H5L_info_t* info, void* x) + { + Vector* names = reinterpret_cast*>(x); + names->push_back(String(name)); + return 0; + } + + static herr_t initCont(hid_t id, const char* name, const H5L_info_t* info, void* x) + { + const String sname(name); + InitContData* icd = reinterpret_cast(x); + BIndex& index = icd->index; + UIndex& ui = std::dynamic_pointer_cast,String>> + (index.pack()[0])->get(); + ui.at(sname); + index(); + H5O_info_t oinfo; + H5Oget_info(id, &oinfo, H5O_INFO_BASIC); + switch (oinfo.type) { + case H5O_TYPE_GROUP: { + *index = std::make_shared(sname, icd->parent); + break; + }/* + case H5O_TYPE_DATASET: { + *index = std::make_shared(sname, ); + break; + }*/ + default: + return 1; + } + return 0; + } + + void Group::mkCont() + { + Vector names; + H5Literate( mId, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, + addName, reinterpret_cast(&names) ); + mCont.init( URangeFactory( names ).create() ); + + InitContData icd; + icd.index = mCont.begin(); + icd.parent = this; + H5Literate( mId, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, + initCont, reinterpret_cast(&icd) ); } } diff --git a/src/opt/hdf5/tests/h5_basic_unit_test.cc b/src/opt/hdf5/tests/h5_basic_unit_test.cc index 7496ab0..5635d55 100644 --- a/src/opt/hdf5/tests/h5_basic_unit_test.cc +++ b/src/opt/hdf5/tests/h5_basic_unit_test.cc @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "gtest/gtest.h" @@ -12,7 +12,6 @@ namespace { using namespace CNORXZ; using namespace CNORXZ::hdf5; - namespace sfs = std::filesystem; class NoFile_Test : public ::testing::Test { @@ -38,10 +37,12 @@ namespace Group_Test() { mFileName = "test_file.h5"; - sfs::remove(mFileName); + std::remove(mFileName.c_str()); + mGrps = { "gr1", "gr2" }; } String mFileName; + Vector mGrps; }; TEST_F(NoFile_Test, NoFile) @@ -63,12 +64,19 @@ namespace File h5f(mFileName, false); EXPECT_FALSE(h5f.ro()); //h5f.append("gr1"); - auto grange = URangeFactory( Vector( { "gr1", "gr2" } ) ).create(); + auto grange = URangeFactory( mGrps ).create(); h5f.set( grange ); for(auto i = grange->begin(); i != grange->end(); ++i){ (*h5f.get())[i] = std::make_shared( i.meta().str(), &h5f ); } } + + TEST_F(Group_Test, Read) + { + File h5f(mFileName, true); + EXPECT_TRUE(h5f.ro()); + + } } // check write to new file