Migration to H5Literate2

I have code that uses H5Literate and I want to update to a newer HDF5, necessitating using H5Literate2.

The problem is my existing code no longer works:

HDF5-DIAG: Error detected in HDF5 (1.14.3) MPI-process 0:
  #000: /var/folders/tr/v_kqwm7x25x3y68l_p5qh1gw0000gn/T/cmarsh/spack-stage/spack-stage-hdf5-1.14.3-vtw2x4axrhoixpcmxjbzlcn6yykcl7oq/spack-src/src/H5L.c line 1647 in H5Literate2(): synchronous link iteration failed
    major: Links
    minor: Iteration failed
  #001: /var/folders/tr/v_kqwm7x25x3y68l_p5qh1gw0000gn/T/cmarsh/spack-stage/spack-stage-hdf5-1.14.3-vtw2x4axrhoixpcmxjbzlcn6yykcl7oq/spack-src/src/H5L.c line 1598 in H5L__iterate_api_common(): can't set object access arguments
    major: Links
    minor: Can't set value
  #002: /var/folders/tr/v_kqwm7x25x3y68l_p5qh1gw0000gn/T/cmarsh/spack-stage/spack-stage-hdf5-1.14.3-vtw2x4axrhoixpcmxjbzlcn6yykcl7oq/spack-src/src/H5VLint.c line 2634 in H5VL_setup_self_args(): invalid location identifier
    major: Invalid arguments to routine
    minor: Inappropriate type
  #003: /var/folders/tr/v_kqwm7x25x3y68l_p5qh1gw0000gn/T/cmarsh/spack-stage/spack-stage-hdf5-1.14.3-vtw2x4axrhoixpcmxjbzlcn6yykcl7oq/spack-src/src/H5VLint.c line 1733 in H5VL_vol_object(): invalid identifier
    major: Invalid arguments to routine
    minor: Inappropriate type

Where the usage is as follows:

typedef struct _MeshParameters {
std::vector<std::string> names;
} MeshParameters;

herr_t
group_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *opdata)
{
    hid_t group;
    MeshParameters *pars = (MeshParameters*)opdata;
    std::string str(name);
    group = H5Gopen2(loc_id, name, H5P_DEFAULT);
    // cout << "Name : " << str << endl; // Display the group name.
    (pars->names).push_back(str);
    H5Gclose(group);
    return 0;
}

// Open an existing file and dataset.
H5File file(param_filename, H5F_ACC_RDONLY);

// Space for extracting the parameter info
std::unique_ptr<MeshParameters> pars(new MeshParameters);

// Extract all of the parameter info (names) from the file
Group group = file.openGroup("parameters");

herr_t idx = H5Literate(group.getId(), H5_INDEX_NAME, H5_ITER_INC, NULL, group_info, (void*)pars.get());

Tracing the code through suggests the problem is with group.getId() causing it to abort, but it isn’t clear /why/.

The documentation on H5Literate1 and H5Literate2 doesn’t indicate (unless I’m totally missing it) what is different between the two functions and what I might be doing wrong.

Earlier you said:

I have a C++ code that uses H5Literate with HDF5 1.10. However, I need to update my HDF5 dependency to HDF 1.12+.

Instead of changing your code, I recommend using the API compatibility macros. This feature was created for situations like yours. Simply use your original code, and add -DH5_USE_110_API to the compile command line. Please refer to “Application Mapping Options” on this page:

https://docs.hdfgroup.org/hdf5/v1_14/api-compat-macros.html

(Stay away from Library Mapping Options and Function Mapping Options. App Mapping Options is by far the simplest solution for your situation.)

Hi Dave, Thanks for this. I’d seen that and previously understood it to be something I could set during the compilation of my application (which doesn’t use h5cc), but I see now this is a configuration of the hdf5 library. I have this working now, so up-side is that I am unblocked.

However, long term, I think it would be best to use the newest api. I use other libraries that use hdf5 (gdal, netcdf) and so if they start to require the new API, I’m going to be in trouble, will I not?

Ultimately I would like to get this working with the new version of the API. Any suggestions?

No. -DH5_USE_110_API is an Application Mapping Option. That means it is an option that you add to the command line when compiling your own application. Please check that doc page carefully. The HDF5 library itself is configured with a completely different set of options under “Library Mapping Options”. That doc page covers a lot of territory, and it is easy to get confused between the various methodologies presented right next to each other.

If you use -DH5_USE_110_API with your current application, it should remain compatible with future HDF5 versions, unless your code does something unusual. The HDF5 team put a lot of effort into backward compatibility, specifically presenting multiple API versions in a single library build by use of these macro options.

Also note that for this to work, the library must have been built with default library compatibility, or one of the so-called “default” options in table 1. The down-level application mapping options such as -DH5_USE_110_API require some of the “deprecated symbols”. I have found that it is best to simply build the HDF5 library as default, then use the app mapping options as needed with older application code.

Ok I will look into this further. Thank you very much for pointing me in the right direction!