Hello,
Question about hyperslab with VL data.
This next program using H5Sselect_elements works as I expected:
#include "hdf5/hdf5.h"
struct s_data {
uint64_t b;
uint16_t a;
};
struct ext_data3 {
uint64_t a;
uint32_t b;
int16_t nelem;
struct s_data data[3];
};
struct ext_data {
uint64_t a;
uint32_t b;
int16_t nelem;
struct s_data data[];
};
int main()
{
hid_t memspace_id, memtype_id;
hsize_t dims_mem = 1;
hsize_t dims = 3;
hsize_t coord;
struct ext_data3 d3;
hid_t stm, dataset, filespace_id, filetype_id;
hvl_t wdata;
dims_mem = 1;
memspace_id = H5Screate_simple(1, &dims_mem, NULL);
memtype_id = H5Tvlen_create(H5T_C_S1);
filespace_id = H5Screate_simple(1, &dims, NULL);
filetype_id = H5Tvlen_create(H5T_C_S1);
stm = H5Fcreate("varsize.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
dataset = H5Dcreate(stm, "event_prod", filetype_id, filespace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
printf("\t\t*** WRITE DATA ***\n");
for (hsize_t i = 0; i < dims; i++) {
struct ext_data *d;
size_t sz;
hsize_t count;
d = (struct ext_data *)&d3;
d3.a = i;
d3.b = i + 1;
d3.nelem = 1;
d3.data[0].a = 2 * i;
d3.data[0].b = 2 * i + 1;
if (0 == i % 2) {
d3.data[1].a = 2 * i + 2;
d3.data[1].b = 2 * i + 3;
d3.nelem = 2;
}
printf("\tpoint # %llu\n", i);
printf("ext_data a = %ld, ext_data b = %d, ext data nelem = %d\n", d3.a, d3.b, d3.nelem);
for (int16_t k = 0; k < d3.nelem; k++)
printf("str_data a = %d, str_data b = %ld\n", d3.data[k].a, d3.data[k].b);
sz = sizeof(*d) + d3.nelem * sizeof(struct s_data);
wdata.p = &d3;
wdata.len = sz;
printf("sizeof d = %lu, sz = %lu\n", sizeof(*d), sz);
count = 1;
coord = i;
H5Sselect_elements(filespace_id, H5S_SELECT_SET, count, &coord);
H5Dwrite(dataset, memtype_id, memspace_id, filespace_id, H5P_DEFAULT, &wdata);
}
H5Dclose(dataset);
H5Fclose(stm);
H5Tclose(filetype_id);
H5Sclose(filespace_id);
H5Tclose(memtype_id);
H5Sclose(memspace_id);
/* Read */
hssize_t npoints;
hvl_t rdata;
hsize_t req_size;
stm = H5Fopen("varsize.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
dataset = H5Dopen(stm, "/event_prod", H5P_DEFAULT);
filespace_id = H5Dget_space(dataset);
npoints = H5Sget_simple_extent_npoints(filespace_id);
filetype_id = H5Tget_native_type(H5Dget_type(dataset), H5T_DIR_DEFAULT);
memspace_id = H5Scopy(filespace_id);
memtype_id = H5Tcopy(filetype_id);
coord = 0;
H5Sselect_elements(memspace_id, H5S_SELECT_SET, 1, &coord);
printf("\t\t*** READ DATA ***\n");
H5Dvlen_get_buf_size(dataset, filetype_id, filespace_id, &req_size);
printf("requared size for all dataset = %llu\n", req_size);
for (hssize_t i = 0; i < npoints; i++) {
struct ext_data *d;
printf("\tpoint # %llu\n", i);
coord = (hsize_t)i;
H5Sselect_elements(filespace_id, H5S_SELECT_SET, 1, &coord);
H5Dvlen_get_buf_size(dataset, filetype_id, filespace_id, &req_size);
printf("requared size for one element = %llu\n", req_size);
H5Dread(dataset, memtype_id, memspace_id, filespace_id, H5P_DEFAULT, &rdata);
d = rdata.p;
printf("ext_data a = %ld, ext_data b = %d, ext data nelem = %d\n", d->a, d->b, d->nelem);
for (int16_t j = 0; j < d->nelem; j++)
printf("str_data a = %d, str_data b = %ld\n", (d->data[j]).a, (d->data[j]).b);
H5Dvlen_reclaim(memtype_id, memspace_id, H5P_DEFAULT, &rdata);
}
H5Tclose(memtype_id);
H5Sclose(memspace_id);
H5Tclose(filetype_id);
H5Sclose(filespace_id);
H5Dclose(dataset);
H5Fclose(stm);
return (0);
}
But when I tried to use hyperslab:
#include "hdf5/hdf5.h"
struct s_data {
uint64_t b;
uint16_t a;
};
struct ext_data3 {
uint64_t a;
uint32_t b;
int16_t nelem;
struct s_data data[3];
};
struct ext_data {
uint64_t a;
uint32_t b;
int16_t nelem;
struct s_data data[];
};
int main()
{
hid_t memspace_id, memtype_id;
hsize_t dims = 3;
hsize_t coord;
hsize_t hyperslab_size = 1;
struct ext_data3 d3[hyperslab_size];
hid_t stm, dataset, filespace_id, filetype_id;
hvl_t wdata[hyperslab_size];
hsize_t pushposition;
memspace_id = H5Screate_simple(1, &hyperslab_size, NULL);
memtype_id = H5Tvlen_create(H5T_C_S1);
filespace_id = H5Screate_simple(1, &dims, NULL);
filetype_id = H5Tvlen_create(H5T_C_S1);
stm = H5Fcreate("varsize.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
dataset = H5Dcreate(stm, "event_prod", filetype_id, filespace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
printf("\t\t*** WRITE DATA ***\n");
hsize_t chunk_quotient = dims / hyperslab_size;
hsize_t chunk_remainder = dims % hyperslab_size;
printf("quotient = %llu\n", chunk_quotient);
printf("remainder = %llu\n", chunk_remainder);
pushposition = 0;
for (hsize_t i = 0; i < chunk_quotient; i++) {
struct ext_data *d;
size_t sz;
hsize_t offset, count;
printf("chunk # %llu\n", i);
d = (struct ext_data *)d3;
for (hsize_t j = 0; j < hyperslab_size; j++) {
d3[j].a = i * hyperslab_size + j;
d3[j].b = i * hyperslab_size + j + 1;
d3[j].nelem = 1;
d3[j].data[0].a = 2 * (i * hyperslab_size + j);
d3[j].data[0].b = 2 * (i * hyperslab_size + j) + 1;
if (0 == (i * hyperslab_size + j) % 2) {
d3[j].data[1].a = 2 * (i * hyperslab_size + j) + 2;
d3[j].data[1].b = 2 * (i * hyperslab_size + j) + 3;
d3[j].nelem = 2;
}
printf("\tpoint # %llu\n", i * hyperslab_size + j);
printf("ext_data a = %ld, ext_data b = %d, ext data nelem = %d\n", d3[j].a, d3[j].b, d3[j].nelem);
for (int16_t k = 0; k < d3[j].nelem; k++)
printf("str_data a = %d, str_data b = %ld\n", d3[j].data[k].a, d3[j].data[k].b);
sz = sizeof(*d) + d3[j].nelem * sizeof(struct s_data);
wdata[j].p = d3 + j;
wdata[j].len = sz;
printf("sizeof d = %lu, sz = %lu\n", sizeof(*d), sz);
}
count = 0;
for (hsize_t j = 0; j < hyperslab_size; j++)
count += wdata[j].len;
offset = 0;
H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, &offset, NULL, &count, NULL);
offset = pushposition;
printf("offset = %llu, count = %llu\n", offset, count);
H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET, &offset, NULL, &count, NULL);
H5Dwrite(dataset, memtype_id, memspace_id, filespace_id, H5P_DEFAULT, wdata);
pushposition += count;
}
H5Dclose(dataset);
H5Fclose(stm);
H5Tclose(filetype_id);
H5Sclose(filespace_id);
H5Tclose(memtype_id);
H5Sclose(memspace_id);
return (0);
}
I have an error:
*** WRITE DATA ***
quotient = 3
remainder = 0
chunk # 0
point # 0
ext_data a = 0, ext_data b = 1, ext data nelem = 2
str_data a = 0, str_data b = 1
str_data a = 2, str_data b = 3
sizeof d = 16, sz = 48
offset = 0, count = 48
HDF5-DIAG: Error detected in HDF5 (1.12.1) thread 0:
#000: …/…/…/…/src/hdf5-1.12.1/src/H5Dio.c line 291 in H5Dwrite(): can’t write data
major: Dataset
minor: Write failed
#001: …/…/…/…/src/hdf5-1.12.1/src/H5VLcallback.c line 2113 in H5VL_dataset_write(): dataset write failed
major: Virtual Object Layer
minor: Write failed
#002: …/…/…/…/src/hdf5-1.12.1/src/H5VLcallback.c line 2080 in H5VL__dataset_write(): dataset write failed
major: Virtual Object Layer
minor: Write failed
#003: …/…/…/…/src/hdf5-1.12.1/src/H5VLnative_dataset.c line 198 in H5VL__native_dataset_write(): could not get a validated dataspace from mem_space_id
major: Invalid arguments to routine
minor: Bad value
#004: …/…/…/…/src/hdf5-1.12.1/src/H5S.c line 266 in H5S_get_validated_dataspace(): selection + offset not within extent
major: Dataspace
minor: Out of range
How to select hyperslab correctly?
Thanks and best,
Nazar