mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Convert HDF5 read_attribute_string/logical to C++
This commit is contained in:
parent
95b05ef02d
commit
c50c6f0700
3 changed files with 81 additions and 96 deletions
|
|
@ -100,6 +100,13 @@ module hdf5_interface
|
|||
public :: get_name
|
||||
|
||||
interface
|
||||
function attribute_typesize(obj_id, name) result(sz) bind(C)
|
||||
import HID_T, C_CHAR, SIZE_T
|
||||
integer(HID_T), value :: obj_id
|
||||
character(kind=C_CHAR), intent(in) :: name(*)
|
||||
integer(SIZE_T) :: sz
|
||||
end function attribute_typesize
|
||||
|
||||
function dataset_typesize(dset) result(sz) bind(C)
|
||||
import HID_T, SIZE_T
|
||||
integer(HID_T), value :: dset
|
||||
|
|
@ -149,6 +156,15 @@ module hdf5_interface
|
|||
real(C_DOUBLE), intent(out) :: buffer(*)
|
||||
end subroutine read_attr_double_c
|
||||
|
||||
subroutine read_attr_string_c(obj_id, name, slen, buffer) &
|
||||
bind(C, name='read_attr_string')
|
||||
import HID_T, C_CHAR, C_SIZE_T
|
||||
integer(HID_T), value :: obj_id
|
||||
character(kind=C_CHAR), intent(in) :: name(*)
|
||||
integer(C_SIZE_T), value :: slen
|
||||
character(kind=C_CHAR), intent(out) :: buffer(*)
|
||||
end subroutine read_attr_string_c
|
||||
|
||||
subroutine read_int_c(obj_id, name, buffer, indep) &
|
||||
bind(C, name='read_int')
|
||||
import HID_T, C_INT, C_BOOL, C_PTR
|
||||
|
|
@ -1290,44 +1306,22 @@ contains
|
|||
integer(HID_T), intent(in) :: obj_id
|
||||
character(*), intent(in) :: name ! name for data
|
||||
|
||||
integer :: hdf5_err
|
||||
integer(HID_T) :: attr_id ! data set handle
|
||||
integer(HID_T) :: filetype
|
||||
integer(HID_T) :: memtype
|
||||
integer(SIZE_T) :: i
|
||||
integer(SIZE_T) :: size
|
||||
character(kind=C_CHAR), allocatable, target :: temp_buffer(:)
|
||||
type(c_ptr) :: f_ptr
|
||||
integer(C_SIZE_T) :: i, n
|
||||
character(kind=C_CHAR), allocatable, target :: buffer_(:)
|
||||
|
||||
! Get dataset and dataspace
|
||||
call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err)
|
||||
! Allocate a C char array to get string
|
||||
n = attribute_typesize(obj_id, to_c_string(name))
|
||||
allocate(buffer_(n))
|
||||
|
||||
! Make sure buffer is large enough
|
||||
call h5aget_type_f(attr_id, filetype, hdf5_err)
|
||||
call h5tget_size_f(filetype, size, hdf5_err)
|
||||
allocate(temp_buffer(size))
|
||||
if (size > len(buffer)) then
|
||||
call fatal_error("Character buffer is not long enough to &
|
||||
&read HDF5 string.")
|
||||
end if
|
||||
! Read attribute
|
||||
call read_attr_string_c(obj_id, to_c_string(name), n, buffer_)
|
||||
|
||||
! Get datatype in memory based on Fortran character
|
||||
call h5tcopy_f(H5T_C_S1, memtype, hdf5_err)
|
||||
call h5tset_size_f(memtype, size + 1, hdf5_err)
|
||||
|
||||
! Get pointer to start of string
|
||||
f_ptr = c_loc(temp_buffer(1))
|
||||
|
||||
call h5aread_f(attr_id, memtype, f_ptr, hdf5_err)
|
||||
! Copy back to Fortran string
|
||||
buffer = ''
|
||||
do i = 1, size
|
||||
if (temp_buffer(i) == C_NULL_CHAR) cycle
|
||||
buffer(i:i) = temp_buffer(i)
|
||||
do i = 1, n
|
||||
if (buffer_(i) == C_NULL_CHAR) cycle
|
||||
buffer(i:i) = buffer_(i)
|
||||
end do
|
||||
|
||||
call h5aclose_f(attr_id, hdf5_err)
|
||||
call h5tclose_f(filetype, hdf5_err)
|
||||
call h5tclose_f(memtype, hdf5_err)
|
||||
end subroutine read_attribute_string
|
||||
|
||||
subroutine read_attribute_string_1D(buffer, obj_id, name)
|
||||
|
|
@ -1335,82 +1329,43 @@ contains
|
|||
integer(HID_T), intent(in) :: obj_id
|
||||
character(*), intent(in) :: name
|
||||
|
||||
integer :: hdf5_err
|
||||
integer(HID_T) :: space_id
|
||||
integer(HID_T) :: attr_id
|
||||
integer(C_SIZE_T) :: i, j, k, n, m
|
||||
integer(HSIZE_T) :: dims(1)
|
||||
integer(HSIZE_T) :: maxdims(1)
|
||||
character(kind=C_CHAR), allocatable, target :: buffer_(:)
|
||||
|
||||
call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err)
|
||||
|
||||
if (allocated(buffer)) then
|
||||
dims(:) = shape(buffer)
|
||||
else
|
||||
call h5aget_space_f(attr_id, space_id, hdf5_err)
|
||||
call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err)
|
||||
if (.not. allocated(buffer)) then
|
||||
call get_shape_attr(obj_id, to_c_string(name), dims)
|
||||
allocate(buffer(dims(1)))
|
||||
call h5sclose_f(space_id, hdf5_err)
|
||||
end if
|
||||
|
||||
call read_attribute_string_1D_explicit(attr_id, dims, buffer)
|
||||
call h5aclose_f(attr_id, hdf5_err)
|
||||
! Allocate a C char array to get strings
|
||||
n = attribute_typesize(obj_id, to_c_string(name))
|
||||
m = size(buffer)
|
||||
allocate(buffer_(n*m))
|
||||
|
||||
! Read attribute
|
||||
call read_attr_string_c(obj_id, to_c_string(name), n, buffer_)
|
||||
|
||||
! Convert null-terminated C strings into Fortran strings
|
||||
do i = 1, m
|
||||
buffer(i) = ''
|
||||
do j = 1, n
|
||||
k = (i-1)*n + j
|
||||
if (buffer_(k) == C_NULL_CHAR) exit
|
||||
buffer(i)(j:j) = buffer_(k)
|
||||
end do
|
||||
end do
|
||||
end subroutine read_attribute_string_1D
|
||||
|
||||
subroutine read_attribute_string_1D_explicit(attr_id, dims, buffer)
|
||||
integer(HID_T), intent(in) :: attr_id
|
||||
integer(HSIZE_T), intent(in) :: dims(1)
|
||||
character(*), target, intent(inout) :: buffer(dims(1))
|
||||
|
||||
integer :: hdf5_err
|
||||
integer(HID_T) :: filetype
|
||||
integer(HID_T) :: memtype
|
||||
integer(SIZE_T) :: size
|
||||
integer(SIZE_T) :: n
|
||||
type(c_ptr) :: f_ptr
|
||||
|
||||
! Make sure buffer is large enough
|
||||
call h5aget_type_f(attr_id, filetype, hdf5_err)
|
||||
call h5tget_size_f(filetype, size, hdf5_err)
|
||||
if (size > len(buffer(1)) + 1) then
|
||||
call fatal_error("Character buffer is not long enough to &
|
||||
&read HDF5 string array.")
|
||||
end if
|
||||
|
||||
! Get datatype in memory based on Fortran character
|
||||
n = len(buffer(1))
|
||||
call h5tcopy_f(H5T_FORTRAN_S1, memtype, hdf5_err)
|
||||
call h5tset_size_f(memtype, n, hdf5_err)
|
||||
|
||||
! Get pointer to start of string
|
||||
f_ptr = c_loc(buffer(1)(1:1))
|
||||
|
||||
call h5aread_f(attr_id, memtype, f_ptr, hdf5_err)
|
||||
|
||||
call h5tclose_f(filetype, hdf5_err)
|
||||
call h5tclose_f(memtype, hdf5_err)
|
||||
end subroutine read_attribute_string_1D_explicit
|
||||
|
||||
subroutine read_attribute_logical(buffer, obj_id, name)
|
||||
logical, intent(inout), target :: buffer
|
||||
integer(HID_T), intent(in) :: obj_id
|
||||
character(*), intent(in) :: name
|
||||
|
||||
integer, target :: int_buffer
|
||||
integer :: hdf5_err
|
||||
integer(HID_T) :: attr_id
|
||||
type(c_ptr) :: f_ptr
|
||||
integer :: tmp
|
||||
|
||||
call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err)
|
||||
f_ptr = c_loc(int_buffer)
|
||||
call h5aread_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err)
|
||||
call h5aclose_f(attr_id, hdf5_err)
|
||||
|
||||
! Convert to Fortran logical
|
||||
if (int_buffer == 0) then
|
||||
buffer = .false.
|
||||
else
|
||||
buffer = .true.
|
||||
end if
|
||||
call read_attribute_integer(tmp, obj_id, name)
|
||||
buffer = (tmp /= 0)
|
||||
end subroutine read_attribute_logical
|
||||
|
||||
subroutine get_shape(obj_id, dims)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,18 @@ attribute_exists(hid_t obj_id, const char* name)
|
|||
}
|
||||
|
||||
|
||||
size_t
|
||||
attribute_typesize(hid_t obj_id, const char* name)
|
||||
{
|
||||
hid_t attr = H5Aopen(obj_id, name, H5P_DEFAULT);
|
||||
hid_t filetype = H5Aget_type(attr);
|
||||
size_t n = H5Tget_size(filetype);
|
||||
H5Tclose(filetype);
|
||||
H5Aclose(attr);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
using_mpio_device(hid_t obj_id)
|
||||
{
|
||||
|
|
@ -238,6 +250,21 @@ read_attr_int(hid_t obj_id, const char* name, int* buffer)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer)
|
||||
{
|
||||
// Create datatype for a string
|
||||
hid_t datatype = H5Tcopy(H5T_C_S1);
|
||||
H5Tset_size(datatype, slen + 1);
|
||||
|
||||
// Read data into buffer
|
||||
read_attr(obj_id, name, datatype, buffer);
|
||||
|
||||
// Free resources
|
||||
H5Tclose(datatype);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id,
|
||||
void* buffer, bool indep)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
namespace openmc {
|
||||
|
||||
extern "C" bool attribute_exists(hid_t obj_id, const char* name);
|
||||
extern "C" size_t attribute_typesize(hid_t obj_id, const char* name);
|
||||
extern "C" hid_t create_group(hid_t parent_id, const char* name);
|
||||
hid_t create_group(hid_t parent_id, const std::string& name);
|
||||
extern "C" void close_dataset(hid_t dataset_id);
|
||||
|
|
@ -51,6 +52,8 @@ void read_attr(hid_t obj_id, const char* name, hid_t mem_type_id,
|
|||
const void* buffer);
|
||||
extern "C" void read_attr_double(hid_t obj_id, const char* name, double* buffer);
|
||||
extern "C" void read_attr_int(hid_t obj_id, const char* name, int* buffer);
|
||||
extern "C" void read_attr_string(hid_t obj_id, const char* name, size_t slen,
|
||||
char* buffer);
|
||||
|
||||
void read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id,
|
||||
void* buffer, bool indep);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue