32 #ifndef VSMC_UTILITY_HDF5IO_HPP 33 #define VSMC_UTILITY_HDF5IO_HPP 44 template <MatrixLayout>
49 std::size_t nrow, std::size_t ncol, ::hsize_t *dim)
57 std::size_t nrow, std::size_t ncol, ::hsize_t *dim)
69 template <
typename OutputIter>
70 void set(std::size_t n, OutputIter)
75 void set(std::size_t, T *ptr) { ptr_ = ptr; }
77 T *
get() {
return ptr_ ==
nullptr ? data_.data() : ptr_; }
92 template <
typename InputIter>
93 InputIter
set(std::size_t n, InputIter first)
96 T *dst = data_.data();
97 for (std::size_t i = 0; i != n; ++i, ++first)
103 T *
set(std::size_t n, T *ptr)
109 const T *
set(std::size_t n,
const T *ptr)
115 const T *
get()
const {
return ptr_ ==
nullptr ? data_.data() : ptr_; }
139 return ::H5Tcopy(H5T_NATIVE_CHAR);
147 return ::H5Tcopy(H5T_NATIVE_SCHAR);
155 return ::H5Tcopy(H5T_NATIVE_UCHAR);
163 return ::H5Tcopy(H5T_NATIVE_SHORT);
171 return ::H5Tcopy(H5T_NATIVE_UCHAR);
179 return ::H5Tcopy(H5T_NATIVE_INT);
187 return ::H5Tcopy(H5T_NATIVE_UINT);
195 return ::H5Tcopy(H5T_NATIVE_LONG);
203 return ::H5Tcopy(H5T_NATIVE_ULONG);
211 return ::H5Tcopy(H5T_NATIVE_LLONG);
219 return ::H5Tcopy(H5T_NATIVE_ULLONG);
227 return ::H5Tcopy(H5T_NATIVE_FLOAT);
235 return ::H5Tcopy(H5T_NATIVE_DOUBLE);
243 return ::H5Tcopy(H5T_NATIVE_LDOUBLE);
249 const std::string &file_name,
const std::string &data_name)
252 ::H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
253 ::hid_t dataset = ::H5Dopen(datafile, data_name.c_str(), H5P_DEFAULT);
254 ::hid_t dataspace = ::H5Dget_space(dataset);
255 ::hid_t datatype = ::H5Dget_type(dataset);
257 static_cast<std::size_t
>(H5Sget_simple_extent_npoints(dataspace));
258 std::size_t b = H5Tget_size(datatype);
259 std::size_t bytes = n * b;
261 ::H5Tclose(datatype);
262 ::H5Sclose(dataspace);
264 ::H5Fclose(datafile);
271 template <
typename T>
273 const std::string &file_name,
const std::string &data_name)
275 return hdf5size(file_name, data_name) /
sizeof(T);
280 template <
typename T,
typename OutputIter>
281 inline OutputIter
hdf5load(
const std::string &file_name,
282 const std::string &data_name, OutputIter first)
284 std::size_t n =
hdf5size(file_name, data_name) /
sizeof(T);
286 data_ptr.
set(n, first);
287 T *data = data_ptr.
get();
290 ::H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
291 ::hid_t dataset = ::H5Dopen(datafile, data_name.c_str(), H5P_DEFAULT);
292 ::hid_t datatype = ::H5Dget_type(dataset);
293 ::H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
297 for (std::size_t i = 0; i != n; ++i, ++first)
301 ::H5Tclose(datatype);
303 ::H5Fclose(datafile);
312 ::hid_t datafile = ::H5Fcreate(
313 file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
314 ::H5Fclose(datafile);
367 template <MatrixLayout Layout,
typename T,
typename InputIter>
369 const std::string &file_name,
const std::string &data_name,
370 InputIter first,
bool append =
false)
372 if (nrow == 0 || ncol == 0)
375 std::string dataset_name(
"/" + data_name);
377 internal::hdf5io_matrix_dim<Layout>(nrow, ncol, dim);
379 InputIter last = data_ptr.
set(nrow * ncol, first);
380 const T *data = data_ptr.get();
384 datafile = ::H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
386 datafile = ::H5Fcreate(
387 file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
389 ::hid_t dataspace = ::H5Screate_simple(2, dim,
nullptr);
390 ::hid_t datatype = hdf5io_datatype<T>();
391 ::hid_t dataset = ::H5Dcreate(datafile, dataset_name.c_str(), datatype,
392 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
393 ::H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
396 ::H5Tclose(datatype);
397 ::H5Sclose(dataspace);
398 ::H5Fclose(datafile);
412 const std::string &data_name,
bool append =
false)
414 std::string group_name(
"/" + data_name);
418 datafile = ::H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
420 datafile = ::H5Fcreate(
421 file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
423 ::hid_t datagroup = ::H5Gcreate(
424 datafile, group_name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
425 ::H5Gclose(datagroup);
426 ::H5Fclose(datafile);
456 template <
typename T,
typename InputIterIter,
typename SInputIter>
458 const std::string &file_name,
const std::string &data_name,
459 InputIterIter first, SInputIter sfirst,
bool append =
false)
461 std::string group_name(
"/" + data_name);
462 ::hsize_t dim[1] = {nrow};
466 datafile = ::H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
468 datafile = ::H5Fcreate(
469 file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
471 ::hid_t datagroup = ::H5Gcreate(
472 datafile, group_name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
474 if (nrow != 0 && ncol != 0) {
475 ::hid_t dataspace = ::H5Screate_simple(1, dim,
nullptr);
476 ::hid_t datatype = hdf5io_datatype<T>();
478 for (std::size_t j = 0; j != ncol; ++j, ++first, ++sfirst) {
479 data_ptr.
set(nrow, *first);
480 const T *data = data_ptr.get();
481 std::string dataset_name(group_name +
"/" + (*sfirst));
482 ::hid_t dataset = ::H5Dcreate(datafile, dataset_name.c_str(),
483 datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
484 ::H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
487 ::H5Tclose(datatype);
488 ::H5Sclose(dataspace);
491 ::H5Gclose(datagroup);
492 ::H5Fclose(datafile);
504 template <
typename T,
typename InputIter>
506 const std::string &data_name, InputIter first,
const std::string &vname)
511 std::string dataset_name(
"/" + data_name +
"/" + vname);
512 ::hsize_t dim[1] = {N};
514 ::hid_t datafile = ::H5Fopen(file_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
515 ::hid_t dataspace = ::H5Screate_simple(1, dim,
nullptr);
516 ::hid_t datatype = hdf5io_datatype<T>();
518 data_ptr.
set(N, first);
519 const T *data = data_ptr.get();
520 ::hid_t dataset = ::H5Dcreate(datafile, dataset_name.c_str(), datatype,
521 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
522 ::H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
525 ::H5Tclose(datatype);
526 ::H5Sclose(dataspace);
527 ::H5Fclose(datafile);
533 template <
typename InputIter,
typename... InputIters>
535 const std::string &file_name,
const std::string &data_name,
536 const std::tuple<InputIter, InputIters...> &first,
const std::string *sptr,
537 std::integral_constant<std::size_t, 0>)
540 typename std::iterator_traits<
typename std::tuple_element<0,
541 std::tuple<InputIter, InputIters...>>::type>::value_type;
543 data_ptr.
set(nrow, std::get<0>(first));
544 const value_type *data = data_ptr.
get();
545 hdf5store_list_insert<value_type>(nrow, file_name, data_name, data, *sptr);
548 template <
typename InputIter,
typename... InputIters, std::size_t Pos>
550 const std::string &file_name,
const std::string &data_name,
551 const std::tuple<InputIter, InputIters...> &first,
const std::string *sptr,
552 std::integral_constant<std::size_t, Pos>)
555 typename std::iterator_traits<
typename std::tuple_element<Pos,
556 std::tuple<InputIter, InputIters...>>::type>::value_type;
558 data_ptr.
set(nrow, std::get<Pos>(first));
559 const value_type *data = data_ptr.
get();
560 hdf5store_list_insert<value_type>(nrow, file_name, data_name, data, *sptr);
562 std::integral_constant<std::size_t, Pos - 1>());
586 template <
typename SInputIter,
typename InputIter,
typename... InputIters>
588 const std::string &data_name,
589 const std::tuple<InputIter, InputIters...> &first, SInputIter sfirst,
592 static constexpr std::size_t dim =
sizeof...(InputIters) + 1;
594 vnames.
set(dim, sfirst);
595 const std::string *sptr = vnames.
get() + dim;
598 --sptr, std::integral_constant<std::size_t, dim - 1>());
604 template <
typename IntType>
607 if (
sizeof(
int) >
sizeof(IntType))
611 for (std::size_t i = 0; i != n; ++i) {
612 if (r[i] > std::numeric_limits<int>::max()) {
621 template <
typename IntType>
624 if (
sizeof(
int) >
sizeof(IntType))
628 for (std::size_t i = 0; i != n; ++i) {
629 if (r[i] < std::numeric_limits<int>::min()) {
633 if (r[i] > std::numeric_limits<int>::max()) {
646 template <
typename T>
648 const std::string &data_name,
bool append =
false)
663 sampler.template summary_data_int<ColMajor>(data_int.begin());
665 data_int.size(), data_int.data(), std::is_signed<size_type>());
668 std::copy(data_int.begin(), data_int.end(), data_int_small.begin());
670 for (std::size_t j = 0; j != ncol_int; ++j)
671 data_ptr_int[j] = data_int_small.data() + j * nrow;
672 for (std::size_t j = 0; j != ncol_int; ++j)
673 hdf5store_list_insert<int>(
674 nrow, file_name, data_name, data_ptr_int[j], header_int[j]);
677 for (std::size_t j = 0; j != ncol_int; ++j)
678 data_ptr_int[j] = data_int.data() + j * nrow;
679 for (std::size_t j = 0; j != ncol_int; ++j)
680 hdf5store_list_insert<size_type>(
681 nrow, file_name, data_name, data_ptr_int[j], header_int[j]);
688 sampler.template summary_data<ColMajor>(data.begin());
690 for (std::size_t j = 0; j != ncol; ++j)
691 data_ptr[j] = data.data() + j * nrow;
692 for (std::size_t j = 0; j != ncol; ++j)
693 hdf5store_list_insert<double>(
694 nrow, file_name, data_name, data_ptr[j], header[j]);
699 template <MatrixLayout Layout, std::
size_t Dim,
typename T>
701 const std::string &file_name,
const std::string &data_name,
704 hdf5store_matrix<Layout, T>(
705 state.size(), state.dim(), file_name, data_name, state.data(), append);
710 template <
MatrixLayout Layout,
typename T, std::size_t StateSize,
711 typename RealType,
typename ID>
713 const std::string &file_name,
const std::string &data_name,
716 std::size_t nrow = state.size();
717 std::size_t ncol = state.state_size() /
sizeof(T);
718 std::size_t N = nrow * ncol;
720 state.manager().template read_buffer<T>(
721 state.state_buffer().data(), N, data.data());
722 hdf5store_matrix<Layout, T>(
723 nrow, ncol, file_name, data_name, data.data(), append);
728 template <
typename T>
730 const std::string &file_name,
const std::string &data_name,
734 hdf5store(particle.
value(), file_name, data_name +
"/value",
true);
735 hdf5store_matrix<ColMajor, double>(particle.
size(), 1, file_name,
736 data_name +
"/weight", particle.
weight().data(),
true);
741 template <MatrixLayout Layout,
typename T,
typename U>
743 const std::string &file_name,
const std::string &data_name,
747 hdf5store<Layout, T>(
748 particle.
value(), file_name, data_name +
"/value",
true);
749 hdf5store_matrix<ColMajor, double>(particle.
size(), 1, file_name,
750 data_name +
"/weight", particle.
weight().data(),
true);
755 #endif // VSMC_UTILITY_HDF5IO_HPP inline::hid_t hdf5io_datatype< signed char >()
HDF5 data type specialization for signed char.
Particle class representing the whole particle set.
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
inline::hid_t hdf5io_datatype< double >()
HDF5 data type specialization for double.
MatrixLayout
Matrix layout.
std::size_t summary_header_size() const
The size of Sampler summary header (floating point data)
value_type & value()
Read and write access to the value collection object.
void hdf5store_list_insert(std::size_t N, const std::string &file_name, const std::string &data_name, InputIter first, const std::string &vname)
Insert a variable into an existing list saved in HDF5 format.
weight_type & weight()
Read and write access to the weight collection object.
inline::hid_t hdf5io_datatype< unsigned char >()
HDF5 data type specialization for unsigned char.
std::size_t iter_size() const
Number of iterations (including initialization)
InputIter hdf5store_matrix(std::size_t nrow, std::size_t ncol, const std::string &file_name, const std::string &data_name, InputIter first, bool append=false)
Store a matrix in the HDF5 format from an input iterator.
void summary_header(OutputIter first) const
Sampler summary header (floating point data)
inline::hid_t hdf5io_datatype()
HDF5 data type.
void hdf5io_matrix_dim< RowMajor >(std::size_t nrow, std::size_t ncol,::hsize_t *dim)
inline::hid_t hdf5io_datatype< char >()
HDF5 data type specialization for char.
void summary_header_int(OutputIter first) const
Sampler summary header (integer data)
inline::hid_t hdf5io_datatype< unsigned int >()
HDF5 data type specialization for unsigned int.
void hdf5io_matrix_dim(std::size_t, std::size_t,::hsize_t *)
inline::hid_t hdf5io_datatype< unsigned short >()
HDF5 data type specialization for unsigned short.
void hdf5io_matrix_dim< ColMajor >(std::size_t nrow, std::size_t ncol,::hsize_t *dim)
inline::hid_t hdf5io_datatype< int >()
HDF5 data type specialization for int.
typename Particle< T >::size_type size_type
void hdf5store_list(std::size_t nrow, std::size_t ncol, const std::string &file_name, const std::string &data_name, InputIterIter first, SInputIter sfirst, bool append=false)
Store a list in the HDF5 format from an iterator to iterators.
inline::hid_t hdf5io_datatype< long >()
HDF5 data type specialization for long.
void hdf5store_new(const std::string &file_name)
Create a new HDF5 file for store data.
inline::hsize_t hdf5size(const std::string &file_name, const std::string &data_name)
Get the number of bytes of the data in the HDF5 format.
void hdf5store_list_insert_tuple(std::size_t nrow, const std::string &file_name, const std::string &data_name, const std::tuple< InputIter, InputIters... > &first, const std::string *sptr, std::integral_constant< std::size_t, 0 >)
void hdf5store_list_empty(const std::string &file_name, const std::string &data_name, bool append=false)
Create an empty list.
std::size_t summary_header_size_int() const
The size of Sampler summary header (integer data, size etc.)
inline::hid_t hdf5io_datatype< unsigned long >()
HDF5 data type specialization for unsigned long.
InputIter set(std::size_t n, InputIter first)
void set(std::size_t n, OutputIter)
OutputIter hdf5load(const std::string &file_name, const std::string &data_name, OutputIter first)
Load raw data in the HDF5 format.
inline::hid_t hdf5io_datatype< short >()
HDF5 data type specialization for short.
inline::hid_t hdf5io_datatype< float >()
HDF5 data type specialization for float.
size_type size() const
Number of particles.
inline::hid_t hdf5io_datatype< long double >()
HDF5 data type specialization for long double.
bool hdf5store_int(std::size_t n, IntType *r, std::false_type)
inline::hid_t hdf5io_datatype< unsigned long long >()
HDF5 data type specialization for unsigned long.
inline::hid_t hdf5io_datatype< long long >()
HDF5 data type specialization for long long.
void hdf5store(const Sampler< T > &sampler, const std::string &file_name, const std::string &data_name, bool append=false)
Store a Sampler in the HDF5 format.