hdf5: several fixes + yrange: add setSub member function + dindex: add missing operator*(dindex,index)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
parent
6f3601daa4
commit
eb3055ddca
9 changed files with 104 additions and 12 deletions
|
@ -5,7 +5,7 @@
|
||||||
@brief ...
|
@brief ...
|
||||||
|
|
||||||
|
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -40,6 +40,12 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class I>
|
||||||
|
decltype(auto) operator*(const Sptr<DIndex>& a, const Sptr<I>& b)
|
||||||
|
{
|
||||||
|
return iptrMul(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
template <class I>
|
template <class I>
|
||||||
I indexAs(const DIndex& i)
|
I indexAs(const DIndex& i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
/**
|
/**
|
||||||
|
|
||||||
@file include/ranges/dindex.h
|
@file include/ranges/dindex.h
|
||||||
@brief ...
|
@brief DIndex declaration
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
Copyright (c) 2022 Christian Zimmermann. All rights reserved.
|
|
||||||
Mail: chizeta@f3l.de
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -154,6 +153,13 @@ namespace CNORXZ
|
||||||
XIndexPtr mI;
|
XIndexPtr mI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Make index pack of a DIndex and another index.
|
||||||
|
@param a pointer to DIndex.
|
||||||
|
@param b pointer to another index.
|
||||||
|
*/
|
||||||
|
template <class I>
|
||||||
|
decltype(auto) operator*(const Sptr<DIndex>& a, const Sptr<I>& b);
|
||||||
|
|
||||||
/** Trait-specialization:
|
/** Trait-specialization:
|
||||||
DIndex can have sub-indices
|
DIndex can have sub-indices
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -186,6 +186,12 @@ namespace CNORXZ
|
||||||
*/
|
*/
|
||||||
YIndex& setFormat(const YFormat& bs);
|
YIndex& setFormat(const YFormat& bs);
|
||||||
|
|
||||||
|
/** Set position of given sub index and update total index position.
|
||||||
|
@param ind Sub-index number [0,dim()-1].
|
||||||
|
@param lex Lexicographic position to be assigned to the index.
|
||||||
|
*/
|
||||||
|
YIndex& setSub(SizeT ind, SizeT lex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline Vector<SizeT> mkFormat() const;
|
inline Vector<SizeT> mkFormat() const;
|
||||||
inline Vector<SizeT> mkLexFormat() const;
|
inline Vector<SizeT> mkLexFormat() const;
|
||||||
|
|
|
@ -494,6 +494,19 @@ namespace CNORXZ
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YIndex& YIndex::setSub(SizeT ind, SizeT lex)
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(ind < dim(), "got index number (" << ind << ") larger than dimension ("
|
||||||
|
<< dim() << ")");
|
||||||
|
auto& idx = mIs[ind];
|
||||||
|
CXZ_ASSERT(lex < idx->lmax().val(), "tried to set sub-index position " << lex
|
||||||
|
<< ", which is out of scope; maximum position in range is " << idx->lmax().val() );
|
||||||
|
(*idx) = lex;
|
||||||
|
(*this)();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
* non-member functions *
|
* non-member functions *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace CNORXZ
|
||||||
Dataset& Dataset::init(const ArrayBase<T>& data)
|
Dataset& Dataset::init(const ArrayBase<T>& data)
|
||||||
{
|
{
|
||||||
const hid_t tid = getTypeId(*data.data());
|
const hid_t tid = getTypeId(*data.data());
|
||||||
|
VCHECK(tid);
|
||||||
init(data.range(), tid);
|
init(data.range(), tid);
|
||||||
if(data.begin().formatIsTrivial()){
|
if(data.begin().formatIsTrivial()){
|
||||||
Vector<hsize_t> dims(mDataRange->dim());
|
Vector<hsize_t> dims(mDataRange->dim());
|
||||||
|
@ -83,11 +84,11 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
Vector<hsize_t> fpos(beg.dim());
|
Vector<hsize_t> fpos(beg.dim());
|
||||||
if constexpr(has_static_sub<I>::value){
|
if constexpr(has_static_sub<I>::value){
|
||||||
iter<0,index_dim<I>::value> ( [&](auto i) { fpos[i] = beg.pack().get(i).lex(); }, NoF{} );
|
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){
|
for(SizeT i = 0; i != beg.dim(); ++i){
|
||||||
fpos[i] = beg.pack().get(i).lex();
|
fpos[i] = beg.THIS().pack().get(i)->lex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -48,17 +48,17 @@ namespace CNORXZ
|
||||||
|
|
||||||
inline hid_t TypeId<SizeT>::get()
|
inline hid_t TypeId<SizeT>::get()
|
||||||
{
|
{
|
||||||
return H5T_NATIVE_ULONG;
|
return H5Tcopy( H5T_NATIVE_ULONG );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hid_t TypeId<Int>::get()
|
inline hid_t TypeId<Int>::get()
|
||||||
{
|
{
|
||||||
return H5T_NATIVE_INT;
|
return H5Tcopy( H5T_NATIVE_INT );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hid_t TypeId<Double>::get()
|
inline hid_t TypeId<Double>::get()
|
||||||
{
|
{
|
||||||
return H5T_NATIVE_DOUBLE;
|
return H5Tcopy( H5T_NATIVE_DOUBLE );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, SizeT N>
|
template <typename T, SizeT N>
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace CNORXZ
|
||||||
Dataset& Dataset::init(const RangePtr& dataRange, hid_t type)
|
Dataset& Dataset::init(const RangePtr& dataRange, hid_t type)
|
||||||
{
|
{
|
||||||
CXZ_ASSERT(not isOpen(), "tried to initialize dataset that is already extisting");
|
CXZ_ASSERT(not isOpen(), "tried to initialize dataset that is already extisting");
|
||||||
|
mDataRange = dataRange;
|
||||||
const H5T_class_t tc = H5Tget_class(type);
|
const H5T_class_t tc = H5Tget_class(type);
|
||||||
CXZ_ASSERT(tc != H5T_NO_CLASS, "id does not correspond to a data type"); // (did not found anythng better to check if type id is valid)...
|
CXZ_ASSERT(tc != H5T_NO_CLASS, "id does not correspond to a data type"); // (did not found anythng better to check if type id is valid)...
|
||||||
const hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
|
const hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
|
||||||
|
add_definitions(-DTEST_NUMBER_FILE="${CMAKE_SOURCE_DIR}/src/tests/numbers.txt")
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/src/tests)
|
||||||
add_executable(h5basic h5_basic_unit_test.cc)
|
add_executable(h5basic h5_basic_unit_test.cc)
|
||||||
add_dependencies(h5basic cnorxz cnorxzhdf5)
|
add_dependencies(h5basic cnorxz cnorxzhdf5 test_lib)
|
||||||
target_link_libraries(h5basic ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${HDF5_LIBS} cnorxz cnorxzhdf5)
|
target_link_libraries(h5basic ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${HDF5_LIBS} cnorxz cnorxzhdf5 test_lib)
|
||||||
add_test(NAME h5basic COMMAND h5basic)
|
add_test(NAME h5basic COMMAND h5basic)
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "cnorxz_hdf5.h"
|
#include "cnorxz_hdf5.h"
|
||||||
|
#include "test_numbers.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using namespace CNORXZ;
|
using namespace CNORXZ;
|
||||||
using namespace CNORXZ::hdf5;
|
using namespace CNORXZ::hdf5;
|
||||||
|
using Test::Numbers;
|
||||||
|
|
||||||
static const String testh5file = "test_file.h5";
|
static const String testh5file = "test_file.h5";
|
||||||
|
|
||||||
|
@ -58,6 +60,16 @@ namespace
|
||||||
iter<0,3>( [&](auto jj)
|
iter<0,3>( [&](auto jj)
|
||||||
{ j = jj; mTabD[i*j] = DType(tget<jj>(v[i.lex()])); }, NoF{} );
|
{ j = jj; mTabD[i*j] = DType(tget<jj>(v[i.lex()])); }, NoF{} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SizeT ddim = 5;
|
||||||
|
Vector<RangePtr> dranges(ddim);
|
||||||
|
dranges[0] = CRangeFactory(7).create();
|
||||||
|
dranges[1] = CRangeFactory(3).create();
|
||||||
|
dranges[2] = CRangeFactory(13).create();
|
||||||
|
dranges[3] = CRangeFactory(5).create();
|
||||||
|
dranges[4] = CRangeFactory(2).create();
|
||||||
|
const RangePtr drange = yrange(dranges);
|
||||||
|
mData = MArray<Double>( drange, Numbers::get(0,drange->size()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
String mFileName;
|
String mFileName;
|
||||||
|
@ -65,6 +77,7 @@ namespace
|
||||||
Arr<String,3> mFs;
|
Arr<String,3> mFs;
|
||||||
MArray<Tuple<Double,Int,SizeT>> mTabA;
|
MArray<Tuple<Double,Int,SizeT>> mTabA;
|
||||||
MArray<DType> mTabD;
|
MArray<DType> mTabD;
|
||||||
|
MArray<Double> mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,10 +131,18 @@ namespace
|
||||||
File h5f(mFileName, false);
|
File h5f(mFileName, false);
|
||||||
h5f.open();
|
h5f.open();
|
||||||
h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs);
|
h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs);
|
||||||
h5f.getGroup("gr2")->open().addTable("tab1", mTabA, mFs);
|
//h5f.getGroup("gr2")->open().addTable("tab1", mTabA, mFs);
|
||||||
h5f.getGroup("moregroups")->open().getGroup("evenmore")->open().getGroup("need")->open().addTable("tab1", mTabA, mFs);
|
h5f.getGroup("moregroups")->open().getGroup("evenmore")->open().getGroup("need")->open().addTable("tab1", mTabA, mFs);
|
||||||
h5f.close();
|
h5f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, CreateDataset)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, false);
|
||||||
|
h5f.open();
|
||||||
|
h5f.getGroup("gr2")->open().addDataset("dat1", mData);
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(Group_Test, Read)
|
TEST_F(Group_Test, Read)
|
||||||
{
|
{
|
||||||
|
@ -181,6 +202,42 @@ namespace
|
||||||
h5f.close();
|
h5f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, ReadDataset)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, true);
|
||||||
|
h5f.open();
|
||||||
|
auto dset = h5f.getGroup("gr2")->open().getDataset("dat1", Double{});
|
||||||
|
auto data = dset->read();
|
||||||
|
EXPECT_EQ(data.range()->dim(), 5u);
|
||||||
|
for(SizeT i = 0; i != 5u; ++i){
|
||||||
|
EXPECT_EQ( data.range()->sub(i)->size(), mData.range()->sub(i)->size() );
|
||||||
|
}
|
||||||
|
auto i = std::make_shared<CIndex>(data.range());
|
||||||
|
i->ifor( operation( [](Double a, Double b) { EXPECT_EQ(a,b); }, data(i), mData(i) ), NoF{} )();
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Group_Test, ReadDatasetPart)
|
||||||
|
{
|
||||||
|
File h5f(mFileName, true);
|
||||||
|
h5f.open();
|
||||||
|
auto dset = h5f.getGroup("gr2")->open().getDataset("dat1", Double{});
|
||||||
|
YIndex beg(dset->dataRange());
|
||||||
|
beg.setSub(0,2);
|
||||||
|
YIndex end = beg - 1;
|
||||||
|
end.setSub(0,2);
|
||||||
|
auto data = dset->read(beg,end);
|
||||||
|
EXPECT_EQ( data.range()->dim(), 5u );
|
||||||
|
EXPECT_EQ( data.range()->sub(0)->size(), 1u );
|
||||||
|
for(SizeT i = 1; i != 5u; ++i){
|
||||||
|
EXPECT_EQ( data.range()->sub(i)->size(), mData.range()->sub(i)->size() );
|
||||||
|
}
|
||||||
|
auto i = std::make_shared<CIndex>(data.range());
|
||||||
|
auto j = std::make_shared<DIndex>( beg.pack().get(0) );
|
||||||
|
i->ifor( operation( [](Double a, Double b) { EXPECT_EQ(a,b); }, data(i), mData(j*i) ), NoF{} )();
|
||||||
|
h5f.close();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(Group_Test, Read2)
|
TEST_F(Group_Test, Read2)
|
||||||
{
|
{
|
||||||
File h5f(mFileName, true);
|
File h5f(mFileName, true);
|
||||||
|
|
Loading…
Reference in a new issue