Skip to content

Commit 5770651

Browse files
committed
modularize build
BUGFIX: Integer scalar read BUGFIX: chunk size through 7d doc string utils add null strip cleanup test cleanup init notes
1 parent 7e9c69f commit 5770651

17 files changed

+269
-194
lines changed

.travis.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
language: c
1+
language: minimal
22
group: travis_latest
33
dist: xenial
44

55
git:
6-
depth: 3
6+
depth: 25
77
quiet: true
88

99
addons:
@@ -20,15 +20,14 @@ matrix:
2020
- os: osx
2121
env: FC=gfortran
2222
before_install:
23-
- brew update
23+
- brew update > /dev/null
2424
- brew upgrade cmake > /dev/null
2525
- brew install gcc > /dev/null
2626
- brew install hdf5 > /dev/null
2727

2828
install:
2929
- cd build
3030
- cmake ..
31-
- cmake --build .
31+
- cmake --build . -j
3232

3333
script: ctest --output-on-failure
34-

CMakeLists.txt

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
1-
# 3.12: Fortran submodule
2-
cmake_minimum_required (VERSION 3.12)
1+
cmake_minimum_required (VERSION 3.12) # 3.12 for Fortran submodule
2+
if(NOT CMAKE_BUILD_TYPE)
3+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Debug or Release")
4+
endif()
35
project(hdf5iface Fortran)
46
enable_testing()
57

68
include(cmake/compilers.cmake)
79

810
include(cmake/hdf5.cmake)
911

10-
add_library(hdf5oo src/hdf5_interface.f90
11-
src/read.f90 src/read_real64.f90 src/read_real32.f90 src/read_int.f90
12-
src/write.f90 src/write_real64.f90 src/write_real32.f90 src/write_int.f90)
13-
# need BOTH includes, for some systems!
14-
target_include_directories(hdf5oo PRIVATE ${HDF5_INCLUDE_DIRS} ${HDF5_Fortran_INCLUDE_DIRS})
15-
target_link_libraries(hdf5oo PRIVATE ${HDF5_Fortran_LIBRARIES} ${HDF5_Fortran_HL_LIBRARIES})
16-
target_compile_options(hdf5oo PRIVATE ${HDF5_Fortran_DEFINITIONS})
12+
add_subdirectory(src)
1713

18-
add_executable(testh5 src/test_hdf5_ifc.f90)
19-
target_link_libraries(testh5 PRIVATE hdf5oo)
20-
target_compile_options(testh5 PRIVATE -Wno-compare-reals)
21-
add_test(NAME h5oo COMMAND testh5)
22-
set_tests_properties(h5oo PROPERTIES FIXTURES_SETUP h5files)
14+
add_subdirectory(tests)
2315

2416
add_executable(shapes_check src/GetShape.f90)
2517
target_link_libraries(shapes_check PRIVATE hdf5oo)

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ call h5f%finalize()
104104
### Add gzip compressed 3-D array "value2" to existing HDF5 file "test.h5"
105105

