Skip to content

Commit 1130fe9

Browse files
committed
add is_hdf5(), %ndim. add test_shape
1 parent 7a9a523 commit 1130fe9

File tree

6 files changed

+219
-100
lines changed

6 files changed

+219
-100
lines changed

src/interface.f90

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module h5mpi
1414
H5S_ALL_F, H5S_SELECT_SET_F, &
1515
H5D_CHUNKED_F, H5D_CONTIGUOUS_F, H5D_COMPACT_F, &
1616
h5dcreate_f, h5dopen_f, h5dclose_f, h5dget_space_f, h5dget_create_plist_f, &
17-
h5fopen_f, h5fclose_f, h5fcreate_f, h5fget_filesize_f, h5fflush_f, &
17+
h5fopen_f, h5fclose_f, h5fcreate_f, h5fget_filesize_f, h5fflush_f, h5fis_hdf5_f, &
1818
h5pcreate_f, h5pclose_f, h5pset_chunk_f, h5pset_dxpl_mpio_f, h5pset_fapl_mpio_f, h5pall_filters_avail_f, &
1919
h5sselect_hyperslab_f, h5screate_simple_f, h5sclose_f, &
2020
h5get_libversion_f, &
@@ -44,7 +44,7 @@ module h5mpi
4444
contains
4545

4646
procedure, public :: open => ph5open, close => ph5close, &
47-
flush => hdf_flush, shape => h5get_shape, exist => hdf_exist, &
47+
flush => hdf_flush, ndim => hdf_get_ndim, shape => hdf_get_shape, exist => hdf_exist, &
4848
create => hdf_create, filesize => hdf_filesize, &
4949
class => get_class, dtype => get_native_dtype, &
5050
deflate => get_deflate, &
@@ -72,7 +72,7 @@ module h5mpi
7272
end type mpi_tags
7373

7474
private
75-
public :: mpi_h5comm, hdf5_file, mpi_tags, has_parallel_compression, &
75+
public :: mpi_h5comm, hdf5_file, mpi_tags, has_parallel_compression, is_hdf5, &
7676
check, hdf_wrapup, hdf_rank_check, hdf_shape_check, mpi_collective, mpi_hyperslab, &
7777
hdf5version, HSIZE_T
7878

@@ -171,6 +171,28 @@ end subroutine ph5write_7d
171171

172172
interface !< read.f90
173173

174+
module integer function get_class(self, dname)
175+
class(hdf5_file), intent(in) :: self
176+
character(*), intent(in) :: dname
177+
end function get_class
178+
179+
module integer(hid_t) function get_native_dtype(self, dname, ds_id)
180+
class(hdf5_file), intent(in) :: self
181+
character(*), intent(in) :: dname
182+
integer(hid_t), intent(in), optional :: ds_id
183+
end function get_native_dtype
184+
185+
module integer function hdf_get_ndim(self, dname) result (drank)
186+
class(hdf5_file), intent(in) :: self
187+
character(*), intent(in) :: dname
188+
end function hdf_get_ndim
189+
190+
module subroutine hdf_get_shape(self, dname, dims)
191+
class(hdf5_file), intent(in) :: self
192+
character(*), intent(in) :: dname
193+
integer(HSIZE_T), intent(out), allocatable :: dims(:)
194+
end subroutine hdf_get_shape
195+
174196
module subroutine h5open_read(self, dname, dims, dset_dims, filespace, memspace, dset_id)
175197
class(hdf5_file), intent(in) :: self
176198
character(*), intent(in) :: dname
@@ -196,16 +218,6 @@ module subroutine hdf_get_chunk(self, dname, chunk_size)
196218
integer(hsize_t), intent(out) :: chunk_size(:)
197219
end subroutine hdf_get_chunk
198220

199-
module integer function get_class(self, dname)
200-
class(hdf5_file), intent(in) :: self
201-
character(*), intent(in) :: dname
202-
end function get_class
203-
204-
module integer(hid_t) function get_native_dtype(self, dname, ds_id)
205-
class(hdf5_file), intent(in) :: self
206-
character(*), intent(in) :: dname
207-
integer(hid_t), intent(in), optional :: ds_id
208-
end function get_native_dtype
209221
end interface
210222

211223

@@ -446,6 +458,23 @@ logical function hdf_is_chunked(self, dname)
446458
end function hdf_is_chunked
447459

448460

461+
logical function is_hdf5(filename)
462+
!! is this file HDF5?
463+
464+
character(*), intent(in) :: filename
465+
integer :: ierr
466+
467+
inquire(file=filename, exist=is_hdf5)
468+
!! avoid warning/error messages
469+
if (.not. is_hdf5) return
470+
471+
call h5fis_hdf5_f(filename, is_hdf5, ierr)
472+
473+
if (ierr/=0) is_hdf5 = .false.
474+
!! sometimes h5fis_hdf5_f is .true. for missing file
475+
476+
end function is_hdf5
477+
449478

450479
subroutine mpi_hyperslab(mem_dims, dset_dims, dset_id, filespace, memspace, dname, istart, iend)
451480
!! Each process defines dataset in memory and writes it to the hyperslab in the file.
@@ -593,28 +622,6 @@ logical function check(ierr, filename, dname)
593622
end function check
594623

