|
| 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