Convert HDF5 read_double to C++

This commit is contained in:
Paul Romano 2018-04-17 22:55:07 -05:00
parent dcde6a331a
commit ef1956e811
3 changed files with 104 additions and 235 deletions

View file

@ -105,9 +105,18 @@ module hdf5_interface
integer(HID_T), value :: file_id
end subroutine file_close
subroutine read_double_c(obj_id, name, buffer, indep) &
bind(C, name='read_double')
import HID_T, C_DOUBLE, C_BOOL, C_PTR
integer(HID_T), value :: obj_id
type(C_PTR), value :: name
real(C_DOUBLE), intent(in) :: buffer(*)
logical(C_BOOL), intent(in) :: indep
end subroutine read_double_c
subroutine write_double_c(group_id, ndim, dims, name, buffer, indep) &
bind(C, name='write_double')
import HID_T, HSIZE_T, C_INT, C_DOUBLE, C_CHAR, C_BOOL, C_PTR
import HID_T, HSIZE_T, C_INT, C_DOUBLE, C_CHAR, C_BOOL
integer(HID_T), value :: group_id
integer(C_INT), value :: ndim
integer(HSIZE_T), intent(in) :: dims(*)
@ -388,40 +397,15 @@ contains
real(8), intent(in), target :: buffer ! data to write
logical, intent(in), optional :: indep ! independent I/O
integer :: hdf5_err
integer :: data_xfer_mode
#ifdef PHDF5
integer(HID_T) :: plist ! property list
#endif
integer(HID_T) :: dset ! data set handle
integer(HID_T) :: dspace ! data or file space handle
type(c_ptr) :: f_ptr
integer(HSIZE_T) :: dims(0)
logical(C_BOOL) :: indep_
real(C_DOUBLE) :: value(1)
! Set up independentive vs. independent I/O
data_xfer_mode = H5FD_MPIO_COLLECTIVE_F
if (present(indep)) then
if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F
end if
indep_ = .false.
if (present(indep)) indep_ = indep
value(1) = buffer
! Create dataspace and dataset
call h5screate_f(H5S_SCALAR_F, dspace, hdf5_err)
call h5dcreate_f(group_id, trim(name), H5T_NATIVE_DOUBLE, &
dspace, dset, hdf5_err)
f_ptr = c_loc(buffer)
if (using_mpio_device(group_id)) then
#ifdef PHDF5
call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err)
call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err)
call h5dwrite_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist)
call h5pclose_f(plist, hdf5_err)
#endif
else
call h5dwrite_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err)
end if
call h5dclose_f(dset, hdf5_err)
call h5sclose_f(dspace, hdf5_err)
call write_double_c(group_id, 0, dims, to_c_string(name), value, indep_)
end subroutine write_double
!===============================================================================
@ -502,62 +486,22 @@ contains
character(*), optional, intent(in) :: name
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer(HID_T) :: dset_id
integer(HSIZE_T) :: dims(1)
logical(C_BOOL) :: indep_
character(kind=C_CHAR), target, allocatable :: name_(:)
indep_ = .false.
if (present(indep)) indep_ = indep
! If 'name' argument is passed, obj_id is interpreted to be a group and
! 'name' is the name of the dataset we should read from
if (present(name)) then
call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err)
name_ = to_c_string(name)
call read_double_c(obj_id, c_loc(name_), buffer, indep_)
else
dset_id = obj_id
call read_double_c(obj_id, C_NULL_PTR, buffer, indep_)
end if
dims(:) = shape(buffer)
if (present(indep)) then
call read_double_1D_explicit(dset_id, dims, buffer, indep)
else
call read_double_1D_explicit(dset_id, dims, buffer)
end if
if (present(name)) call h5dclose_f(dset_id, hdf5_err)
end subroutine read_double_1D
subroutine read_double_1D_explicit(dset_id, dims, buffer, indep)
integer(HID_T), intent(in) :: dset_id
integer(HSIZE_T), intent(in) :: dims(1)
real(8), target, intent(inout) :: buffer(dims(1))
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer :: data_xfer_mode
#ifdef PHDF5
integer(HID_T) :: plist ! property list
#endif
type(c_ptr) :: f_ptr
! Set up collective vs. independent I/O
data_xfer_mode = H5FD_MPIO_COLLECTIVE_F
if (present(indep)) then
if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F
end if
f_ptr = c_loc(buffer)
if (using_mpio_device(dset_id)) then
#ifdef PHDF5
call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err)
call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err)
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist)
call h5pclose_f(plist, hdf5_err)
#endif
else
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err)
end if
end subroutine read_double_1D_explicit
!===============================================================================
! WRITE_DOUBLE_2D writes double precision 2-D array data
!===============================================================================
@ -588,62 +532,22 @@ contains
character(*), optional, intent(in) :: name
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer(HID_T) :: dset_id
integer(HSIZE_T) :: dims(2)
logical(C_BOOL) :: indep_
character(kind=C_CHAR), target, allocatable :: name_(:)
indep_ = .false.
if (present(indep)) indep_ = indep
! If 'name' argument is passed, obj_id is interpreted to be a group and
! 'name' is the name of the dataset we should read from
if (present(name)) then
call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err)
name_ = to_c_string(name)
call read_double_c(obj_id, c_loc(name_), buffer, indep_)
else
dset_id = obj_id
call read_double_c(obj_id, C_NULL_PTR, buffer, indep_)
end if
dims(:) = shape(buffer)
if (present(indep)) then
call read_double_2D_explicit(dset_id, dims, buffer, indep)
else
call read_double_2D_explicit(dset_id, dims, buffer)
end if
if (present(name)) call h5dclose_f(dset_id, hdf5_err)
end subroutine read_double_2D
subroutine read_double_2D_explicit(dset_id, dims, buffer, indep)
integer(HID_T), intent(in) :: dset_id
integer(HSIZE_T), intent(in) :: dims(2)
real(8), target, intent(inout) :: buffer(dims(1),dims(2))
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer :: data_xfer_mode
#ifdef PHDF5
integer(HID_T) :: plist ! property list
#endif
type(c_ptr) :: f_ptr
! Set up collective vs. independent I/O
data_xfer_mode = H5FD_MPIO_COLLECTIVE_F
if (present(indep)) then
if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F
end if
f_ptr = c_loc(buffer)
if (using_mpio_device(dset_id)) then
#ifdef PHDF5
call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err)
call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err)
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist)
call h5pclose_f(plist, hdf5_err)
#endif
else
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err)
end if
end subroutine read_double_2D_explicit
!===============================================================================
! WRITE_DOUBLE_3D writes double precision 3-D array data
!===============================================================================
@ -674,62 +578,22 @@ contains
character(*), optional, intent(in) :: name
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer(HID_T) :: dset_id
integer(HSIZE_T) :: dims(3)
logical(C_BOOL) :: indep_
character(kind=C_CHAR), target, allocatable :: name_(:)
indep_ = .false.
if (present(indep)) indep_ = indep
! If 'name' argument is passed, obj_id is interpreted to be a group and
! 'name' is the name of the dataset we should read from
if (present(name)) then
call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err)
name_ = to_c_string(name)
call read_double_c(obj_id, c_loc(name_), buffer, indep_)
else
dset_id = obj_id
call read_double_c(obj_id, C_NULL_PTR, buffer, indep_)
end if
dims(:) = shape(buffer)
if (present(indep)) then
call read_double_3D_explicit(dset_id, dims, buffer, indep)
else
call read_double_3D_explicit(dset_id, dims, buffer)
end if
if (present(name)) call h5dclose_f(dset_id, hdf5_err)
end subroutine read_double_3D
subroutine read_double_3D_explicit(dset_id, dims, buffer, indep)
integer(HID_T), intent(in) :: dset_id
integer(HSIZE_T), intent(in) :: dims(3)
real(8), target, intent(inout) :: buffer(dims(1),dims(2),dims(3))
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer :: data_xfer_mode
#ifdef PHDF5
integer(HID_T) :: plist ! property list
#endif
type(c_ptr) :: f_ptr
! Set up collective vs. independent I/O
data_xfer_mode = H5FD_MPIO_COLLECTIVE_F
if (present(indep)) then
if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F
end if
f_ptr = c_loc(buffer)
if (using_mpio_device(dset_id)) then
#ifdef PHDF5
call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err)
call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err)
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist)
call h5pclose_f(plist, hdf5_err)
#endif
else
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err)
end if
end subroutine read_double_3D_explicit
!===============================================================================
! WRITE_DOUBLE_4D writes double precision 4-D array data
!===============================================================================
@ -760,62 +624,22 @@ contains
character(*), optional, intent(in) :: name
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer(HID_T) :: dset_id
integer(HSIZE_T) :: dims(4)
logical(C_BOOL) :: indep_
character(kind=C_CHAR), target, allocatable :: name_(:)
indep_ = .false.
if (present(indep)) indep_ = indep
! If 'name' argument is passed, obj_id is interpreted to be a group and
! 'name' is the name of the dataset we should read from
if (present(name)) then
call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err)
name_ = to_c_string(name)
call read_double_c(obj_id, c_loc(name_), buffer, indep_)
else
dset_id = obj_id
call read_double_c(obj_id, C_NULL_PTR, buffer, indep_)
end if
dims(:) = shape(buffer)
if (present(indep)) then
call read_double_4D_explicit(dset_id, dims, buffer, indep)
else
call read_double_4D_explicit(dset_id, dims, buffer)
end if
if (present(name)) call h5dclose_f(dset_id, hdf5_err)
end subroutine read_double_4D
subroutine read_double_4D_explicit(dset_id, dims, buffer, indep)
integer(HID_T), intent(in) :: dset_id
integer(HSIZE_T), intent(in) :: dims(4)
real(8), target, intent(inout) :: buffer(dims(1),dims(2),dims(3),dims(4))
logical, optional, intent(in) :: indep ! independent I/O
integer :: hdf5_err
integer :: data_xfer_mode
#ifdef PHDF5
integer(HID_T) :: plist ! property list
#endif
type(c_ptr) :: f_ptr
! Set up collective vs. independent I/O
data_xfer_mode = H5FD_MPIO_COLLECTIVE_F
if (present(indep)) then
if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F
end if
f_ptr = c_loc(buffer)
if (using_mpio_device(dset_id)) then
#ifdef PHDF5
call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err)
call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err)
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist)
call h5pclose_f(plist, hdf5_err)
#endif
else
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err)
end if
end subroutine read_double_4D_explicit
!===============================================================================
! WRITE_INTEGER writes integer precision scalar data
!===============================================================================

