Skip to content

Commit

Permalink
add boost support
Browse files Browse the repository at this point in the history
  • Loading branch information
1uc committed Nov 28, 2023
1 parent 7addd27 commit 59b720a
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 11 deletions.
97 changes: 86 additions & 11 deletions tests/unit/data_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <array>
#include <cmath>

#ifdef H5_USE_BOOST
#include <boost/multi_array.hpp>
#endif

#include <highfive/bits/H5Inspector_misc.hpp>

namespace HighFive {
Expand Down Expand Up @@ -58,7 +62,10 @@ static size_t flat_size(const std::vector<size_t>& dims) {
return n;
}

template <class Container, class = void>
struct DataGeneratorTraits;

// -- Scalar basecases ---------------------------------------------------------
template <class T>
struct ScalarDataGeneratorTraits {
using container_type = T;
Expand All @@ -77,9 +84,18 @@ struct ScalarDataGeneratorTraits {
}
};

template <class Container, class = void>
struct DataGeneratorTraits;
template <class T>
struct DataGeneratorTraits<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
: public ScalarDataGeneratorTraits<T> {};

template <class T>
struct DataGeneratorTraits<T, typename std::enable_if<std::is_integral<T>::value>::type>
: public ScalarDataGeneratorTraits<T> {};

template <>
struct DataGeneratorTraits<std::string>: public ScalarDataGeneratorTraits<std::string> {};

// -- STL ----------------------------------------------------------------------
template <>
struct DataGeneratorTraits<std::vector<bool>> {
using container_type = std::vector<bool>;
Expand All @@ -101,7 +117,6 @@ struct DataGeneratorTraits<std::vector<bool>> {
}
};


template <class Container, class ValueType = typename Container::value_type>
struct DataGeneratorSTLLikeTraits {
using container_type = Container;
Expand Down Expand Up @@ -156,16 +171,76 @@ struct DataGeneratorTraits<std::array<T, N>>: public DataGeneratorSTLLikeTraits<
}
};

template <class T>
struct DataGeneratorTraits<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
: public ScalarDataGeneratorTraits<T> {};
// -- Boost -------------------------------------------------------------------
#ifdef H5_USE_BOOST
template<class T, size_t n>
struct DataGeneratorTraits<boost::multi_array<T, n>> {
using container_type = typename boost::multi_array<T, n>;
using value_type = T;
using base_type = typename DataGeneratorTraits<value_type>::base_type;

template <class T>
struct DataGeneratorTraits<T, typename std::enable_if<std::is_integral<T>::value>::type>
: public ScalarDataGeneratorTraits<T> {};
static void set(container_type& array,
const std::vector<size_t>& indices,
const base_type& value) {
auto i = std::vector<size_t>(indices.begin(), indices.begin() + n);
return DataGeneratorTraits<value_type>::set(array(i), lstrip(indices, n), value);
}

static base_type get(const container_type& array, const std::vector<size_t>& indices) {
auto i = std::vector<size_t>(indices.begin(), indices.begin() + n);
return DataGeneratorTraits<value_type>::get(array(i), lstrip(indices, n));
}

static container_type allocate(const std::vector<size_t>& dims) {
auto local_dims = std::vector<size_t>(dims.begin(), dims.begin() + n);
container_type array(local_dims);

size_t n_elements = flat_size(local_dims);
for (size_t i = 0; i < n_elements; ++i) {
auto element = DataGeneratorTraits<value_type>::allocate(lstrip(dims, n));
set(array, unravel(i, local_dims), element);
}

return array;
}
};

template<class T>
struct DataGeneratorTraits<boost::numeric::ublas::matrix<T>> {
using container_type = typename boost::numeric::ublas::matrix<T>;
using value_type = T;
using base_type = typename DataGeneratorTraits<value_type>::base_type;

static void set(container_type& array,
const std::vector<size_t>& indices,
const base_type& value) {
auto i = indices[0];
auto j = indices[1];
return DataGeneratorTraits<value_type>::set(array(i, j), lstrip(indices, 2), value);
}

static base_type get(const container_type& array, const std::vector<size_t>& indices) {
auto i = indices[0];
auto j = indices[1];
return DataGeneratorTraits<value_type>::get(array(i, j), lstrip(indices, 2));
}

static container_type allocate(const std::vector<size_t>& dims) {
auto local_dims = std::vector<size_t>(dims.begin(), dims.begin() + 2);
container_type array(local_dims[0], local_dims[1]);

size_t n_elements = flat_size(local_dims);
for (size_t i = 0; i < n_elements; ++i) {
auto element = DataGeneratorTraits<value_type>::allocate(lstrip(dims, 2));
set(array, unravel(i, local_dims), element);
}

return array;
}
};

