From 3943452ff3cc26938fd69c1d75380bb7d0edb8ef Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 16 Mar 2017 16:22:46 -0500 Subject: 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. --- examples/h5dsm_ttconv.c | 1165 +++++++++++++++++++++++++++++++++++++++++++++-- src/H5VLdaosm.c | 352 +++++++++++--- 2 files changed, 1414 insertions(+), 103 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,45 +883,1095 @@ int main(int argc, char *argv[]) { printf("\n"); /* - * Close + * Test dataset */ - if(H5Aclose(attr) < 0) - ERROR; - if(H5Aclose(attr_a) < 0) - ERROR; - if(H5Aclose(attr_b) < 0) - ERROR; - if(H5Aclose(attr_c) < 0) - ERROR; - if(H5Dclose(dset) < 0) - ERROR; - if(H5Dclose(dset_a) < 0) - ERROR; - if(H5Dclose(dset_b) < 0) - ERROR; - if(H5Dclose(dset_c) < 0) - ERROR; - if(H5Fclose(file) < 0) - ERROR; - if(H5Tclose(file_type) < 0) - ERROR; - if(H5Tclose(file_type_a) < 0) - ERROR; - if(H5Tclose(file_type_b) < 0) + /* + * 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; - if(H5Tclose(file_type_c) < 0) + + /* 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; - if(H5Tclose(mem_type) < 0) + + /* 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; - if(H5Tclose(mem_type_conv) < 0) + + /* 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; - if(H5Tclose(mem_type_a) < 0) + + /* 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; - if(H5Tclose(mem_type_b) < 0) + + /* 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; - if(H5Tclose(mem_type_c) < 0) + + /* 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; - if(H5Sclose(space) < 0) + + /* 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) + ERROR; + if(H5Aclose(attr_a) < 0) + ERROR; + if(H5Aclose(attr_b) < 0) + ERROR; + if(H5Aclose(attr_c) < 0) + ERROR; + if(H5Dclose(dset) < 0) + ERROR; + if(H5Dclose(dset_a) < 0) + ERROR; + if(H5Dclose(dset_b) < 0) + ERROR; + if(H5Dclose(dset_c) < 0) + ERROR; + if(H5Dclose(dset2) < 0) + ERROR; + if(H5Fclose(file) < 0) + ERROR; + if(H5Tclose(file_type) < 0) + ERROR; + if(H5Tclose(file_type_a) < 0) + ERROR; + if(H5Tclose(file_type_b) < 0) + ERROR; + if(H5Tclose(file_type_c) < 0) + ERROR; + if(H5Tclose(mem_type) < 0) + ERROR; + if(H5Tclose(mem_type_conv) < 0) + ERROR; + if(H5Tclose(mem_type_a) < 0) + ERROR; + if(H5Tclose(mem_type_b) < 0) + ERROR; + if(H5Tclose(mem_type_c) < 0) + 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() */ -- cgit v0.12