20 #ifndef __DOLFIN_HDF5_INTERFACE_H 21 #define __DOLFIN_HDF5_INTERFACE_H 31 #include <dolfin/common/MPI.h> 33 #include <dolfin/log/log.h> 50 static hid_t
open_file(MPI_Comm mpi_comm,
const std::string filename,
51 const std::string mode,
const bool use_mpi_io);
54 static void close_file(
const hid_t hdf5_file_handle);
58 static void flush_file(
const hid_t hdf5_file_handle);
60 static std::string get_filename(hid_t hdf5_file_handle);
71 const std::string dataset_path,
72 const std::vector<T>& data,
73 const std::pair<std::int64_t, std::int64_t> range,
74 const std::vector<std::int64_t> global_size,
75 bool use_mpio,
bool use_chunking);
83 const std::string dataset_path,
84 const std::pair<std::int64_t, std::int64_t> range,
85 std::vector<T>& data);
88 static bool has_group(
const hid_t hdf5_file_handle,
89 const std::string group_name);
92 static bool has_dataset(
const hid_t hdf5_file_handle,
93 const std::string dataset_path);
96 static void add_group(
const hid_t hdf5_file_handle,
97 const std::string dataset_path);
101 const std::string dataset_path);
105 const std::string group_name);
108 static std::vector<std::int64_t>
110 const std::string dataset_path);
113 static std::vector<std::string>
dataset_list(
const hid_t hdf5_file_handle,
114 const std::string group_name);
117 static const std::string
119 const std::string dataset_path,
120 const std::string attribute_name);
123 template <
typename T>
125 const std::string dataset_path,
126 const std::string attribute_name,
130 template <
typename T>
132 const std::string dataset_path,
133 const std::string attribute_name,
134 const T& attribute_value);
138 const std::string dataset_path,
139 const std::string attribute_name);
143 const std::string dataset_path,
144 const std::string attribute_name);
147 static const std::vector<std::string>
148 list_attributes(
const hid_t hdf5_file_handle,
149 const std::string dataset_path);
168 static herr_t attribute_iteration_function(hid_t loc_id,
170 const H5A_info_t*
info,
173 template <
typename T>
174 static void add_attribute_value(
const hid_t dset_id,
175 const std::string attribute_name,
176 const T& attribute_value);
178 template <
typename T>
179 static void add_attribute_value(
const hid_t dset_id,
180 const std::string attribute_name,
181 const std::vector<T>& attribute_value);
183 template <
typename T>
184 static void get_attribute_value(
const hid_t attr_type,
188 template <
typename T>
189 static void get_attribute_value(
const hid_t attr_type,
191 std::vector<T>& attribute_value);
194 template <
typename T>
195 static hid_t hdf5_type()
198 "get HDF5 primitive data type",
199 "No specialised function for this data type");
206 template <>
inline hid_t HDF5Interface::hdf5_type<float>()
207 {
return H5T_NATIVE_FLOAT; }
209 template <>
inline hid_t HDF5Interface::hdf5_type<double>()
210 {
return H5T_NATIVE_DOUBLE; }
212 template <>
inline hid_t HDF5Interface::hdf5_type<int>()
213 {
return H5T_NATIVE_INT; }
215 template <>
inline hid_t HDF5Interface::hdf5_type<std::int64_t>()
216 {
return H5T_NATIVE_INT64; }
218 template <>
inline hid_t HDF5Interface::hdf5_type<std::size_t>()
220 if (
sizeof(std::size_t) ==
sizeof(
unsigned long))
221 return H5T_NATIVE_ULONG;
222 else if (
sizeof(std::size_t) ==
sizeof(
unsigned int))
223 return H5T_NATIVE_UINT;
226 "determine size of std::size_t",
227 "std::size_t is not the same size as long or int");
231 template <
typename T>
234 const std::string dataset_path,
235 const std::vector<T>& data,
236 const std::pair<std::int64_t, std::int64_t> range,
237 const std::vector<int64_t> global_size,
238 bool use_mpi_io,
bool use_chunking)
241 const std::size_t rank = global_size.size();
242 dolfin_assert(rank != 0);
247 "write dataset to HDF5 file",
248 "Only rank 1 and rank 2 dataset are supported");
252 const hid_t h5type = hdf5_type<T>();
255 std::vector<hsize_t> count(global_size.begin(), global_size.end());
256 count[0] = range.second - range.first;
259 std::vector<hsize_t> offset(rank, 0);
260 offset[0] = range.first;
263 const std::vector<hsize_t> dimsf(global_size.begin(), global_size.end());
269 const hid_t filespace0 = H5Screate_simple(rank, dimsf.data(), NULL);
270 dolfin_assert(filespace0 != HDF5_FAIL);
273 hid_t chunking_properties;
277 hsize_t chunk_size = dimsf[0]/2;
278 if (chunk_size > 1048576)
279 chunk_size = 1048576;
280 if (chunk_size < 1024)
283 hsize_t chunk_dims[2] = {chunk_size, dimsf[1]};
284 chunking_properties = H5Pcreate(H5P_DATASET_CREATE);
285 H5Pset_chunk(chunking_properties, rank, chunk_dims);
288 chunking_properties = H5P_DEFAULT;
291 const std::string group_name(dataset_path, 0, dataset_path.rfind(
'/'));
295 const hid_t dset_id = H5Dcreate2(file_handle, dataset_path.c_str(), h5type,
296 filespace0, H5P_DEFAULT,
297 chunking_properties, H5P_DEFAULT);
298 dolfin_assert(dset_id != HDF5_FAIL);
301 status = H5Sclose(filespace0);
302 dolfin_assert(status != HDF5_FAIL);
305 const hid_t memspace = H5Screate_simple(rank, count.data(), NULL);
306 dolfin_assert(memspace != HDF5_FAIL);
309 const hid_t filespace1 = H5Dget_space(dset_id);
310 status = H5Sselect_hyperslab(filespace1, H5S_SELECT_SET, offset.data(),
311 NULL, count.data(), NULL);
312 dolfin_assert(status != HDF5_FAIL);
315 const hid_t plist_id = H5Pcreate(H5P_DATASET_XFER);
318 #ifdef H5_HAVE_PARALLEL 319 status = H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);
320 dolfin_assert(status != HDF5_FAIL);
324 "HDF5 library has not been configured with MPI");
329 status = H5Dwrite(dset_id, h5type, memspace, filespace1, plist_id,
331 dolfin_assert(status != HDF5_FAIL);
336 status = H5Pclose(chunking_properties);
337 dolfin_assert(status != HDF5_FAIL);
341 status = H5Dclose(dset_id);
342 dolfin_assert(status != HDF5_FAIL);
345 status = H5Sclose(filespace1);
346 dolfin_assert(status != HDF5_FAIL);
349 status = H5Sclose(memspace);
350 dolfin_assert(status != HDF5_FAIL);
353 status = H5Pclose(plist_id);
354 dolfin_assert(status != HDF5_FAIL);
357 template <
typename T>
360 const std::string dataset_path,
361 const std::pair<std::int64_t, std::int64_t> range,
362 std::vector<T>& data)
365 const hid_t dset_id = H5Dopen2(file_handle, dataset_path.c_str(),
367 dolfin_assert(dset_id != HDF5_FAIL);
370 const hid_t dataspace = H5Dget_space(dset_id);
371 dolfin_assert(dataspace != HDF5_FAIL);
374 const int rank = H5Sget_simple_extent_ndims(dataspace);
375 dolfin_assert(rank >= 0);
378 warning(
"HDF5Interface::read_dataset untested for rank > 2.");
381 std::vector<hsize_t> shape(rank);
384 const int ndims = H5Sget_simple_extent_dims(dataspace, shape.data(), NULL);
385 dolfin_assert(ndims == rank);
388 std::vector<hsize_t> offset(rank, 0);
389 std::vector<hsize_t> count = shape;
390 if (range.first != -1 and range.second != -1)
392 offset[0]= range.first;
393 count[0] = range.second - range.first;
400 herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
401 offset.data(), NULL, count.data(),
403 dolfin_assert(status != HDF5_FAIL);
406 const hid_t memspace = H5Screate_simple(rank, count.data(), NULL);
407 dolfin_assert (memspace != HDF5_FAIL);
410 std::size_t data_size = 1;
411 for (std::size_t i = 0; i < count.size(); ++i)
412 data_size *= count[i];
413 data.resize(data_size);
416 const hid_t h5type = hdf5_type<T>();
417 status = H5Dread(dset_id, h5type, memspace, dataspace, H5P_DEFAULT,
419 dolfin_assert(status != HDF5_FAIL);
422 status = H5Sclose(dataspace);
423 dolfin_assert(status != HDF5_FAIL);
426 status = H5Sclose(memspace);
427 dolfin_assert(status != HDF5_FAIL);
430 status = H5Dclose(dset_id);
431 dolfin_assert(status != HDF5_FAIL);
434 template <
typename T>
436 const std::string dataset_path,
437 const std::string attribute_name,
443 const hid_t dset_id = H5Oopen(hdf5_file_handle, dataset_path.c_str(),
445 dolfin_assert(dset_id != HDF5_FAIL);
448 const hid_t attr_id = H5Aopen(dset_id, attribute_name.c_str(), H5P_DEFAULT);
449 dolfin_assert(attr_id != HDF5_FAIL);
450 const hid_t attr_type = H5Aget_type(attr_id);
451 dolfin_assert(attr_type != HDF5_FAIL);
454 get_attribute_value(attr_type, attr_id, attribute_value);
457 status = H5Tclose(attr_type);
458 dolfin_assert(status != HDF5_FAIL);
461 status = H5Aclose(attr_id);
462 dolfin_assert(status != HDF5_FAIL);
465 status = H5Oclose(dset_id);
466 dolfin_assert(status != HDF5_FAIL);
469 template <
typename T>
471 const std::string dataset_path,
472 const std::string attribute_name,
473 const T& attribute_value)
477 hid_t dset_id = H5Oopen(hdf5_file_handle, dataset_path.c_str(),
479 dolfin_assert(dset_id != HDF5_FAIL);
482 htri_t has_attr = H5Aexists(dset_id, attribute_name.c_str());
483 dolfin_assert(has_attr != HDF5_FAIL);
486 herr_t status = H5Adelete(dset_id, attribute_name.c_str());
487 dolfin_assert(status != HDF5_FAIL);
491 add_attribute_value(dset_id, attribute_name, attribute_value);
494 herr_t status = H5Oclose(dset_id);
495 dolfin_assert(status != HDF5_FAIL);
506 HDF5Interface::add_attribute_value(
const hid_t dset_id,
507 const std::string attribute_name,
508 const T& attribute_value)
511 hid_t dataspace_id = H5Screate(H5S_SCALAR);
512 dolfin_assert(dataspace_id != HDF5_FAIL);
514 const hid_t h5type = hdf5_type<T>();
517 hid_t attribute_id = H5Acreate2(dset_id, attribute_name.c_str(),
518 h5type, dataspace_id,
519 H5P_DEFAULT, H5P_DEFAULT);
520 dolfin_assert(attribute_id != HDF5_FAIL);
523 herr_t status = H5Awrite(attribute_id, h5type, &attribute_value);
524 dolfin_assert(status != HDF5_FAIL);
527 status = H5Sclose(dataspace_id);
528 dolfin_assert(status != HDF5_FAIL);
531 status = H5Aclose(attribute_id);
532 dolfin_assert(status != HDF5_FAIL);
536 inline void HDF5Interface::add_attribute_value(
const hid_t dset_id,
537 const std::string attribute_name,
538 const std::vector<T>& attribute_value)
541 const hid_t h5type = hdf5_type<T>();
544 const hsize_t dimsf = attribute_value.size();
545 const hid_t dataspace_id = H5Screate_simple(1, &dimsf, NULL);
546 dolfin_assert(dataspace_id != HDF5_FAIL);
549 const hid_t attribute_id = H5Acreate2(dset_id, attribute_name.c_str(),
550 h5type, dataspace_id,
551 H5P_DEFAULT, H5P_DEFAULT);
552 dolfin_assert(attribute_id != HDF5_FAIL);
555 herr_t status = H5Awrite(attribute_id, h5type, attribute_value.data());
556 dolfin_assert(status != HDF5_FAIL);
559 status = H5Sclose(dataspace_id);
560 dolfin_assert(status != HDF5_FAIL);
563 status = H5Aclose(attribute_id);
564 dolfin_assert(status != HDF5_FAIL);
568 inline void HDF5Interface::add_attribute_value(
const hid_t dset_id,
569 const std::string attribute_name,
570 const std::string& attribute_value)
573 const hid_t dataspace_id = H5Screate(H5S_SCALAR);
574 dolfin_assert(dataspace_id != HDF5_FAIL);
577 const hid_t datatype_id = H5Tcopy(H5T_C_S1);
578 herr_t status = H5Tset_size(datatype_id, attribute_value.size());
579 dolfin_assert(status != HDF5_FAIL);
582 const hid_t attribute_id = H5Acreate2(dset_id, attribute_name.c_str(),
583 datatype_id, dataspace_id,
584 H5P_DEFAULT, H5P_DEFAULT);
585 dolfin_assert(attribute_id != HDF5_FAIL);
588 status = H5Awrite(attribute_id, datatype_id, attribute_value.c_str());
589 dolfin_assert(status != HDF5_FAIL);
592 status = H5Sclose(dataspace_id);
593 dolfin_assert(status != HDF5_FAIL);
596 status = H5Tclose(datatype_id);
597 dolfin_assert(status != HDF5_FAIL);
600 status = H5Aclose(attribute_id);
601 dolfin_assert(status != HDF5_FAIL);
605 inline void HDF5Interface::get_attribute_value(
const hid_t attr_type,
609 const hid_t h5type = hdf5_type<T>();
612 dolfin_assert(H5Tget_class(attr_type) == H5Tget_class(h5type));
615 herr_t status = H5Aread(attr_id, h5type, &attribute_value);
616 dolfin_assert(status != HDF5_FAIL);
621 HDF5Interface::get_attribute_value(
const hid_t attr_type,
623 std::vector<T>& attribute_value)
625 const hid_t h5type = hdf5_type<T>();
628 dolfin_assert(H5Tget_class(attr_type) == H5Tget_class(h5type));
631 const hid_t dataspace = H5Aget_space(attr_id);
632 dolfin_assert(dataspace != HDF5_FAIL);
634 hsize_t cur_size[10];
635 hsize_t max_size[10];
636 const int ndims = H5Sget_simple_extent_dims(dataspace, cur_size, max_size);
637 dolfin_assert(ndims == 1);
639 attribute_value.resize(cur_size[0]);
642 herr_t status = H5Aread(attr_id, h5type, attribute_value.data());
643 dolfin_assert(status != HDF5_FAIL);
646 status = H5Sclose(dataspace);
647 dolfin_assert(status != HDF5_FAIL);
651 inline void HDF5Interface::get_attribute_value(
const hid_t attr_type,
653 std::string& attribute_value)
656 dolfin_assert(H5Tget_class(attr_type) == H5T_STRING);
659 const hid_t memtype = H5Tcopy(H5T_C_S1);
660 const int string_length = H5Tget_size(attr_type) + 1;
661 herr_t status = H5Tset_size(memtype, string_length);
662 dolfin_assert(status != HDF5_FAIL);
667 std::vector<char> attribute_data(string_length);
668 status = H5Aread(attr_id, memtype, attribute_data.data());
669 dolfin_assert(status != HDF5_FAIL);
671 attribute_value.assign(attribute_data.data());
674 status = H5Tclose(memtype);
675 dolfin_assert(status != HDF5_FAIL);
static hid_t open_file(MPI_Comm mpi_comm, const std::string filename, const std::string mode, const bool use_mpi_io)
Open HDF5 and return file descriptor.
Definition: HDF5Interface.cpp:37
static const std::string get_attribute_type(const hid_t hdf5_file_handle, const std::string dataset_path, const std::string attribute_name)
Get type of attribute.
Definition: HDF5Interface.cpp:130
static void delete_attribute(const hid_t hdf5_file_handle, const std::string dataset_path, const std::string attribute_name)
Delete an attribute from a dataset or group.
Definition: HDF5Interface.cpp:192
void warning(std::string msg,...)
Print warning.
Definition: log.cpp:115
static void read_dataset(const hid_t file_handle, const std::string dataset_path, const std::pair< std::int64_t, std::int64_t > range, std::vector< T > &data)
Definition: HDF5Interface.h:359
Definition: HDF5Interface.h:44
static void get_attribute(const hid_t hdf5_file_handle, const std::string dataset_path, const std::string attribute_name, T &attribute_value)
Get a named attribute of a dataset of known type.
Definition: HDF5Interface.h:435
static void flush_file(const hid_t hdf5_file_handle)
Definition: HDF5Interface.cpp:108
static void close_file(const hid_t hdf5_file_handle)
Close HDF5 file.
Definition: HDF5Interface.cpp:102
static int num_datasets_in_group(const hid_t hdf5_file_handle, const std::string group_name)
Return number of data sets in a group.
Definition: HDF5Interface.cpp:399
static int dataset_rank(const hid_t hdf5_file_handle, const std::string dataset_path)
Get dataset rank.
Definition: HDF5Interface.cpp:342
static bool get_mpi_atomicity(const hid_t hdf5_file_handle)
Definition: HDF5Interface.cpp:455
static void add_attribute(const hid_t hdf5_file_handle, const std::string dataset_path, const std::string attribute_name, const T &attribute_value)
Add attribute to dataset or group.
Definition: HDF5Interface.h:470
static std::vector< std::string > dataset_list(const hid_t hdf5_file_handle, const std::string group_name)
Return list all datasets in named group of file.
Definition: HDF5Interface.cpp:412
static bool has_dataset(const hid_t hdf5_file_handle, const std::string dataset_path)
Check for existence of dataset in HDF5 file.
Definition: HDF5Interface.cpp:295
static void add_group(const hid_t hdf5_file_handle, const std::string dataset_path)
Add group to HDF5 file.
Definition: HDF5Interface.cpp:309
void info(std::string msg,...)
Print message.
Definition: log.cpp:72
void dolfin_error(std::string location, std::string task, std::string reason,...)
Definition: log.cpp:129
static bool has_attribute(const hid_t hdf5_file_handle, const std::string dataset_path, const std::string attribute_name)
Check if an attribute exists on a dataset or group.
Definition: HDF5Interface.cpp:246
static std::vector< std::int64_t > get_dataset_shape(const hid_t hdf5_file_handle, const std::string dataset_path)
Get dataset shape (size of each dimension)
Definition: HDF5Interface.cpp:368
static void write_dataset(const hid_t file_handle, const std::string dataset_path, const std::vector< T > &data, const std::pair< std::int64_t, std::int64_t > range, const std::vector< std::int64_t > global_size, bool use_mpio, bool use_chunking)
static bool has_group(const hid_t hdf5_file_handle, const std::string group_name)
Check for existence of group in HDF5 file.
Definition: HDF5Interface.cpp:269
static void set_mpi_atomicity(const hid_t hdf5_file_handle, const bool atomic)
Definition: HDF5Interface.cpp:444