|
H5CPP
v1.14.0
Modern C++ templates for HDF5 serial and parallel I/O
|
|
SWMR lets one writer process append to a dataset while several reader processes see the growth live, on the same host, with no locks and no coordination beyond explicit h5::flush (writer) and h5::refresh (reader). This cookbook is three small standalone programs — one writer and two interchangeable readers.
Linux-only this release: each source opens with an #ifndef __linux__ guard and the CMake targets are registered only on CMAKE_SYSTEM_NAME STREQUAL "Linux".
| File | Purpose |
|---|---|
swmr-write.cpp | writer — create/append/flush, cold+warm start, clean Ctrl-C |
swmr-read.cpp | reader — follows via h5::read<std::vector<T>> (materializes the extent) |
swmr-view.cpp | reader — follows via h5::view<T> (C++20 ranges, constant-memory streaming) |
SWMR is a cross-**process** feature, so use two terminals — writer first, then a reader:
h5::flush on the writer and h5::refresh on the reader. No polling helper is provided — cadence is your policy.h5::create makes a normal latest-format file; h5::start_swmr_write(fd) flips it into SWMR mode after the datasets exist. The call is idempotent — a no-op if the file is already SWMR-write (e.g. a warm restart).h5::get_extent(ds)[0]. Re-running the writer picks up the stream where it left off.H5Fclose leaves the file in a dirty "write-in-progress" state. The writer installs a signal handler that just sets a flag; the loop exits and RAII closes the file — never call HDF5 from a signal handler.H5Pset_file_locking(fapl, /*use=*/false, /*ignore_disabled=*/true). Trade-off: single-writer discipline is then yours to enforce.std::uint64_t, so readers use h5::view<std::uint64_t> / h5::read<std::vector<std::uint64_t>> — a type mismatch reads garbage.H5CPP_SWMR_NO_FS_CHECK=1).H5F_ACC_* flags to h5::open/h5::create and reach for raw H5Pset_file_locking through an h5::fapl_t — the C-API is always one static_cast<hid_t> away to fill any gap.Note: pass the raw H5F_ACC_SWMR_WRITE flag and h5cpp does the right thing — it creates a normal latest-format file (it can't enable SWMR at create), so you then call h5::start_swmr_write. The packet table's flush(pt) issues the SWMR metadata flush itself, so the writer needs no separate h5::ds_t to flush.
Both open H5F_ACC_RDONLY | H5F_ACC_SWMR_READ and loop on h5::refresh; they differ only in how they pull the newly-visible tail.
swmr-read — materialize the extentSimple, fine for modest streams — but it reads the whole dataset every poll.
swmr-view — stream in constant memoryh5::view<std::uint64_t>(ds) is a C++20 ranges input-view that streams a rank-1 chunked dataset one chunk at a time and never materializes a full vector — the right tool for a large stream. It snapshots the extent when constructed, so the discipline is: refresh first, then build a fresh view each poll; std::views::drop(seen) streams only the new tail.
h5::append packet-table surface this builds on