Add C++ routines for HDF5 get_groups, get_datasets, get_name

This commit is contained in:
Paul Romano 2018-04-24 15:25:58 -05:00
parent 70173aa25c
commit 1a77f8afee
3 changed files with 201 additions and 78 deletions

View file

@ -13,13 +13,12 @@ module hdf5_interface
use, intrinsic :: ISO_C_BINDING
use hdf5
use h5lt
use error, only: fatal_error
#ifdef PHDF5
use message_passing, only: mpi_intracomm, MPI_INFO_NULL
#endif
use string, only: to_c_string
use string, only: to_c_string, to_f_string
implicit none
private
@ -316,31 +315,37 @@ contains
integer(HID_T), intent(in) :: object_id
character(len=150), allocatable, intent(out) :: names(:)
integer :: n_members, i, group_count, type
integer :: hdf5_err
character(len=150) :: name
integer :: i
integer(C_INT) :: n
character(len=150,kind=C_CHAR), target, allocatable :: names_(:)
type(C_PTR), allocatable :: name_ptrs(:)
! Get number of members in this location
call h5gn_members_f(object_id, './', n_members, hdf5_err)
interface
function get_num_groups(group_id) result(n) bind(C)
import HID_T, C_INT
integer(HID_T), value :: group_id
integer(C_INT) :: n
end function get_num_groups
subroutine get_groups_c(group_id, name) bind(C, name='get_groups')
import HID_T, C_PTR
integer(HID_T), value :: group_id
type(C_PTR) :: name(*)
end subroutine get_groups_c
end interface
! Get the number of groups
group_count = 0
do i = 0, n_members - 1
call h5gget_obj_info_idx_f(object_id, "./", i, name, type, hdf5_err)
if (type == H5G_GROUP_F) then
group_count = group_count + 1
end if
! Determine number of groups and allocate
n = get_num_groups(object_id)
allocate(names(n), names_(n), name_ptrs(n))
! Set C pointers to beginning of each string
do i = 1, size(names)
name_ptrs(i) = c_loc(names_(i))
end do
! Now we can allocate the storage for the ids
allocate(names(group_count))
group_count = 0
do i = 0, n_members - 1
call h5gget_obj_info_idx_f(object_id, "./", i, name, type, hdf5_err)
if (type == H5G_GROUP_F) then
group_count = group_count + 1
names(group_count) = trim(name)
end if
! Get names of groups and copy to Fortran strings
call get_groups_c(object_id, name_ptrs)
do i = 1, size(names)
names(i) = to_f_string(names_(i))
end do
end subroutine get_groups
@ -398,32 +403,37 @@ contains
integer(HID_T), intent(in) :: object_id
character(len=150), allocatable, intent(out) :: names(:)
integer :: n_members, i, dset_count, type
integer :: hdf5_err
character(len=150) :: name
integer :: i
integer(C_INT) :: n
character(len=150,kind=C_CHAR), target, allocatable :: names_(:)
type(C_PTR), allocatable :: name_ptrs(:)
interface
function get_num_datasets(group_id) result(n) bind(C)
import HID_T, C_INT
integer(HID_T), value :: group_id
integer(C_INT) :: n
end function get_num_datasets
subroutine get_datasets_c(group_id, name) bind(C, name='get_datasets')
import HID_T, C_PTR
integer(HID_T), value :: group_id
type(C_PTR) :: name(*)
end subroutine get_datasets_c
end interface
! Get number of members in this location
call h5gn_members_f(object_id, './', n_members, hdf5_err)
! Determine number of datasets and allocate
n = get_num_datasets(object_id)
allocate(names(n), names_(n), name_ptrs(n))
! Get the number of datasets
dset_count = 0
do i = 0, n_members - 1
call h5gget_obj_info_idx_f(object_id, "./", i, name, type, hdf5_err)
if (type == H5G_DATASET_F ) then
dset_count = dset_count + 1
end if
! Set C pointers to beginning of each string
do i = 1, size(names)
name_ptrs(i) = c_loc(names_(i))
end do
! Now we can allocate the storage for the ids
allocate(names(dset_count))
dset_count = 0
do i = 0, n_members - 1
call h5gget_obj_info_idx_f(object_id, "./", i, name, type, hdf5_err)
if (type == H5G_DATASET_F ) then
dset_count = dset_count + 1
names(dset_count) = trim(name)
end if
! Get names of datasets and copy to Fortran strings
call get_datasets_c(object_id, name_ptrs)
do i = 1, size(names)
names(i) = to_f_string(names_(i))
end do
end subroutine get_datasets
@ -432,21 +442,22 @@ contains
! GET_NAME Obtains the name of the current group in group_id
!===============================================================================
function get_name(group_id, name_len_) result(name)
integer(HID_T), intent(in) :: group_id
function get_name(object_id, name_len_) result(name)
integer(HID_T), intent(in) :: object_id
integer(SIZE_T), optional, intent(in) :: name_len_
character(len=150) :: name ! name of group
integer(SIZE_T) :: name_len, name_file_len
integer :: hdf5_err ! HDF5 error code
character(150) :: name ! name of object
character(kind=C_CHAR) :: name_(150)
interface
subroutine get_name_c(obj_id, name) bind(C, name='get_name')
import HID_T, C_CHAR
integer(HID_T), value :: obj_id
character(kind=C_CHAR), intent(out) :: name(*)
end subroutine get_name_c
end interface
if (present(name_len_)) then
name_len = name_len_
else
name_len = 150
end if
call h5iget_name_f(group_id, name, name_len, name_file_len, hdf5_err)
call get_name_c(object_id, name_)
name = to_f_string(name_)
end function get_name
!===============================================================================