595624

596-
subroutine h5get_shape(self, dname, dims)
597-
class(hdf5_file), intent(in) :: self
598-
character(*), intent(in) :: dname
599-
integer(HSIZE_T), intent(inout), allocatable :: dims(:)
600-
601-
!! must get rank before info, as "dims" must be allocated first.
602-
integer(SIZE_T) :: type_size
603-
integer :: type_class, drank, ier
604-
605-
if(.not. self%exist(dname)) error stop 'h5fortran:get_shape: ' // dname // ' does not exist in ' // self%filename
606-
607-
call h5ltget_dataset_ndims_f(self%file_id, dname, drank, ier)
608-
if (ier /= 0) error stop "h5fortran:get_shape: could not get rank of " // dname // " in " // self%filename
609-
610-
allocate(dims(drank))
611-
call h5ltget_dataset_info_f(self%file_id, dname, dims=dims, &
612-
type_class=type_class, type_size=type_size, errcode=ier)
613-
if (ier /= 0) error stop "h5fortran:get_shape: could not get shape of " // dname // " in " // self%filename
614-
615-
end subroutine h5get_shape
616-
617-
618625
logical function hdf_exist(self, dname) result(exists)
619626
class(hdf5_file), intent(in) :: self
620627
character(*), intent(in) :: dname

src/read/read.f90

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -93,67 +93,6 @@
9393
end procedure get_deflate
9494

9595

