hdf5: several fixes + yrange: add setSub member function + dindex: add missing operator*(dindex,index)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Christian Zimmermann 2024-02-01 18:22:08 +01:00
parent 6f3601daa4
commit eb3055ddca
9 changed files with 104 additions and 12 deletions

View file

@ -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)
{ {

View file

@ -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
*/ */

View file

@ -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;

View file

@ -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 *
****************************/ ****************************/

View file

@ -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 {

View file

@ -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>

View file

@ -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);

View file

@ -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)

View file

@ -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,11 +131,19 @@ 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)
{ {
File h5f(mFileName, true); File h5f(mFileName, true);
@ -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);