Skip to content

wip: Expose HDF5 type conversion handling#43

Draft
lukas-weber wants to merge 1 commit into
TRIQS:unstablefrom
lukas-weber:type-conversion-fallback
Draft

wip: Expose HDF5 type conversion handling#43
lukas-weber wants to merge 1 commit into
TRIQS:unstablefrom
lukas-weber:type-conversion-fallback

Conversation

@lukas-weber

Copy link
Copy Markdown

This PR introduces a way to control the currently hard-coded handling of type mismatches between HDF5 files and what is requested on the C++ side,
which will simply print a warning if types are not different.

HDF5 has rich support to customize this behavior via dataset transfer property list and the associated type_conv callback. h5 now maintains a default transfer property list on the library global scope. This transfer property list is passed to every HDF5 read and write call that takes it. Setting a callback is exposed to the user via h5::set_type_conv_cb.

The callback closely mirrors what HDF5 does, up to two additional calling conditions h5::conv_except::not_equal (types not equal) h5::conv_except::narrower (dst type is narrower), for which HDF5 will just handle silently unless the value being read/written will actually not fit in the destination. h5 calls the callback manually for that reason to reproduce the old behavior.

API Example

#include <h5/h5.hpp>

// Custom datatype-conversion callback: only fail when a *stored value* cannot be
// represented in the destination type. Merely differing / narrower types are fine
// as long as every value actually fits.
h5::set_type_conv_cb(
   [](h5::conv_except except, h5::datatype src, h5::datatype dst, void *src_buf, void *dst_buf) -> h5::conv_ret {
     switch (except) {
       // Type-level mismatches detected by h5 (no offending element): tolerate them.
       // These come with src_buf == dst_buf == nullptr.
       case h5::conv_except::not_equal:
       case h5::conv_except::narrower:
         return h5::conv_ret::unhandled;   // let HDF5 perform the conversion

       // HDF5's native per-element exceptions: a concrete value can't be represented
       // exactly in `dst` (out of range, precision/truncation loss, non-finite).
       // src_buf / dst_buf point at the offending element.
       case h5::conv_except::range_hi:
       case h5::conv_except::range_low:
       case h5::conv_except::precision:
       case h5::conv_except::truncate:
       case h5::conv_except::pinf:
       case h5::conv_except::ninf:
       case h5::conv_except::nan:
         std::cerr << "value not representable converting "
                   << h5::get_name_of_h5_type(src) << " -> " << h5::get_name_of_h5_type(dst) << "\n";
         return h5::conv_ret::abort;       // h5 turns this into a thrown exception
     }
     return h5::conv_ret::unhandled;
   });

@Wentzell Wentzell force-pushed the unstable branch 2 times, most recently from fdbcacc to fca9584 Compare June 24, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant