Skip to content

Commit 68468e8

Browse files
committed
note that compact dataset write may not work with MPI collective write
1 parent faedff3 commit 68468e8

File tree

6 files changed

+78
-40
lines changed

6 files changed

+78
-40
lines changed

API.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class(*), intent(in) :: value(..) !< array to write
182182
integer, intent(in), dimension(rank(value)), optional :: dset_dims
183183
integer, intent(in), optional, dimension(rank(value)) :: istart, iend, stride !< array slicing for hyperslab
184184
integer, intent(in), optional :: chunk_size(rank(value)) !< override auto-chunking
185-
logical, intent(in), optional :: compact !< faster I/O for sub-64 kB datasets
185+
logical, intent(in), optional :: compact !< faster I/O for sub-64 kB datasets--May not work for MPI collective write
186186
```
187187

188188
Write dataset attribute (e.g. units or instrument)

src/write.f90

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
call set_deflate(self, mem_dims, dcpl, chunk_size)
125125
endif
126126

127-
if(present(compact)) call set_compact(dcpl, dset_dims, compact)
127+
if(present(compact)) call set_compact(dcpl, dset_dims, compact, dname)
128128

129129
!> create dataset dataspace
130130
if(size(dset_dims) == 0) then
@@ -181,21 +181,28 @@
181181
end procedure hdf_create
182182

183183

184-
subroutine set_compact(dcpl, dset_dims, compact)
184+
subroutine set_compact(dcpl, dset_dims, compact, dset_name)
185185
!! compact dataset (for very small datasets to increase I/O speed)
186+
!! NOTE: this does not work for collective writes, at least for HDF5 1.12.2. The dataset will be all zero.
186187

187188
integer(HID_T), intent(inout) :: dcpl
188189
integer(HSIZE_T), intent(in) :: dset_dims(:)
189190
logical, intent(in) :: compact
191+
character(*), intent(in) :: dset_name
190192

191193
integer :: ierr
194+
integer(HSIZE_T) :: Nbytes
192195

193196
if(.not. compact) return
194197

195198
if(dcpl /= H5P_DEFAULT_F) return
196199
!! datasets are EITHER compact or chunked.
197200

198-
if(product(dset_dims) * 8 > 60000) return
201+
Nbytes = product(dset_dims) * 8
202+
if(Nbytes > 60000) then
203+
write(stderr,'(a,i0,1x,a)') "WARNING:h5fortran:set_compact: dataset is too large to be compact: bytes: ", Nbytes, dset_name
204+
return
205+
endif
199206
!! 64000 byte limit, here we assumed 8 bytes / element
200207

201208
call h5pcreate_f(H5P_DATASET_CREATE_F, dcpl, ierr)
@@ -204,6 +211,8 @@ subroutine set_compact(dcpl, dset_dims, compact)
204211
call h5pset_layout_f(dcpl, H5D_COMPACT_F, ierr)
205212
if (ierr /= 0) error stop "ERROR:h5fortran:hdf_create:h5pset_layout:set_compact"
206213

214+
print *, "TRACE:h5fortran:set_compact: " // dset_name
215+
207216
end subroutine set_compact
208217

209218

test/CMakeLists.txt

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,49 +16,62 @@ endif()
1616

1717
# --- h5fortran unit tests
1818

19-
function(setup_test names use_runner)
19+
function(nompi_test names)
20+
21+
foreach(name IN LISTS names)
22+
23+
add_executable(test_${name} test_${name}.f90)
24+
target_link_libraries(test_${name} PRIVATE h5mpi::h5mpi)
25+
26+
add_test(NAME ${name} COMMAND test_${name})
27+
28+
endforeach()
29+
30+
endfunction(nompi_test)
31+
32+
33+
function(mpi_test names use_runner)
2034

2135
foreach(name IN LISTS names)
2236

2337
add_executable(test_${name} test_${name}.f90)
2438
target_link_libraries(test_${name} PRIVATE h5mpi::h5mpi)
2539

2640
if(use_runner)
27-
set(cmd test_runner -exe $<TARGET_FILE:test_${name}> -mpiexec ${MPIEXEC_EXECUTABLE} -lx 1000)
41+
set(cmd test_runner -exe $<TARGET_FILE:test_${name}> -mpiexec ${MPIEXEC_EXECUTABLE} -lx 1000)
2842
else()
29-
set(cmd ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} $<TARGET_FILE:test_${name}>)
30-
# these tests could also be -n 2 instead of max_numprocs.
31-
# Just trying to keep aware of possible problems vs. MPI worker count.
43+
set(cmd ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} $<TARGET_FILE:test_${name}>)
44+
# these tests could also be -n 2 instead of max_numprocs.
45+
# Just trying to keep aware of possible problems vs. MPI worker count.
46+
endif()
47+
3248
if(${name} STREQUAL "string_read")
3349
list(APPEND cmd ${string_file})
3450
endif()
35-
endif()
36-
37-
3851

3952
add_test(NAME ${name} COMMAND ${cmd})
4053

54+
set_tests_properties(${name} PROPERTIES
55+
RESOUCE_LOCK cpu_mpi
56+
)
57+
4158
endforeach()
4259

43-
endfunction(setup_test)
60+
endfunction(mpi_test)
4461

4562
cmake_path(SET string_file ${CMAKE_CURRENT_BINARY_DIR}/test_string_py.h5)
4663

4764
# --- write test data
48-
add_executable(test_write test_write.f90)
49-
target_link_libraries(test_write PRIVATE h5mpi::h5mpi)
50-
51-
add_test(NAME write COMMAND test_write)
5265

53-
set(test_names array attributes cast destructor exist fill groups layout shape
54-
string string_read
66+
set(mpi_tests array_mpi attributes cast destructor exist fill groups layout shape
67+
string string_read write
5568
)
5669

57-
setup_test("${test_names}" false)
70+
mpi_test("${mpi_tests}" false)
5871

5972
set(runner_tests deflate_write deflate_props deflate_read)
6073

61-
setup_test("${runner_tests}" true)
74+
mpi_test("${runner_tests}" true)
6275

6376
# --- test dependencies
6477

@@ -68,7 +81,7 @@ FIXTURES_SETUP test_files
6881

6982
set_tests_properties(layout shape PROPERTIES
7083
FIXTURES_REQUIRED test_files
71-
REQUIRED_FILES ${CMAKE_CURRENT_BINARY_DIR}/test_write.h5
84+
REQUIRED_FILES "${CMAKE_CURRENT_BINARY_DIR}/test_write.h5;${CMAKE_CURRENT_BINARY_DIR}/test_layout.h5"
7285
)
7386

7487
set_tests_properties(deflate_write PROPERTIES
@@ -87,13 +100,6 @@ EXECUTABLE ${CMAKE_CTEST_COMMAND}
87100
)
88101
endif()
89102

90-
# --- Windows shared DLLs
91-
if(WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
92-
set_tests_properties(${test_names} PROPERTIES
93-
ENVIRONMENT_MODIFICATION "PATH=path_list_append:${ZLIB_INCLUDE_DIRS}/../bin;PATH=path_list_append:${ZLIB_INCLUDE_DIR}/../bin"
94-
)
95-
endif()
96-
97103
# --- Python h5py
98104
find_package(Python COMPONENTS Interpreter)
99105
if(NOT DEFINED h5py_ok)
@@ -117,14 +123,22 @@ COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_string.py ${string
117123
)
118124

119125
set_tests_properties(PythonString PROPERTIES
120-
FIXTURES_REQUIRED h5lib
121126
FIXTURES_SETUP h5str
122127
DISABLED $<NOT:$<BOOL:${h5py_ok}>>
123128
)
124129

130+
# --- test properties
131+
125132
get_property(test_names DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY TESTS)
126133

127134
set_tests_properties(${test_names} PROPERTIES
128135
TIMEOUT 30
129136
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
130137
)
138+
139+
# --- Windows shared DLLs
140+
if(WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
141+
set_tests_properties(${test_names} PROPERTIES
142+
ENVIRONMENT_MODIFICATION "PATH=path_list_append:${ZLIB_INCLUDE_DIRS}/../bin;PATH=path_list_append:${ZLIB_INCLUDE_DIR}/../bin"
143+
)
144+
endif()
File renamed without changes.

test/test_layout.f90

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
program test_layout
22

3-
use, intrinsic :: iso_fortran_env, only : real32, real64, int32
3+
use, intrinsic :: iso_fortran_env, only : real32, real64, int32, stderr => error_unit
44

55
use h5mpi, only : hdf5_file
66

@@ -48,18 +48,21 @@ subroutine test_layout_read(fn)
4848
call h%open(fn, action="r", mpi=.true.)
4949

5050
call h%read("/compact_r32", r64)
51-
if(r64 /= 142) error stop "read real32 => real64"
51+
if(abs(r64 - 142) > 0.001) then
52+
write(stderr,*) r64
53+
error stop "ERROR:test_layout_read: read real32 => real64: " // fn
54+
endif
5255
call h%read("/compact_r64", r32)
53-
if(r32 /= 142) error stop "read real64 => real32"
56+
if(abs(r32 - 142) > 0.001) error stop "ERROR:test_layout_read: read real64 => real32"
5457
call h%read("/compact_i32", i32)
55-
if(r32 /= 142) error stop "read int32 => int32"
58+
if(r32 /= 142) error stop "ERROR:test_layout_read: read int32 => int32"
5659

5760

5861
call h%read("/compact7d_32", r7_64)
59-
if (any(r7_64 /= 42)) error stop "read real32 => real64"
62+
if (any(r7_64 /= 42)) error stop "ERROR:test_layout: read real32 => real64"
6063

6164
call h%read("/compact7d_64", r7_32)
62-
if (any(r7_32 /= 42)) error stop "read real64 => real32"
65+
if (any(r7_32 /= 42)) error stop "ERROR:test_layout: read real64 => real32"
6366

6467
call h%close()
6568

test/test_write.f90

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ program test_scalar
2020
call test_simple_write('test_write.h5')
2121
if(mpi_id == 0) print *, "OK: test simple write"
2222

23-
call test_layout_write('test_layout.h5')
24-
if(mpi_id == 0) print *, "OK: test layout write"
23+
if(mpi_id == 0) then
24+
call test_layout_write('test_layout.h5')
25+
print *, "OK: test layout write"
26+
endif
2527

2628
call mpi_finalize(ierr)
2729
if (ierr /= 0) error stop "mpi_finalize"
@@ -38,6 +40,16 @@ subroutine test_simple_write(fn)
3840

3941
call h5%open(fn, action="w", mpi=.true.)
4042

43+
!> just to have some default value
44+
d0 = 0
45+
d1 = 1
46+
d2 = 2
47+
d3 = 3
48+
d4 = 4
49+
d5 = 5
50+
d6 = 6
51+
d7 = 7
52+
4153
call h5%write("/d0", d0)
4254
call h5%write("/d1", d1)
4355
call h5%write("/d2", d2)
@@ -53,7 +65,7 @@ end subroutine test_simple_write
5365

5466

5567
subroutine test_layout_write(fn)
56-
68+
!! NOTE: compact datsets do not work for collective writes, at least for HDF5 1.12.2. The dataset will be all zero.
5769
character(*), intent(in) :: fn
5870

5971
type(hdf5_file) :: h
@@ -65,7 +77,7 @@ subroutine test_layout_write(fn)
6577
d7_64 = 42
6678

6779

68-
call h%open(fn, action="w", mpi=.true.)
80+
call h%open(fn, action="w", mpi=.false.)
6981

7082
call h%write("/compact1d", [1,2,3], compact=.true.)
7183
call h%write("/contig1d", [1,2,3], compact=.false.)

0 commit comments

Comments
 (0)