View file

@ -11,7 +11,8 @@
namespace openmc {
bool
using_mpio_device(hid_t obj_id) {
using_mpio_device(hid_t obj_id)
{
// Determine file that this object is part of
hid_t file_id = H5Iget_file_id(obj_id);
@ -109,16 +110,19 @@ file_open(const char* filename, char mode, bool parallel)
}
hid_t
file_open(const std::string& filename, char mode, bool parallel=false) {
file_open(const std::string& filename, char mode, bool parallel=false)
{
file_open(filename.c_str(), mode, parallel);
}
void file_close(hid_t file_id) {
void file_close(hid_t file_id)
{
H5Fclose(file_id);
}
bool
object_exists(hid_t object_id, const char* name) {
object_exists(hid_t object_id, const char* name)
{
htri_t out = H5LTpath_valid(object_id, name, true);
if (out < 0) {
std::stringstream err_msg;
@ -130,7 +134,8 @@ object_exists(hid_t object_id, const char* name) {
hid_t
open_dataset(hid_t group_id, const char* name){
open_dataset(hid_t group_id, const char* name)
{
if (object_exists(group_id, name)) {
return H5Dopen(group_id, name, H5P_DEFAULT);
} else {
@ -142,7 +147,8 @@ open_dataset(hid_t group_id, const char* name){
hid_t
open_group(hid_t group_id, const char* name){
open_group(hid_t group_id, const char* name)
{
if (object_exists(group_id, name)) {
return H5Gopen(group_id, name, H5P_DEFAULT);
} else {
@ -153,10 +159,46 @@ open_group(hid_t group_id, const char* name){
}
void
read_double(hid_t obj_id, const char* name, double* buffer, bool indep)
{
hid_t dset = obj_id;
if (name) dset = H5Dopen(obj_id, name, H5P_DEFAULT);
if (using_mpio_device(dset)) {
#ifdef PHDF5
// Set up collective vs independent I/O
auto data_xfer_mode {indep ? H5FD_MPIO_INDEPENDENT : H5FD_MPIO_COLLECTIVE};
// Create dataset transfer property list
hid_t plist = H5Pcreate(H5P_DATASET_XFER);
H5Pset_dxpl_mpio(plist, data_xfer_mode);
// Write data
H5Dread(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, plist, buffer);
H5Pclose(plist);
#endif
} else {
H5Dread(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer);
}
if (name) H5Dclose(dset);
}
void
write_double(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
const double* buffer, bool indep) {
hid_t dspace = H5Screate_simple(ndim, dims, nullptr);
const double* buffer, bool indep)
{
// If array is given, create a simple dataspace. Otherwise, create a scalar
// datascape.
hid_t dspace;
if (ndim > 0) {
dspace = H5Screate_simple(ndim, dims, nullptr);
} else {
dspace = H5Screate(H5S_SCALAR);
}
hid_t dset = H5Dcreate(group_id, name, H5T_NATIVE_DOUBLE, dspace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

View file

@ -41,8 +41,11 @@ write_double_1D(hid_t group_id, char const *name,
H5Dclose(dataset);
}
extern "C" void write_double(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
const double* buffer, bool indep);
extern "C" void read_double(hid_t obj_id, const char* name, double* buffer,
bool indep);
extern "C" void write_double(hid_t group_id, int ndim, const hsize_t* dims,
const char* name, const double* buffer, bool indep);
void write_string(hid_t group_id, char const *name, char const *buffer);
void write_string(hid_t group_id, char const *name, const std::string &buffer);