Skip to content

Commit b5b0f09

Browse files
committed
read: correct for non-mpi reads, add non-mpi test
1 parent 68468e8 commit b5b0f09

File tree

6 files changed

+246
-33
lines changed

6 files changed

+246
-33
lines changed

src/interface.f90

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,6 @@ module subroutine hdf_get_shape(self, dname, dims)
249249
integer(HSIZE_T), intent(out), allocatable :: dims(:)
250250
end subroutine
251251

252-
module subroutine h5open_read(self, dname, dims, dset_dims, filespace, memspace, dset_id)
253-
class(hdf5_file), intent(in) :: self
254-
character(*), intent(in) :: dname
255-
integer(HSIZE_T), intent(in) :: dims(:)
256-
integer(HSIZE_T), intent(out) :: dset_dims(:)
257-
integer(HID_T), intent(out) :: filespace, memspace, dset_id
258-
end subroutine
259-
260252
module integer function get_strpad(self, dset_name)
261253
class(hdf5_file), intent(in) :: self
262254
character(*), intent(in) :: dset_name

src/read.f90

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,6 @@
1717
contains
1818

1919

20-
module procedure h5open_read
21-
22-
integer :: ierr
23-
integer(HID_T) :: plist_id
24-
25-
filespace = H5S_ALL_F
26-
memspace = H5S_ALL_F
27-
plist_id = H5P_DEFAULT_F
28-
29-
call hdf_shape_check(self, dname, dims, dset_dims)
30-
31-
call h5dopen_f(self%file_id, dname, dset_id, ierr)
32-
if(ierr /= 0) error stop 'ERROR:h5open_read: open ' // dname // ' from ' // self%filename
33-
34-
end procedure h5open_read
35-
36-
3720
module procedure get_class
3821
call get_dset_class(self, dname, get_class)
3922
end procedure get_class

src/reader.inc

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,24 @@ integer(HSIZE_T), dimension(rank(A)) :: dims, dset_dims
22
integer(HID_T) :: dset_id, file_space_id, mem_space_id, xfer_id
33
integer :: dclass, ier
44

5-
xfer_id = H5P_DEFAULT_F
5+
file_space_id = H5S_ALL_F
6+
mem_space_id = H5S_ALL_F
7+
68
dims = shape(A, HSIZE_T)
79

8-
call h5open_read(self, dname, dims, dset_dims, file_space_id, mem_space_id, dset_id)
10+
call H5Dopen_f(self%file_id, dname, dset_id, ier)
11+
if(ier /= 0) error stop 'ERROR:h5open_read: open ' // dname // ' from ' // self%filename
12+
13+
if(present(istart) .and. present(iend)) then
14+
call mpi_hyperslab(dims, dset_dims, dset_id, file_space_id, mem_space_id, istart=istart, iend=iend, stride=stride)
15+
else
16+
call hdf_shape_check(self, dname, dims, dset_dims)
17+
endif
918

1019
if(self%use_mpi) then
11-
if(present(istart) .and. present(iend)) then
12-
call mpi_hyperslab(dims, dset_dims, dset_id, file_space_id, mem_space_id, istart=istart, iend=iend, stride=stride)
13-
endif
1420
xfer_id = mpi_collective(dname)
21+
else
22+
xfer_id = H5P_DEFAULT_F
1523
endif
1624

1725
call get_dset_class(self, dname, dclass, dset_id)

src/utils.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@
181181
if(ierr /= 0) error stop "ERROR:h5fortran:close:h5fget_name: could not get filename of open dataset: " // self%filename
182182

183183
call h5iget_name_f(obj_ids(i), dset_name, L, Lds_name, ierr)
184+
if(ierr /= 0) error stop "ERROR:h5fortran:close:h5iget_name could not get dataset name: " // self%filename
184185

185186
write(stderr,*) "h5fortran:close: open dataset: " // dset_name(:Lds_name) // " in file: " // file_name(:Lf_name)
186187
end do

test/CMakeLists.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ add_test(NAME ${name} COMMAND test_${name})
2727

2828
endforeach()
2929

30+
set_tests_properties(${names} PROPERTIES
31+
LABELS nompi
32+
)
33+
3034
endfunction(nompi_test)
3135

3236

@@ -51,18 +55,23 @@ endif()
5155

5256
add_test(NAME ${name} COMMAND ${cmd})
5357