#endif

template <>
struct DataGeneratorTraits<std::string>: public ScalarDataGeneratorTraits<std::string> {};

template <class T>
T default_real_value(const std::vector<size_t>& indices, T shift, T base, T factor) {
Expand Down
36 changes: 36 additions & 0 deletions tests/unit/test_all_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,18 @@ TEMPLATE_TEST_CASE("TestreadRegularSTLArray", "[read]", int, unsigned int, float
check_read_regular<std::array<TestType, 4>>(file_name, {4});
}

#ifdef H5_USE_BOOST
TEMPLATE_TEST_CASE("TestReadRegularBoostMultiArray", "[runme]", int, unsigned int, float, double) {
const std::string file_name("rw_read_regular_boost_multi_array" + typeNameHelper<TestType>() + ".h5");
check_read_regular<boost::multi_array<TestType, 4>>(file_name, {2, 3, 5, 7});
}

TEMPLATE_TEST_CASE("TestReadRegularBoostUblasMatrix", "[runme]", int, unsigned int, float, double) {
const std::string file_name("rw_read_regular_boost_ublas_matrix" + typeNameHelper<TestType>() + ".h5");
check_read_regular<boost::numeric::ublas::matrix<TestType>>(file_name, {3, 5});
}
#endif


template <class Container, class Write>
void check_writing(const std::vector<size_t>& dims, Write write) {
Expand Down Expand Up @@ -494,6 +506,18 @@ TEMPLATE_TEST_CASE("TestWriteRegularSTLArray", "[runme]", int, unsigned int, flo
check_write_regular<std::array<TestType, 4>>(file_name, {4});
}

#ifdef H5_USE_BOOST
TEMPLATE_TEST_CASE("TestWriteRegularBoostMultiArray", "[runme]", int, unsigned int, float, double) {
const std::string file_name("rw_write_regular_boost_multi_array" + typeNameHelper<TestType>() + ".h5");
check_write_regular<boost::multi_array<TestType, 4>>(file_name, {2, 3, 5, 7});
}

TEMPLATE_TEST_CASE("TestWriteRegularBoostUblasMatrix", "[runme]", int, unsigned int, float, double) {
const std::string file_name("rw_write_regular_boost_ublas_matrix" + typeNameHelper<TestType>() + ".h5");
check_write_regular<boost::numeric::ublas::matrix<TestType>>(file_name, {3, 5});
}
#endif

template <class CreateTraits, class Container>
void check_write_read_cycle(File& file, const std::string& name, const std::vector<size_t>& dims) {
auto vr = testing::DataGenerator<Container>::create(dims);
Expand Down Expand Up @@ -529,3 +553,15 @@ TEMPLATE_TEST_CASE("TestWriteReadCycleSTDArray", "[runme]", bool, std::string) {
const std::string file_name("rw_cycle_std_array" + typeNameHelper<TestType>() + ".h5");
check_write_read_cycle<std::array<TestType, 6>>(file_name, {6});
}

#ifdef H5_USE_BOOST
TEMPLATE_TEST_CASE("TestWriteReadCycleBoostMulti", "[runme]", int, double) {
const std::string file_name("rw_cycle_boost_multi_array" + typeNameHelper<TestType>() + ".h5");
check_write_read_cycle<boost::multi_array<TestType, 3>>(file_name, {2, 5, 7});
}

TEMPLATE_TEST_CASE("TestWriteReadCycleBoostUblasMatrix", "[runme]", int, double) {
const std::string file_name("rw_cycle_boost_ublas_matrix" + typeNameHelper<TestType>() + ".h5");
check_write_read_cycle<boost::numeric::ublas::matrix<TestType>>(file_name, {2, 5});
}
#endif

0 comments on commit 59b720a

Please sign in to comment.