96-
module procedure hdf_get_chunk
97-
98-
integer :: ierr, drank
99-
integer(HID_T) :: pid, dset_id
100-
101-
if(.not.self%is_open) error stop 'h5fortran:read: file handle is not open'
102-
103-
chunk_size = -1
104-
if (.not.self%exist(dname)) then
105-
write(stderr, *) 'ERROR:get_chunk: ' // dname // ' does not exist in ' // self%filename
106-
ierr = -1
107-
return
108-
endif
109-
110-
if(.not.self%is_chunked(dname)) return
111-
112-
call h5ltget_dataset_ndims_f(self%file_id, dname, drank, ierr)
113-
if (check(ierr, 'ERROR:get_chunk: get rank ' // dname // ' ' // self%filename)) return
114-
call h5dopen_f(self%file_id, dname, dset_id, ierr)
115-
if (check(ierr, 'ERROR:get_chunk: open dataset ' // dname // ' ' // self%filename)) return
116-
call h5dget_create_plist_f(dset_id, pid, ierr)
117-
if (check(ierr, 'ERROR:get_chunk: get property list ID ' // dname // ' ' // self%filename)) return
118-
119-
call h5pget_chunk_f(pid, drank, chunk_size, ierr)
120-
if (ierr /= drank) then
121-
write(stderr,*) 'ERROR:get_chunk read ' // dname // ' ' // self%filename
122-
return
123-
endif
124-
125-
call h5dclose_f(dset_id, ierr)
126-
if (check(ierr, 'ERROR:get_chunk: close dataset: ' // dname // ' ' // self%filename)) return
127-
128-
end procedure hdf_get_chunk
129-
130-
131-
module procedure hdf_get_layout
132-
133-
integer(HID_T) :: pid, dset_id
134-
integer :: ierr
135-
136-
if(.not.self%is_open) error stop 'h5fortran:read: file handle is not open'
137-
138-
layout = -1
139-
140-
if (.not.self%exist(dname)) then
141-
write(stderr, *) 'ERROR:get_layout: ' // dname // ' does not exist in ' // self%filename
142-
return
143-
endif
144-
145-
call h5dopen_f(self%file_id, dname, dset_id, ierr)
146-
if (check(ierr, 'ERROR:get_layout: open dataset ' // dname // ' ' // self%filename)) return
147-
call h5dget_create_plist_f(dset_id, pid, ierr)
148-
if (check(ierr, 'ERROR:get_layout: get property list ID ' // dname // ' ' // self%filename)) return
149-
call h5pget_layout_f(pid, layout, ierr)
150-
if (check(ierr, 'ERROR:get_layout read ' // dname //' ' // self%filename)) return
151-
call h5dclose_f(dset_id, ierr)
152-
if (check(ierr, 'ERROR:get_layout: close dataset: ' // dname //' ' // self%filename)) return
153-
154-
end procedure hdf_get_layout
155-
156-
15796
subroutine get_dset_class(self, dname, class, ds_id, size_bytes)
15897
!! get the dataset class (integer, float, string, ...)
15998
!! {H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F}
@@ -245,4 +184,101 @@ end subroutine get_dset_class
245184

246185
end procedure get_native_dtype
247186

187+
188+
module procedure hdf_get_ndim
189+
!! get rank or "ndims"
190+
integer :: ier
191+
192+
if(.not.self%is_open) error stop 'h5fortran:read: file handle is not open'
193+
194+
drank = -1
195+
196+
if (self%exist(dname)) then
197+
call h5ltget_dataset_ndims_f(self%file_id, dname, drank, ier)
198+
else
199+
write(stderr, '(a)') 'ERROR:get_ndim: ' // dname // ' does not exist in ' // self%filename
200+
endif
201+
202+
end procedure hdf_get_ndim
203+
204+
205+
module procedure hdf_get_shape
206+
207+
!! must get rank before info, as "dims" must be allocated first.
208+
integer(SIZE_T) :: type_size
209+
integer :: type_class, drank, ier
210+
211+
if(.not. self%exist(dname)) error stop 'h5fortran:get_shape: ' // dname // ' does not exist in ' // self%filename
212+
213+
call h5ltget_dataset_ndims_f(self%file_id, dname, drank, ier)
214+
if (ier /= 0) error stop "h5fortran:get_shape: could not get rank of " // dname // " in " // self%filename
215+
216+
allocate(dims(drank))
217+
call h5ltget_dataset_info_f(self%file_id, dname, dims=dims, &
218+
type_class=type_class, type_size=type_size, errcode=ier)
219+
if (ier /= 0) error stop "h5fortran:get_shape: could not get shape of " // dname // " in " // self%filename
220+
221+
end procedure hdf_get_shape
222+
223+
224+
module procedure hdf_get_chunk
225+
226+
integer :: ierr, drank
227+
integer(HID_T) :: pid, dset_id
228+
229+
if(.not.self%is_open) error stop 'h5fortran:read: file handle is not open'
230+
231+
chunk_size = -1
232+
if (.not.self%exist(dname)) then
233+
write(stderr, *) 'ERROR:get_chunk: ' // dname // ' does not exist in ' // self%filename
234+
ierr = -1
235+
return
236+
endif
237+
238+
if(.not.self%is_chunked(dname)) return
239+
240+
call h5ltget_dataset_ndims_f(self%file_id, dname, drank, ierr)
241+
if (check(ierr, 'ERROR:get_chunk: get rank ' // dname // ' ' // self%filename)) return
242+
call h5dopen_f(self%file_id, dname, dset_id, ierr)
243+
if (check(ierr, 'ERROR:get_chunk: open dataset ' // dname // ' ' // self%filename)) return
244+
call h5dget_create_plist_f(dset_id, pid, ierr)
245+
if (check(ierr, 'ERROR:get_chunk: get property list ID ' // dname // ' ' // self%filename)) return
246+
247+
call h5pget_chunk_f(pid, drank, chunk_size, ierr)
248+
if (ierr /= drank) then
249+
write(stderr,*) 'ERROR:get_chunk read ' // dname // ' ' // self%filename
250+
return
251+
endif
252+
253+
call h5dclose_f(dset_id, ierr)
254+
if (check(ierr, 'ERROR:get_chunk: close dataset: ' // dname // ' ' // self%filename)) return
255+
256+
end procedure hdf_get_chunk
257+
258+
259+
module procedure hdf_get_layout
260+
261+
integer(HID_T) :: pid, dset_id
262+
integer :: ierr
263+
264+
if(.not.self%is_open) error stop 'h5fortran:read: file handle is not open'
265+
266+
layout = -1
267+
268+
if (.not.self%exist(dname)) then
269+
write(stderr, *) 'ERROR:get_layout: ' // dname // ' does not exist in ' // self%filename
270+
return
271+
endif
272+
273+
call h5dopen_f(self%file_id, dname, dset_id, ierr)
274+
if (check(ierr, 'ERROR:get_layout: open dataset ' // dname // ' ' // self%filename)) return
275+
call h5dget_create_plist_f(dset_id, pid, ierr)
276+
if (check(ierr, 'ERROR:get_layout: get property list ID ' // dname // ' ' // self%filename)) return
277+
call h5pget_layout_f(pid, layout, ierr)
278+
if (check(ierr, 'ERROR:get_layout read ' // dname //' ' // self%filename)) return
279+
call h5dclose_f(dset_id, ierr)
280+
if (check(ierr, 'ERROR:get_layout: close dataset: ' // dname //' ' // self%filename)) return
281+
282+
end procedure hdf_get_layout
283+
248284
end submodule hdf5_read

src/tests/unit/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ max_gcd(${MPI_MAX} ${MPIEXEC_MAX_NUMPROCS} Nmpi)
55

66
message(STATUS "Unit tests using ${Nmpi} processes")
77

8-
set(test_names deflate_write deflate_props deflate_read scalar)
8+
set(test_names deflate_write deflate_props deflate_read scalar shape)
99

1010
foreach(t IN LISTS test_names)
1111

src/tests/unit/test_deflate_read.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ program test_deflate_read
2626
call test_read_deflate(fn1, N, mpi_id, Nmpi)
2727
if(mpi_id==0) print *,'OK: HDF5 read deflate'
2828

29-
3029
call mpi_finalize(ierr)
3130
if (ierr /= 0) error stop "mpi_finalize"
3231

src/tests/unit/test_scalar.f90

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ subroutine test_scalar_collective(mpi_id)
4343

4444
call h5%close()
4545

46-
47-
4846
end subroutine test_scalar_collective
4947

5048

0 commit comments

Comments
 (0)