hdf5: some reorganization of the code + new member functions

This commit is contained in:
Christian Zimmermann 2024-10-29 00:56:17 -07:00
parent 8b66ad04ba
commit b4ab639747
3 changed files with 100 additions and 47 deletions

View file

@ -23,15 +23,9 @@ namespace CNORXZ
{ {
const hid_t tid = getTypeId(*data.data()); const hid_t tid = getTypeId(*data.data());
//VCHECK(tid); //VCHECK(tid);
init(data.range(), tid); //init(data.range(), tid);
if(data.begin().formatIsTrivial()){ if(data.begin().formatIsTrivial()){
Vector<hsize_t> dims(mDataRange->dim()); init(data.range(), tid, data.data());
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);
} }
else { else {
CXZ_ERROR("Got array type with non-trivial format; non-contiguous data formats are not supported yet!"); CXZ_ERROR("Got array type with non-trivial format; non-contiguous data formats are not supported yet!");
@ -47,19 +41,23 @@ namespace CNORXZ
template <typename T> template <typename T>
MArray<T> SDataset<T>::read() const MArray<T> SDataset<T>::read() const
{ {
Vector<hsize_t> 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<hsize_t>(dims.size()),
dims.data(), nullptr);
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
MArray<T> out(mDataRange); MArray<T> out(mDataRange);
const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, out.data()); readbase(out.data(), nullptr, nullptr);
CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName return out;
<< "', errorcode :" << err); }
H5Pclose(xfer_plist_id);
H5Sclose(mem_space_id); template <typename T>
template <class I, typename M>
MArray<T> SDataset<T>::read(const IndexInterface<I,M>& 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<T> out(outrange);
readbase(out.data(), outrange, nullptr);
return out; return out;
} }
@ -70,43 +68,25 @@ namespace CNORXZ
CXZ_ASSERT(beg.dim() == mDataRange->dim(), "got index of inconsistent dimension, got" CXZ_ASSERT(beg.dim() == mDataRange->dim(), "got index of inconsistent dimension, got"
<< beg.dim() << ", expected " << mDataRange->dim()); << beg.dim() << ", expected " << mDataRange->dim());
const RangePtr outrange = beg.prange(end); const RangePtr outrange = beg.prange(end);
Vector<hsize_t> dims(outrange->dim());
for(SizeT i = 0; i != dims.size(); ++i){
dims[i] = outrange->sub(i)->size();
}
const Vector<hsize_t> 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<hsize_t>(dims.size()),
dims.data(), nullptr);
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
MArray<T> out(outrange); MArray<T> out(outrange);
const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, out.data()); readbase(out.data(), outrange, toYptr(beg));
CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName
<< "', errorcode :" << err);
H5Pclose(xfer_plist_id);
H5Sclose(mem_space_id);
return out; return out;
} }
template <typename T> template <typename T>
template <class I, typename M> template <class I, typename M>
Vector<hsize_t> SDataset<T>::mkFPos(const IndexInterface<I,M>& beg) const Sptr<YIndex> SDataset<T>::toYptr(const IndexInterface<I,M>& beg) const
{ {
Vector<hsize_t> fpos(beg.dim()); if constexpr(std::is_same<YIndex,I>::value){
if constexpr(has_static_sub<I>::value){ return std::make_shared<YIndex>(beg.THIS());
iter<0,index_dim<I>::value> ( [&](auto i) { fpos[i] = beg.THIS().pack().get(i)->lex(); }, NoF{} );
} }
else if constexpr(has_sub<I>::value){ else if constexpr(has_sub<I>::value) {
for(SizeT i = 0; i != beg.dim(); ++i){ return yindexPtr(beg.pack());
fpos[i] = beg.THIS().pack().get(i)->lex();
}
} }
else { else {
fpos[0] = beg.lex(); return yindexPtr(DPack(std::make_shared<I>(beg)));
} }
return fpos;
} }
} }
} }

View file

@ -48,7 +48,21 @@ namespace CNORXZ
@param dataRange A potentially multi-dimensional range characterizing the dataset. @param dataRange A potentially multi-dimensional range characterizing the dataset.
@param type Data type id. @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<YIndex> beg) const;
/** Initalize the dataset. /** Initalize the dataset.
@param data Array containing the dataset. @param data Array containing the dataset.
@ -62,6 +76,8 @@ namespace CNORXZ
const RangePtr& dataRange() const; const RangePtr& dataRange() const;
protected: protected:
Vector<hsize_t> mkOff(const Sptr<YIndex>& beg) const;
RangePtr mDataRange; /**< The data range. */ RangePtr mDataRange; /**< The data range. */
hid_t mType; /**< The data type identifier. */ hid_t mType; /**< The data type identifier. */
hid_t mFilespace; /**< The hdf5 file space identifier. */ hid_t mFilespace; /**< The hdf5 file space identifier. */
@ -89,6 +105,14 @@ namespace CNORXZ
*/ */
MArray<T> read() const; MArray<T> 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 <class I, typename M>
MArray<T> read(const IndexInterface<I,M>& idx) const;
/** Read a given subset of the dataset. /** Read a given subset of the dataset.
The subset needs to be hypercubic. The subset needs to be hypercubic.
@param beg Index indicating the begin edge of the hypercube. @param beg Index indicating the begin edge of the hypercube.
@ -100,8 +124,10 @@ namespace CNORXZ
private: private:
//template <class I, typename M>
//Vector<hsize_t> mkFPos(const IndexInterface<I,M>& beg) const;
template <class I, typename M> template <class I, typename M>
Vector<hsize_t> mkFPos(const IndexInterface<I,M>& beg) const; Sptr<YIndex> toYptr(const IndexInterface<I,M>& beg) const;
}; };
} }
} }

View file

@ -105,10 +105,57 @@ namespace CNORXZ
return *this; return *this;
} }
Dataset& Dataset::init(const RangePtr& dataRange, hid_t type, const void* data)
{
init(dataRange, type);
Vector<hsize_t> 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<YIndex> beg) const
{
// TODO: Check if readrange is compatible with mDataRange!!!
if(not readrange){
readrange = mDataRange;
}
Vector<hsize_t> dims(readrange->dim());
for(SizeT i = 0; i != dims.size(); ++i){
dims[i] = readrange->sub(i)->size();
}
if(beg){
const Vector<hsize_t> 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<hsize_t>(dims.size()),
dims.data(), nullptr);
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
//MArray<T> 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 const RangePtr& Dataset::dataRange() const
{ {
return mDataRange; return mDataRange;
} }
Vector<hsize_t> Dataset::mkOff(const Sptr<YIndex>& beg) const
{
Vector<hsize_t> off(beg->dim());
for(SizeT i = 0; i != beg->dim(); ++i){
off[i] = beg->pack().get(i)->lex();
}
return off;
}
} }
} }