54-
set_tests_properties(${name} PROPERTIES
58+
endforeach()
59+
60+
set_tests_properties(${names} PROPERTIES
5561
RESOUCE_LOCK cpu_mpi
62+
LABELS mpi
5663
)
5764

58-
endforeach()
59-
6065
endfunction(mpi_test)
6166

6267
cmake_path(SET string_file ${CMAKE_CURRENT_BINARY_DIR}/test_string_py.h5)
6368

6469
# --- write test data
6570

71+
set(nompi_tests array)
72+
73+
nompi_test(${nompi_tests})
74+
6675
set(mpi_tests array_mpi attributes cast destructor exist fill groups layout shape
6776
string string_read write
6877
)

test/test_array.f90

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
program array_test
2+
3+
use, intrinsic:: ieee_arithmetic, only: ieee_value, ieee_quiet_nan, ieee_is_nan
4+
use, intrinsic :: iso_fortran_env, only: real32, real64, int32, stderr=>error_unit
5+
6+
use h5mpi, only : hdf5_file, HSIZE_T, H5T_NATIVE_INTEGER
7+
8+
implicit none (type, external)
9+
10+
real(real32) :: nan
11+
12+
call test_basic_array('test_array.h5')
13+
print *, 'PASSED: array write'
14+
15+
call test_read_slice('test_array.h5')
16+
print *, 'PASSED: slice read'
17+
18+
call test_write_slice('test_array.h5')
19+
print *, 'PASSED: slice write'
20+
21+
call test_readwrite_array('test_group_array.h5', ng=69, nn=100, pn=5)
22+
print *,'PASSED: array write / read'
23+
24+
25+
contains
26+
27+
subroutine test_basic_array(filename)
28+
29+
character(*), intent(in) :: filename
30+
!! tests that compression doesn't fail for very small datasets, where it really shouldn't be used (makes file bigger)
31+
type(hdf5_file) :: h
32+
integer(HSIZE_T), allocatable :: dims(:)
33+
34+
integer(int32), dimension(4) :: i1, i1t
35+
integer(int32), dimension(4,4) :: i2, i2t
36+
real(real32), allocatable :: rr2(:,:)
37+
real(real32) :: nant, r1(4), r2(4,4), B(6,6)
38+
integer :: i
39+
integer(int32) :: i2_8(8,8)
40+
41+
nan = ieee_value(1.0, ieee_quiet_nan)
42+
43+
do i = 1,size(i1)
44+
i1(i) = i
45+
enddo
46+
47+
i2(1,:) = i1
48+
do i = 1,size(i2,2)
49+
i2(i,:) = i2(1,:) * i
50+
enddo
51+
52+
r1 = i1
53+
r2 = i2
54+
55+
call h%open(filename, action='w', comp_lvl=1, mpi=.false.)
56+
57+
call h%write('/int32-1d', i1)
58+
call h%write('/test/group2/int32-2d', i2)
59+
call h%write('/real32-2d', r2)
60+
call h%write('/nan', nan)
61+
62+
call h%close()
63+
64+
!! read
65+
call h%open(filename, action='r', mpi=.false.)
66+
67+
!> int32
68+
call h%read('/int32-1d', i1t)
69+
if (.not.all(i1==i1t)) error stop 'read 1-d int32: does not match write'
70+
71+
call h%read('/test/group2/int32-2d',i2t)
72+
if (.not.all(i2==i2t)) error stop 'read 2-D: int32 does not match write'
73+
74+
!> verify reading into larger array
75+
i2_8 = 0
76+
call h%read('/test/group2/int32-2d', i2_8(2:5,3:6))
77+
if (.not.all(i2_8(2:5,3:6) == i2)) error stop 'read into larger array fail'
78+
79+
!> real
80+
call h%shape('/real32-2d',dims)
81+
allocate(rr2(dims(1), dims(2)))
82+
call h%read('real32-2d',rr2)
83+
if (.not.all(r2 == rr2)) error stop 'real 2-D: read does not match write'
84+
85+
! check read into a variable slice
86+
call h%read('real32-2d', B(2:5,3:6))
87+
if(.not.all(B(2:5,3:6) == r2)) error stop 'real 2D: reading into variable slice'
88+
89+
call h%read('/nan',nant)
90+
if (.not.ieee_is_nan(nant)) error stop 'failed storing or reading NaN'
91+
92+
call h%close()
93+
94+
end subroutine test_basic_array
95+
96+
97+
subroutine test_read_slice(filename)
98+
99+
character(*), intent(in) :: filename
100+
101+
type(hdf5_file) :: h
102+
integer :: i
103+
integer(int32), dimension(4) :: i1, i1t
104+
integer(int32), dimension(4,4) :: i2, i2t
105+
106+
do i = 1,size(i1)
107+
i1(i) = i
108+
enddo
109+
110+
i2(1,:) = i1
111+
do i = 1,size(i2,2)
112+
i2(i,:) = i2(1,:) * i
113+
enddo
114+
115+
call h%open(filename, action='r', mpi=.false.)
116+
117+
i1t = 0
118+
call h%read('/int32-1d', i1t(:2), istart=[2], iend=[3], stride=[1])
119+
if (any(i1t(:2) /= [2,3])) then
120+
write(stderr, *) 'read 1D slice does not match. expected [2,3] but got ',i1t(:2)
121+
error stop
122+
endif
123+
124+
i1t = 0
125+
call h%read('/int32-1d', i1t(:2), istart=[2], iend=[3])
126+
if (any(i1t(:2) /= [2,3])) then
127+
write(stderr, *) 'read 1D slice does not match. expected [2,3] but got ',i1t(:2)
128+
error stop
129+
endif
130+
131+
i2t = 0
132+
call h%read('/test/group2/int32-2d', i2t(:2,:3), istart=[2,1], iend=[3,3], stride=[1,1])
133+
if (any(i2t(:2,:3) /= i2(2:3,1:3))) then
134+
write(stderr, *) 'read 2D slice does not match. expected:',i2(2:3,1:3),' but got ',i2t(:2,:3)
135+
error stop
136+
endif
137+
138+
call h%close()
139+
140+
end subroutine test_read_slice
141+
142+
143+
subroutine test_write_slice(filename)
144+
145+
character(*), intent(in) :: filename
146+
147+
type(hdf5_file) :: h
148+
integer(int32), dimension(4) :: i1t
149+
integer(int32), dimension(4,4) :: i2t
150+
integer :: dims(1), dims2(2)
151+
152+
dims = [3]
153+
154+
call h%open(filename, action='r+', debug=.true., mpi=.false.)
155+
156+
call h%create('/int32a-1d', dtype=H5T_NATIVE_INTEGER, dset_dims=dims)
157+
call h%write('/int32a-1d', [1,3], dset_dims=dims, istart=[1], iend=[2])
158+
print *, 'PASSED: create dataset and write slice 1D'
159+
160+
call h%write('/int32-1d', [35, 70], dset_dims=dims, istart=[2], iend=[3], stride=[1])
161+
162+
call h%read('/int32-1d', i1t)
163+
if (.not.all(i1t==[1,35,70,4])) then
164+
write(stderr, *) 'write 1D slice does not match. Got ',i1t, ' in ', filename
165+
error stop
166+
endif
167+
print *, 'PASSED: overwrite slice 1d, stride=1'
168+
169+
call h%write('/int32-1d', [23,34,45], dset_dims=dims, istart=[2], iend=[4])
170+
171+
call h%read('/int32-1d', i1t)
172+
if (.not.all(i1t==[1,23,34,45])) then
173+
write(stderr, *) 'read 1D slice does not match. Got ',i1t
174+
error stop
175+
endif
176+
print *, 'PASSED: overwrite slice 1d, no stride'
177+
178+
dims2 = [4,4]
179+
180+
call h%create('/int32a-2d', dtype=H5T_NATIVE_INTEGER, dset_dims=dims2)
181+
print *, 'create and write slice 2d, stride=1'
182+
call h%write('/int32a-2d', reshape([76,65,54,43], [2,2]), dset_dims=dims2, istart=[2,1], iend=[3,2])
183+
184+
call h%read('/int32a-2d', i2t)
185+
186+
call h%close()
187+
188+
189+
end subroutine test_write_slice
190+
191+
192+
subroutine test_readwrite_array(filename, ng, nn, pn)
193+
!! more group
194+
type(hdf5_file) :: h
195+
character(*), intent(in) :: filename
196+
integer, intent(in) :: ng, nn, pn
197+
198+
real(real32), allocatable :: flux(:,:),fo(:)
199+
character(2) :: pnc,ic
200+
integer :: i
201+
202+
allocate(flux(nn,ng),fo(nn))
203+
flux = 1.0
204+
write(pnc,'(I2)') pn
205+
206+
call h%open(filename, action='rw', mpi=.false.)
207+
208+
do i = 1,ng
209+
write(ic,'(I2)') i
210+
call h%write('/group'//trim(adjustl(ic))//'/flux_node',flux(:,i))
211+
enddo
212+
213+
call h%read('/group1/flux_node',fo)
214+
if (.not.all(fo == flux(:,1))) error stop 'test_read_write: read does not match write'
215+
216+
call h%close()
217+
218+
end subroutine test_readwrite_array
219+
220+
end program

0 commit comments

Comments
 (0)