Skip to content

Commit 195bec1

Browse files
committed
add get_strpad tests
1 parent 766f601 commit 195bec1

File tree

6 files changed

+59
-25
lines changed

6 files changed

+59
-25
lines changed

src/interface.f90

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,23 @@ module h5mpi
4545
procedure, public :: shape => hdf_get_shape
4646
procedure, public :: layout => hdf_get_layout
4747
procedure, public :: chunks => hdf_get_chunk
48-
procedure, public :: exist => hdf_check_exist
4948
procedure, public :: class => get_class
5049
procedure, public :: dtype => get_native_dtype
5150
procedure, public :: deflate => get_deflate
51+
procedure, public :: exist => hdf_check_exist
5252
procedure, public :: is_contig => hdf_is_contig
5353
procedure, public :: is_chunked => hdf_is_chunked
5454
procedure, public :: is_compact => hdf_is_compact
55+
procedure, public :: get_strpad
5556
procedure, public :: softlink => create_softlink
5657
procedure, public :: is_open
5758
!! procedures without mapping
5859

60+
!> below are procedure that need generic mapping (type or rank agnostic)
61+
5962
generic, public :: write => h5write_scalar, h5write_1d, h5write_2d, h5write_3d, h5write_4d, h5write_5d, h5write_6d, h5write_7d
6063

6164
generic, public :: read => h5read_scalar, h5read_1d, h5read_2d, h5read_3d, h5read_4d, h5read_5d, h5read_6d, h5read_7d
62-
!! mapped procedures
6365

