H5Scombine_select with non-hyperslab selections

While debugging a workaround for H5Sselect_hyperslab we noticed that H5Scombine_select can’t be used with certain special selections, e.g. H5S_SEL_NONE and H5S_SEL_ALL. Note that the intersection of two hyperslabs might not be considered a hyperslab selection. For example when using H5S_SELECT_AND with two non-overlapping selections (the result is H5S_SEL_NONE). We’re wondering if there’s a more rebust way of combining two selections than H5Scombine_select? Even a partial solution that works only for all combination of H5S_SEL_{NONE,HYPERSLAB,ALL} and all combination of H5S_SEL_{NONE,POINT,ALL} would be very helpful.

Here’s a reproducer:

// file: select_none-v2.cpp
#include <hdf5.h>
#include <iostream>

#include <array>

hid_t select_none(hsize_t * dims) {
  auto space_id = H5Screate_simple(2, dims, nullptr);
  H5Sselect_none(space_id);

  return space_id;
}

void select_hyperslab(hid_t space_id, H5S_seloper_t op, std::array<hsize_t, 2> offset, std::array<hsize_t, 2> count) {
  H5Sselect_hyperslab(space_id, op, offset.data(), nullptr, count.data(), nullptr);
}


int main() {
  size_t n = 100000000, m = 20;
  hsize_t dims[] = {n, m};

  auto left_space_id = select_none(dims);
  select_hyperslab(left_space_id, H5S_SELECT_OR, {0, 0}, {1, 4});
  select_hyperslab(left_space_id, H5S_SELECT_AND, {3, 0}, {1, 4});

  if(H5Sget_select_type(left_space_id) == H5S_SEL_NONE) {
    std::cout << "left_space_id is H5S_SEL_NONE. \n" << std::endl;
  }

  auto right_space_id = select_none(dims);
  select_hyperslab(right_space_id, H5S_SELECT_OR, {1, 0}, {1, 4});

  auto space_id = H5Scombine_select(left_space_id, H5S_SELECT_OR, right_space_id);

  H5Sclose(left_space_id);
  H5Sclose(right_space_id);
  H5Sclose(space_id);

  return 0;
}

which we compile and run as follows:

$  g++ select_none-v2.cpp -o select_none-v2 -l hdf5 && ./select_none-v2
left_space_id is H5S_SEL_NONE. 

HDF5-DIAG: Error detected in HDF5 (1.14.4-3) thread 0:
  #000: H5Shyper.c line 10774 in H5Scombine_select(): dataspaces don't have hyperslab selections
    major: Invalid arguments to routine
    minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.14.4-3) thread 0:
  #000: H5S.c line 438 in H5Sclose(): not a dataspace
    major: Invalid arguments to routine
    minor: Inappropriate type

Why is this an issue for us?

This is becomes tedious when trying to write generic code that combines two selections. For example in library code, we’re given two selections and an operation to join them and no additional information. We need to check if either of the two selections is empty and implement special cases, if they are. Then we also need to avoid H5S_SEL_ALL. Then we need to consider that the result of combining H5S_SEL_ALL with a “hyperslab” needs to be hand-coded for each operation (OR, AND, XOR, NOTA, etc).

I’d like to repeat that the intersection or union of hyperslabs is not always a hyperslab. Therefore, even if we know that we’d dealing with a sequence of operations on “hyperslabs” we can’t avoid the logic for checking the corner cases. As a result very precise testing (or luck) is required to avoid writing code that is mostly correct, but breaks for specific input.

Thanks for positing this. The engineering team has discussed this and it seems like a reasonable enhancement. I’ve added an issue to github here: H5Scombine_select with non-hyperslab selections. Please follow this issue for further discussions and resolution.

Thank you that’s wonderful news. You link points to this forum post. This is the issue:

I’ve had to double check the statements I made in the post and I can’t back up the following claim:

  • The union of hyperslabs can turn into an ALL selection.

I’ve tried and I’m unable to make a reproducer for that. The other case, namely that the non-overlapping instersection of hyperslabs is a NONE is valid. Also hyperslabs with counts {0, 0} are considered NONE.

I’m very happy this corner case will be dealt with. Thank you!

Sorry, I had the wrong link to the github issue. It should be this: Enable H5Scombine to be used with special selections · Issue #4695 · HDFGroup/hdf5 · GitHub