106106
```fortran
107-
108107
real :: val2(1000,1000,3) = 0.
109108
110109
call h5f%initialize('test.h5', comp_lvl=1)
@@ -116,8 +115,21 @@ call h5f%finalize()
116115

117116
chunk_size may optionally be set in the `%add()` method.
118117

119-
## Notes
118+
### Create group "scope"
119+
120+
```fortran
121+
real :: val2(1000,1000,3) = 0.
122+
123+
call h5f%initialize('test.h5')
120124
121-
The first character of the filename should be a character, NOT whitespace to avoid file open/creation errors.
125+
call h5f%add('/scope/')
126+
127+
call h5f%finalize()
128+
```
129+
130+
Note the trailing `/` on `/scope/`, that tells the API you are creating a group instead of a variable.
131+
## Notes
122132

123-
Using compilers like PGI or Flang may require first compiling the HDF5 library yourself.
133+
* The first character of the filename should be a character, NOT whitespace to avoid file open/creation errors.
134+
* Using compilers like PGI or Flang may require first compiling the HDF5 library yourself.
135+
* Polymorphic array rank is implemented by explicit code internally. We could have used pointers, but the code is simple enough to avoid the risk associated with explicit array pointers.

cmake/compilers.cmake

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
if(CMAKE_BUILD_TYPE STREQUAL Debug)
2-
add_compile_options(-g -O1) # O0 will throw SIGFPE intermittantly on whatever last subroutine called was.
3-
else()
4-
add_compile_options(-g -O3)
5-
endif()
61

72
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
83

94
if(CMAKE_BUILD_TYPE STREQUAL Debug)
105
list(APPEND FFLAGS -debug extended -check all -heap-arrays -fp-stack-check)
6+
list(APPEND FFLAGS -warn -traceback)
117
endif()
12-
list(APPEND FFLAGS -warn -traceback)
8+
139
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
1410
list(APPEND FFLAGS -march=native -fimplicit-none)
1511

@@ -27,7 +23,7 @@ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
2723
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL PGI)
2824

2925
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Flang)
30-
list(APPEND FFLAGS -Mallocatable=03)
26+
3127
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL NAG)
3228
list(APPEND FFLAGS -u -C=all)
3329
endif()

meson.build

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,10 @@ if h5run.returncode() != 0
1919
error('HDF5 linking problems: ' + h5run.stderr())
2020
endif
2121

22-
ooh5 = library('oohdf5', 'src/hdf5_interface.f90','src/read.f90', 'src/read_real64.f90', 'src/read_real32.f90', 'src/read_int.f90', 'src/write.f90', 'src/write_real64.f90', 'src/write_real32.f90', 'src/write_int.f90',
23-
dependencies: hdf5)
22+
ooh5 = library('oohdf5', hdf5_src, dependencies: hdf5)
2423

2524
# --- testing
26-
testh5 = executable('test_hdf5', 'src/test_hdf5_ifc.f90',
27-
dependencies: hdf5,
28-
link_with: ooh5,
29-
fortran_args: quiet)
30-
test('Test HDF5 OO', testh5, is_parallel: false)
25+
subdir(tests)
3126

3227
shapes = executable('shapes_hdf5', 'src/GetShape.f90',
3328
dependencies: hdf5,

src/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
add_library(hdf5oo hdf5_interface.f90
2+
read.f90 read_real64.f90 read_real32.f90 read_int.f90
3+
write.f90 write_real64.f90 write_real32.f90 write_int.f90
4+
string_utils.f90)
5+
# need BOTH includes, for some systems!
6+
target_include_directories(hdf5oo PRIVATE ${HDF5_INCLUDE_DIRS} ${HDF5_Fortran_INCLUDE_DIRS})
7+
target_link_libraries(hdf5oo PRIVATE ${HDF5_Fortran_LIBRARIES} ${HDF5_Fortran_HL_LIBRARIES})
8+
target_compile_options(hdf5oo PRIVATE ${HDF5_Fortran_DEFINITIONS})
9+
set_target_properties(hdf5oo PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR})

src/hdf5_interface.f90

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
module hdf5_interface
22
!! HDF5 object-oriented polymorphic interface
33

4-
use, intrinsic:: iso_fortran_env, only: real32, real64, stderr=>error_unit
4+
use, intrinsic:: iso_fortran_env, only: real32, real64, int32, stderr=>error_unit
55
use H5LT
66

7+
use string_utils, only : toLower, strip_trailing_null
8+
79
implicit none
810

911
!> main type
@@ -15,8 +17,8 @@ module hdf5_interface
1517
glid, & !< group location identifier
1618
sid, did, pid
1719

18-
integer :: comp_lvl = 0 !< compression level (1-9) 0: disable compression
19-
integer(HSIZE_T) :: chunk_size(6) = [64,64,1,1,1,1] !< chunk size per dimension (arbitrary)
20+
integer :: comp_lvl = 0 !< compression level (1-9) 0: disable compression
21+
integer(HSIZE_T) :: chunk_size(7) = [64,64,1,1,1,1,1] !< chunk size per dimension (arbitrary)
2022
logical :: verbose=.false.
2123

2224

@@ -25,7 +27,7 @@ module hdf5_interface
2527
procedure, public :: initialize => hdf_initialize, finalize => hdf_finalize, writeattr, &
2628
open => hdf_open_group, close => hdf_close_group, shape => hdf_get_shape
2729

28-
!> add group or dataset integer/real
30+
!> add group or dataset integer/real
2931
generic, public :: add => &
3032
hdf_add_group, hdf_add_int, hdf_add_int_1d, hdf_add_int_2d, hdf_add_int_3d, hdf_add_int_5d, hdf_add_int_6d, hdf_add_int_7d,&
3133
hdf_add_real32, hdf_add_real32_1d, hdf_add_real32_2d, hdf_add_real32_3d, &
@@ -57,7 +59,7 @@ module hdf5_interface
5759
hdf_get_real64, hdf_get_real64_1d, hdf_get_real64_2d, hdf_get_real64_3d, &
5860
hdf_get_real64_4d, hdf_get_real64_5d, hdf_get_real64_6d, hdf_get_real64_7d, &
5961
hdf_add_string, hdf_get_string
60-
62+
6163
end type hdf5_file
6264

6365

@@ -89,26 +91,26 @@ end subroutine hdf_add_string
8991
module subroutine hdf_add_int(self,dname,value)
9092
class(hdf5_file), intent(in) :: self
9193
character(*), intent(in) :: dname
92-
integer, intent(in) :: value
94+
integer(int32), intent(in) :: value
9395
end subroutine hdf_add_int
9496

9597
module subroutine hdf_add_int_1d(self,dname,value)
9698
class(hdf5_file), intent(in) :: self
9799
character(*), intent(in) :: dname
98-
integer, intent(in) :: value(:)
100+
integer(int32), intent(in) :: value(:)
99101
end subroutine hdf_add_int_1d
100102

101103
module subroutine hdf_add_int_2d(self,dname,value, chunk_size)
102104
class(hdf5_file), intent(inout) :: self
103105
character(*), intent(in) :: dname
104-
integer, intent(in) :: value(:,:)
106+
integer(int32), intent(in) :: value(:,:)
105107
integer, intent(in), optional :: chunk_size(:)
106108
end subroutine hdf_add_int_2d
107109

108110
module subroutine hdf_add_int_3d(self,dname,value, chunk_size)
109111
class(hdf5_file), intent(inout) :: self
110112
character(*), intent(in) :: dname
111-
integer, intent(in) :: value(:,:,:)
113+
integer(int32), intent(in) :: value(:,:,:)
112114
integer, intent(in), optional :: chunk_size(:)
113115
end subroutine hdf_add_int_3d
114116

@@ -122,21 +124,21 @@ end subroutine hdf_add_int_4d
122124
module subroutine hdf_add_int_5d(self,dname,value, chunk_size)
123125
class(hdf5_file), intent(inout) :: self
124126
character(*), intent(in) :: dname
125-
integer, intent(in) :: value(:,:,:,:,:)
127+
integer(int32), intent(in) :: value(:,:,:,:,:)
126128
integer, intent(in), optional :: chunk_size(:)
127129
end subroutine hdf_add_int_5d
128130

129131
module subroutine hdf_add_int_6d(self,dname,value, chunk_size)
130132
class(hdf5_file), intent(inout) :: self
131133
character(*), intent(in) :: dname
132-
integer, intent(in) :: value(:,:,:,:,:,:)
134+
integer(int32), intent(in) :: value(:,:,:,:,:,:)
133135
integer, intent(in), optional :: chunk_size(:)
134136
end subroutine hdf_add_int_6d
135137

136138
module subroutine hdf_add_int_7d(self,dname,value, chunk_size)
137139
class(hdf5_file), intent(inout) :: self
138140
character(*), intent(in) :: dname
139-
integer, intent(in) :: value(:,:,:,:,:,:,:)
141+
integer(int32), intent(in) :: value(:,:,:,:,:,:,:)
140142
integer, intent(in), optional :: chunk_size(:)
141143
end subroutine hdf_add_int_7d
142144

@@ -263,49 +265,49 @@ end subroutine hdf_get_string
263265
module subroutine hdf_get_int(self, dname, value)
264266
class(hdf5_file), intent(in) :: self
265267
character(*), intent(in) :: dname
266-
integer, intent(out) :: value
268+
integer(int32), intent(out) :: value
267269
end subroutine hdf_get_int
268270

269271
module subroutine hdf_get_int_1d(self, dname, value)
270272
class(hdf5_file), intent(in) :: self
271273
character(*), intent(in) :: dname
272-
integer, intent(out),allocatable :: value(:)
274+
integer(int32), intent(out),allocatable :: value(:)
273275
end subroutine hdf_get_int_1d
274276

275277
module subroutine hdf_get_int_2d(self, dname, value)
276278
class(hdf5_file), intent(in) :: self
277279
character(*), intent(in) :: dname
278-
integer, intent(out),allocatable :: value(:,:)
280+
integer(int32), intent(out),allocatable :: value(:,:)
279281
end subroutine hdf_get_int_2d
280282

281283
module subroutine hdf_get_int_3d(self, dname, value)
282284
class(hdf5_file), intent(in) :: self
283285
character(*), intent(in) :: dname
284-
integer, intent(out),allocatable :: value(:,:,:)
286+
integer(int32), intent(out),allocatable :: value(:,:,:)
285287
end subroutine hdf_get_int_3d
286288

287289
module subroutine hdf_get_int_4d(self, dname, value)
288290
class(hdf5_file), intent(in) :: self
289291
character(*), intent(in) :: dname
290-
integer, intent(out),allocatable :: value(:,:,:,:)
292+
integer(int32), intent(out),allocatable :: value(:,:,:,:)
291293
end subroutine hdf_get_int_4d
292294

293295
module subroutine hdf_get_int_5d(self, dname, value)
294296
class(hdf5_file), intent(in) :: self
295297
character(*), intent(in) :: dname
296-
integer, intent(out),allocatable :: value(:,:,:,:,:)
298+
integer(int32), intent(out),allocatable :: value(:,:,:,:,:)
297299
end subroutine hdf_get_int_5d
298300

299301
module subroutine hdf_get_int_6d(self, dname, value)
300302
class(hdf5_file), intent(in) :: self
301303
character(*), intent(in) :: dname
302-
integer, intent(out),allocatable :: value(:,:,:,:,:,:)
304+
integer(int32), intent(out),allocatable :: value(:,:,:,:,:,:)
303305
end subroutine hdf_get_int_6d
304306

305307
module subroutine hdf_get_int_7d(self, dname, value)
306308
class(hdf5_file), intent(in) :: self
307309
character(*), intent(in) :: dname
308-
integer, intent(out),allocatable :: value(:,:,:,:,:,:,:)
310+
integer(int32), intent(out),allocatable :: value(:,:,:,:,:,:,:)
309311
end subroutine hdf_get_int_7d
310312

311313

@@ -422,7 +424,7 @@ end subroutine writeattr
422424
end interface
423425

424426

425-
public :: hdf5_file, toLower, hsize_t
427+
public :: hdf5_file, toLower, hsize_t, strip_trailing_null
426428

427429
private
428430

@@ -446,12 +448,12 @@ subroutine hdf_initialize(self,filename,status,action,comp_lvl)
446448

447449
!> Initialize FORTRAN interface.
448450
call h5open_f(ierr)
449-
if (ierr /= 0) error stop 'Error: HDF5 library initialize Failed!'
451+
if (ierr /= 0) error stop 'Error: HDF5 library initialize Failed for ' // self%filename
450452

451-
lstatus = 'old' ! not merge() due to unequal character length
453+
lstatus = 'old'
452454
if(present(status)) lstatus = toLower(status)
453455

454-
laction = 'rw' ! not merge() due to unequal character length
456+
laction = 'rw'
455457
if(present(action)) laction = toLower(action)
456458

457459

@@ -487,7 +489,6 @@ subroutine hdf_finalize(self)
487489

488490
!> Close Fortran interface.
489491
call h5close_f(ierr)
490-
491492
if (ierr /= 0) error stop 'Error: HDF5 finalization: '//self%filename
492493

493494
end subroutine hdf_finalize
@@ -517,38 +518,17 @@ subroutine hdf_add_group(self, gname)
517518
! check subgroup exists
518519
sp = sp + ep
519520
call h5lexists_f(self%lid, gname(1:sp-1), gexist, ierr)
520-
if (ierr /= 0) error stop 'problem finding group '//gname
521+
if (ierr /= 0) error stop 'did not find group ' // gname // ' in ' // self%filename
521522

522523
if(.not.gexist) then
523524
call h5gcreate_f(self%lid, gname(1:sp-1), gid, ierr)
524-
if (ierr /= 0) error stop 'problem creating group '//gname
525-
525+
if (ierr /= 0) error stop 'problem creating group ' // gname // ' in ' // self%filename
526+
526527
call h5gclose_f(gid, ierr)
527-
if (ierr /= 0) error stop 'problem closing group '//gname
528+
if (ierr /= 0) error stop 'problem closing group ' // gname // ' in ' // self%filename
528529
endif
529530
end do
530531

531532
end subroutine hdf_add_group
532533

533-
534-
535-
!----- Helper functions
536-
537-
elemental function toLower(str)
538-
! can be trivially extended to non-ASCII
539-
character(*), intent(in) :: str
540-
character(len(str)) :: toLower
541-
character(*), parameter :: lower="abcdefghijklmnopqrstuvwxyz", &
542-
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
543-
integer :: i,j
544-
545-
toLower = str
546-
547-
do concurrent (i = 1:len(str))
548-
j = index(upper,str(i:i))
549-
if (j > 0) toLower(i:i) = lower(j:j)
550-
end do
551-
552-
end function toLower
553-
554534
end module hdf5_interface

src/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
hdf5_src = files('hdf5_interface.f90','read.f90', 'read_real64.f90', 'read_real32.f90', 'read_int.f90', 'write.f90', 'write_real64.f90', 'write_real32.f90', 'write_int.f90',
2+
'string_utils.f90')

0 commit comments

Comments
 (0)