H5Dflush does not flush metadata
- Dominant language
- C
- Stars
- 988
- Forks
- 355
- Avg merge
- 4d 2h
- Merged PRs (30d)
- 12
Description
# Description
`H5Dflush` appears to not flush all the metadata for the dataset. A reproducer based on a single writer and reader without file locking (disabled via env variable):
```c
// writer.c
#include
#include
#include
#include
#define RANK 3
#define X 10
#define Y 10
#define TYPE H5T_NATIVE_DOUBLE
int main()
{
const char* use_lock = getenv("HDF5_USE_FILE_LOCKING");
printf("%s\n", use_lock);
const hsize_t dims[RANK] = {1, X, Y};
const hsize_t offset[RANK] = {0, 0, 0};
const double data[X * Y] = {1.0};
//All error handling omitted for the sake of brevity
hid_t file = H5Fcreate("file.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
H5Pset_chunk(dcpl, RANK, dims);
hid_t dspace = H5Screate_simple(RANK, dims, dims);
hid_t dset = H5Dcreate(file, "dataset", TYPE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
H5Fflush(file, H5F_SCOPE_GLOBAL); //make sure that file and dset are on disk for reader
H5Sselect_hyperslab(dspace, H5S_SELECT_SET, offset, NULL, dims, NULL);
hid_t memspace = H5Screate_simple(RANK, dims, NULL);
H5Dwrite(dset, TYPE, memspace, dspace, H5P_DEFAULT, data);
H5Dflush(dset);
/*H5Fflush(file, H5F_SCOPE_GLOBAL);*/ //flushing the file instead produces the expected result
// the following only ensures that the file stays open until pressing Enter
const size_t size = 8;
char buf[size];
while(1)
{
fgets(buf, size, stdin);
if (strcmp(buf, "\n") == 0)
break;
}
H5Fclose(file);
}
//reader.c
#include
#include
#include
#include
#define RANK 3
#define X 10
#define Y 10
#define TYPE H5T_NATIVE_DOUBLE
int main()
{
const char* use_lock = getenv("HDF5_USE_FILE_LOCKING");
printf("%s\n", use_lock);
const hsize_t count[RANK] = {1, 10, 10};
const hsize_t offset[RANK] = {0, 0 ,0};
double data[X * Y];
hid_t file = H5Fopen("file.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
hid_t dset = H5Dopen(file, "dataset", H5P_DEFAULT);
hid_t dspace = H5Dget_space(dset);
H5Sselect_hyperslab(dspace, H5S_SELECT_SET, offset, NULL, count, NULL);
hid_t memspace = H5Screate_simple(RANK, count, NULL);
H5Dread(dset, TYPE, memspace, dspace, H5P_DEFAULT, data);
printf("%lf, %lf\n", data[0], data[1]);
H5Fclose(file);
}
```
If I start the writer first and then the reader, the reader produces the following output:
```
HDF5-DIAG: Error detected in HDF5 (2.0.1):
#000: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5D.c line 1051 in H5Dread(): can't synchronously read data
major: Dataset
minor: Read failed
#001: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5D.c line 999 in H5D__read_api_common(): can't read data
major: Dataset
minor: Read failed
#002: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5VLcallback.c line 2209 in H5VL_dataset_read(): dataset read failed
major: Virtual Object Layer
minor: Read failed
#003: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5VLcallback.c line 2165 in H5VL__dataset_read(): dataset read failed
major: Virtual Object Layer
minor: Read failed
#004: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5VLnative_dataset.c line 374 in H5VL__native_dataset_read(): can't read data
major: Dataset
minor: Read failed
#005: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Dio.c line 402 in H5D__read(): can't read data
major: Dataset
minor: Read failed
#006: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Dchunk.c line 3134 in H5D__chunk_read(): error looking up chunk address
major: Dataset
minor: Can't get value
#007: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Dchunk.c line 4108 in H5D__chunk_lookup(): can't query chunk address
major: Dataset
minor: Can't get value
#008: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Dbtree.c line 1025 in H5D__btree_idx_get_addr(): can't check for chunk in B-tree
major: Dataset
minor: Unable to check for record
#009: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5B.c line 296 in H5B_find(): can't lookup key
major: B-Tree node
minor: Object not found
#010: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5B.c line 357 in H5B_find_helper(): unable to load B-tree node
major: B-Tree node
minor: Unable to protect metadata
#011: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5AC.c line 1303 in H5AC_protect(): H5C_protect() failed
major: Object cache
minor: Unable to protect metadata
#012: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Centry.c line 3154 in H5C_protect(): can't load entry
major: Object cache
minor: Unable to load metadata into cache
#013: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Centry.c line 1117 in H5C__load_entry(): Can't read image*
major: Object cache
minor: Read failed
#014: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Fio.c line 138 in H5F_block_read(): read through page buffer failed
major: Low-level I/O
minor: Read failed
#015: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5PB.c line 697 in H5PB_read(): read through metadata accumulator failed
major: Page Buffering
minor: Read failed
#016: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5Faccum.c line 198 in H5F__accum_read(): driver read request failed
major: Low-level I/O
minor: Read failed
#017: /tmp/niclas/spack-stage/spack-stage-hdf5-develop-2.0-m5qx6nwpgag4cis6qybqy6kaeztigdht/spack-src/src/H5FDint.c line 258 in H5FD_read(): addr overflow, addr = 479, size = 3136, eoa = 479
major: Invalid arguments to routine
minor: Address overflowed
```
# Expected behaviour
I would have assumed that flushing the dataset makes all the necessary metadata available for subsequent reads as well. If I flush the entire file with `H5Fflush`, I get the expected output (namely a print of `1.000000, 0.000000`, without errors), but the source code for [H5D__flush](https://github.com/HDFGroup/hdf5/blob/bd76ec789a394c9440516ff45e42852f21b2a1f1/src/H5Dint.c#L3311) suggests that a dset flush should suffice. Having disabled the file locks (probably) shouldn't affect the metadata flush either. Is this a bug or am I missing something fundamental?
# Platform
- hdf5 v2.0.1
- Linux fedora 6.17.8-100.fc41.x86_64
- gcc 14.3.1
- built via spack (CMake)
Contributor guide
Assessment
This issue has not been assessed yet.