summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2017-03-16 21:22:46 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2017-03-16 21:22:46 (GMT)
commit3943452ff3cc26938fd69c1d75380bb7d0edb8ef (patch)
treeb4dde897e7fb27446c0ab17a4bbb75cf908de358
parent89d1b13319bc7790333236fb607d7d7f18d088b8 (diff)
downloadhdf5-3943452ff3cc26938fd69c1d75380bb7d0edb8ef.zip
hdf5-3943452ff3cc26938fd69c1d75380bb7d0edb8ef.tar.gz
hdf5-3943452ff3cc26938fd69c1d75380bb7d0edb8ef.tar.bz2
Add support for datatype conversion with datasets, including with
partial I/O. Add test cases covering this to h5dsm_ttconv.c. Other fixes to general type conversion code. Other minor fixes/cleanup.
-rw-r--r--examples/h5dsm_ttconv.c1103
-rw-r--r--src/H5VLdaosm.c352
2 files changed, 1383 insertions, 72 deletions
diff --git a/examples/h5dsm_ttconv.c b/examples/h5dsm_ttconv.c
index ddfa847..9f07c31 100644
--- a/examples/h5dsm_ttconv.c
+++ b/examples/h5dsm_ttconv.c
@@ -20,16 +20,20 @@ hbool_t verbose_g = 1;
int main(int argc, char *argv[]) {
uuid_t pool_uuid;
char *pool_grp = NULL;
- hid_t file = -1, dset = -1, dset_a = -1, dset_b = -1, dset_c = -1, attr = -1, attr_a = -1, attr_b = -1 , attr_c = -1, space = -1, fapl = -1;
+ hid_t file = -1, dset = -1, dset_a = -1, dset_b = -1, dset_c = -1, dset2 = -1, attr = -1, attr_a = -1, attr_b = -1 , attr_c = -1, space = -1, space2 = -1, space2_contig, fapl = -1;
hid_t file_type = -1, file_type_a = -1, file_type_b = -1, file_type_c = -1;
hid_t mem_type = -1, mem_type_conv = -1, mem_type_a = -1, mem_type_b = -1, mem_type_c = -1;
- hsize_t dims[1] = {4};
+ hsize_t dims[2] = {4, 2};
+ hsize_t start[2], count[2];
type_all buf[4];
type_all file_buf[4];
+ type_all file_buf2[4][2];
type_convall buf_conv[4];
+ type_convall buf2[4][2];
const type_all buf_init[4] = {{-1, 'a', (double)-1.}, {-2, 'b', (double)-2.}, {-3, 'c', (double)-3.}, {-4, 'd', (double)-4.}};
const type_convall buf_conv_init[4] = {{(long long)-5, 'e', (float)-5.}, {(long long)-6, 'f', (float)-6.}, {(long long)-7, 'g', (float)-7.}, {(long long)-8, 'h', (float)-8.}};
- int i;
+ const type_convall buf2_init[4][2] = {{{(long long)-1, 'a', (float)-1.}, {(long long)-2, 'b', (float)-2.}}, {{(long long)-3, 'c', (float)-3.}, {(long long)-4, 'd', (float)-4.}}, {{(long long)-5, 'e', (float)-5.}, {(long long)-6, 'f', (float)-6.}}, {{(long long)-7, 'g', (float)-7.}, {(long long)-8, 'h', (float)-8.}}};
+ int i, j, i2;
(void)MPI_Init(&argc, &argv);
@@ -61,6 +65,14 @@ int main(int argc, char *argv[]) {
if((space = H5Screate_simple(1, dims, NULL)) < 0)
ERROR;
+ /* Set up 2-D dataspace */
+ if((space2 = H5Screate_simple(2, dims, NULL)) < 0)
+ ERROR;
+
+ /* Set up second 2-D dataspace */
+ if((space2_contig = H5Screate_simple(2, dims, NULL)) < 0)
+ ERROR;
+
/*
* Set up types
*/
@@ -130,6 +142,9 @@ int main(int argc, char *argv[]) {
if(H5Tinsert(mem_type_c, "c", HOFFSET(type_convall, c), H5T_NATIVE_FLOAT) < 0)
ERROR;
+ /*
+ * Create objects
+ */
/* Create dataset */
if((dset = H5Dcreate2(file, "dset", file_type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
ERROR;
@@ -146,6 +161,10 @@ int main(int argc, char *argv[]) {
if((dset_c = H5Dcreate2(file, "dset_c", file_type_c, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
ERROR;
+ /* Create 2-D dataset */
+ if((dset2 = H5Dcreate2(file, "dset2", file_type, space2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+
/* Create attribute */
if((attr = H5Acreate2(dset, "attr", file_type, space, H5P_DEFAULT, H5P_DEFAULT)) < 0)
ERROR;
@@ -163,6 +182,25 @@ int main(int argc, char *argv[]) {
ERROR;
/*
+ * Create selections
+ */
+ /* Create non-contiguous 2-D selection */
+ start[0] = 0;
+ start[1] = 1;
+ count[0] = 4;
+ count[1] = 1;
+ if(H5Sselect_hyperslab(space2, H5S_SELECT_SET, start, NULL, count, NULL) < 0)
+ ERROR;
+
+ /* Create contiguous 2-D selection */
+ start[0] = 1;
+ start[1] = 0;
+ count[0] = 2;
+ count[1] = 2;
+ if(H5Sselect_hyperslab(space2_contig, H5S_SELECT_SET, start, NULL, count, NULL) < 0)
+ ERROR;
+
+ /*
* Test attribute
*/
/*
@@ -329,7 +367,7 @@ int main(int argc, char *argv[]) {
/* Check buffer */
for(i = 0; i< dims[0]; i++) {
- if(file_buf[i].a != (int)buf_conv[i].a)
+ if((long long)file_buf[i].a != buf_conv[i].a)
PRINTF_ERROR("Member a at location %d does not match", i);
if(file_buf[i].b != buf_conv[i].b)
PRINTF_ERROR("Member b at location %d does not match", i);
@@ -564,7 +602,7 @@ int main(int argc, char *argv[]) {
/* Check buffer */
for(i = 0; i< dims[0]; i++) {
- if(file_buf[i].a != (int)buf_conv[i].a)
+ if((long long)file_buf[i].a != buf_conv[i].a)
PRINTF_ERROR("Member a at location %d does not match", i);
if(buf_conv_init[i].b != buf_conv[i].b)
PRINTF_ERROR("Member b at location %d does not match", i);
@@ -705,7 +743,7 @@ int main(int argc, char *argv[]) {
/* Check buffer */
for(i = 0; i< dims[0]; i++) {
- if(file_buf[i].a != (int)buf_conv[i].a)
+ if((long long)file_buf[i].a != buf_conv[i].a)
PRINTF_ERROR("Member a at location %d does not match", i);
if(buf_conv_init[i].b != buf_conv[i].b)
PRINTF_ERROR("Member b at location %d does not match", i);
@@ -845,6 +883,1050 @@ int main(int argc, char *argv[]) {
printf("\n");
/*
+ * Test dataset
+ */
+ /*
+ * Full write/read, no member conversion
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf[i].a = rand() % 10;
+ buf[i].b = 'A' + (char)(rand() % 26);
+ buf[i].c = (double)(rand() % 100) / (double)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing dataset with no member conversion\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", buf[i].a, buf[i].b, buf[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++) {
+ file_buf[i].a = buf[i].a;
+ file_buf[i].b = buf[i].b;
+ file_buf[i].c = buf[i].c;
+ } /* end for */
+
+ /* Read data */
+ memcpy(buf, buf_init, sizeof(buf));
+ if(H5Dread(dset, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset with no member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, file_buf[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", buf[i].a, buf[i].b, buf[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(file_buf[i].a != buf[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - buf[i].c) > (double)0.01)
+ || ((file_buf[i].c - buf[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Full write/read, with member conversion
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing dataset with member conversion\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++) {
+ file_buf[i].a = (int)buf_conv[i].a;
+ file_buf[i].b = buf_conv[i].b;
+ file_buf[i].c = (double)buf_conv[i].c;
+ } /* end for */
+
+ /* Read data */
+ memcpy(buf, buf_init, sizeof(buf));
+ if(H5Dread(dset, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset with no member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, file_buf[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", buf[i].a, buf[i].b, buf[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(file_buf[i].a != buf[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - buf[i].c) > (double)0.01)
+ || ((file_buf[i].c - buf[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ /* Read data */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset with member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, file_buf[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if((long long)file_buf[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - (double)buf_conv[i].c) > (double)0.01)
+ || ((file_buf[i].c - (double)buf_conv[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Write by parts
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing dataset compound member \'a\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset, mem_type_a, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ file_buf[i].a = (int)buf_conv[i].a;
+
+ /* Read data */
+ memcpy(buf, buf_init, sizeof(buf));
+ if(H5Dread(dset, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset with no member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, file_buf[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", buf[i].a, buf[i].b, buf[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(file_buf[i].a != buf[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - buf[i].c) > (double)0.01)
+ || ((file_buf[i].c - buf[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing dataset compound member \'b\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset, mem_type_b, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ file_buf[i].b = buf_conv[i].b;
+
+ /* Read data */
+ memcpy(buf, buf_init, sizeof(buf));
+ if(H5Dread(dset, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset with no member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, file_buf[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", buf[i].a, buf[i].b, buf[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(file_buf[i].a != buf[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - buf[i].c) > (double)0.01)
+ || ((file_buf[i].c - buf[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing dataset compound member \'c\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset, mem_type_c, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ file_buf[i].c = (double)buf_conv[i].c;
+
+ /* Read data */
+ memcpy(buf, buf_init, sizeof(buf));
+ if(H5Dread(dset, mem_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset with no member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, file_buf[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", buf[i].a, buf[i].b, buf[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(file_buf[i].a != buf[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - buf[i].c) > (double)0.01)
+ || ((file_buf[i].c - buf[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Read by parts
+ */
+ /* Read member a */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset, mem_type_a, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read full dataset compound member \'a\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, buf_conv_init[i].b, (double)buf_conv_init[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if((long long)file_buf[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(buf_conv_init[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((buf_conv_init[i].c - buf_conv[i].c) > 0.01f)
+ || ((buf_conv_init[i].c - buf_conv[i].c) < -0.01f))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /* Read member b */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset, mem_type_b, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read full dataset compound member \'b\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv_init[i].a, file_buf[i].b, (double)buf_conv_init[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(buf_conv_init[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((buf_conv_init[i].c - buf_conv[i].c) > 0.01f)
+ || ((buf_conv_init[i].c - buf_conv[i].c) < -0.01f))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /* Read member c */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset, mem_type_c, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read full dataset compound member \'c\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv_init[i].a, buf_conv_init[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(buf_conv_init[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(buf_conv_init[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - (double)buf_conv[i].c) > (double)0.01)
+ || ((file_buf[i].c - (double)buf_conv[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Write/read partial datasets
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing full memory type to dataset containing only member \'a\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset_a, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ file_buf[i].a = (int)buf_conv[i].a;
+
+ /* Read data */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset_a, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset containing only member \'a\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf[i].a, buf_conv_init[i].b, (double)buf_conv_init[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if((long long)file_buf[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(buf_conv_init[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((buf_conv_init[i].c - buf_conv[i].c) > 0.01f)
+ || ((buf_conv_init[i].c - buf_conv[i].c) < -0.01f))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing full memory type to dataset containing only member \'b\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset_b, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ file_buf[i].b = buf_conv[i].b;
+
+ /* Read data */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset_b, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset containing only member \'b\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv_init[i].a, file_buf[i].b, (double)buf_conv_init[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(buf_conv_init[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((buf_conv_init[i].c - buf_conv[i].c) > 0.01f)
+ || ((buf_conv_init[i].c - buf_conv[i].c) < -0.01f))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++) {
+ buf_conv[i].a = (long long)(rand() % 10);
+ buf_conv[i].b = 'A' + (char)(rand() % 26);
+ buf_conv[i].c = (float)(rand() % 100) / (float)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing full memory type to dataset containing only member \'c\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset_c, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ file_buf[i].c = (double)buf_conv[i].c;
+
+ /* Read data */
+ memcpy(buf_conv, buf_conv_init, sizeof(buf_conv));
+ if(H5Dread(dset_c, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_conv) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read dataset containing only member \'c\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv_init[i].a, buf_conv_init[i].b, file_buf[i].c);
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf_conv[i].a, buf_conv[i].b, (double)buf_conv[i].c);
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++) {
+ if(buf_conv_init[i].a != buf_conv[i].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(buf_conv_init[i].b != buf_conv[i].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf[i].c - (double)buf_conv[i].c) > (double)0.01)
+ || ((file_buf[i].c - (double)buf_conv[i].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Test dataset with selections
+ */
+ /*
+ * Full write/read, member conversion
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ buf2[i][j].a = rand() % 10;
+ buf2[i][j].b = 'A' + (char)(rand() % 26);
+ buf2[i][j].c = (double)(rand() % 100) / (double)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing full 2-D dataset with member conversion\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset2, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ for(i = 0; i < dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ file_buf2[i][j].a = (int)buf2[i][j].a;
+ file_buf2[i][j].b = buf2[i][j].b;
+ file_buf2[i][j].c = (double)buf2[i][j].c;
+ } /* end for */
+
+ /* Read data */
+ memcpy(buf2, buf2_init, sizeof(buf2));
+ if(H5Dread(dset2, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read full 2-D dataset with member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf2[i][j].a, file_buf2[i][j].b, file_buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ if((long long)file_buf2[i][j].a != buf2[i][j].a)
+ PRINTF_ERROR("Member a at location %d does not match", i);
+ if(file_buf2[i][j].b != buf2[i][j].b)
+ PRINTF_ERROR("Member b at location %d does not match", i);
+ if(((file_buf2[i][j].c - (double)buf2[i][j].c) > (double)0.01)
+ || ((file_buf2[i][j].c - (double)buf2[i][j].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d does not match", i);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Partial write with full type/full read to full type
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ buf2[i][j].a = rand() % 10;
+ buf2[i][j].b = 'A' + (char)(rand() % 26);
+ buf2[i][j].c = (double)(rand() % 100) / (double)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing partial 2-D dataset with member conversion\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset2, mem_type_conv, space2_contig, space2, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ i2 = 0;
+ for(i = 1; i < 3; i++)
+ for(j = 0; j < 2; j++) {
+ file_buf2[i2][1].a = (int)buf2[i][j].a;
+ file_buf2[i2][1].b = buf2[i][j].b;
+ file_buf2[i2][1].c = (double)buf2[i][j].c;
+ i2++;
+ } /* end for */
+
+ /* Read data */
+ memcpy(buf2, buf2_init, sizeof(buf2));
+ if(H5Dread(dset2, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read full 2-D dataset with member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf2[i][j].a, file_buf2[i][j].b, file_buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ if((long long)file_buf2[i][j].a != buf2[i][j].a)
+ PRINTF_ERROR("Member a at location %d, %d does not match", i, j);
+ if(file_buf2[i][j].b != buf2[i][j].b)
+ PRINTF_ERROR("Member b at location %d, %d does not match", i, j);
+ if(((file_buf2[i][j].c - (double)buf2[i][j].c) > (double)0.01)
+ || ((file_buf2[i][j].c - (double)buf2[i][j].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d, %d does not match", i, j);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Partial write with member a/full read to full type
+ */
+ /* Fill buffer */
+ for(i = 0; i < dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ buf2[i][j].a = rand() % 10;
+ buf2[i][j].b = 'A' + (char)(rand() % 26);
+ buf2[i][j].c = (double)(rand() % 100) / (double)10;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing partial 2-D dataset with member conversion to member \'a\'\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Write data */
+ if(H5Dwrite(dset2, mem_type_a, space2_contig, space2, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Update file_buf */
+ i2 = 0;
+ for(i = 1; i < 3; i++)
+ for(j = 0; j < 2; j++) {
+ file_buf2[i2][1].a = (int)buf2[i][j].a;
+ i2++;
+ } /* end for */
+
+ /* Read data */
+ memcpy(buf2, buf2_init, sizeof(buf2));
+ if(H5Dread(dset2, mem_type_conv, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read full 2-D dataset with member conversion\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%d, %c, %.1f}", file_buf2[i][j].a, file_buf2[i][j].b, file_buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ if((long long)file_buf2[i][j].a != buf2[i][j].a)
+ PRINTF_ERROR("Member a at location %d, %d does not match", i, j);
+ if(file_buf2[i][j].b != buf2[i][j].b)
+ PRINTF_ERROR("Member b at location %d, %d does not match", i, j);
+ if(((file_buf2[i][j].c - (double)buf2[i][j].c) > (double)0.01)
+ || ((file_buf2[i][j].c - (double)buf2[i][j].c) < (double)-0.01))
+ PRINTF_ERROR("Member c at location %d, %d does not match", i, j);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Partial read to contiguous buffer, member conversion to type "a"
+ */
+ /* Read data */
+ memcpy(buf2, buf2_init, sizeof(buf2));
+ if(H5Dread(dset2, mem_type_a, H5S_ALL, space2_contig, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read partial 2-D dataset to contiguous buffer with member conversion to member \'a\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", (i == 1 || i == 2) ? (long long)file_buf2[i][j].a : buf2_init[i][j].a, buf2_init[i][j].b, (double)buf2_init[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ if(((i == 1 || i == 2)
+ ? (long long)file_buf2[i][j].a : buf2_init[i][j].a)
+ != buf2[i][j].a)
+ PRINTF_ERROR("Member a at location %d, %d does not match", i, j);
+ if(buf2_init[i][j].b != buf2[i][j].b)
+ PRINTF_ERROR("Member b at location %d, %d does not match", i, j);
+ if(((buf2_init[i][j].c - buf2[i][j].c) > 0.01f)
+ || ((buf2_init[i][j].c - buf2[i][j].c) < -0.01f))
+ PRINTF_ERROR("Member c at location %d, %d does not match", i, j);
+ } /* end for */
+
+ printf("\n");
+
+ /*
+ * Partial read to non-contiguous buffer, member conversion to type "a"
+ */
+ /* Read data */
+ memcpy(buf2, buf2_init, sizeof(buf2));
+ if(H5Dread(dset2, mem_type_a, space2, space2_contig, H5P_DEFAULT, buf2) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read partial 2-D dataset to non-contiguous buffer with member conversion to member \'a\'\n");
+ printf("exp = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", (j == 1) ? (long long)file_buf2[i / 2 + 1][i % 2].a : buf2_init[i][j].a, buf2_init[i][j].b, (double)buf2_init[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ printf("buf = {");
+ for(i = 0; i < dims[0]; i++) {
+ if(i > 0)
+ printf("\n ");
+ for(j = 0; j < dims[1]; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{%lld, %c, %.1f}", buf2[i][j].a, buf2[i][j].b, (double)buf2[i][j].c);
+ } /* end for */
+ } /* end for */
+ printf("}\n");
+ } /* end if */
+
+ /* Check buffer */
+ for(i = 0; i< dims[0]; i++)
+ for(j = 0; j < dims[1]; j++) {
+ if(((j == 1) ? (long long)file_buf2[i / 2 + 1][i % 2].a
+ : buf2_init[i][j].a)
+ != buf2[i][j].a)
+ PRINTF_ERROR("Member a at location %d, %d does not match", i, j);
+ if(buf2_init[i][j].b != buf2[i][j].b)
+ PRINTF_ERROR("Member b at location %d, %d does not match", i, j);
+ if(((buf2_init[i][j].c - buf2[i][j].c) > 0.01f)
+ || ((buf2_init[i][j].c - buf2[i][j].c) < -0.01f))
+ PRINTF_ERROR("Member c at location %d, %d does not match", i, j);
+ } /* end for */
+
+ printf("\n");
+
+ /*
* Close
*/
if(H5Aclose(attr) < 0)
@@ -863,6 +1945,8 @@ int main(int argc, char *argv[]) {
ERROR;
if(H5Dclose(dset_c) < 0)
ERROR;
+ if(H5Dclose(dset2) < 0)
+ ERROR;
if(H5Fclose(file) < 0)
ERROR;
if(H5Tclose(file_type) < 0)
@@ -885,6 +1969,10 @@ int main(int argc, char *argv[]) {
ERROR;
if(H5Sclose(space) < 0)
ERROR;
+ if(H5Sclose(space2) < 0)
+ ERROR;
+ if(H5Sclose(space2_contig) < 0)
+ ERROR;
if(H5Pclose(fapl) < 0)
ERROR;
@@ -903,6 +1991,7 @@ error:
H5Dclose(dset_a);
H5Dclose(dset_b);
H5Dclose(dset_c);
+ H5Dclose(dset2);
H5Fclose(file);
H5Tclose(file_type);
H5Tclose(file_type_a);
@@ -914,6 +2003,8 @@ error:
H5Tclose(mem_type_b);
H5Tclose(mem_type_c);
H5Sclose(space);
+ H5Sclose(space2);
+ H5Sclose(space2_contig);
H5Pclose(fapl);
} H5E_END_TRY;
diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c
index 18c088e..c1a1108 100644
--- a/src/H5VLdaosm.c
+++ b/src/H5VLdaosm.c
@@ -68,6 +68,12 @@ typedef enum {
H5VL_DAOSM_TCONV_REUSE_BKG /* Use buffer as background buffer */
} H5VL_daosm_tconv_reuse_t;
+/* Udata type for H5Dscatter callback */
+typedef struct H5VL_daosm_scatter_cb_ud_t {
+ void *buf;
+ size_t len;
+} H5VL_daosm_scatter_cb_ud_t;
+
/* Prototypes */
static void *H5VL_daosm_fapl_copy(const void *_old_fa);
static herr_t H5VL_daosm_fapl_free(void *_fa);
@@ -152,12 +158,14 @@ static void *H5VL_daosm_group_create_helper(H5VL_daosm_file_t *file,
static void *H5VL_daosm_group_open_helper(H5VL_daosm_file_t *file,
daos_obj_id_t oid, hid_t gapl_id, hid_t dxpl_id, void **req);
static htri_t H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id,
- hbool_t *fill_bkg);
+ size_t *dst_type_size, hbool_t *fill_bkg);
static herr_t H5VL_daosm_tconv_init(hid_t src_type_id, size_t *src_type_size,
hid_t dst_type_id, size_t *dst_type_size, size_t num_elem, void **tconv_buf,
void **bkg_buf, H5VL_daosm_tconv_reuse_t *reuse, hbool_t *fill_bkg);
static herr_t H5VL_daosm_sel_to_recx_iov(H5S_t *space, size_t type_size,
void *buf, daos_recx_t **recxs, daos_iov_t **sg_iovs, size_t *list_nused);
+static herr_t H5VL_daosm_scatter_cb(const void **src_buf,
+ size_t *src_buf_bytes_used, void *_udata);
static herr_t H5VL_daosm_object_close(void *_obj, hid_t dxpl_id, void **req);
/* Free list definitions */
@@ -2682,16 +2690,22 @@ H5VL_daosm_group_close(void *_grp, hid_t H5_ATTR_UNUSED dxpl_id,
*-------------------------------------------------------------------------
*/
static htri_t
-H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, hbool_t *fill_bkg)
+H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, size_t *dst_type_size,
+ hbool_t *fill_bkg)
{
hid_t memb_type_id = -1;
hid_t src_memb_type_id = -1;
char *memb_name = NULL;
+ size_t memb_size;
H5T_class_t tclass;
htri_t ret_value;
FUNC_ENTER_NOAPI_NOINIT
+ /* Get destination type size */
+ if((*dst_type_size = H5Tget_size(dst_type_id)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get source type size")
+
/* Get datatype class */
if(H5T_NO_CLASS == (tclass = H5Tget_class(dst_type_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get type class")
@@ -2712,6 +2726,7 @@ H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, hbool_t *fill_bkg)
case H5T_COMPOUND:
{
int nmemb;
+ size_t size_used = 0;
int src_i;
int i;
@@ -2722,7 +2737,7 @@ H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, hbool_t *fill_bkg)
/* Get number of compound members */
if((nmemb = H5Tget_nmembers(dst_type_id)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get number of compound members")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get number of destination compound members")
/* Iterate over compound members, checking for a member in
* dst_type_id with no match in src_type_id */
@@ -2761,7 +2776,7 @@ H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, hbool_t *fill_bkg)
/* Recursively check member type, this will fill in the
* member size */
- if(H5VL_daosm_need_bkg(src_memb_type_id, memb_type_id, fill_bkg) < 0)
+ if(H5VL_daosm_need_bkg(src_memb_type_id, memb_type_id, &memb_size, fill_bkg) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't check if background buffer needed")
/* Close source member type */
@@ -2778,8 +2793,17 @@ H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, hbool_t *fill_bkg)
* does the parent */
if(*fill_bkg)
HGOTO_DONE(TRUE)
+
+ /* Keep track of the size used in compound */
+ size_used += memb_size;
} /* end for */
+ /* Check if all the space in the type is used. If not, we must
+ * fill the background buffer. */
+ HDassert(size_used <= *dst_type_size);
+ if(size_used != *dst_type_size)
+ *fill_bkg = TRUE;
+
break;
} /* end block */
@@ -2793,7 +2817,7 @@ H5VL_daosm_need_bkg(hid_t src_type_id, hid_t dst_type_id, hbool_t *fill_bkg)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get array parent type")
/* Recursively check parent type */
- if((ret_value = H5VL_daosm_need_bkg(src_memb_type_id, memb_type_id, fill_bkg)) < 0)
+ if((ret_value = H5VL_daosm_need_bkg(src_memb_type_id, memb_type_id, &memb_size, fill_bkg)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't check if background buffer needed")
/* Close source parent type */
@@ -2881,12 +2905,8 @@ H5VL_daosm_tconv_init(hid_t src_type_id, size_t *src_type_size,
/* Types are equal, no need for conversion, just set dst_type_size */
*dst_type_size = *src_type_size;
else {
- /* Get destination type size */
- if((*dst_type_size = H5Tget_size(dst_type_id)) == 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get source type size")
-
/* Check if we need a background buffer */
- if((need_bkg = H5VL_daosm_need_bkg(src_type_id, dst_type_id, fill_bkg)) < 0)
+ if((need_bkg = H5VL_daosm_need_bkg(src_type_id, dst_type_id, dst_type_size, fill_bkg)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't check if background buffer needed")
/* Check for reusable destination buffer */
@@ -3395,6 +3415,35 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_scatter_cb
+ *
+ * Purpose: Callback function for H5Dscatter. Simply passes the
+ * entire buffer described by udata to H5Dscatter.
+ *
+ * Return: SUCCEED (never fails)
+ *
+ * Programmer: Neil Fortner
+ * March, 2017
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_daosm_scatter_cb(const void **src_buf, size_t *src_buf_bytes_used,
+ void *_udata)
+{
+ H5VL_daosm_scatter_cb_ud_t *udata = (H5VL_daosm_scatter_cb_ud_t *)_udata;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Set src_buf and src_buf_bytes_used to use the entire buffer */
+ *src_buf = udata->buf;
+ *src_buf_bytes_used = udata->len;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_daosm_scatter_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5VL_daosm_dataset_read
*
* Purpose: Reads raw data from a dataset into a buffer.
@@ -3408,13 +3457,16 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5VL_daosm_dataset_read(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
- hid_t mem_space_id, hid_t file_space_id, hid_t H5_ATTR_UNUSED dxpl_id,
- void *buf, void H5_ATTR_UNUSED **req)
+H5VL_daosm_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, void *buf, void H5_ATTR_UNUSED **req)
{
H5VL_daosm_dset_t *dset = (H5VL_daosm_dset_t *)_dset;
+ H5S_sel_iter_t sel_iter; /* Selection iteration info */
+ hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */
int ndims;
hsize_t dim[H5S_MAX_RANK];
+ hid_t real_file_space_id;
+ hid_t real_mem_space_id;
H5S_t *space = NULL;
uint64_t chunk_coords[H5S_MAX_RANK];
daos_key_t dkey;
@@ -3427,7 +3479,11 @@ H5VL_daosm_dataset_read(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
size_t tot_nseq;
uint8_t dkey_buf[1 + H5S_MAX_RANK];
uint8_t akey = H5VL_DAOSM_CHUNK_KEY;
- size_t type_size;
+ size_t file_type_size;
+ htri_t types_equal;
+ void *tconv_buf = NULL;
+ void *bkg_buf = NULL;
+ H5VL_daosm_tconv_reuse_t reuse = H5VL_DAOSM_TCONV_REUSE_NONE;
uint8_t *p;
int ret;
int i;
@@ -3441,8 +3497,18 @@ H5VL_daosm_dataset_read(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
if(ndims != H5Sget_simple_extent_dims(dset->space_id, dim, NULL))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dimensions")
+ /* Get "real" space ids */
+ if(file_space_id == H5S_ALL)
+ real_file_space_id = dset->space_id;
+ else
+ real_file_space_id = file_space_id;
+ if(mem_space_id == H5S_ALL)
+ real_mem_space_id = real_file_space_id;
+ else
+ real_mem_space_id = mem_space_id;
+
/* Get datatype size */
- if((type_size = H5Tget_size(dset->type_id)) == 0)
+ if((file_type_size = H5Tget_size(dset->type_id)) == 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype size")
/* Encode dkey (chunk coordinates). Prefix with '/' to avoid accidental
@@ -3462,49 +3528,143 @@ H5VL_daosm_dataset_read(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
daos_iov_set(&iod.vd_name, (void *)&akey, (daos_size_t)(sizeof(akey)));
daos_csum_set(&iod.vd_kcsum, NULL, 0);
- /* Build recxs and sg_iovs */
/* Get file dataspace object */
- if(NULL == (space = (H5S_t *)H5I_object((file_space_id == H5S_ALL)
- ? dset->space_id : file_space_id)))
+ if(NULL == (space = (H5S_t *)H5I_object(real_file_space_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
- /* Check for memory space is H5S_ALL, use file space in this case */
- if(mem_space_id == H5S_ALL) {
+ /* Check if the types are equal */
+ if((types_equal = H5Tequal(dset->type_id, mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOMPARE, FAIL, "can't check if types are equal")
+ if(types_equal) {
+ /* No type conversion necessary */
+ /* Check for memory space is H5S_ALL, use file space in this case */
+ if(mem_space_id == H5S_ALL) {
/* Calculate both recxs and sg_iovs at the same time from file space */
- if(H5VL_daosm_sel_to_recx_iov(space, type_size, buf, &recxs, &sg_iovs, &tot_nseq) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
- iod.vd_nr = (unsigned)tot_nseq;
- sgl.sg_nr.num = (uint32_t)tot_nseq;
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, buf, &recxs, &sg_iovs, &tot_nseq) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
+ iod.vd_nr = (unsigned)tot_nseq;
+ sgl.sg_nr.num = (uint32_t)tot_nseq;
+ } /* end if */
+ else {
+ /* Calculate recxs from file space */
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, buf, &recxs, NULL, &tot_nseq) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
+ iod.vd_nr = (unsigned)tot_nseq;
+
+ /* Get memory dataspace object */
+ if(NULL == (space = (H5S_t *)H5I_object(real_mem_space_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Calculate sg_iovs from mem space */
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, buf, NULL, &sg_iovs, &tot_nseq) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
+ sgl.sg_nr.num = (uint32_t)tot_nseq;
+ } /* end else */
+
+ /* Point iod and sgl to lists generated above */
+ iod.vd_recxs = recxs;
+ sgl.sg_iovs = sg_iovs;
+
+ /* Read data from dataset */
+ if(0 != (ret = daos_obj_fetch(dset->obj.obj_oh, dset->obj.item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data from dataset: %d", ret)
} /* end if */
else {
+ hssize_t num_elem;
+ size_t nseq_tmp;
+ size_t nelem_tmp;
+ hsize_t sel_off;
+ size_t sel_len;
+ size_t mem_type_size;
+ hbool_t fill_bkg = FALSE;
+ hbool_t contig;
+
+ /* Type conversion necessary */
+ /* Get number of elements in selection */
+ if((num_elem = H5Sget_select_npoints(real_mem_space_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of points in selection")
+
/* Calculate recxs from file space */
- if(H5VL_daosm_sel_to_recx_iov(space, type_size, buf, &recxs, NULL, &tot_nseq) < 0)
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, buf, &recxs, NULL, &tot_nseq) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
iod.vd_nr = (unsigned)tot_nseq;
+ iod.vd_recxs = recxs;
+ /* Set up constant sgl info */
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ /* Check for contiguous memory buffer */
/* Get memory dataspace object */
- if(NULL == (space = (H5S_t *)H5I_object(mem_space_id)))
+ if(NULL == (space = (H5S_t *)H5I_object(real_mem_space_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
- /* Calculate sg_iovs from mem space */
- if(H5VL_daosm_sel_to_recx_iov(space, type_size, buf, NULL, &sg_iovs, &tot_nseq) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
- sgl.sg_nr.num = (uint32_t)tot_nseq;
- } /* end else */
+ /* Initialize selection iterator */
+ if(H5S_select_iter_init(&sel_iter, space, (size_t)1) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ sel_iter_init = TRUE; /* Selection iteration info has been initialized */
+
+ /* Get the sequence list - only check the first sequence because we only
+ * care if it is contiguous and if so where the contiguous selection
+ * begins */
+ if(H5S_SELECT_GET_SEQ_LIST(space, 0, &sel_iter, (size_t)1, (size_t)-1, &nseq_tmp, &nelem_tmp, &sel_off, &sel_len) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed")
+ contig = (sel_len == (size_t)num_elem);
+
+ /* Initialize type conversion */
+ if(H5VL_daosm_tconv_init(dset->type_id, &file_type_size, mem_type_id, &mem_type_size, (size_t)num_elem, &tconv_buf, &bkg_buf, contig ? &reuse : NULL, &fill_bkg) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize type conversion")
+
+ /* Reuse buffer as appropriate */
+ if(contig) {
+ sel_off *= (hsize_t)mem_type_size;
+ if(reuse == H5VL_DAOSM_TCONV_REUSE_TCONV)
+ tconv_buf = (char *)buf + (size_t)sel_off;
+ else if(reuse == H5VL_DAOSM_TCONV_REUSE_BKG)
+ bkg_buf = (char *)buf + (size_t)sel_off;
+ } /* end if */
+
+ /* Set sg_iov to point to tconv_buf */
+ daos_iov_set(&sg_iov, tconv_buf, (daos_size_t)num_elem * (daos_size_t)file_type_size);
- /* Point iod and sgl to lists generated above */
- iod.vd_recxs = recxs;
- sgl.sg_iovs = sg_iovs;
+ /* Read data to tconv_buf */
+ if(0 != (ret = daos_obj_fetch(dset->obj.obj_oh, dset->obj.item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret)
- /* Read data from dataset */
- if(0 != (ret = daos_obj_fetch(dset->obj.obj_oh, dset->obj.item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data from dataset: %d", ret)
+ /* Gather data to background buffer if necessary */
+ if(fill_bkg && (reuse != H5VL_DAOSM_TCONV_REUSE_BKG))
+ if(H5Dgather(real_mem_space_id, buf, mem_type_id, (size_t)num_elem * mem_type_size, bkg_buf, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't gather data to background buffer")
+
+ /* Perform type conversion */
+ if(H5Tconvert(dset->type_id, mem_type_id, (size_t)num_elem, tconv_buf, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't perform type conversion")
+
+ /* Scatter data to memory buffer if necessary */
+ if(reuse != H5VL_DAOSM_TCONV_REUSE_TCONV) {
+ H5VL_daosm_scatter_cb_ud_t scatter_cb_ud;
+
+ scatter_cb_ud.buf = tconv_buf;
+ scatter_cb_ud.len = (size_t)num_elem * mem_type_size;
+ if(H5Dscatter(H5VL_daosm_scatter_cb, &scatter_cb_ud, mem_type_id, real_mem_space_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't scatter data to read buffer")
+ } /* end if */
+ } /* end else */
done:
+ /* Free memory */
if(recxs != &recx)
H5MM_free(recxs);
if(sg_iovs != &sg_iov)
H5MM_free(sg_iovs);
+ if(tconv_buf && (reuse != H5VL_DAOSM_TCONV_REUSE_TCONV))
+ H5MM_free(tconv_buf);
+ if(bkg_buf && (reuse != H5VL_DAOSM_TCONV_REUSE_BKG))
+ H5MM_free(bkg_buf);
+
+ /* Release selection iterator */
+ if(sel_iter_init && H5S_SELECT_ITER_RELEASE(&sel_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_dataset_read() */
@@ -3531,7 +3691,10 @@ H5VL_daosm_dataset_write(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
H5VL_daosm_dset_t *dset = (H5VL_daosm_dset_t *)_dset;
int ndims;
hsize_t dim[H5S_MAX_RANK];
+ hid_t real_file_space_id;
+ hid_t real_mem_space_id;
H5S_t *space = NULL;
+ hssize_t num_elem;
uint64_t chunk_coords[H5S_MAX_RANK];
daos_key_t dkey;
daos_vec_iod_t iod;
@@ -3543,7 +3706,11 @@ H5VL_daosm_dataset_write(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
size_t tot_nseq;
uint8_t dkey_buf[1 + H5S_MAX_RANK];
uint8_t akey = H5VL_DAOSM_CHUNK_KEY;
- size_t type_size;
+ size_t file_type_size;
+ size_t mem_type_size;
+ void *tconv_buf = NULL;
+ void *bkg_buf = NULL;
+ hbool_t fill_bkg = FALSE;
uint8_t *p;
int ret;
int i;
@@ -3561,9 +3728,23 @@ H5VL_daosm_dataset_write(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
if(ndims != H5Sget_simple_extent_dims(dset->space_id, dim, NULL))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dimensions")
- /* Get datatype size */
- if((type_size = H5Tget_size(dset->type_id)) == 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype size")
+ /* Get "real" space ids */
+ if(file_space_id == H5S_ALL)
+ real_file_space_id = dset->space_id;
+ else
+ real_file_space_id = file_space_id;
+ if(mem_space_id == H5S_ALL)
+ real_mem_space_id = real_file_space_id;
+ else
+ real_mem_space_id = mem_space_id;
+
+ /* Get number of elements in selection */
+ if((num_elem = H5Sget_select_npoints(real_mem_space_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of points in selection")
+
+ /* Initialize type conversion */
+ if(H5VL_daosm_tconv_init(mem_type_id, &mem_type_size, dset->type_id, &file_type_size, (size_t)num_elem, &tconv_buf, &bkg_buf, NULL, &fill_bkg) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize type conversion")
/* Encode dkey (chunk coordinates). Prefix with '/' to avoid accidental
* collisions with other d-keys in this object. For now just 1 chunk,
@@ -3584,47 +3765,86 @@ H5VL_daosm_dataset_write(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id,
/* Build recxs and sg_iovs */
/* Get file dataspace object */
- if(NULL == (space = (H5S_t *)H5I_object((file_space_id == H5S_ALL)
- ? dset->space_id : file_space_id)))
+ if(NULL == (space = (H5S_t *)H5I_object(real_file_space_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
- /* Check for memory space is H5S_ALL, use file space in this case */
- if(mem_space_id == H5S_ALL) {
- /* Calculate both recxs and sg_iovs at the same time from file space */
- if(H5VL_daosm_sel_to_recx_iov(space, type_size, (void *)buf, &recxs, &sg_iovs, &tot_nseq) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
- iod.vd_nr = (unsigned)tot_nseq;
- sgl.sg_nr.num = (uint32_t)tot_nseq;
- } /* end if */
- else {
+ /* Check for type conversion */
+ if(tconv_buf) {
/* Calculate recxs from file space */
- if(H5VL_daosm_sel_to_recx_iov(space, type_size, (void *)buf, &recxs, NULL, &tot_nseq) < 0)
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, (void *)buf, &recxs, NULL, &tot_nseq) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
iod.vd_nr = (unsigned)tot_nseq;
+ iod.vd_recxs = recxs;
- /* Get memory dataspace object */
- if(NULL == (space = (H5S_t *)H5I_object(mem_space_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ /* Set up constant sgl info */
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
- /* Calculate sg_iovs from mem space */
- if(H5VL_daosm_sel_to_recx_iov(space, type_size, (void *)buf, NULL, &sg_iovs, &tot_nseq) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
- sgl.sg_nr.num = (uint32_t)tot_nseq;
- } /* end else */
+ /* Check if we need to fill background buffer */
+ if(fill_bkg) {
+ HDassert(bkg_buf);
+
+ /* Set sg_iov to point to background buffer */
+ daos_iov_set(&sg_iov, bkg_buf, (daos_size_t)num_elem * (daos_size_t)file_type_size);
+
+ /* Read data from dataset to background buffer */
+ if(0 != (ret = daos_obj_fetch(dset->obj.obj_oh, dset->obj.item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data from dataset: %d", ret)
+ } /* end if */
- /* Point iod and sgl to lists generated above */
- iod.vd_recxs = recxs;
- sgl.sg_iovs = sg_iovs;
+ /* Gather data to conversion buffer */
+ if(H5Dgather(real_mem_space_id, buf, mem_type_id, (size_t)num_elem * mem_type_size, tconv_buf, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't gather data to conversion buffer")
+
+ /* Perform type conversion */
+ if(H5Tconvert(mem_type_id, dset->type_id, (size_t)num_elem, tconv_buf, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't perform type conversion")
+
+ /* Set sg_iovs to write from tconv_buf */
+ daos_iov_set(&sg_iov, tconv_buf, (daos_size_t)num_elem * (daos_size_t)file_type_size);
+ } /* end if */
+ else {
+ /* Check for memory space is H5S_ALL, use file space in this case */
+ if(mem_space_id == H5S_ALL) {
+ /* Calculate both recxs and sg_iovs at the same time from file space */
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, (void *)buf, &recxs, &sg_iovs, &tot_nseq) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
+ iod.vd_nr = (unsigned)tot_nseq;
+ sgl.sg_nr.num = (uint32_t)tot_nseq;
+ } /* end if */
+ else {
+ /* Calculate recxs from file space */
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, (void *)buf, &recxs, NULL, &tot_nseq) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
+ iod.vd_nr = (unsigned)tot_nseq;
+
+ /* Get memory dataspace object */
+ if(NULL == (space = (H5S_t *)H5I_object(real_mem_space_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Calculate sg_iovs from mem space */
+ if(H5VL_daosm_sel_to_recx_iov(space, file_type_size, (void *)buf, NULL, &sg_iovs, &tot_nseq) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't generate sequence lists for DAOS I/O")
+ sgl.sg_nr.num = (uint32_t)tot_nseq;
+ } /* end else */
+
+ /* Point iod and sgl to lists generated above */
+ iod.vd_recxs = recxs;
+ sgl.sg_iovs = sg_iovs;
+ } /* end else */
/* Write data to dataset */
if(0 != (ret = daos_obj_update(dset->obj.obj_oh, dset->obj.item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/)))
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data to dataset: %d", ret)
done:
+ /* Free memory */
if(recxs != &recx)
H5MM_free(recxs);
if(sg_iovs != &sg_iov)
H5MM_free(sg_iovs);
+ tconv_buf = H5MM_xfree(tconv_buf);
+ bkg_buf = H5MM_xfree(bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_dataset_write() */
@@ -4258,8 +4478,8 @@ done:
akey = (char *)H5MM_xfree(akey);
if(tconv_buf && (tconv_buf != buf))
H5MM_free(tconv_buf);
- if(bkg_buf &&(bkg_buf != buf))
- H5MM_free(buf);
+ if(bkg_buf && (bkg_buf != buf))
+ H5MM_free(bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_attribute_read() */