1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-06-10 03:17:07 +01:00

First implementation of HDF5 serial IO writer, reader is still empty

This commit is contained in:
2017-01-17 16:21:18 -08:00
parent 91a3534054
commit 5803933aea
10 changed files with 357 additions and 5 deletions

View File

@ -0,0 +1,84 @@
#include <Grid.h>
using namespace Grid;
#ifndef H5_NO_NAMESPACE
using namespace H5NS;
#endif
// Writer implementation ///////////////////////////////////////////////////////
Hdf5Writer::Hdf5Writer(const std::string &fileName)
: fileName_(fileName)
, file_(fileName.c_str(), H5F_ACC_TRUNC)
{
group_ = file_.openGroup("/");
}
Hdf5Writer::~Hdf5Writer(void)
{
file_.close();
}
void Hdf5Writer::push(const std::string &s)
{
group_ = group_.createGroup(s);
path_.push_back(s);
}
void Hdf5Writer::pop(void)
{
path_.pop_back();
if (path_.empty())
{
group_ = file_.openGroup("/");
}
else
{
auto binOp = [](const std::string &a, const std::string &b)->std::string
{
return a + "/" + b;
};
group_ = group_.openGroup(std::accumulate(path_.begin(), path_.end(),
std::string(""), binOp));
}
}
template <>
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x)
{
StrType strType(PredType::C_S1, x.size());
Attribute attribute;
hsize_t attrDim = 1;
DataSpace attrSpace(1, &attrDim);
attribute = group_.createAttribute(s, strType, attrSpace);
attribute.write(strType, x.data());
}
void Hdf5Writer::writeDefault(const std::string &s, const char *x)
{
std::string sx(x);
writeDefault(s, sx);
}
// Reader implementation ///////////////////////////////////////////////////////
Hdf5Reader::Hdf5Reader(const std::string &fileName)
{
}
Hdf5Reader::~Hdf5Reader(void)
{
}
void Hdf5Reader::push(const std::string &s)
{
}
void Hdf5Reader::pop(void)
{
}

169
lib/serialisation/Hdf5IO.h Normal file
View File

@ -0,0 +1,169 @@
#ifndef GRID_SERIALISATION_HDF5_H
#define GRID_SERIALISATION_HDF5_H
#include <stack>
#include <string>
#include <vector>
#include <H5Cpp.h>
#include "Hdf5Type.h"
#ifndef H5_NO_NAMESPACE
#define H5NS H5
#endif
// default thresold above which datasets are used instead of attributes
#ifndef H5_DEF_DATASET_THRES
#define H5_DEF_DATASET_THRES 6u
#endif
namespace Grid
{
template <typename T>
struct is_arithmetic_vector
{
static constexpr bool value = false;
};
template <typename T>
struct is_arithmetic_vector<std::vector<T>>
{
static constexpr bool value = std::is_arithmetic<T>::value
or is_arithmetic_vector<T>::value;
};
class Hdf5Writer: public Writer<Hdf5Writer>
{
public:
Hdf5Writer(const std::string &fileName);
virtual ~Hdf5Writer(void);
void push(const std::string &s);
void pop(void);
void writeDefault(const std::string &s, const char *x);
template <typename U>
void writeDefault(const std::string &s, const U &x);
template <typename U>
typename std::enable_if<is_arithmetic_vector<std::vector<U>>::value
and std::is_arithmetic<U>::value, void>::type
writeDefault(const std::string &s, const std::vector<U> &x);
template <typename U>
typename std::enable_if<is_arithmetic_vector<std::vector<U>>::value
and !std::is_arithmetic<U>::value, void>::type
writeDefault(const std::string &s, const std::vector<U> &x);
template <typename U>
typename std::enable_if<!is_arithmetic_vector<std::vector<U>>::value, void>::type
writeDefault(const std::string &s, const std::vector<U> &x);
private:
std::string fileName_;
std::vector<std::string> path_;
std::vector<hsize_t> dim_;
bool multiDim_{true};
H5NS::H5File file_;
H5NS::Group group_;
unsigned int datasetThres_{H5_DEF_DATASET_THRES};
};
class Hdf5Reader: public Reader<Hdf5Reader>
{
public:
Hdf5Reader(const std::string &fileName);
virtual ~Hdf5Reader(void);
void push(const std::string &s);
void pop(void);
template <typename U>
void readDefault(const std::string &s, U &output);
template <typename U>
void readDefault(const std::string &s, std::vector<U> &output);
private:
};
// Writer template implementation ////////////////////////////////////////////
template <typename U>
void Hdf5Writer::writeDefault(const std::string &s, const U &x)
{
H5NS::Attribute attribute;
hsize_t attrDim = 1;
H5NS::DataSpace attrSpace(1, &attrDim);
attribute = group_.createAttribute(s, *Hdf5Type<U>::type, attrSpace);
attribute.write(*Hdf5Type<U>::type, &x);
}
template <>
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x);
template <typename U>
typename std::enable_if<is_arithmetic_vector<std::vector<U>>::value
and std::is_arithmetic<U>::value, void>::type
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
{
hsize_t size = 1;
dim_.push_back(x.size());
for (auto d: dim_)
{
size *= d;
}
H5NS::DataSpace dataspace(dim_.size(), dim_.data());
if (size > datasetThres_)
{
H5NS::DataSet dataset;
dataset = group_.createDataSet(s, *Hdf5Type<U>::type, dataspace);
dataset.write(x.data(), *Hdf5Type<U>::type);
}
else
{
H5NS::Attribute attribute;
attribute = group_.createAttribute(s, *Hdf5Type<U>::type, dataspace);
attribute.write(*Hdf5Type<U>::type, x.data());
}
dim_.clear();
multiDim_ = true;
}
template <typename U>
typename std::enable_if<is_arithmetic_vector<std::vector<U>>::value
and !std::is_arithmetic<U>::value, void>::type
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
{
hsize_t firstSize = x[0].size();
for (auto &v: x)
{
multiDim_ = (multiDim_ and (v.size() == firstSize));
}
assert(multiDim_);
dim_.push_back(x.size());
writeDefault(s, x[0]);
}
template <typename U>
typename std::enable_if<!is_arithmetic_vector<std::vector<U>>::value, void>::type
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
{
push(s);
for (hsize_t i = 0; i < x.size(); ++i)
{
write(s + "_" + std::to_string(i), x[i]);
}
pop();
}
// Reader template implementation ////////////////////////////////////////////
template <typename U>
void Hdf5Reader::readDefault(const std::string &s, U &output)
{
}
template <typename U>
void Hdf5Reader::readDefault(const std::string &s, std::vector<U> &output)
{
}
}
#endif