6466
!> write attributes
6567
generic, public :: writeattr => writeattr_char, writeattr_num
@@ -253,6 +255,11 @@ module subroutine h5open_read(self, dname, dims, dset_dims, filespace, memspace,
253255
integer(HID_T), intent(out) :: filespace, memspace, dset_id
254256
end subroutine h5open_read
255257

258+
module integer function get_strpad(self, dset_name)
259+
class(hdf5_file), intent(in) :: self
260+
character(*), intent(in) :: dset_name
261+
end function get_strpad
262+
256263
module logical function get_deflate(self, dname)
257264
class(hdf5_file), intent(in) :: self
258265
character(*), intent(in) :: dname

src/read.f90

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
h5pget_layout_f, h5pget_chunk_f, h5pclose_f, h5pget_nfilters_f, h5pget_filter_f, &
77
h5dget_type_f, h5dopen_f, h5dclose_f, &
88
h5lexists_f, &
9-
h5tclose_f, h5tget_native_type_f, h5tget_class_f, H5Tget_order_f, h5tget_size_f, &
9+
h5tclose_f, h5tget_native_type_f, h5tget_class_f, H5Tget_order_f, h5tget_size_f, h5tget_strpad_f, &
1010
h5z_filter_deflate_f, &
1111
H5T_DIR_ASCEND_F
1212

@@ -35,12 +35,22 @@
3535

3636

3737
module procedure get_class
38-
3938
call get_dset_class(self, dname, get_class)
40-
4139
end procedure get_class
4240

4341

42+
module procedure get_strpad
43+
!! H5T_STR_NULLTERM Null terminate (as C does).
44+
!! H5T_STR_NULLPAD Pad with zeros.
45+
!! H5T_STR_SPACEPAD Pad with spaces (as FORTRAN does).
46+
47+
integer :: class
48+
49+
call get_dset_class(self, dset_name, class, pad_type=get_strpad)
50+
51+
end procedure get_strpad
52+
53+
4454
module procedure get_deflate
4555
!! h5pget_filter_f doesn't work collectively, will crash on h5fclose_f
4656
!! if(mpi_id==0) with mpi_bcast does not work, same crash.
@@ -61,6 +71,7 @@
6171

6272
Naux = size(Aux, kind=SIZE_T)
6373

74+
if(.not.self%exist(dname)) error stop "ERROR:h5fortran:get_deflate: " // dname // " does not exist: " // self%filename
6475
call h5dopen_f(self%file_id, dname, dset_id, ierr)
6576
if (ierr/=0) error stop "ERROR:h5fortran:get_deflate:h5dopen: " // dname // " in " // self%filename
6677

@@ -99,40 +110,34 @@
99110
end procedure get_deflate
100111

101112

102-
subroutine get_dset_class(self, dname, class, ds_id, size_bytes)
113+
subroutine get_dset_class(self, dname, class, ds_id, size_bytes, pad_type)
103114
!! get the dataset class (integer, float, string, ...)
104115
!! {H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F}
105116
class(hdf5_file), intent(in) :: self
106117
character(*), intent(in) :: dname
107118
integer, intent(out) :: class
108-
integer(hid_t), intent(in), optional :: ds_id
109-
integer(size_t), intent(out), optional :: size_bytes
119+
integer(HID_T), intent(in), optional :: ds_id
120+
integer(SIZE_T), intent(out), optional :: size_bytes
121+
integer, intent(out), optional :: pad_type
110122

111123
integer :: ierr
112-
integer(hid_t) :: dtype_id, native_dtype_id, dset_id
124+
integer(HID_T) :: dtype_id, native_dtype_id, dset_id
113125

114126
if(present(ds_id)) then
115127
dset_id = ds_id
116128
else
129+
if(.not.self%exist(dname)) error stop "ERROR:h5fortran:get_dset_class: " // dname // " does not exist: " // self%filename
130+
117131
call h5dopen_f(self%file_id, dname, dset_id, ierr)
118132
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: ' // dname // ' from ' // self%filename
119133
endif
120134

121135
call h5dget_type_f(dset_id, dtype_id, ierr)
122136
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: dtype_id ' // dname // ' from ' // self%filename
123137

124-
if(.not.present(ds_id)) then
125-
call h5dclose_f(dset_id, ierr)
126-
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: close dataset ' // dname // ' from ' // self%filename
127-
endif
128-
129138
call h5tget_native_type_f(dtype_id, H5T_DIR_ASCEND_F, native_dtype_id, ierr)
130139
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: native_dtype_id ' // dname // ' from ' // self%filename
131140

132-
call h5tclose_f(dtype_id, ierr)
133-
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: closing dtype ' // dname // ' from ' // self%filename
134-
135-
136141
!> compose datatype inferred
137142
call h5tget_class_f(native_dtype_id, class, ierr)
138143
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: class ' // dname // ' from ' // self%filename
@@ -142,9 +147,25 @@ subroutine get_dset_class(self, dname, class, ds_id, size_bytes)
142147
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: byte size ' // dname // ' from ' // self%filename
143148
endif
144149

150+
if(present(pad_type)) then
151+
if(class /= H5T_STRING_F) error stop "ERROR:h5fortran:get_class: pad_type only for string"
152+
153+
call H5Tget_strpad_f(dtype_id, pad_type, ierr)
154+
if(ierr /= 0) error stop "h5fortran:read:h5tget_strpad " // dname // " in " // self%filename
155+
endif
156+
157+
!> close to avoid memory leaks
145158
call h5tclose_f(native_dtype_id, ierr)
146159
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: closing native dtype ' // dname // ' from ' // self%filename
147160

161+
call h5tclose_f(dtype_id, ierr)
162+
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: closing dtype ' // dname // ' from ' // self%filename
163+
164+
if(.not.present(ds_id)) then
165+
call h5dclose_f(dset_id, ierr)
166+
if(ierr/=0) error stop 'ERROR:h5fortran:get_class: close dataset ' // dname // ' from ' // self%filename
167+
endif
168+
148169
end subroutine get_dset_class
149170

150171

@@ -209,7 +230,6 @@ end subroutine get_dset_class
209230

210231

211232
module procedure hdf_get_shape
212-
213233
!! must get rank before info, as "dims" must be allocated first.
214234
integer(SIZE_T) :: type_size
215235
integer :: type_class, drank, ier

src/read_scalar.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
submodule (h5mpi:hdf5_read) read_scalar
22

33
use h5lt, only : h5ltread_dataset_string_f
4-
use hdf5, only : h5dread_f, h5dvlen_get_max_len_f, h5dread_vl_f, h5dvlen_reclaim_f,&
5-
h5tis_variable_str_f, h5tget_strpad_f, &
6-
H5T_STR_NULLTERM_F, &
7-
H5Dget_space_f, h5sclose_f
4+
use hdf5, only : h5dread_f, h5dget_space_f, h5dvlen_get_max_len_f, h5dread_vl_f, h5dvlen_reclaim_f,&
5+
h5tis_variable_str_f, &
6+
h5sclose_f, &
7+
H5T_STR_NULLTERM_F
88

99
implicit none (type, external)
1010

src/write.f90

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ subroutine set_deflate(self, dims, dcpl, chunk_size)
195195
dcpl = H5P_DEFAULT_F
196196

197197
if (present(chunk_size)) then
198+
if(size(chunk_size) /= size(dims)) then
199+
write(stderr,*) "ERROR:h5fortran:write:set_deflate: chunk_size length ", size(chunk_size), " /= dims length ", size(dims)
200+
error stop
201+
endif
198202
cs = chunk_size
199203
where (cs > dims) cs = dims
200204
if(self%debug) print *,'TRACE: user request chunk_size ',cs

test/test_attributes.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ program test_attributes
3333

3434
contains
3535

36-
3736
subroutine test_write_attributes(path)
3837

3938
type(hdf5_file) :: h

test/test_string.f90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ program test_string
44

55
use mpi, only : mpi_init, MPI_COMM_WORLD, mpi_comm_rank
66

7-
use h5mpi, only : hdf5_file
7+
use hdf5, only: H5T_STR_SPACEPAD_F
8+
use h5mpi, only: hdf5_file
89

910
implicit none (type, external)
1011

@@ -70,6 +71,9 @@ subroutine test_read(fn)
7071
endif
7172
if (value /= '42') error stop 'test_string: read/write verification failure. Value: '// value
7273

74+
!> check padding
75+
if (h%get_strpad("/little") /= H5T_STR_SPACEPAD_F) error stop "SPACEPAD expected for /little"
76+
7377
!> longer character than data
7478
call h%read('/little', val1k)
7579

0 commit comments

Comments
 (0)