View file

@ -36,26 +36,6 @@ attribute_typesize(hid_t obj_id, const char* name)
}
bool
using_mpio_device(hid_t obj_id)
{
// Determine file that this object is part of
hid_t file_id = H5Iget_file_id(obj_id);
// Get file access property list
hid_t fapl_id = H5Fget_access_plist(file_id);
// Get low-level driver identifier
hid_t driver = H5Pget_driver(fapl_id);
// Free resources
H5Pclose(fapl_id);
H5Fclose(file_id);
return driver == H5FD_MPIO;
}
void
get_shape(hid_t obj_id, hsize_t* dims)
{
@ -199,6 +179,113 @@ void file_close(hid_t file_id)
H5Fclose(file_id);
}
void
get_name(hid_t obj_id, char* name)
{
size_t size = 1 + H5Iget_name(obj_id, nullptr, 0);
H5Iget_name(obj_id, name, size);
}
int get_num_datasets(hid_t group_id)
{
// Determine number of links in the group
H5G_info_t info;
H5Gget_info(group_id, &info);
// Iterate over links to get number of groups
H5O_info_t oinfo;
int ndatasets = 0;
for (hsize_t i = 0; i < info.nlinks; ++i) {
// Determine type of object (and skip non-group)
H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo,
H5P_DEFAULT);
if (oinfo.type == H5O_TYPE_DATASET) ndatasets += 1;
}
return ndatasets;
}
int get_num_groups(hid_t group_id)
{
// Determine number of links in the group
H5G_info_t info;
H5Gget_info(group_id, &info);
// Iterate over links to get number of groups
H5O_info_t oinfo;
int ngroups = 0;
for (hsize_t i = 0; i < info.nlinks; ++i) {
// Determine type of object (and skip non-group)
H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo,
H5P_DEFAULT);
if (oinfo.type == H5O_TYPE_GROUP) ngroups += 1;
}
return ngroups;
}
void
get_datasets(hid_t group_id, char* name[])
{
// Determine number of links in the group
H5G_info_t info;
H5Gget_info(group_id, &info);
// Iterate over links to get names
H5O_info_t oinfo;
hsize_t count = 0;
size_t size;
for (hsize_t i = 0; i < info.nlinks; ++i) {
// Determine type of object (and skip non-group)
H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo,
H5P_DEFAULT);
if (oinfo.type != H5O_TYPE_DATASET) continue;
// Get size of name
size = 1 + H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC,
i, nullptr, 0, H5P_DEFAULT);
// Read name
H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
name[count], size, H5P_DEFAULT);
count += 1;
}
}
void
get_groups(hid_t group_id, char* name[])
{
// Determine number of links in the group
H5G_info_t info;
H5Gget_info(group_id, &info);
// Iterate over links to get names
H5O_info_t oinfo;
hsize_t count = 0;
size_t size;
for (hsize_t i = 0; i < info.nlinks; ++i) {
// Determine type of object (and skip non-group)
H5Oget_info_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i, &oinfo,
H5P_DEFAULT);
if (oinfo.type != H5O_TYPE_GROUP) continue;
// Get size of name
size = 1 + H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC,
i, nullptr, 0, H5P_DEFAULT);
// Read name
H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, i,
name[count], size, H5P_DEFAULT);
count += 1;
}
}
bool
object_exists(hid_t object_id, const char* name)
{
@ -548,4 +635,24 @@ write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, const dou
H5Sclose(dspace);
}
bool
using_mpio_device(hid_t obj_id)
{
// Determine file that this object is part of
hid_t file_id = H5Iget_file_id(obj_id);
// Get file access property list
hid_t fapl_id = H5Fget_access_plist(file_id);
// Get low-level driver identifier
hid_t driver = H5Pget_driver(fapl_id);
// Free resources
H5Pclose(fapl_id);
H5Fclose(file_id);
return driver == H5FD_MPIO;
}
} // namespace openmc

View file

@ -23,8 +23,13 @@ extern "C" size_t dataset_typesize(hid_t dset);
extern "C" hid_t file_open(const char* filename, char mode, bool parallel);
hid_t file_open(const std::string& filename, char mode, bool parallel);
extern "C" void file_close(hid_t file_id);
extern "C" void get_shape(hid_t obj_if, hsize_t* dims);
extern "C" void get_shape_attr(hid_t obj_if, const char* name, hsize_t* dims);
extern "C" void get_name(hid_t obj_id, char* name);
extern "C" int get_num_datasets(hid_t group_id);
extern "C" int get_num_groups(hid_t group_id);
extern "C" void get_datasets(hid_t group_id, char* name[]);
extern "C" void get_groups(hid_t group_id, char* name[]);
extern "C" void get_shape(hid_t obj_id, hsize_t* dims);
extern "C" void get_shape_attr(hid_t obj_id, const char* name, hsize_t* dims);
extern "C" bool object_exists(hid_t object_id, const char* name);
extern "C" hid_t open_dataset(hid_t group_id, const char* name);
extern "C" hid_t open_group(hid_t group_id, const char* name);