diff --git a/src/opt/hdf5/include/h5_dataset.cc.h b/src/opt/hdf5/include/h5_dataset.cc.h index 0991597..74a3762 100644 --- a/src/opt/hdf5/include/h5_dataset.cc.h +++ b/src/opt/hdf5/include/h5_dataset.cc.h @@ -23,15 +23,9 @@ namespace CNORXZ { const hid_t tid = getTypeId(*data.data()); //VCHECK(tid); - init(data.range(), tid); + //init(data.range(), tid); if(data.begin().formatIsTrivial()){ - Vector dims(mDataRange->dim()); - for(SizeT i = 0; i != dims.size(); ++i){ - dims[i] = mDataRange->sub(i)->size(); - } - const hid_t memspace = H5Screate_simple(dims.size(), dims.data(), NULL); - H5Dwrite(mId, mType, memspace, mFilespace, H5P_DEFAULT, data.data()); - H5Sclose(memspace); + init(data.range(), tid, data.data()); } else { CXZ_ERROR("Got array type with non-trivial format; non-contiguous data formats are not supported yet!"); @@ -47,19 +41,23 @@ namespace CNORXZ template MArray SDataset::read() const { - Vector dims(mDataRange->dim()); - for(SizeT i = 0; i != dims.size(); ++i){ - dims[i] = mDataRange->sub(i)->size(); - } - const hid_t mem_space_id = H5Screate_simple(static_cast(dims.size()), - dims.data(), nullptr); - const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER); MArray out(mDataRange); - const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, out.data()); - CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName - << "', errorcode :" << err); - H5Pclose(xfer_plist_id); - H5Sclose(mem_space_id); + readbase(out.data(), nullptr, nullptr); + return out; + } + + template + template + MArray SDataset::read(const IndexInterface& idx) const + { + CXZ_ASSERT(idx.dim() == mDataRange->dim(), "got index of inconsistent dimension, got" + << idx.dim() << ", expected " << mDataRange->dim()); + const RangePtr outrange = idx.range(); + CXZ_ASSERT(outrange->size() == mDataRange->size(), + "got index of range of inconsistent size, expected " + << mDataRange->size() << ", got " << outrange->size()); + MArray out(outrange); + readbase(out.data(), outrange, nullptr); return out; } @@ -70,43 +68,25 @@ namespace CNORXZ CXZ_ASSERT(beg.dim() == mDataRange->dim(), "got index of inconsistent dimension, got" << beg.dim() << ", expected " << mDataRange->dim()); const RangePtr outrange = beg.prange(end); - Vector dims(outrange->dim()); - for(SizeT i = 0; i != dims.size(); ++i){ - dims[i] = outrange->sub(i)->size(); - } - const Vector fpos = mkFPos(beg); - H5Sselect_hyperslab(mFilespace, H5S_SELECT_SET, fpos.data(), NULL, dims.data(), NULL); - const hid_t mem_space_id = H5Screate_simple(static_cast(dims.size()), - dims.data(), nullptr); - const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER); MArray out(outrange); - const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, out.data()); - CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName - << "', errorcode :" << err); - H5Pclose(xfer_plist_id); - H5Sclose(mem_space_id); + readbase(out.data(), outrange, toYptr(beg)); return out; } template template - Vector SDataset::mkFPos(const IndexInterface& beg) const + Sptr SDataset::toYptr(const IndexInterface& beg) const { - Vector fpos(beg.dim()); - if constexpr(has_static_sub::value){ - iter<0,index_dim::value> ( [&](auto i) { fpos[i] = beg.THIS().pack().get(i)->lex(); }, NoF{} ); + if constexpr(std::is_same::value){ + return std::make_shared(beg.THIS()); } - else if constexpr(has_sub::value){ - for(SizeT i = 0; i != beg.dim(); ++i){ - fpos[i] = beg.THIS().pack().get(i)->lex(); - } + else if constexpr(has_sub::value) { + return yindexPtr(beg.pack()); } else { - fpos[0] = beg.lex(); + return yindexPtr(DPack(std::make_shared(beg))); } - return fpos; } - } } diff --git a/src/opt/hdf5/include/h5_dataset.h b/src/opt/hdf5/include/h5_dataset.h index 671af1b..ddd2079 100644 --- a/src/opt/hdf5/include/h5_dataset.h +++ b/src/opt/hdf5/include/h5_dataset.h @@ -48,8 +48,22 @@ namespace CNORXZ @param dataRange A potentially multi-dimensional range characterizing the dataset. @param type Data type id. */ - Dataset& init(const RangePtr& dataRange, hid_t type); + virtual Dataset& init(const RangePtr& dataRange, hid_t type); + /** Initalize the dataset. + @param dataRange A potentially multi-dimensional range characterizing the dataset. + @param type Data type id. + @param data Pointer to raw data. + */ + virtual Dataset& init(const RangePtr& dataRange, hid_t type, const void* data); + + /** Read the dataset. + @param dest Pointer to destination. + @param readrange Range of the destination data. + @param beg Position within the file space. + */ + virtual void readbase(void* dest, RangePtr readrange, Sptr beg) const; + /** Initalize the dataset. @param data Array containing the dataset. */ @@ -62,6 +76,8 @@ namespace CNORXZ const RangePtr& dataRange() const; protected: + Vector mkOff(const Sptr& beg) const; + RangePtr mDataRange; /**< The data range. */ hid_t mType; /**< The data type identifier. */ hid_t mFilespace; /**< The hdf5 file space identifier. */ @@ -89,6 +105,14 @@ namespace CNORXZ */ MArray read() const; + /** Read the dataset using range of given index. + The index position is ignored. + @param idx Index specifying the range type. + @return Array containing the dataset values. + */ + template + MArray read(const IndexInterface& idx) const; + /** Read a given subset of the dataset. The subset needs to be hypercubic. @param beg Index indicating the begin edge of the hypercube. @@ -100,8 +124,10 @@ namespace CNORXZ private: + //template + //Vector mkFPos(const IndexInterface& beg) const; template - Vector mkFPos(const IndexInterface& beg) const; + Sptr toYptr(const IndexInterface& beg) const; }; } } diff --git a/src/opt/hdf5/lib/h5_dataset.cc b/src/opt/hdf5/lib/h5_dataset.cc index a3ef41d..c944aeb 100644 --- a/src/opt/hdf5/lib/h5_dataset.cc +++ b/src/opt/hdf5/lib/h5_dataset.cc @@ -105,10 +105,57 @@ namespace CNORXZ return *this; } + Dataset& Dataset::init(const RangePtr& dataRange, hid_t type, const void* data) + { + init(dataRange, type); + Vector dims(mDataRange->dim()); + for(SizeT i = 0; i != dims.size(); ++i){ + dims[i] = mDataRange->sub(i)->size(); + } + const hid_t memspace = H5Screate_simple(dims.size(), dims.data(), NULL); + H5Dwrite(mId, mType, memspace, mFilespace, H5P_DEFAULT, data); + H5Sclose(memspace); + return *this; + } + + void Dataset::readbase(void* dest, RangePtr readrange, Sptr beg) const + { + // TODO: Check if readrange is compatible with mDataRange!!! + if(not readrange){ + readrange = mDataRange; + } + Vector dims(readrange->dim()); + for(SizeT i = 0; i != dims.size(); ++i){ + dims[i] = readrange->sub(i)->size(); + } + if(beg){ + const Vector fpos = mkOff(beg); + H5Sselect_hyperslab(mFilespace, H5S_SELECT_SET, fpos.data(), NULL, dims.data(), NULL); + } + const hid_t mem_space_id = H5Screate_simple(static_cast(dims.size()), + dims.data(), nullptr); + const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER); + //MArray out(readrange); + const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, dest); + CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName + << "', errorcode :" << err); + H5Pclose(xfer_plist_id); + H5Sclose(mem_space_id); + } + const RangePtr& Dataset::dataRange() const { return mDataRange; } + Vector Dataset::mkOff(const Sptr& beg) const + { + Vector off(beg->dim()); + for(SizeT i = 0; i != beg->dim(); ++i){ + off[i] = beg->pack().get(i)->lex(); + } + return off; + } + } }