Skip to content

Commit 78b9dd6

Browse files
committed
add group write dataset
1 parent e5d5a03 commit 78b9dd6

File tree

5 files changed

+120
-3
lines changed

5 files changed

+120
-3
lines changed

src/interface.f90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ module h5mpi
5757
softlink => create_softlink, &
5858
layout => hdf_get_layout, chunks => hdf_get_chunk, &
5959
is_contig => hdf_is_contig, is_chunked => hdf_is_chunked, is_compact => hdf_is_compact, &
60-
is_open
60+
is_open, write_group
6161
!! procedures without mapping
6262

6363
generic, public :: write => h5write_scalar,ph5write_1d, ph5write_2d, ph5write_3d, ph5write_4d, ph5write_5d, ph5write_6d, ph5write_7d
@@ -104,6 +104,10 @@ module subroutine hdf_create(self, dname, dtype, mem_dims, dset_dims, filespace,
104104
logical, intent(in), optional :: compact
105105
end subroutine hdf_create
106106

107+
module subroutine write_group(self, group_path)
108+
class(hdf5_file), intent(in) :: self
109+
character(*), intent(in) :: group_path !< full path to group
110+
end subroutine write_group
107111
module subroutine create_softlink(self, tgt, link)
108112
class(hdf5_file), intent(inout) :: self
109113
character(*), intent(in) :: tgt, & !< target path to link

src/tests/unit/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ add_library(test_utils OBJECT utils.f90)
2020

2121
# --- unit tests
2222

23-
set(test_names cast deflate_write deflate_props deflate_read destructor exist layout shape string)
23+
set(test_names cast deflate_write deflate_props deflate_read destructor exist groups layout shape string)
2424

2525
foreach(t IN LISTS test_names)
2626

src/tests/unit/test_cast.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ program test_cast
2929
call test_cast_read(fn)
3030
if(mpi_id == 0) print "(A)", "OK: cast read"
3131

32+
3233
call mpi_finalize(ierr)
3334
if (ierr /= 0) error stop "mpi_finalize"
3435

src/tests/unit/test_groups.f90

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
program test_groups
2+
!! groups test
3+
use, intrinsic:: iso_fortran_env, only: int32, real32, real64, stderr=>error_unit
4+
5+
use h5mpi, only: hdf5_file
6+
use mpi, only : mpi_init, MPI_COMM_WORLD, mpi_comm_rank
7+
8+
implicit none (type, external)
9+
10+
external :: mpi_finalize
11+
12+
integer :: ierr, mpi_id
13+
14+
call mpi_init(ierr)
15+
if (ierr /= 0) error stop "mpi_init"
16+
17+
call mpi_comm_rank(MPI_COMM_WORLD, mpi_id, ierr)
18+
if (ierr /= 0) error stop "mpi_comm_rank"
19+
20+
21+
call test_group('test_groups.h5')
22+
if(mpi_id == 0) print *,'OK: group variable'
23+
24+
call test_write_existing('overwrite.h5')
25+
if(mpi_id == 0) print *,'OK: write existing variable'
26+
27+
28+
call mpi_finalize(ierr)
29+
if (ierr /= 0) error stop "mpi_finalize"
30+
31+
32+
contains
33+
34+
subroutine test_group(fn)
35+
36+
character(*), intent(in) :: fn
37+
38+
type(hdf5_file) :: h5f
39+
40+
call h5f%open(fn, action='w', mpi=.true.)
41+
42+
call h5f%write('/test/group3/scalar', 1_int32)
43+
44+
call h5f%write('/test/group3/scalar_real', 1._real32)
45+
46+
if(.not. h5f%exist('/test/group3/scalar')) error stop "/test/group3/scalar does not exist: create group failed"
47+
48+
call h5f%close()
49+
50+
end subroutine test_group
51+
52+
53+
subroutine test_write_existing(fn)
54+
type(hdf5_file) :: h5f
55+
character(*), intent(in) :: fn
56+
57+
call h5f%open(fn, action='w', mpi=.true.)
58+
call h5f%write('/scalar_int', 42_int32)
59+
call h5f%write('/int1d', [42_int32, 1_int32])
60+
call h5f%close()
61+
62+
call h5f%open(fn, action='r+', mpi=.true.)
63+
call h5f%write('/scalar_int', 100_int32)
64+
call h5f%write('/int1d', [100_int32, 10_int32])
65+
call h5f%close()
66+
67+
end subroutine test_write_existing
68+
69+
end program

src/write/write.f90

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
use hdf5, only : h5pset_deflate_f, h5pset_fletcher32_f, h5pset_shuffle_f, h5pset_layout_f, &
44
h5dwrite_f, &
5-
h5lcreate_soft_f, &
5+
h5gcreate_f, h5gclose_f, &
6+
h5lcreate_soft_f, h5lexists_f, &
67
h5screate_f, &
78
H5S_SCALAR_F
89

@@ -54,6 +55,9 @@
5455

5556
!> Only new datasets go past this point
5657

58+
call self%write_group(dname)
59+
!! write_group is needed for any dataset in a group e.g. /hi/there/var
60+
5761
!> compression
5862
if(size(mem_dims) >= 2) then
5963
call set_deflate(self, mem_dims, dcpl, chunk_size)
@@ -103,6 +107,45 @@
103107
end procedure create_softlink
104108

105109

110+
module procedure write_group
111+
112+
integer(HID_T) :: gid
113+
integer :: ier
114+
115+
integer :: sp, ep, L
116+
logical :: gexist
117+
118+
if(.not.self%is_open()) error stop 'h5fortran:write_group: file handle is not open'
119+
120+
L = len_trim(group_path)
121+
if(L < 2) return !< not a new group
122+
123+
sp = 1
124+
ep = 0
125+
126+
do
127+
ep = index(group_path(sp+1:L), "/")
128+
129+
! no subgroup found
130+
if (ep == 0) return
131+
132+
! check subgroup exists
133+
sp = sp + ep
134+
call h5lexists_f(self%file_id, group_path(:sp-1), gexist, ier)
135+
if (ier /= 0) error stop "ERROR:h5fortran:write_group: check exists group " // group_path // " in " // self%filename
136+
137+
if(.not.gexist) then
138+
call h5gcreate_f(self%file_id, group_path(:sp-1), gid, ier)
139+
if (ier /= 0) error stop "ERROR:h5fortran:write_group: create group " // group_path // " in " // self%filename
140+
141+
call h5gclose_f(gid, ier)
142+
if (ier /= 0) error stop "ERROR:h5fortran:write_group: close new group " // group_path // " in " // self%filename
143+
endif
144+
end do
145+
146+
end procedure write_group
147+
148+
106149
subroutine set_deflate(self, dims, dcpl, chunk_size)
107150
class(hdf5_file), intent(in) :: self
108151
integer(HSIZE_T), intent(in) :: dims(:)

0 commit comments

Comments
 (0)