View File

@ -0,0 +1,8 @@
#include "Hdf5Type.h"
using namespace Grid;
#define HDF5_NATIVE_TYPE(predType, cType)\
const H5NS::PredType * Hdf5Type<cType>::type = &H5NS::PredType::predType;
DEFINE_HDF5_NATIVE_TYPES;

View File

@ -0,0 +1,48 @@
#ifndef GRID_SERIALISATION_HDF5_TYPE_H
#define GRID_SERIALISATION_HDF5_TYPE_H
#include <H5Cpp.h>
#include <vector>
#ifndef H5_NO_NAMESPACE
#define H5NS H5
#endif
#define HDF5_NATIVE_TYPE(predType, cType)\
template <>\
struct Hdf5Type<cType>\
{\
static const H5NS::PredType *type;\
static constexpr bool isNative = true;\
};
#define DEFINE_HDF5_NATIVE_TYPES \
HDF5_NATIVE_TYPE(NATIVE_B8, bool);\
HDF5_NATIVE_TYPE(NATIVE_CHAR, char);\
HDF5_NATIVE_TYPE(NATIVE_SCHAR, signed char);\
HDF5_NATIVE_TYPE(NATIVE_UCHAR, unsigned char);\
HDF5_NATIVE_TYPE(NATIVE_SHORT, short);\
HDF5_NATIVE_TYPE(NATIVE_USHORT, unsigned short);\
HDF5_NATIVE_TYPE(NATIVE_INT, int);\
HDF5_NATIVE_TYPE(NATIVE_UINT, unsigned int);\
HDF5_NATIVE_TYPE(NATIVE_LONG, long);\
HDF5_NATIVE_TYPE(NATIVE_ULONG, unsigned long);\
HDF5_NATIVE_TYPE(NATIVE_LLONG, long long);\
HDF5_NATIVE_TYPE(NATIVE_ULLONG, unsigned long long);\
HDF5_NATIVE_TYPE(NATIVE_FLOAT, float);\
HDF5_NATIVE_TYPE(NATIVE_DOUBLE, double);\
HDF5_NATIVE_TYPE(NATIVE_LDOUBLE, long double);
namespace Grid
{
template <typename T> struct Hdf5Type
{
static constexpr bool isNative = false;
};
DEFINE_HDF5_NATIVE_TYPES;
}
#undef HDF5_NATIVE_TYPE
#endif /* GRID_SERIALISATION_HDF5_TYPE_H */

View File

@ -36,6 +36,9 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#include "BinaryIO.h"
#include "TextIO.h"
#include "XmlIO.h"
#ifdef HAVE_HDF5
#include "Hdf5IO.h"
#endif
//////////////////////////////////////////
// Todo:
//////////////////////////////////////////