tmaric
tmaric

Reputation: 5477

Creating HDF5 groups within nested for loops using the C API fails

I am trying to create groups in a HDF5 file with a HDF5Gcreate call in a nested for loop like this:

#include "hdf5.h"
#include <string> 
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<string> firstIDs =  {"A", "B", "C"}; 
    vector<string> secondIDs =  {"1", "2", "3"}; 

    hid_t file_id; 
    file_id = H5Fcreate ("RBF_RANDOM_POINTS.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    for (const auto& firstID : firstIDs)
    {
        for (const auto& secondID : secondIDs)
        {
            // Create the HDF5 group for each RBF and random test size. 
            std::string groupName {
                "/FIRST/" + firstID + "/SECOND/" + secondID 
            };
            hid_t group_id; 
            cout << groupName << endl;
            group_id = H5Gcreate(file_id, groupName.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
            H5Gclose (group_id);
        }
    }

    H5Fclose(file_id); 
};

And this is the error I get:

/FIRST/A/SECOND/1
HDF5-DIAG: Error detected in HDF5 (1.10.4) thread 0:
  #000: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5G.c line 323 in H5Gcreate2(): unable to create group
    major: Symbol table
    minor: Unable to initialize object
  #001: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5Gint.c line 157 in H5G__create_named(): unable to create and link to group
    major: Symbol table
    minor: Unable to initialize object
  #002: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5L.c line 1572 in H5L_link_object(): unable to create new link to object
    major: Links
    minor: Unable to initialize object
  #003: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5L.c line 1813 in H5L__create_real(): can't insert link
    major: Links
    minor: Unable to insert object
  #004: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5Gtraverse.c line 851 in H5G_traverse(): internal path traversal failed
    major: Symbol table
    minor: Object not found
  #005: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5Gtraverse.c line 741 in H5G__traverse_real(): component not found
    major: Symbol table
    minor: Object not found
HDF5-DIAG: Error detected in HDF5 (1.10.4) thread 0:
  #000: /.cache/pacaur/hdf5-openmpi-java/src/hdf5-1.10.4/src/H5G.c line 682 in H5Gclose(): not a group
    major: Invalid arguments to routine
    minor: Inappropriate type
/FIRST/A/SECOND/2
HDF5-DIAG: Error detected in HDF5 (1.10.4) thread 0:

What is happening? The individual call outside the for loops is working fine.

Upvotes: 1

Views: 552

Answers (1)

From the HDF5 User's Guide: Groups

The structure of the HDF5 file constitutes the name space for the objects in the file. A path name is a string of components separated by slashes (/). Each component is the name of a hard or soft link which points to an object in the file. The slash not only separates the components, but indicates their hierarchical relationship; the component indicated by the link name following a slash is a always a member of the component indicated by the link name preceding that slash.

The groups your are trying to create reference groups that don't exist which is why the errors are stating that objects cannot be found. You can verify that a group is successfully created by making sure that the group_id is not -1. You need to create any group higher in the hierarchy before creating something below it as in the changes below.

int main(int argc, char* argv[])
{
  vector<string> firstIDs = { "A", "B", "C" };
  vector<string> secondIDs = { "1", "2", "3" };
  hid_t file_id = H5Fcreate("RBF_RANDOM_POINTS.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  hid_t group_id = H5Gcreate(file_id, "/FIRST", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group_id);
  for (const auto& firstID : firstIDs)
  {
    std::string parent{
      "/FIRST/" + firstID
    };
    std::string child1{
      "/FIRST/" + firstID + "/SECOND"
    };
    group_id = H5Gcreate(file_id, parent.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Gclose(group_id);
    group_id = H5Gcreate(file_id, child1.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Gclose(group_id);
    for (const auto& secondID : secondIDs)
    {
      // Create the HDF5 group for each RBF and random test size. 
      std::string whatYouWanted{
        "/FIRST/" + firstID + "/SECOND/" + secondID
      };
      cout << whatYouWanted << endl;
      group_id = H5Gcreate(file_id, whatYouWanted.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
      // if(-1 == group_id) something went wrong
      H5Gclose(group_id);
    }
  }
  H5Fclose(file_id);
}

Upvotes: 1

Related Questions