diff options
136 files changed, 25586 insertions, 230 deletions
@@ -129,6 +129,14 @@ ./examples/h5_ref2reg.c ./examples/h5_shared_mesg.c ./examples/ph5example.c +./examples/h5_vds.c +./examples/h5_vds-exc.c +./examples/h5_vds-exclim.c +./examples/h5_vds-eiger.c +./examples/h5_vds-simpleIO.c +./examples/h5_vds-percival.c +./examples/h5_vds-percival-unlim.c +./examples/h5_vds-percival-unlim-maxmin.c ./examples/testh5cc.sh.in ./examples/README @@ -483,6 +491,7 @@ ./src/H5Dscatgath.c ./src/H5Dselect.c ./src/H5Dtest.c +./src/H5Dvirtual.c ./src/H5E.c ./src/H5Edeprec.c ./src/H5Eint.c @@ -982,6 +991,7 @@ ./test/test_filters_be.h5 ./test/gen_filters.c ./test/chunk_info.c +./test/vds.c ./test/testfiles/err_compat_1 ./test/testfiles/err_compat_2 @@ -1125,6 +1135,7 @@ ./tools/h5dump/testh5dump.sh.in ./tools/h5dump/testh5dumppbits.sh.in ./tools/h5dump/testh5dumpxml.sh.in +./tools/h5dump/testh5dumpvds.sh.in ./tools/h5dump/binread.c ./tools/h5import/Makefile.am @@ -1212,9 +1223,11 @@ ./tools/h5repack/testh5repack_detect_szip.c # h5ls sources +./tools/h5ls/CMakeTestsVDS.cmake ./tools/h5ls/Makefile.am ./tools/h5ls/h5ls.c ./tools/h5ls/testh5ls.sh.in +./tools/h5ls/testh5lsvds.sh.in # h5copy sources ./tools/h5copy/testh5copy.sh.in @@ -1263,6 +1276,18 @@ ./tools/misc/testfiles/h5mkgrp_help.txt ./tools/misc/testfiles/h5mkgrp_version.txt.in ./tools/misc/h5perf_gentest.c +./tools/misc/vds/Makefile.am +./tools/misc/vds/UC_1.h +./tools/misc/vds/UC_1_one_dim_gen.c +./tools/misc/vds/UC_2.h +./tools/misc/vds/UC_2_two_dims_gen.c +./tools/misc/vds/UC_3.h +./tools/misc/vds/UC_3_gaps_gen.c +./tools/misc/vds/UC_4.h +./tools/misc/vds/UC_4_printf_gen.c +./tools/misc/vds/UC_5.h +./tools/misc/vds/UC_5_stride_gen.c +./tools/misc/vds/UC_common.h # h5stat sources ./tools/h5stat/Makefile.am @@ -1682,6 +1707,43 @@ ./tools/testfiles/pbits/tpbitsOverlapped.ddl ./tools/testfiles/packedbits.h5 +# h5dump vds validation +./tools/testfiles/vds/tvds-1.ddl +./tools/testfiles/vds/tvds-2.ddl +./tools/testfiles/vds/tvds-3_1.ddl +./tools/testfiles/vds/tvds-3_2.ddl +./tools/testfiles/vds/tvds-4.ddl +./tools/testfiles/vds/tvds-5.ddl +./tools/testfiles/vds/tvds_layout-1.ddl +./tools/testfiles/vds/tvds_layout-2.ddl +./tools/testfiles/vds/tvds_layout-3_1.ddl +./tools/testfiles/vds/tvds_layout-3_2.ddl +./tools/testfiles/vds/tvds_layout-4.ddl +./tools/testfiles/vds/tvds_layout-5.ddl +./tools/testfiles/vds/1_a.h5 +./tools/testfiles/vds/1_b.h5 +./tools/testfiles/vds/1_c.h5 +./tools/testfiles/vds/1_d.h5 +./tools/testfiles/vds/1_e.h5 +./tools/testfiles/vds/1_f.h5 +./tools/testfiles/vds/1_vds.h5 +./tools/testfiles/vds/2_a.h5 +./tools/testfiles/vds/2_b.h5 +./tools/testfiles/vds/2_c.h5 +./tools/testfiles/vds/2_d.h5 +./tools/testfiles/vds/2_e.h5 +./tools/testfiles/vds/2_vds.h5 +./tools/testfiles/vds/3_1_vds.h5 +./tools/testfiles/vds/3_2_vds.h5 +./tools/testfiles/vds/4_0.h5 +./tools/testfiles/vds/4_1.h5 +./tools/testfiles/vds/4_2.h5 +./tools/testfiles/vds/4_vds.h5 +./tools/testfiles/vds/5_a.h5 +./tools/testfiles/vds/5_b.h5 +./tools/testfiles/vds/5_c.h5 +./tools/testfiles/vds/5_vds.h5 + # h5dump h5import validation ./tools/testfiles/out3.h5import ./tools/testfiles/tordergr.h5 @@ -1758,7 +1820,13 @@ ./tools/testfiles/thlinks-nodangle-1.ls ./tools/testfiles/tudlink-1.ls - +# h5ls vds validation +./tools/testfiles/vds/tvds-1.ls +./tools/testfiles/vds/tvds-2.ls +./tools/testfiles/vds/tvds-3_1.ls +./tools/testfiles/vds/tvds-3_2.ls +./tools/testfiles/vds/tvds-4.ls +./tools/testfiles/vds/tvds-5.ls #additional test input and output for h5dump XML ./tools/testfiles/tall.h5.xml @@ -2073,6 +2141,10 @@ ./tools/h5diff/testfiles/tmptest.he5 ./tools/h5diff/testfiles/h5diff_tmp2.txt ./tools/h5diff/testfiles/tmpSingleSiteBethe.output.h5 +#vds +./tools/h5diff/testfiles/h5diff_v1.txt +./tools/h5diff/testfiles/h5diff_v2.txt +./tools/h5diff/testfiles/h5diff_v3.txt #test files for h5repack ./tools/h5repack/testfiles/README @@ -2427,6 +2499,7 @@ ./tools/h5dump/CMakeTests.cmake ./tools/h5dump/CMakeTestsPBITS.cmake ./tools/h5dump/CMakeTestsXML.cmake +./tools/h5dump/CMakeTestsVDS.cmake ./tools/h5import/CMakeLists.txt ./tools/h5import/CMakeTests.cmake ./tools/h5jam/CMakeLists.txt @@ -2440,6 +2513,7 @@ ./tools/lib/CMakeLists.txt ./tools/misc/CMakeLists.txt ./tools/misc/CMakeTests.cmake +./tools/misc/vds/CMakeLists.txt ./tools/perform/CMakeLists.txt ./tools/perform/CMakeTests.cmake @@ -41,6 +41,7 @@ $Source = ""; "H5D_mpio_no_collective_cause_t" => "Dn", "H5D_mpio_actual_chunk_opt_mode_t" => "Do", "H5D_space_status_t" => "Ds", + "H5D_vds_view_t" => "Dv", "H5FD_mpio_xfer_t" => "Dt", "herr_t" => "e", "H5E_direction_t" => "Ed", diff --git a/configure.ac b/configure.ac index 96b26c6..18601f1 100644 --- a/configure.ac +++ b/configure.ac @@ -3055,8 +3055,10 @@ AC_CONFIG_FILES([src/libhdf5.settings tools/h5dump/Makefile tools/h5dump/testh5dump.sh tools/h5dump/testh5dumppbits.sh + tools/h5dump/testh5dumpvds.sh tools/h5dump/testh5dumpxml.sh tools/h5ls/testh5ls.sh + tools/h5ls/testh5lsvds.sh tools/h5import/Makefile tools/h5import/h5importtestutil.sh tools/h5diff/Makefile @@ -3075,6 +3077,7 @@ AC_CONFIG_FILES([src/libhdf5.settings tools/misc/h5cc tools/misc/testh5mkgrp.sh tools/misc/testh5repart.sh + tools/misc/vds/Makefile tools/h5stat/testh5stat.sh tools/h5stat/Makefile tools/perform/Makefile diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7953161..8849ce7 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -34,6 +34,14 @@ set (examples h5_extlink h5_elink_unix2win h5_shared_mesg + h5_vds + h5_vds-exc + h5_vds-exclim + h5_vds-eiger + h5_vds-simpleIO + h5_vds-percival + h5_vds-percival-unlim + h5_vds-percival-unlim-maxmin ) foreach (example ${examples}) diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index 42b42b3..2cf82b8 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -46,6 +46,18 @@ blue/prefix_target.h5 red/prefix_target.h5 u2w/u2w_target.h5 + vds.h5 + vds-excalibur.h5 + vds-exclim.h5 + vds-percival.h5 + vds-percival-unlim.h5 + vds-percival-unlim-maxmin.h5 + a.h5 + b.h5 + c.h5 + d.h5 + vds-simpleIO.h5 + vds-eiger.h5 ) if (NOT "${last_test}" STREQUAL "") set_tests_properties (EXAMPLES-clear-objects PROPERTIES DEPENDS ${last_test}) diff --git a/examples/Makefile.am b/examples/Makefile.am index 5d0da93..883b99d 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -37,7 +37,9 @@ EXAMPLE_PROG = h5_write h5_read h5_extend_write h5_chunk_read h5_compound \ h5_crtgrpd h5_subset h5_cmprss h5_rdwt h5_crtgrpar h5_extend \ h5_crtatt h5_crtgrp h5_crtdat \ h5_group h5_select h5_attribute h5_mount h5_reference h5_drivers \ - h5_ref2reg h5_extlink h5_elink_unix2win h5_shared_mesg + h5_ref2reg h5_extlink h5_elink_unix2win h5_shared_mesg h5_vds h5_vds-exc \ + h5_vds-exclim h5_vds-eiger h5_vds-simpleIO h5_vds-percival \ + h5_vds-percival-unlim h5_vds-percival-unlim-maxmin TEST_SCRIPT=testh5cc.sh TEST_EXAMPLES_SCRIPT=$(INSTALL_SCRIPT_FILES) @@ -48,7 +50,9 @@ INSTALL_FILES = h5_write.c h5_read.c h5_extend_write.c h5_chunk_read.c \ h5_extend.c h5_crtatt.c h5_crtgrp.c h5_crtdat.c \ h5_compound.c h5_group.c h5_select.c h5_attribute.c h5_mount.c \ h5_reference.c h5_drivers.c h5_extlink.c h5_elink_unix2win.c \ - h5_ref2reg.c h5_shared_mesg.c ph5example.c + h5_ref2reg.c h5_shared_mesg.c ph5example.c h5_vds.c h5_vds-exc.c \ + h5_vds-exclim.c h5_vds-eiger.c h5_vds-simpleIO.c h5_vds-percival.c \ + h5_vds-percival-unlim.c h5_vds-percival-unlim-maxmin.c @@ -117,6 +121,14 @@ h5_dtransform: $(srcdir)/h5_dtransform.c h5_extlink: $(srcdir)/h5_extlink.c $(EXTLINK_DIRS) h5_elink_unix2win: $(srcdir)/h5_elink_unix2win.c $(EXTLINK_DIRS) h5_shared_mesg: $(srcdir)/h5_shared_mesg.c +h5_vds: $(srcdir)/h5_vds.c +h5_vds-exc: $(srcdir)/h5_vds-exc.c +h5_vds-exclim: $(srcdir)/h5_vds-exclim.c +h5_vds-eiger: $(srcdir)/h5_vds-eiger.c +h5_vds-simpleIO: $(srcdir)/h5_vds-simpleIO.c +h5_vds-percival: $(srcdir)/h5_vds-percival.c +h5_vds-percival-unlim: $(srcdir)/h5_vds-percival-unlim.c +h5_vds-percival-unlim-maxmin: $(srcdir)/h5_vds-percival-unlim-maxmin.c if BUILD_SHARED_SZIP_CONDITIONAL LD_LIBRARY_PATH=$(LL_PATH) diff --git a/examples/h5_vds-eiger.c b/examples/h5_vds-eiger.c new file mode 100644 index 0000000..ea22243 --- /dev/null +++ b/examples/h5_vds-eiger.c @@ -0,0 +1,177 @@ +/************************************************************ + + This example illustrates the concept of the virtual dataset. + Eiger use case. Every 5 frames 10x10 are in the source + dataset "/A" in file with the name f-<#>.h5 + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "vds-eiger.h5" +#define DATASET "VDS-Eiger" +#define VDSDIM0 5 +#define VDSDIM1 10 +#define VDSDIM2 10 +#define DIM0 5 +#define DIM1 10 +#define DIM2 10 +#define RANK 3 + +int +main (void) +{ + hid_t file, src_space, vspace, + dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + vdsdims_max[3] = {H5S_UNLIMITED, VDSDIM1, VDSDIM1}, + dims[3] = {DIM0, DIM1, DIM2}, + start[3], /* Hyperslab parameters */ + stride[3], + count[3], + block[3]; + hsize_t start_out[3], /* Hyperslab parameter out */ + stride_out[3], + count_out[3], + block_out[3]; + int i; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + + + file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + vspace = H5Screate_simple (RANK, vdsdims, vdsdims_max); + + /* Create dataspaces for the source dataset. */ + src_space = H5Screate_simple (RANK, dims, NULL); + + /* Create VDS creation property */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* Initialize hyperslab values */ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + stride[0] = DIM0; + stride[1] = 1; + stride[2] = 1; + count[0] = H5S_UNLIMITED; + count[1] = 1; + count[2] = 1; + block[0] = DIM0; + block[1] = DIM1; + block[2] = DIM2; + + /* + * Build the mappings + * + */ + status = H5Sselect_hyperslab (vspace, H5S_SELECT_SET, start, stride, count, block); + status = H5Pset_virtual (dcpl, vspace, "f-%b.h5", "/A", src_space); + + + + /* Create a virtual dataset */ + dset = H5Dcreate2 (file, DATASET, H5T_NATIVE_INT, vspace, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (vspace); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + + + /* + * Now we begin the read section of this example. + */ + + /* + * Open file and dataset using the default properties. + */ + file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen2 (file, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (dset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf(" Wrong layout found \n"); + + /* + * Find number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %d\n", (int)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset \n"); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + /* Get source file name */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset */ + printf(" Selection in the source dataset "); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + if(H5Sget_select_type(src_space) == H5S_SEL_ALL) { + printf("H5S_ALL \n"); + } +/* EIP read data back */ + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } + + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + + return 0; +} + diff --git a/examples/h5_vds-exc.c b/examples/h5_vds-exc.c new file mode 100644 index 0000000..039cdb8 --- /dev/null +++ b/examples/h5_vds-exc.c @@ -0,0 +1,226 @@ +/************************************************************ + + This example illustrates the concept of the virtual dataset. + Excalibur use case with k=2 and m=3. + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "vds-exc.h5" +#define DATASET "VDS-Excalibur" +#define VDSDIM0 0 +#define VDSDIM1 15 +#define VDSDIM2 6 +#define KDIM0 0 +#define KDIM1 2 +#define KDIM2 6 +#define NDIM0 0 +#define NDIM1 3 +#define NDIM2 6 +#define RANK 3 + +const char *SRC_FILE[] = { + "a.h5", + "b.h5", + "c.h5", + "d.h5", + "e.h5", + "f.h5" +}; + +const char *SRC_DATASET[] = { + "A", + "B", + "C", + "D", + "E", + "F" +}; + +int +main (void) +{ + hid_t file, space, ksrc_space, nsrc_space, vspace, + src_space, + dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + vdsdims_max[3] = {H5S_UNLIMITED,VDSDIM1, VDSDIM2}, + kdims[3] = {KDIM0, KDIM1, KDIM2}, + kdims_max[3] = {H5S_UNLIMITED, KDIM1, KDIM2}, + ndims[3] = {NDIM0, NDIM1, NDIM2}, + ndims_max[3] = {H5S_UNLIMITED, NDIM1, NDIM2}, + start[3], /* Hyperslab parameters */ + stride[3], + count[3], + block[3]; + hsize_t start_out[3], + stride_out[3], + count_out[3], + block_out[3]; + int k = 2; + int n = 3; + int i; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + + + file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + space = H5Screate_simple (RANK, vdsdims, vdsdims_max); + /* Create dataspaces for A, C, and E datasets. */ + ksrc_space = H5Screate_simple (RANK, kdims, kdims_max); + /* Create dataspaces for B, D, and F datasets. */ + nsrc_space = H5Screate_simple (RANK, ndims, ndims_max); + + /* Create VDS creation property */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* Initialize hyperslab values */ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + count[0] = H5S_UNLIMITED; + count[1] = 1; + count[2] = 1; + block[0] = 1; + block[1] = k; + block[2] = VDSDIM2; + + /* + * Build the mappings for A, C and E source datasets. + * Unlimited hyperslab selection is the same in the source datasets. + * Unlimited hyperslab selections in the virtual dataset have different offsets. + */ + status = H5Sselect_hyperslab (ksrc_space, H5S_SELECT_SET, start, NULL, count, block); + for (i = 0; i < 3; i++) { + start[1] = (hsize_t)((k+n)*i); + status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Pset_virtual (dcpl, space, SRC_FILE[2*i], SRC_DATASET[2*i], ksrc_space); + } + + /* Reinitialize start[1] and block[1] to build the second set of mappings. */ + start[1] = 0; + block[1] = n; + /* + * Build the mappings for B, D and F source datasets. + * Unlimited hyperslab selection is the same in the source datasets. + * Unlimited hyperslab selections in the virtual dataset have different offsets. + */ + status = H5Sselect_hyperslab (nsrc_space, H5S_SELECT_SET, start, NULL, count, block); + for (i = 0; i < 3; i++) { + start[1] = (hsize_t)(k+(k+n)*i); + status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Pset_virtual (dcpl, space, SRC_FILE[2*i+1], SRC_DATASET[2*i+1], nsrc_space); + } + + /* Create a virtual dataset */ + dset = H5Dcreate2 (file, DATASET, H5T_NATIVE_INT, space, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (space); + status = H5Sclose (nsrc_space); + status = H5Sclose (ksrc_space); + status = H5Dclose (dset); + status = H5Fclose (file); + + + /* + * Now we begin the read section of this example. + */ + + /* + * Open file and dataset using the default properties. + */ + file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen2 (file, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (dset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf("Wrong layout found \n"); + + /* + * Find number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset \n"); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + /* Get source file name */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset */ + printf(" Selection in the source dataset \n"); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + if (H5Sget_select_type(src_space) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (src_space, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } +/* EIP read data back */ + + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + + return 0; +} + diff --git a/examples/h5_vds-exclim.c b/examples/h5_vds-exclim.c new file mode 100644 index 0000000..4933471 --- /dev/null +++ b/examples/h5_vds-exclim.c @@ -0,0 +1,222 @@ +/************************************************************ + + This example illustrates the concept of the virtual dataset. + Excalibur use case with k=2 and m=3 and only 3 planes in + Z-direction (i.e., not unlimited). + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "vds-exclim.h5" +#define DATASET "VDS-Excaliburlim" +#define VDSDIM0 3 +#define VDSDIM1 15 +#define VDSDIM2 6 +#define KDIM0 3 +#define KDIM1 2 +#define KDIM2 6 +#define NDIM0 3 +#define NDIM1 3 +#define NDIM2 6 +#define RANK 3 + +const char *SRC_FILE[] = { + "a.h5", + "b.h5", + "c.h5", + "d.h5", + "e.h5", + "f.h5" +}; + +const char *SRC_DATASET[] = { + "A", + "B", + "C", + "D", + "E", + "F" +}; + +int +main (void) +{ + hid_t file, space, ksrc_space, nsrc_space, vspace, + src_space, + dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + kdims[3] = {KDIM0, KDIM1, KDIM2}, + ndims[3] = {NDIM0, NDIM1, NDIM2}, + start[3], /* Hyperslab parameters */ + stride[3], + count[3], + block[3]; + hsize_t start_out[3], + stride_out[3], + count_out[3], + block_out[3]; + int k = 2; + int n = 3; + int i; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + + + file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + space = H5Screate_simple (RANK, vdsdims, NULL); + /* Create dataspaces for A, C, and E datasets. */ + ksrc_space = H5Screate_simple (RANK, kdims, NULL); + /* Create dataspaces for B, D, and F datasets. */ + nsrc_space = H5Screate_simple (RANK, ndims, NULL); + + /* Create VDS creation property */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* Initialize hyperslab values */ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + count[0] = VDSDIM0; + count[1] = 1; + count[2] = 1; + block[0] = 1; + block[1] = k; + block[2] = VDSDIM2; + + /* + * Build the mappings for A, C and E source datasets. + * + */ + status = H5Sselect_hyperslab (ksrc_space, H5S_SELECT_SET, start, NULL, count, block); + for (i = 0; i < 3; i++) { + start[1] = (hsize_t)((k+n)*i); + status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Pset_virtual (dcpl, space, SRC_FILE[2*i], SRC_DATASET[2*i], ksrc_space); + } + + /* Reinitialize start[0] and block[1] */ + start[0] = 0; + block[1] = n; + /* + * Build the mappings for B, D and F source datasets. + * + */ + status = H5Sselect_hyperslab (nsrc_space, H5S_SELECT_SET, start, NULL, count, block); + for (i = 0; i < 3; i++) { + start[1] = (hsize_t)(k+(k+n)*i); + status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Pset_virtual (dcpl, space, SRC_FILE[2*i+1], SRC_DATASET[2*i+1], nsrc_space); + } + + /* Create a virtual dataset */ + dset = H5Dcreate2 (file, DATASET, H5T_NATIVE_INT, space, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (space); + status = H5Sclose (nsrc_space); + status = H5Sclose (ksrc_space); + status = H5Dclose (dset); + status = H5Fclose (file); + + + /* + * Now we begin the read section of this example. + */ + + /* + * Open file and dataset using the default properties. + */ + file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen2 (file, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (dset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf("Wrong layout found \n"); + + /* + * Find number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset \n"); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + /* Get source file name */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset */ + printf(" Selection in the source dataset \n"); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + if(H5Sget_select_type(src_space) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%d, %d, %d] \n", (int)start_out[0], (int)start_out[1], (int)start_out[2]); + printf(" stride = [%d, %d, %d] \n", (int)stride_out[0], (int)stride_out[1], (int)stride_out[2]); + printf(" count = [%d, %d, %d] \n", (int)count_out[0], (int)count_out[1], (int)count_out[2]); + printf(" block = [%d, %d, %d] \n", (int)block_out[0], (int)block_out[1], (int)block_out[2]); + } + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } +/* EIP read data back */ + + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + + return 0; +} + diff --git a/examples/h5_vds-percival-unlim-maxmin.c b/examples/h5_vds-percival-unlim-maxmin.c new file mode 100644 index 0000000..a6eecfb --- /dev/null +++ b/examples/h5_vds-percival-unlim-maxmin.c @@ -0,0 +1,309 @@ +/************************************************************ + + This example illustrates the concept of the virtual dataset. + Percival use case. Every fifth 10x10 plane in VDS is stored in + the corresponding 3D unlimited dataset. + There are 4 source datasets total. + Each of the source datasets is extended to different sizes. + VDS access property can be used to get max and min extent. + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define VFILE "vds-percival-unlim-maxmin.h5" +#define DATASET "VDS-Percival-unlim-maxmin" +#define VDSDIM0 H5S_UNLIMITED +#define VDSDIM1 10 +#define VDSDIM2 10 + +#define DIM0 H5S_UNLIMITED +#define DIM0_1 4 /* Initial size of the source datasets */ +#define DIM1 10 +#define DIM2 10 +#define RANK 3 +#define PLANE_STRIDE 4 + +const char *SRC_FILE[] = { + "a.h5", + "b.h5", + "c.h5", + "d.h5" +}; + +const char *SRC_DATASET[] = { + "A", + "B", + "C", + "D" +}; + +int +main (void) +{ + hid_t vfile, file, src_space, mem_space, vspace, + vdset, dset; /* Handles */ + hid_t dcpl, dapl; + herr_t status; + hsize_t vdsdims[3] = {4*DIM0_1, VDSDIM1, VDSDIM2}, + vdsdims_max[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + dims[3] = {DIM0_1, DIM1, DIM2}, + memdims[3] = {DIM0_1, DIM1, DIM2}, + extdims[3] = {0, DIM1, DIM2}, /* Dimensions of the extended source datasets */ + chunk_dims[3] = {DIM0_1, DIM1, DIM2}, + dims_max[3] = {DIM0, DIM1, DIM2}, + vdsdims_out[3], + vdsdims_max_out[3], + start[3], /* Hyperslab parameters */ + stride[3], + count[3], + src_count[3], + block[3]; + hsize_t start_out[3], /* Hyperslab parameter out */ + stride_out[3], + count_out[3], + block_out[3]; + int i, j; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + int wdata[DIM0_1*DIM1*DIM2]; + + /* + * Create source files and datasets. This step is optional. + */ + for (i=0; i < PLANE_STRIDE; i++) { + /* + * Initialize data for i-th source dataset. + */ + for (j = 0; j < DIM0_1*DIM1*DIM2; j++) wdata[j] = i+1; + + /* + * Create the source files and datasets. Write data to each dataset and + * close all resources. + */ + + file = H5Fcreate (SRC_FILE[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + src_space = H5Screate_simple (RANK, dims, dims_max); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + status = H5Pset_chunk (dcpl, RANK, chunk_dims); + dset = H5Dcreate2 (file, SRC_DATASET[i], H5T_NATIVE_INT, src_space, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Dwrite (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + wdata); + status = H5Sclose (src_space); + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + } + + vfile = H5Fcreate (VFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + vspace = H5Screate_simple (RANK, vdsdims, vdsdims_max); + + /* Create dataspaces for the source dataset. */ + src_space = H5Screate_simple (RANK, dims, dims_max); + + /* Create VDS creation property */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* Initialize hyperslab values */ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + stride[0] = PLANE_STRIDE; /* we will select every fifth plane in VDS */ + stride[1] = 1; + stride[2] = 1; + count[0] = H5S_UNLIMITED; + count[1] = 1; + count[2] = 1; + src_count[0] = H5S_UNLIMITED; + src_count[1] = 1; + src_count[2] = 1; + block[0] = 1; + block[1] = DIM1; + block[2] = DIM2; + + /* + * Build the mappings + * + */ + status = H5Sselect_hyperslab (src_space, H5S_SELECT_SET, start, NULL, src_count, block); + for (i=0; i < PLANE_STRIDE; i++) { + status = H5Sselect_hyperslab (vspace, H5S_SELECT_SET, start, stride, count, block); + status = H5Pset_virtual (dcpl, vspace, SRC_FILE[i], SRC_DATASET[i], src_space); + start[0]++; + } + + H5Sselect_none(vspace); + + /* Create a virtual dataset */ + vdset = H5Dcreate2 (vfile, DATASET, H5T_NATIVE_INT, vspace, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (vspace); + status = H5Sclose (src_space); + status = H5Pclose (dcpl); + + /* Let's add data to the source datasets and check new dimensions for VDS */ + /* We will add only one plane to the first source dataset, two planes to the + second one, three to the third, and four to the forth. */ + + for (i=0; i < PLANE_STRIDE; i++) { + /* + * Initialize data for i-th source dataset. + */ + for (j = 0; j < (i+1)*DIM1*DIM2; j++) wdata[j] = 10*(i+1); + + /* + * Open the source files and datasets. Appen data to each dataset and + * close all resources. + */ + + file = H5Fopen (SRC_FILE[i], H5F_ACC_RDWR, H5P_DEFAULT); + dset = H5Dopen2 (file, SRC_DATASET[i], H5P_DEFAULT); + extdims[0] = DIM0_1+i+1; + status = H5Dset_extent (dset, extdims); + src_space = H5Dget_space (dset); + start[0] = DIM0_1; + start[1] = 0; + start[2] = 0; + count[0] = 1; + count[1] = 1; + count[2] = 1; + block[0] = i+1; + block[1] = DIM1; + block[2] = DIM2; + + memdims[0] = i+1; + mem_space = H5Screate_simple(RANK, memdims, NULL); + status = H5Sselect_hyperslab (src_space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, src_space, H5P_DEFAULT, + wdata); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + } + + status = H5Dclose (vdset); + status = H5Fclose (vfile); + + /* + * Now we begin the read section of this example. + */ + + /* + * Open file and dataset using the default properties. + */ + vfile = H5Fopen (VFILE, H5F_ACC_RDONLY, H5P_DEFAULT); + + /* + * Open VDS using different access properties to use max or + * min extents depending on the sizes of the underlying datasets + */ + dapl = H5Pcreate (H5P_DATASET_ACCESS); + + for(i = 0; i < 2; i++) { + status = H5Pset_virtual_view (dapl, i ? H5D_VDS_LAST_AVAILABLE : H5D_VDS_FIRST_MISSING); + vdset = H5Dopen2 (vfile, DATASET, dapl); + + /* Let's get space of the VDS and its dimension; we should get 32(or 20)x10x10 */ + vspace = H5Dget_space (vdset); + H5Sget_simple_extent_dims (vspace, vdsdims_out, vdsdims_max_out); + printf ("VDS dimensions, bounds = H5D_VDS_%s: ", i ? "LAST_AVAILABLE" : "FIRST_MISSING"); + for (j=0; j<RANK; j++) + printf (" %d ", (int)vdsdims_out[j]); + printf ("\n"); + + /* Close */ + status = H5Dclose (vdset); + status = H5Sclose (vspace); + } + + status = H5Pclose (dapl); + + vdset = H5Dopen2 (vfile, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (vdset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf(" Wrong layout found \n"); + + /* + * Find number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset \n"); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + /* Get source file name */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset */ + printf(" Selection in the source dataset \n"); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + if (H5Sget_select_type(src_space) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(src_space)) { + status = H5Sget_regular_hyperslab (src_space, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (vdset); + status = H5Fclose (vfile); + return 0; +} + diff --git a/examples/h5_vds-percival-unlim.c b/examples/h5_vds-percival-unlim.c new file mode 100644 index 0000000..b5f3ebd --- /dev/null +++ b/examples/h5_vds-percival-unlim.c @@ -0,0 +1,352 @@ +/************************************************************ + + This example illustrates the concept of the virtual dataset. + Percival use case. Every fifth 10x10 plane in VDS is stored in + the corresponding 3D unlimited dataset. + There are 4 source datasets total. + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define VFILE "vds-percival-unlim.h5" +#define DATASET "VDS-Percival-unlim" +#define VDSDIM0 H5S_UNLIMITED +#define VDSDIM1 10 +#define VDSDIM2 10 + +#define DIM0 H5S_UNLIMITED +#define DIM0_1 10 /* Initial size of the datasets */ +#define DIM1 10 +#define DIM2 10 +#define RANK 3 +#define PLANE_STRIDE 4 + +const char *SRC_FILE[] = { + "a.h5", + "b.h5", + "c.h5", + "d.h5" +}; + +const char *SRC_DATASET[] = { + "A", + "B", + "C", + "D" +}; + +int +main (void) +{ + hid_t vfile, file, src_space, mem_space, vspace, + vdset, dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[3] = {4*DIM0_1, VDSDIM1, VDSDIM2}, + vdsdims_max[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + dims[3] = {DIM0_1, DIM1, DIM2}, + extdims[3] = {2*DIM0_1, DIM1, DIM2}, + chunk_dims[3] = {DIM0_1, DIM1, DIM2}, + dims_max[3] = {DIM0, DIM1, DIM2}, + vdsdims_out[3], + vdsdims_max_out[3], + start[3], /* Hyperslab parameters */ + stride[3], + count[3], + src_count[3], + block[3]; + hsize_t start_out[3], /* Hyperslab parameter out */ + stride_out[3], + count_out[3], + block_out[3]; + int i, j, k; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + int wdata[DIM0_1*DIM1*DIM2]; + int rdata[80][10][10]; + int a_rdata[20][10][10]; + + /* + * Create source files and datasets. This step is optional. + */ + for (i=0; i < PLANE_STRIDE; i++) { + /* + * Initialize data for i-th source dataset. + */ + for (j = 0; j < DIM0_1*DIM1*DIM2; j++) wdata[j] = i+1; + + /* + * Create the source files and datasets. Write data to each dataset and + * close all resources. + */ + + file = H5Fcreate (SRC_FILE[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + src_space = H5Screate_simple (RANK, dims, dims_max); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + status = H5Pset_chunk (dcpl, RANK, chunk_dims); + dset = H5Dcreate2 (file, SRC_DATASET[i], H5T_NATIVE_INT, src_space, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Dwrite (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + wdata); + status = H5Sclose (src_space); + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + } + + vfile = H5Fcreate (VFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + vspace = H5Screate_simple (RANK, vdsdims, vdsdims_max); + + /* Create dataspaces for the source dataset. */ + src_space = H5Screate_simple (RANK, dims, dims_max); + + /* Create VDS creation property */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* Initialize hyperslab values */ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + stride[0] = PLANE_STRIDE; /* we will select every fifth plane in VDS */ + stride[1] = 1; + stride[2] = 1; + count[0] = H5S_UNLIMITED; + count[1] = 1; + count[2] = 1; + src_count[0] = H5S_UNLIMITED; + src_count[1] = 1; + src_count[2] = 1; + block[0] = 1; + block[1] = DIM1; + block[2] = DIM2; + + /* + * Build the mappings + * + */ + status = H5Sselect_hyperslab (src_space, H5S_SELECT_SET, start, NULL, src_count, block); + for (i=0; i < PLANE_STRIDE; i++) { + status = H5Sselect_hyperslab (vspace, H5S_SELECT_SET, start, stride, count, block); + status = H5Pset_virtual (dcpl, vspace, SRC_FILE[i], SRC_DATASET[i], src_space); + start[0]++; + } + + H5Sselect_none(vspace); + + /* Create a virtual dataset */ + vdset = H5Dcreate2 (vfile, DATASET, H5T_NATIVE_INT, vspace, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (vspace); + status = H5Sclose (src_space); + status = H5Pclose (dcpl); + /* Let's get space of the VDS and its dimension; we should get 40x10x10 */ + vspace = H5Dget_space (vdset); + H5Sget_simple_extent_dims (vspace, vdsdims_out, vdsdims_max_out); + printf ("VDS dimensions first time \n"); + printf (" Current: "); + for (i=0; i<RANK; i++) + printf (" %d ", (int)vdsdims_out[i]); + printf ("\n"); + + /* Let's add data to the source datasets and check new dimensions for VDS */ + + for (i=0; i < PLANE_STRIDE; i++) { + /* + * Initialize data for i-th source dataset. + */ + for (j = 0; j < DIM0_1*DIM1*DIM2; j++) wdata[j] = 10*(i+1); + + /* + * Create the source files and datasets. Write data to each dataset and + * close all resources. + */ + + file = H5Fopen (SRC_FILE[i], H5F_ACC_RDWR, H5P_DEFAULT); + dset = H5Dopen2 (file, SRC_DATASET[i], H5P_DEFAULT); + status = H5Dset_extent (dset, extdims); + src_space = H5Dget_space (dset); + start[0] = DIM0_1; + start[1] = 0; + start[2] = 0; + count[0] = 1; + count[1] = 1; + count[2] = 1; + block[0] = DIM0_1; + block[1] = DIM1; + block[2] = DIM2; + + mem_space = H5Screate_simple(RANK, dims, NULL); + status = H5Sselect_hyperslab (src_space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, src_space, H5P_DEFAULT, + wdata); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + } + + status = H5Dclose (vdset); + status = H5Fclose (vfile); + + /* + * Now we begin the read section of this example. + */ + + /* + * Open file and dataset using the default properties. + */ + vfile = H5Fopen (VFILE, H5F_ACC_RDONLY, H5P_DEFAULT); + vdset = H5Dopen2 (vfile, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (vdset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf(" Wrong layout found \n"); + + /* + * Find number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset \n"); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + /* Get source file name */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset */ + printf(" Selection in the source dataset \n"); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + if (H5Sget_select_type(src_space) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(src_space)) { + status = H5Sget_regular_hyperslab (src_space, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } + /* + * Read data from VDS. + */ + vspace = H5Dget_space (vdset); + H5Sget_simple_extent_dims (vspace, vdsdims_out, vdsdims_max_out); + printf ("VDS dimensions second time \n"); + printf (" Current: "); + for (i=0; i<RANK; i++) + printf (" %d ", (int)vdsdims_out[i]); + printf ("\n"); + + /* Read all VDS data */ + + //EIP We should be able to do it by using H5S_ALL instead of making selection + // or using H5Sselect_all from vspace. + start[0] = 0; + start[1] = 0; + start[2] = 0; + count[0] = 1; + count[1] = 1; + count[2] = 1; + block[0] = vdsdims_out[0]; + block[1] = vdsdims_out[1]; + block[2] = vdsdims_out[2]; + + status = H5Sselect_hyperslab (vspace, H5S_SELECT_SET, start, NULL, count, block); + mem_space = H5Screate_simple(RANK, vdsdims_out, NULL); + status = H5Dread (vdset, H5T_NATIVE_INT, mem_space, vspace, H5P_DEFAULT, + rdata); + printf (" All data: \n"); + for (i=0; i < (int)vdsdims_out[0]; i++) { + for (j=0; j < (int)vdsdims_out[1]; j++) { + printf ("(%d, %d, 0)", i, j); + for (k=0; k < (int)vdsdims_out[2]; k++) + printf (" %d ", rdata[i][j][k]); + printf ("\n"); + } + } + /* Read VDS, but only data mapeed to dataset a.h5 */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + stride[0] = PLANE_STRIDE; + stride[1] = 1; + stride[2] = 1; + count[0] = 2*DIM0_1; + count[1] = 1; + count[2] = 1; + block[0] = 1; + block[1] = vdsdims_out[1]; + block[2] = vdsdims_out[2]; + dims[0] = 2*DIM0_1; + status = H5Sselect_hyperslab (vspace, H5S_SELECT_SET, start, stride, count, block); + mem_space = H5Screate_simple(RANK, dims, NULL); + status = H5Dread (vdset, H5T_NATIVE_INT, mem_space, vspace, H5P_DEFAULT, + a_rdata); + printf (" All data: \n"); + for (i=0; i < 2*DIM0_1; i++) { + for (j=0; j < (int)vdsdims_out[1]; j++) { + printf ("(%d, %d, 0)", i, j); + for (k=0; k < (int)vdsdims_out[2]; k++) + printf (" %d ", a_rdata[i][j][k]); + printf ("\n"); + } + } + /* + * Close and release resources. + */ + status = H5Sclose(mem_space); + status = H5Pclose (dcpl); + status = H5Dclose (vdset); + status = H5Fclose (vfile); + return 0; +} + diff --git a/examples/h5_vds-percival.c b/examples/h5_vds-percival.c new file mode 100644 index 0000000..757bb69 --- /dev/null +++ b/examples/h5_vds-percival.c @@ -0,0 +1,242 @@ +/************************************************************ + + This example illustrates the concept of the virtual dataset. + Percival use case. Every fifth 10x10 plane in VDS is stored in + the corresponding 3D unlimited dataset. + EIP: For now we will use finite dimension. + There are 4 source datasets total. + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "vds-percival.h5" +#define DATASET "VDS-Percival" +/* later +#define VDSDIM0 H5S_UNLIMITED +*/ +#define VDSDIM0 40 +#define VDSDIM1 10 +#define VDSDIM2 10 +/* later +#define DIM0 H5S_UNLIMITED +*/ +#define DIM0 10 +#define DIM1 10 +#define DIM2 10 +#define RANK 3 +#define PLANE_STRIDE 4 + +const char *SRC_FILE[] = { + "a.h5", + "b.h5", + "c.h5", + "d.h5" +}; + +const char *SRC_DATASET[] = { + "A", + "B", + "C", + "D" +}; + +int +main (void) +{ + hid_t file, src_space, vspace, + dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + vdsdims_max[3] = {VDSDIM0, VDSDIM1, VDSDIM2}, + dims[3] = {DIM0, DIM1, DIM2}, + dims_max[3] = {DIM0, DIM1, DIM2}, + start[3], /* Hyperslab start parameter for VDS */ + stride[3], + count[3], + src_count[3], + block[3]; + hsize_t start_out[3], /* Hyperslab parameter out */ + stride_out[3], + count_out[3], + block_out[3]; + int i, j; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + int wdata[DIM0*DIM1*DIM2]; + + /* + * Create source files and datasets. This step is optional. + */ + for (i=0; i < PLANE_STRIDE; i++) { + /* + * Initialize data for i-th source dataset. + */ + for (j = 0; j < DIM0*DIM1*DIM2; j++) wdata[j] = i+1; + + /* + * Create the source files and datasets. Write data to each dataset and + * close all resources. + */ + + file = H5Fcreate (SRC_FILE[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + src_space = H5Screate_simple (RANK, dims, NULL); + dset = H5Dcreate2 (file, SRC_DATASET[i], H5T_NATIVE_INT, src_space, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + status = H5Dwrite (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + wdata); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + } + + file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + vspace = H5Screate_simple (RANK, vdsdims, vdsdims_max); + + /* Create dataspaces for the source dataset. */ + src_space = H5Screate_simple (RANK, dims, dims_max); + + /* Create VDS creation property */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* Initialize hyperslab values */ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + stride[0] = PLANE_STRIDE; /* we will select every fifth plane in VDS */ + stride[1] = 1; + stride[2] = 1; +/* later + count[0] = H5S_UNLIMITED; +*/ + count[0] = VDSDIM0/4; + count[1] = 1; + count[2] = 1; +/* later + src_count[0] = H5S_UNLIMITED; +*/ + src_count[0] = DIM0; + src_count[1] = 1; + src_count[2] = 1; + block[0] = 1; + block[1] = DIM1; + block[2] = DIM2; + + /* + * Build the mappings + * + */ + status = H5Sselect_hyperslab (src_space, H5S_SELECT_SET, start, NULL, src_count, block); + for (i=0; i < PLANE_STRIDE; i++) { + status = H5Sselect_hyperslab (vspace, H5S_SELECT_SET, start, stride, count, block); + status = H5Pset_virtual (dcpl, vspace, SRC_FILE[i], SRC_DATASET[i], src_space); + start[0]++; + } + + H5Sselect_none(vspace); + + /* Create a virtual dataset */ + dset = H5Dcreate2 (file, DATASET, H5T_NATIVE_INT, vspace, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (vspace); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + + /* + * Now we begin the read section of this example. + */ + + /* + * Open file and dataset using the default properties. + */ + file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen2 (file, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (dset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf(" Wrong layout found \n"); + + /* + * Find number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset \n"); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + /* Get source file name */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset */ + printf(" Selection in the source dataset \n"); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + if (H5Sget_select_type(src_space) == H5S_SEL_HYPERSLABS) { + if (H5Sis_regular_hyperslab(src_space)) { + status = H5Sget_regular_hyperslab (src_space, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1], (unsigned long long)start_out[2]); + printf(" stride = [%llu, %llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1], (unsigned long long)stride_out[2]); + printf(" count = [%llu, %llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1], (unsigned long long)count_out[2]); + printf(" block = [%llu, %llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1], (unsigned long long)block_out[2]); + } + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + return 0; +} + diff --git a/examples/h5_vds-simpleIO.c b/examples/h5_vds-simpleIO.c new file mode 100644 index 0000000..b707ae4 --- /dev/null +++ b/examples/h5_vds-simpleIO.c @@ -0,0 +1,184 @@ +/************************************************************ + + This example illustrates the concept of virtual dataset I/O + The program creates 2-dim source dataset and writes + data to it. Then it creates 2-dim virtual dataset that has + the same dimesnion sizes and maps the all elements of the + virtual dataset to all elements of the source dataset. + Then VDS is read back. + + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "vds-simpleIO.h5" +#define DATASET "VDS" +#define DIM1 6 +#define DIM0 4 +#define RANK 2 + +#define SRC_FILE "a.h5" +#define SRC_DATASET "/A" + + +int +main (void) +{ + hid_t file, space, src_space, vspace, dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[2] = {DIM0, DIM1}, /* Virtual dataset dimension */ + dims[2] = {DIM0, DIM1}; /* Source dataset dimensions */ + int wdata[DIM0][DIM1], /* Write buffer for source dataset */ + rdata[DIM0][DIM1], /* Read buffer for virtual dataset */ + i, j; + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + /* + * Initialize data. + */ + for (i = 0; i < DIM0; i++) + for (j = 0; j < DIM1; j++) wdata[i][j] = i+1; + + /* + * Create the source file and the dataset. Write data to the source dataset + * and close all resources. + */ + + file = H5Fcreate (SRC_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + space = H5Screate_simple (RANK, dims, NULL); + dset = H5Dcreate2 (file, SRC_DATASET, H5T_NATIVE_INT, space, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + status = H5Dwrite (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + wdata[0]); + status = H5Sclose (space); + status = H5Dclose (dset); + status = H5Fclose (file); + + /* Create file in which virtual dataset will be stored. */ + file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + vspace = H5Screate_simple (RANK, vdsdims, NULL); + + /* Set VDS creation property. */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + + /* + * Build the mappings. + * Selections in the source datasets are H5S_ALL. + * In the virtual dataset we select the first, the second and the third rows + * and map each row to the data in the corresponding source dataset. + */ + src_space = H5Screate_simple (RANK, dims, NULL); + status = H5Pset_virtual (dcpl, vspace, SRC_FILE, SRC_DATASET, src_space); + + /* Create a virtual dataset. */ + dset = H5Dcreate2 (file, DATASET, H5T_NATIVE_INT, vspace, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (vspace); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + + /* + * Now we begin the read section of this example. + */ + + /* + * Open the file and virtual dataset. + */ + file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen2 (file, DATASET, H5P_DEFAULT); + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (dset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf(" Wrong layout found \n"); + + /* + * Find the number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset "); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + + /* Make sure it is ALL selection and then print selection. */ + if(H5Sget_select_type(vspace) == H5S_SEL_ALL) { + printf("Selection is H5S_ALL \n"); + } + /* Get source file name. */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name. */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset. */ + printf(" Selection in the source dataset "); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + + /* Make sure it is ALL selection and then print selection. */ + if(H5Sget_select_type(src_space) == H5S_SEL_ALL) { + printf("Selection is H5S_ALL \n"); + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + } + /* + * Read the data using the default properties. + */ + status = H5Dread (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + rdata[0]); + + /* + * Output the data to the screen. + */ + printf (" VDS Data:\n"); + for (i=0; i<DIM0; i++) { + printf (" ["); + for (j=0; j<DIM1; j++) + printf (" %3d", rdata[i][j]); + printf ("]\n"); + } + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + + return 0; +} + diff --git a/examples/h5_vds.c b/examples/h5_vds.c new file mode 100644 index 0000000..1e502c6 --- /dev/null +++ b/examples/h5_vds.c @@ -0,0 +1,267 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/************************************************************ + + This example illustrates the concept of virtual dataset. + The program creates three 1-dim source datasets and writes + data to them. Then it creates a 2-dim virtual dataset and + maps the first three rows of the virtual dataset to the data + in the source datasets. Elements of a row are mapped to all + elements of the corresponding source dataset. + The fourth row is not mapped and will be filled with the fill + values when virtual dataset is read back. + + The program closes all datasets, and then reopens the virtual + dataset, and finds and prints its creation properties. + Then it reads the values. + + This file is intended for use with HDF5 Library version 1.10 + + ************************************************************/ +/* EIP Add link to the picture */ + +#include "hdf5.h" +#include <stdio.h> +#include <stdlib.h> + +#define FILE "vds.h5" +#define DATASET "VDS" +#define VDSDIM1 6 +#define VDSDIM0 4 +#define DIM0 6 +#define RANK1 1 +#define RANK2 2 + +const char *SRC_FILE[] = { + "a.h5", + "b.h5", + "c.h5" +}; + +const char *SRC_DATASET[] = { + "A", + "B", + "C" +}; + +int +main (void) +{ + hid_t file, space, src_space, vspace, dset; /* Handles */ + hid_t dcpl; + herr_t status; + hsize_t vdsdims[2] = {VDSDIM0, VDSDIM1}, /* Virtual datasets dimension */ + dims[1] = {DIM0}, /* Source datasets dimensions */ + start[2], /* Hyperslab parameters */ + stride[2], + count[2], + block[2]; + hsize_t start_out[2], + stride_out[2], + count_out[2], + block_out[2]; + int wdata[DIM0], /* Write buffer for source dataset */ + rdata[VDSDIM0][VDSDIM1], /* Read buffer for virtual dataset */ + i, j, k, l; + int fill_value = -1; /* Fill value for VDS */ + H5D_layout_t layout; /* Storage layout */ + size_t num_map; /* Number of mappings */ + ssize_t len; /* Length of the string; also a return value */ + char *filename; + char *dsetname; + hsize_t nblocks; + hsize_t *buf; /* Buffer to hold hyperslab coordinates */ + + /* + * Create source files and datasets. This step is optional. + */ + for (i=0; i < 3; i++) { + /* + * Initialize data for i-th source dataset. + */ + for (j = 0; j < DIM0; j++) wdata[j] = i+1; + + /* + * Create the source files and datasets. Write data to each dataset and + * close all resources. + */ + + file = H5Fcreate (SRC_FILE[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + space = H5Screate_simple (RANK1, dims, NULL); + dset = H5Dcreate2 (file, SRC_DATASET[i], H5T_NATIVE_INT, space, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + status = H5Dwrite (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + wdata); + status = H5Sclose (space); + status = H5Dclose (dset); + status = H5Fclose (file); + } + + /* Create file in which virtual dataset will be stored. */ + file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Create VDS dataspace. */ + space = H5Screate_simple (RANK2, vdsdims, NULL); + + /* Set VDS creation property. */ + dcpl = H5Pcreate (H5P_DATASET_CREATE); + status = H5Pset_fill_value (dcpl, H5T_NATIVE_INT, &fill_value); + + /* Initialize hyperslab values. */ + start[0] = 0; + start[1] = 0; + count[0] = 1; + count[1] = 1; + block[0] = 1; + block[1] = VDSDIM1; + + /* + * Build the mappings. + * Selections in the source datasets are H5S_ALL. + * In the virtual dataset we select the first, the second and the third rows + * and map each row to the data in the corresponding source dataset. + */ + src_space = H5Screate_simple (RANK1, dims, NULL); + for (i = 0; i < 3; i++) { + start[0] = (hsize_t)i; + /* Select i-th row in the virtual dataset; selection in the source datasets is the same. */ + status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, NULL, count, block); + status = H5Pset_virtual (dcpl, space, SRC_FILE[i], SRC_DATASET[i], src_space); + } + + /* Create a virtual dataset. */ + dset = H5Dcreate2 (file, DATASET, H5T_NATIVE_INT, space, H5P_DEFAULT, + dcpl, H5P_DEFAULT); + status = H5Sclose (space); + status = H5Sclose (src_space); + status = H5Dclose (dset); + status = H5Fclose (file); + + /* + * Now we begin the read section of this example. + */ + + /* + * Open the file and virtual dataset. + */ + file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + dset = H5Dopen2 (file, DATASET, H5P_DEFAULT); + + /* + * Get creation property list and mapping properties. + */ + dcpl = H5Dget_create_plist (dset); + + /* + * Get storage layout. + */ + layout = H5Pget_layout (dcpl); + if (H5D_VIRTUAL == layout) + printf(" Dataset has a virtual layout \n"); + else + printf(" Wrong layout found \n"); + + /* + * Find the number of mappings. + */ + status = H5Pget_virtual_count (dcpl, &num_map); + printf(" Number of mappings is %lu\n", (unsigned long)num_map); + + /* + * Get mapping parameters for each mapping. + */ + for (i = 0; i < (int)num_map; i++) { + printf(" Mapping %d \n", i); + printf(" Selection in the virtual dataset "); + /* Get selection in the virttual dataset */ + vspace = H5Pget_virtual_vspace (dcpl, (size_t)i); + + /* Make sure that this is a hyperslab selection and then print information. */ + if (H5Sget_select_type(vspace) == H5S_SEL_HYPERSLABS) { + nblocks = H5Sget_select_hyper_nblocks (vspace); + buf = (hsize_t *)malloc(sizeof(hsize_t)*2*RANK2*nblocks); + status = H5Sget_select_hyper_blocklist (vspace, (hsize_t)0, nblocks, buf); + for (l=0; l<nblocks; l++) { + printf("("); + for (k=0; k<RANK2-1; k++) + printf("%d,", (int)buf[k]); + printf("%d ) - (", (int)buf[k]); + for (k=0; k<RANK2-1; k++) + printf("%d,", (int)buf[RANK2+k]); + printf("%d)\n", (int)buf[RANK2+k]); + } + /* We also can use new APIs to get start, stride, count and block */ + if (H5Sis_regular_hyperslab(vspace)) { + status = H5Sget_regular_hyperslab (vspace, start_out, stride_out, count_out, block_out); + printf(" start = [%llu, %llu] \n", (unsigned long long)start_out[0], (unsigned long long)start_out[1]); + printf(" stride = [%llu, %llu] \n", (unsigned long long)stride_out[0], (unsigned long long)stride_out[1]); + printf(" count = [%llu, %llu] \n", (unsigned long long)count_out[0], (unsigned long long)count_out[1]); + printf(" block = [%llu, %llu] \n", (unsigned long long)block_out[0], (unsigned long long)block_out[1]); + } + } + /* Get source file name. */ + len = H5Pget_virtual_filename (dcpl, (size_t)i, NULL, 0); + filename = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_filename (dcpl, (size_t)i, filename, len+1); + printf(" Source filename %s\n", filename); + + /* Get source dataset name. */ + len = H5Pget_virtual_dsetname (dcpl, (size_t)i, NULL, 0); + dsetname = (char *)malloc((size_t)len*sizeof(char)+1); + H5Pget_virtual_dsetname (dcpl, (size_t)i, dsetname, len+1); + printf(" Source dataset name %s\n", dsetname); + + /* Get selection in the source dataset. */ + printf(" Selection in the source dataset "); + src_space = H5Pget_virtual_srcspace (dcpl, (size_t)i); + + /* Make sure it is ALL selection and then print the coordinates. */ + if(H5Sget_select_type(src_space) == H5S_SEL_ALL) { + printf("(0) - (%d) \n", DIM0-1); + } + H5Sclose(vspace); + H5Sclose(src_space); + free(filename); + free(dsetname); + free(buf); + } + + /* + * Read the data using the default properties. + */ + status = H5Dread (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, + rdata[0]); + + /* + * Output the data to the screen. + */ + printf (" VDS Data:\n"); + for (i=0; i<VDSDIM0; i++) { + printf (" ["); + for (j=0; j<VDSDIM1; j++) + printf (" %3d", rdata[i][j]); + printf ("]\n"); + } + /* + * Close and release resources. + */ + status = H5Pclose (dcpl); + status = H5Dclose (dset); + status = H5Fclose (file); + + return 0; +} + diff --git a/examples/run-c-ex.sh.in b/examples/run-c-ex.sh.in index 6b5d0f7..1661344 100644 --- a/examples/run-c-ex.sh.in +++ b/examples/run-c-ex.sh.in @@ -125,7 +125,23 @@ then RunTest h5_elink_unix2win &&\ rm h5_elink_unix2win &&\ RunTest h5_shared_mesg &&\ - rm h5_shared_mesg); then + rm h5_shared_mesg &&\ + RunTest h5_vds-eiger &&\ + rm h5_vds-eiger &&\ + RunTest h5_vds-exclim &&\ + rm h5_vds-exclim &&\ + RunTest h5_vds-exc &&\ + rm h5_vds-exc &&\ + RunTest h5_vds-simpleIO &&\ + rm h5_vds-simpleIO &&\ + RunTest h5_vds-percival &&\ + rm h5_vds-percival &&\ + RunTest h5_vds-percival-unlim &&\ + rm h5_vds-percival-unlim &&\ + RunTest h5_vds-percival-unlim-maxmin&&\ + rm h5_vds-percival-unlim-maxmin &&\ + RunTest h5_vds &&\ + rm h5_vds); then EXIT_VALUE=${EXIT_SUCCESS} else EXIT_VALUE=${EXIT_FAILURE} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6d74939..ef3e760 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -118,6 +118,7 @@ set (H5D_SRCS ${HDF5_SRC_DIR}/H5Dscatgath.c ${HDF5_SRC_DIR}/H5Dselect.c ${HDF5_SRC_DIR}/H5Dtest.c + ${HDF5_SRC_DIR}/H5Dvirtual.c ) set (H5D_HDRS @@ -284,12 +284,12 @@ H5_term_library(void) n) : n)) do { - pending = 0; + pending = 0; /* Try to organize these so the "higher" level components get shut * down before "lower" level components that they might rely on. -QAK */ - pending += DOWN(L); + pending += DOWN(L); /* Close the "top" of various interfaces (IDs, etc) but don't shut * down the whole interface yet, so that the object header messages @@ -300,7 +300,7 @@ H5_term_library(void) pending += DOWN(A_top); pending += DOWN(D_top); pending += DOWN(G_top); - pending += DOWN(R_top); + pending += DOWN(R_top); pending += DOWN(S_top); pending += DOWN(T_top); @@ -308,6 +308,11 @@ H5_term_library(void) if(pending == 0) pending += DOWN(F); + /* Don't shut down the property list code until all objects that might + * use property lists are shut down */ + if(pending == 0) + pending += DOWN(P); + /* Wait to shut down the "bottom" of various interfaces until the * files are closed, so pieces of the file can be serialized * correctly. @@ -333,7 +338,6 @@ H5_term_library(void) if(pending == 0) { pending += DOWN(AC); pending += DOWN(Z); - pending += DOWN(P); pending += DOWN(FD); pending += DOWN(PL); /* Don't shut down the error code until other APIs which use it are shut down */ diff --git a/src/H5Dint.c b/src/H5Dint.c index 01b6dbf..b0e31a6 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1461,6 +1461,10 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id) fill_prop->alloc_time = H5D_ALLOC_TIME_INCR; break; + case H5D_VIRTUAL: + fill_prop->alloc_time = H5D_ALLOC_TIME_INCR; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1475,7 +1479,8 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id) alloc_time_state = 0; if((dataset->shared->layout.type == H5D_COMPACT && fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY) || (dataset->shared->layout.type == H5D_CONTIGUOUS && fill_prop->alloc_time == H5D_ALLOC_TIME_LATE) - || (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR)) + || (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR) + || (dataset->shared->layout.type == H5D_VIRTUAL && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR)) alloc_time_state = 1; /* Set revised fill value properties, if they are different from the defaults */ @@ -1601,6 +1606,34 @@ H5D_close(H5D_t *dataset) /* Nothing special to do (info freed in the layout destroy) */ break; + case H5D_VIRTUAL: + { + size_t i, j; + + HDassert(dataset->shared->layout.storage.u.virt.list || (dataset->shared->layout.storage.u.virt.list_nused == 0)); + + /* Close source datasets */ + for(i = 0; i < dataset->shared->layout.storage.u.virt.list_nused; i++) { + /* Close source dataset */ + if(dataset->shared->layout.storage.u.virt.list[i].source_dset.dset) { + HDassert(dataset->shared->layout.storage.u.virt.list[i].source_dset.dset != dataset); + if(H5D_close(dataset->shared->layout.storage.u.virt.list[i].source_dset.dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset") + dataset->shared->layout.storage.u.virt.list[i].source_dset.dset = NULL; + } /* end if */ + + /* Close sub datasets */ + for(j = 0; j < dataset->shared->layout.storage.u.virt.list[i].sub_dset_nused; j++) + if(dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset) { + HDassert(dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset != dataset); + if(H5D_close(dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset") + dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset = NULL; + } /* end if */ + } /* end for */ + } /* end block */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1857,6 +1890,15 @@ H5D__alloc_storage(const H5D_t *dset, hid_t dxpl_id, H5D_time_alloc_t time_alloc } /* end if */ break; + case H5D_VIRTUAL: + /* No-op, as the raw data is stored elsewhere and the global + * heap object containing the mapping information is created + * when the layout message is encoded. We may wish to move the + * creation of the global heap object here at some point, but we + * will have to make sure is it always created before the + * dataset is closed. */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1976,6 +2018,9 @@ H5D__init_storage(const H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[], break; } /* end block */ + case H5D_VIRTUAL: + /* No-op, as the raw data is stored elsewhere */ + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -2032,6 +2077,12 @@ H5D__get_storage_size(H5D_t *dset, hid_t dxpl_id, hsize_t *storage_size) *storage_size = dset->shared->layout.storage.u.compact.size; break; + case H5D_VIRTUAL: + /* Just set to 0, as virtual datasets do not actually store raw data + */ + *storage_size = 0; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -2068,6 +2119,7 @@ H5D__get_offset(const H5D_t *dset) HDassert(dset); switch(dset->shared->layout.type) { + case H5D_VIRTUAL: case H5D_CHUNKED: case H5D_COMPACT: break; @@ -2307,7 +2359,7 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) { hsize_t curr_dims[H5S_MAX_RANK]; /* Current dimension sizes */ htri_t changed; /* Whether the dataspace changed size */ - size_t u; /* Local index variable */ + size_t u, v; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dxpl_id, dset->oloc.addr, FAIL) @@ -2406,6 +2458,30 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices") } /* end if */ + /* Operations for virtual datasets */ + if(H5D_VIRTUAL == dset->shared->layout.type) { + /* Check that the dimensions of the VDS are large enough */ + if(H5D_virtual_check_min_dims(dset) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual dataset dimensions not large enough to contain all limited dimensions in all selections") + + /* Patch the virtual selection dataspaces */ + for(u = 0; u < dset->shared->layout.storage.u.virt.list_nused; u++) { + /* Patch extent */ + if(H5S_set_extent(dset->shared->layout.storage.u.virt.list[u].source_dset.virtual_select, size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + dset->shared->layout.storage.u.virt.list[u].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT; + + /* Patch sub-source datasets */ + for(v = 0; v < dset->shared->layout.storage.u.virt.list[u].sub_dset_nalloc; v++) + if(H5S_set_extent(dset->shared->layout.storage.u.virt.list[u].sub_dset[v].virtual_select, size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + } /* end for */ + + /* Mark virtual datasets as not fully initialized so internal + * selections are recalculated (at next I/O operation) */ + dset->shared->layout.storage.u.virt.init = FALSE; + } /* end if */ + /* Allocate space for the new parts of the dataset, if appropriate */ if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY) if(H5D__alloc_storage(dset, dxpl_id, H5D_ALLOC_EXTEND, FALSE, curr_dims) < 0) @@ -2731,6 +2807,11 @@ H5D_get_create_plist(H5D_t *dset) copied_layout.storage.u.chunk.ops = NULL; break; + case H5D_VIRTUAL: + copied_layout.storage.u.virt.serial_list_hobjid.addr = HADDR_UNDEF; + copied_layout.storage.u.virt.serial_list_hobjid.idx = 0; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -2913,6 +2994,11 @@ H5D_get_space(H5D_t *dset) FUNC_ENTER_NOAPI_NOINIT + /* If the layout is virtual, update the extent */ + if(dset->shared->layout.type == H5D_VIRTUAL) + if(H5D__virtual_set_extent_unlim(dset, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update virtual dataset extent") + /* Read the data space message and return a data space object */ if(NULL == (space = H5S_copy(dset->shared->space, FALSE, TRUE))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space") diff --git a/src/H5Dio.c b/src/H5Dio.c index d85632a..c0aa83e 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -52,9 +52,6 @@ /********************/ /* Internal I/O routines */ -static herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, - const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, - const void *buf); static herr_t H5D__pre_write(H5D_t *dset, hbool_t direct_write, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, const void *buf); @@ -581,7 +578,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, const void *buf) { @@ -614,7 +611,7 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, char fake_char; /* Temporary variable for NULL buffer pointers */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_TAG(dxpl_id, dataset->oloc.addr, FAIL) + FUNC_ENTER_PACKAGE_TAG(dxpl_id, dataset->oloc.addr, FAIL) /* check args */ HDassert(dataset && dataset->oloc.file); diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index c2d547f..ae478b2 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -104,6 +104,10 @@ H5D__layout_set_io_ops(const H5D_t *dataset) dataset->shared->layout.ops = H5D_LOPS_COMPACT; break; + case H5D_VIRTUAL: + dataset->shared->layout.ops = H5D_LOPS_VIRTUAL; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -169,6 +173,11 @@ H5D__layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t includ ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */ break; + case H5D_VIRTUAL: + ret_value += H5F_SIZEOF_ADDR(f); /* Address of global heap */ + ret_value += 4; /* Global heap index */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Doh.c b/src/H5Doh.c index 057c904..f8a733d 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -398,6 +398,17 @@ H5O__dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) if(H5D__chunk_bh_info(f, dxpl_id, &layout, &pline, &(bh_info->index_size)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine chunked dataset btree info") } /* end if */ + else if(layout.type == H5D_VIRTUAL + && (layout.storage.u.virt.serial_list_hobjid.addr != HADDR_UNDEF)) { + size_t virtual_heap_size; + + /* Get size of global heap object for virtual dataset */ + if(H5HG_get_obj_size(f, dxpl_id, &(layout.storage.u.virt.serial_list_hobjid), &virtual_heap_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get global heap size for virtual dataset mapping") + + /* Return heap size */ + bh_info->heap_size = (hsize_t)virtual_heap_size; + } /* end if */ /* Check for External File List message in the object header */ if((exists = H5O_msg_exists_oh(oh, H5O_EFL_ID)) < 0) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 801800c..552c61b 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -522,6 +522,7 @@ H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CONTIG[1]; H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_EFL[1]; H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_COMPACT[1]; H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1]; +H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1]; /* Chunked layout operations */ H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BTREE[1]; @@ -558,6 +559,9 @@ H5_DLL herr_t H5D__flush_real(H5D_t *dataset, hid_t dxpl_id); H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, void *buf/*out*/); +H5_DLL herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, + const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, + const void *buf); /* Functions that perform direct serial I/O operations */ H5_DLL herr_t H5D__select_read(const H5D_io_info_t *io_info, @@ -649,6 +653,17 @@ H5_DLL herr_t H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src H5F_t *f_dst, H5O_storage_compact_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); +/* Functions that operate on virtual dataset storage */ +H5_DLL herr_t H5D__virtual_copy_layout(H5O_layout_t *layout); +H5_DLL herr_t H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id); +H5_DLL herr_t H5D__virtual_reset_layout(H5O_layout_t *layout); +H5_DLL herr_t H5D__virtual_delete(H5F_t *f, hid_t dxpl_id, H5O_storage_t *storage); +H5_DLL herr_t H5D__virtual_copy(H5F_t *f_src, H5O_layout_t *layout_dst, + hid_t dxpl_id); +H5_DLL herr_t H5D__virtual_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, + hid_t dapl_id); +H5_DLL hbool_t H5D__virtual_is_space_alloc(const H5O_storage_t *storage); + /* Functions that operate on EFL (External File List)*/ H5_DLL hbool_t H5D__efl_is_space_alloc(const H5O_storage_t *storage); H5_DLL herr_t H5D__efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 55e5b47..3b43aaf 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -52,6 +52,8 @@ #define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */ #define H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */ #define H5D_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */ +#define H5D_ACS_VDS_VIEW_NAME "vds_view" /* VDS view option */ +#define H5D_ACS_VDS_PRINTF_GAP_NAME "vds_printf_gap" /* VDS printf gap size */ /* ======== Data transfer properties ======== */ #define H5D_XFER_MAX_TEMP_BUF_NAME "max_temp_buf" /* Maximum temp buffer size */ @@ -106,6 +108,9 @@ #define H5D_VLEN_FREE NULL #define H5D_VLEN_FREE_INFO NULL +/* Default virtual dataset list size */ +#define H5D_VIRTUAL_DEF_LIST_SIZE 8 + /****************************/ /* Library Private Typedefs */ @@ -174,6 +179,18 @@ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, /* Functions that operate on chunked storage */ H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr); +/* Functions that operate on virtual storage */ +H5_DLL herr_t H5D_virtual_check_mapping_pre(const H5S_t *vspace, + const H5S_t *src_space, H5O_virtual_space_status_t space_status); +H5_DLL herr_t H5D_virtual_check_mapping_post( + const H5O_storage_virtual_ent_t *ent); +H5_DLL herr_t H5D_virtual_check_min_dims(const H5D_t *dset); +H5_DLL herr_t H5D_virtual_update_min_dims(H5O_layout_t *layout, size_t idx); +H5_DLL herr_t H5D_virtual_parse_source_name(const char *source_name, + H5O_storage_virtual_name_seg_t **parsed_name, size_t *static_strlen, + size_t *nsubs); +H5_DLL herr_t H5D_virtual_free_parsed_name(H5O_storage_virtual_name_seg_t *name_seg); + /* Functions that operate on indexed storage */ H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth, unsigned ndims, const uint32_t *dim); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 1b5fed7..a1f87e3 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -51,7 +51,8 @@ typedef enum H5D_layout_t { H5D_COMPACT = 0, /*raw data is very small */ H5D_CONTIGUOUS = 1, /*the default */ H5D_CHUNKED = 2, /*slow and fancy */ - H5D_NLAYOUTS = 3 /*this one must be last! */ + H5D_VIRTUAL = 3, /*actual data is stored in other datasets */ + H5D_NLAYOUTS = 4 /*this one must be last! */ } H5D_layout_t; /* Types of chunk index data structures */ @@ -93,6 +94,13 @@ typedef enum H5D_fill_value_t { H5D_FILL_VALUE_USER_DEFINED =2 } H5D_fill_value_t; +/* Values for VDS bounds option */ +typedef enum H5D_vds_view_t { + H5D_VDS_ERROR = -1, + H5D_VDS_FIRST_MISSING = 0, + H5D_VDS_LAST_AVAILABLE = 1 +} H5D_vds_view_t; + /********************/ /* Public Variables */ /********************/ diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c new file mode 100644 index 0000000..cbd9e35 --- /dev/null +++ b/src/H5Dvirtual.c @@ -0,0 +1,2735 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Neil Fortner <nfortne2@hdfgroup.org> + * Wednesday, January 28, 2015 + * + * Purpose: + * Virtual Dataset (VDS) functions. Creates a layout type which allows + * definition of a virtual dataset, where the actual dataset is stored in + * other datasets (called source datasets). The mappings between the + * virtual and source datasets are specified by hyperslab or "all" + * dataspace selections. Point selections are not currently supported. + * Overlaps in the mappings in the virtual dataset result in undefined + * behaviour. + * + * Mapping selections may be unlimited, in which case the size of the + * virtual dataset is determined by the size of the source dataset(s). + * Names for the source datasets may also be generated procedurally, in + * which case the virtual selection should be unlimited with an unlimited + * count and the source selection should be limited with a size equal to + * that of the virtual selection with the unlimited count set to 1. + * + * Source datasets are opened lazily (only when needed for I/O or to + * determine the size of the virtual dataset), and are currently held open + * until the virtual dataset is closed. + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5Dmodule.h" /* This source code file is part of the H5D module */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Dpkg.h" /* Dataset functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* Files */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Gprivate.h" /* Groups */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5Sprivate.h" /* Dataspaces */ + + +/****************/ +/* Local Macros */ +/****************/ + +/* Default size for sub_dset array */ +#define H5D_VIRTUAL_DEF_SUB_DSET_SIZE 128 + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Layout operation callbacks */ +static herr_t H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t + *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, + H5D_chunk_map_t *fm); +static herr_t H5D__virtual_write(H5D_io_info_t *io_info, + const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, + const H5S_t *mem_space, H5D_chunk_map_t *fm); +static herr_t H5D__virtual_flush(H5D_t *dset, hid_t dxpl_id); + +/* Other functions */ +static herr_t H5D__virtual_open_source_dset(const H5D_t *vdset, + H5O_storage_virtual_ent_t *virtual_ent, + H5O_storage_virtual_srcdset_t *source_dset, hid_t dxpl_id); +static herr_t H5D__virtual_reset_source_dset( + H5O_storage_virtual_ent_t *virtual_ent, + H5O_storage_virtual_srcdset_t *source_dset); +static herr_t H5D__virtual_str_append(const char *src, size_t src_len, char **p, + char **buf, size_t *buf_size); +static herr_t H5D__virtual_copy_parsed_name( + H5O_storage_virtual_name_seg_t **dst, H5O_storage_virtual_name_seg_t *src); +static herr_t H5D__virtual_build_source_name(char *source_name, + const H5O_storage_virtual_name_seg_t *parsed_name, size_t static_strlen, + size_t nsubs, hsize_t blockno, char **built_name); +static herr_t H5D__virtual_init_all(const H5D_t *dset, hid_t dxpl_id); +static herr_t H5D__virtual_pre_io(H5D_io_info_t *io_info, + H5O_storage_virtual_t *storage, const H5S_t *file_space, + const H5S_t *mem_space, hsize_t *tot_nelmts); +static herr_t H5D__virtual_post_io(H5O_storage_virtual_t *storage); +static herr_t H5D__virtual_read_one(H5D_io_info_t *io_info, + const H5D_type_info_t *type_info, const H5S_t *file_space, + H5O_storage_virtual_srcdset_t *source_dset); +static herr_t H5D__virtual_write_one(H5D_io_info_t *io_info, + const H5D_type_info_t *type_info, const H5S_t *file_space, + H5O_storage_virtual_srcdset_t *source_dset); + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Contiguous storage layout I/O ops */ +const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{ + NULL, + H5D__virtual_init, + H5D__virtual_is_space_alloc, + NULL, + H5D__virtual_read, + H5D__virtual_write, +#ifdef H5_HAVE_PARALLEL + NULL, + NULL, +#endif /* H5_HAVE_PARALLEL */ + NULL, + NULL, + H5D__virtual_flush, + NULL +}}; + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5O_storage_virtual_name_seg_t struct */ +H5FL_DEFINE(H5O_storage_virtual_name_seg_t); + + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_check_mapping_pre + * + * Purpose: Checks that the provided virtual and source selections are + * legal for use as a VDS mapping, prior to creating the rest + * of the mapping entry. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * August 12, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_check_mapping_pre(const H5S_t *vspace, const H5S_t *src_space, + H5O_virtual_space_status_t space_status) +{ + H5S_sel_type select_type; /* Selection type */ + hsize_t nelmts_vs; /* Number of elements in virtual selection */ + hsize_t nelmts_ss; /* Number of elements in source selection */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check for point selections (currently unsupported) */ + if(H5S_SEL_ERROR == (select_type = H5S_GET_SELECT_TYPE(vspace))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get selection type") + if(select_type == H5S_SEL_POINTS) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "point selections not currently supported with virtual datasets") + if(H5S_SEL_ERROR == (select_type = H5S_GET_SELECT_TYPE(src_space))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get selection type") + if(select_type == H5S_SEL_POINTS) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "point selections not currently supported with virtual datasets") + + /* Get number of elements in spaces */ + nelmts_vs = (hsize_t)H5S_GET_SELECT_NPOINTS(vspace); + nelmts_ss = (hsize_t)H5S_GET_SELECT_NPOINTS(src_space); + + /* Check for unlimited vspace */ + if(nelmts_vs == H5S_UNLIMITED) { + /* Check for unlimited src_space */ + if(nelmts_ss == H5S_UNLIMITED) { + hsize_t nenu_vs; /* Number of elements in the non-unlimited dimensions of vspace */ + hsize_t nenu_ss; /* Number of elements in the non-unlimited dimensions of src_space */ + + /* Non-printf unlimited selection. Make sure both selections have + * the same number of elements in the non-unlimited dimension. Note + * we can always check this even if the space status is invalid + * because unlimited selections are never dependent on the extent. + */ + if(H5S_get_select_num_elem_non_unlim(vspace, &nenu_vs) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension") + if(H5S_get_select_num_elem_non_unlim(src_space, &nenu_ss) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension") + if(nenu_vs != nenu_ss) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "numbers of elemnts in the non-unlimited dimensions is different for source and virtual spaces") + } /* end if */ + /* We will handle the printf case after parsing the source names */ + } /* end if */ + else if(space_status != H5O_VIRTUAL_STATUS_INVALID) + /* Limited selections. Check number of points is the same. */ + if(nelmts_vs != nelmts_ss) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual and source space selections have different numbers of elements") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_check_mapping_pre() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_check_mapping_post + * + * Purpose: Checks that the provided virtual dataset mapping entry is + * legal, after the mapping is otherwise complete. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * August 12, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_check_mapping_post(const H5O_storage_virtual_ent_t *ent) +{ + hsize_t nelmts_vs; /* Number of elements in virtual selection */ + hsize_t nelmts_ss; /* Number of elements in source selection */ + H5S_t *tmp_space = NULL; /* Temporary dataspace */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Get number of elements in spaces */ + nelmts_vs = (hsize_t)H5S_GET_SELECT_NPOINTS(ent->source_dset.virtual_select); + nelmts_ss = (hsize_t)H5S_GET_SELECT_NPOINTS(ent->source_select); + + /* Check for printf selection */ + if((nelmts_vs == H5S_UNLIMITED) && (nelmts_ss != H5S_UNLIMITED)) { + /* Make sure there at least one %b substitution in the source file or + * dataset name */ + if((ent->psfn_nsubs == 0) && (ent->psdn_nsubs == 0)) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unlimited virtual selection, limited source selection, and no printf specifiers in source names") + + /* Make sure virtual space uses hyperslab selection */ + if(H5S_GET_SELECT_TYPE(ent->source_dset.virtual_select) != H5S_SEL_HYPERSLABS) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "virtual selection with printf mapping must be hyperslab") + + /* Check that the number of elements in one block in the virtual + * selection matches the total number of elements in the source + * selection, if the source space status is not invalid (virtual space + * status does not matter here because it is unlimited) */ + if(ent->source_space_status != H5O_VIRTUAL_STATUS_INVALID) { + /* Get first block in virtual selection */ + if(NULL == (tmp_space = H5S_hyper_get_unlim_block(ent->source_dset.virtual_select, (hsize_t)0))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get first block in virtual selection") + + /* Check number of points */ + nelmts_vs = (hsize_t)H5S_GET_SELECT_NPOINTS(tmp_space); + if(nelmts_vs != nelmts_ss) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual (single block) and source space selections have different numbers of elements") + } /* end if */ + } /* end if */ + else + /* Make sure there are no printf substitutions */ + if((ent->psfn_nsubs > 0) || (ent->psdn_nsubs > 0)) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "printf specifier(s) in source name(s) without an unlimited virtual selection and limited source selection") + +done: + /* Free temporary space */ + if(tmp_space) + if(H5S_close(tmp_space) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "can't close dataspace") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_check_mapping_post() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_update_min_dims + * + * Purpose: Updates the virtual layout's "min_dims" field to take into + * account the "idx"th entry in the mapping list. The entry + * must be complete, though top level field list_nused (and + * of course min_dims) does not need to take it into account. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 10, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_update_min_dims(H5O_layout_t *layout, size_t idx) +{ + H5S_sel_type sel_type; + int rank; + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + int i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(layout); + HDassert(layout->type == H5D_VIRTUAL); + HDassert(idx < layout->storage.u.virt.list_nalloc); + + /* Get type of selection */ + if(H5S_SEL_ERROR == (sel_type = H5S_GET_SELECT_TYPE(layout->storage.u.virt.list[idx].source_dset.virtual_select))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection type") + + /* Do not update min_dims for "all" or "none" selections */ + if((sel_type == H5S_SEL_ALL) || (sel_type == H5S_SEL_NONE)) + HGOTO_DONE(SUCCEED) + + /* Get rank of vspace */ + if((rank = H5S_GET_EXTENT_NDIMS(layout->storage.u.virt.list[idx].source_dset.virtual_select)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions") + + /* Get selection bounds */ + if(H5S_SELECT_BOUNDS(layout->storage.u.virt.list[idx].source_dset.virtual_select, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds") + + /* Update min_dims */ + for(i = 0; i < rank; i++) + /* Don't check unlimited dimensions in the selection */ + if((i != layout->storage.u.virt.list[idx].unlim_dim_virtual) + && (bounds_end[i] >= layout->storage.u.virt.min_dims[i])) + layout->storage.u.virt.min_dims[i] = bounds_end[i] + (hsize_t)1; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_update_min_dims() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_check_min_dims + * + * Purpose: Checks if the dataset's dimensions are at least the + * calculated minimum dimensions from the mappings. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * August 13, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_check_min_dims(const H5D_t *dset) +{ + int rank; + hsize_t dims[H5S_MAX_RANK]; + int i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(dset); + HDassert(dset->shared); + HDassert(dset->shared->layout.type == H5D_VIRTUAL); + + /* Get rank of dataspace */ + if((rank = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions") + + /* Get VDS dimensions */ + if(H5S_get_simple_extent_dims(dset->shared->space, dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions") + + /* Verify that dimensions are larger than min_dims */ + for(i = 0; i < rank; i++) + if(dims[i] < dset->shared->layout.storage.u.virt.min_dims[i]) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual dataset dimensions not large enough to contain all limited dimensions in all selections") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_check_min_dims() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_copy_layout + * + * Purpose: Deep copies virtual storage layout message in memory. + * This function assumes that the top-level struct has + * already been copied (so the source struct retains + * ownership of the fields passed to this function). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 10, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_copy_layout(H5O_layout_t *layout) +{ + H5O_storage_virtual_ent_t *orig_list = NULL; + hid_t orig_source_fapl; + hid_t orig_source_dapl; + H5P_genplist_t *plist; + size_t i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(layout); + HDassert(layout->type == H5D_VIRTUAL); + + /* Save original entry list and top-level property lists and reset in layout + * so the originals aren't closed on error */ + orig_source_fapl = layout->storage.u.virt.source_fapl; + layout->storage.u.virt.source_fapl = -1; + orig_source_dapl = layout->storage.u.virt.source_dapl; + layout->storage.u.virt.source_dapl = -1; + orig_list = layout->storage.u.virt.list; + layout->storage.u.virt.list = NULL; + + /* Copy entry list */ + if(layout->storage.u.virt.list_nused > 0) { + HDassert(orig_list); + + /* Allocate memory for the list */ + if(NULL == (layout->storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(layout->storage.u.virt.list_nused * sizeof(H5O_storage_virtual_ent_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate memory for virtual dataset entry list") + layout->storage.u.virt.list_nalloc = layout->storage.u.virt.list_nused; + + /* Copy the list entries, though set source_dset.dset and sub_dset to + * NULL */ + for(i = 0; i < layout->storage.u.virt.list_nused; i++) { + /* Copy virtual selection */ + if(NULL == (layout->storage.u.virt.list[i].source_dset.virtual_select + = H5S_copy(orig_list[i].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Copy original source names */ + if(NULL == (layout->storage.u.virt.list[i].source_file_name + = HDstrdup(orig_list[i].source_file_name))) + HGOTO_ERROR(H5E_DATASET, H5E_RESOURCE, FAIL, "unable to duplicate source file name") + if(NULL == (layout->storage.u.virt.list[i].source_dset_name + = HDstrdup(orig_list[i].source_dset_name))) + HGOTO_ERROR(H5E_DATASET, H5E_RESOURCE, FAIL, "unable to duplicate source dataset name") + + /* Copy source selection */ + if(NULL == (layout->storage.u.virt.list[i].source_select + = H5S_copy(orig_list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Initialize clipped selections */ + if(orig_list[i].unlim_dim_virtual < 0) { + layout->storage.u.virt.list[i].source_dset.clipped_source_select = layout->storage.u.virt.list[i].source_select; + layout->storage.u.virt.list[i].source_dset.clipped_virtual_select = layout->storage.u.virt.list[i].source_dset.virtual_select; + } /* end if */ + + /* Copy parsed names */ + if(H5D__virtual_copy_parsed_name(&layout->storage.u.virt.list[i].parsed_source_file_name, orig_list[i].parsed_source_file_name) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy parsed source file name") + layout->storage.u.virt.list[i].psfn_static_strlen = orig_list[i].psfn_static_strlen; + layout->storage.u.virt.list[i].psfn_nsubs = orig_list[i].psfn_nsubs; + if(H5D__virtual_copy_parsed_name(&layout->storage.u.virt.list[i].parsed_source_dset_name, orig_list[i].parsed_source_dset_name) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy parsed source dataset name") + layout->storage.u.virt.list[i].psdn_static_strlen = orig_list[i].psdn_static_strlen; + layout->storage.u.virt.list[i].psdn_nsubs = orig_list[i].psdn_nsubs; + + /* Copy source names in source dset or add reference as appropriate + */ + if(orig_list[i].source_dset.file_name) { + if(orig_list[i].source_dset.file_name + == orig_list[i].source_file_name) + layout->storage.u.virt.list[i].source_dset.file_name = layout->storage.u.virt.list[i].source_file_name; + else if(orig_list[i].parsed_source_file_name + && (orig_list[i].source_dset.file_name + != orig_list[i].parsed_source_file_name->name_segment)) { + HDassert(layout->storage.u.virt.list[i].parsed_source_file_name); + HDassert(layout->storage.u.virt.list[i].parsed_source_file_name->name_segment); + layout->storage.u.virt.list[i].source_dset.file_name = layout->storage.u.virt.list[i].parsed_source_file_name->name_segment; + } /* end if */ + else + if(NULL == (layout->storage.u.virt.list[i].source_dset.file_name + = HDstrdup(orig_list[i].source_dset.file_name))) + HGOTO_ERROR(H5E_DATASET, H5E_RESOURCE, FAIL, "unable to duplicate source file name") + } /* end if */ + if(orig_list[i].source_dset.dset_name) { + if(orig_list[i].source_dset.dset_name + == orig_list[i].source_dset_name) + layout->storage.u.virt.list[i].source_dset.dset_name = layout->storage.u.virt.list[i].source_dset_name; + else if(orig_list[i].parsed_source_dset_name + && (orig_list[i].source_dset.dset_name + != orig_list[i].parsed_source_dset_name->name_segment)) { + HDassert(layout->storage.u.virt.list[i].parsed_source_dset_name); + HDassert(layout->storage.u.virt.list[i].parsed_source_dset_name->name_segment); + layout->storage.u.virt.list[i].source_dset.dset_name = layout->storage.u.virt.list[i].parsed_source_dset_name->name_segment; + } /* end if */ + else + if(NULL == (layout->storage.u.virt.list[i].source_dset.dset_name + = HDstrdup(orig_list[i].source_dset.dset_name))) + HGOTO_ERROR(H5E_DATASET, H5E_RESOURCE, FAIL, "unable to duplicate source dataset name") + } /* end if */ + + /* Copy other fields in entry */ + layout->storage.u.virt.list[i].unlim_dim_source = orig_list[i].unlim_dim_source; + layout->storage.u.virt.list[i].unlim_dim_virtual = orig_list[i].unlim_dim_virtual; + layout->storage.u.virt.list[i].unlim_extent_source = orig_list[i].unlim_extent_source; + layout->storage.u.virt.list[i].unlim_extent_virtual = orig_list[i].unlim_extent_virtual; + layout->storage.u.virt.list[i].clip_size_source = orig_list[i].clip_size_source; + layout->storage.u.virt.list[i].clip_size_virtual = orig_list[i].clip_size_virtual; + layout->storage.u.virt.list[i].source_space_status = orig_list[i].source_space_status; + layout->storage.u.virt.list[i].virtual_space_status = orig_list[i].virtual_space_status; + } /* end for */ + } /* end if */ + else { + /* Zero out other fields related to list, just to be sure */ + layout->storage.u.virt.list = NULL; + layout->storage.u.virt.list_nalloc = 0; + } /* end else */ + + /* Copy property lists */ + if(orig_source_fapl >= 0) { + if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(orig_source_fapl, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + if((layout->storage.u.virt.source_fapl = H5P_copy_plist(plist, FALSE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy fapl") + } /* end if */ + if(orig_source_dapl >= 0) { + if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(orig_source_dapl, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + if((layout->storage.u.virt.source_dapl = H5P_copy_plist(plist, FALSE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dapl") + } /* end if */ + + /* New layout is not fully initialized */ + layout->storage.u.virt.init = FALSE; + +done: + /* Release allocated resources on failure */ + if(ret_value < 0) + if(H5D__virtual_reset_layout(layout) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset virtual layout") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_copy_layout() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_reset_layout + * + * Purpose: Frees internal structures in a virtual storage layout + * message in memory. This function is safe to use on + * incomplete structures (for recovery from failure) provided + * the internal structures are initialized with all bytes set + * to 0. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 11, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_reset_layout(H5O_layout_t *layout) +{ + size_t i, j; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(layout); + HDassert(layout->type == H5D_VIRTUAL); + + /* Free the list entries. Note we always attempt to free everything even in + * the case of a failure. Because of this, and because we free the list + * afterwards, we do not need to zero out the memory in the list. */ + for(i = 0; i < layout->storage.u.virt.list_nused; i++) { + /* Free source_dset */ + if(H5D__virtual_reset_source_dset(&layout->storage.u.virt.list[i], &layout->storage.u.virt.list[i].source_dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset source dataset") + + /* Free original source names */ + (void)H5MM_xfree(layout->storage.u.virt.list[i].source_file_name); + (void)H5MM_xfree(layout->storage.u.virt.list[i].source_dset_name); + + /* Free sub_dset */ + for(j = 0; j < layout->storage.u.virt.list[i].sub_dset_nalloc; j++) + if(H5D__virtual_reset_source_dset(&layout->storage.u.virt.list[i], &layout->storage.u.virt.list[i].sub_dset[j]) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset source dataset") + layout->storage.u.virt.list[i].sub_dset = (H5O_storage_virtual_srcdset_t *)H5MM_xfree(layout->storage.u.virt.list[i].sub_dset); + + /* Free source_select */ + if(layout->storage.u.virt.list[i].source_select) + if(H5S_close(layout->storage.u.virt.list[i].source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + + /* Free parsed_source_file_name */ + H5D_virtual_free_parsed_name(layout->storage.u.virt.list[i].parsed_source_file_name); + + /* Free parsed_source_dset_name */ + H5D_virtual_free_parsed_name(layout->storage.u.virt.list[i].parsed_source_dset_name); + } /* end for */ + + /* Free the list */ + layout->storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_xfree(layout->storage.u.virt.list); + layout->storage.u.virt.list_nalloc = (size_t)0; + layout->storage.u.virt.list_nused = (size_t)0; + (void)HDmemset(layout->storage.u.virt.min_dims, 0, sizeof(layout->storage.u.virt.min_dims)); + + /* Close access property lists */ + if(layout->storage.u.virt.source_fapl >= 0) { + if(H5I_dec_ref(layout->storage.u.virt.source_fapl) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't close source fapl") + layout->storage.u.virt.source_fapl = -1; + } /* end if */ + if(layout->storage.u.virt.source_dapl >= 0) { + if(H5I_dec_ref(layout->storage.u.virt.source_dapl) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't close source dapl") + layout->storage.u.virt.source_dapl = -1; + } /* end if */ + + /* The list is no longer initialized */ + layout->storage.u.virt.init = FALSE; + + /* Note the lack of a done: label. This is because there are no HGOTO_ERROR + * calls. If one is added, a done: label must also be added */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_reset_layout() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_copy + * + * Purpose: Copy virtual storage raw data from SRC file to DST file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_copy(H5F_t H5_ATTR_UNUSED *f_dst, H5O_layout_t *layout_dst, + hid_t H5_ATTR_UNUSED dxpl_id) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Copy message in memory */ + if(H5D__virtual_copy_layout(layout_dst) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual layout") + +#ifdef NOT_YET + /* Check for copy to the same file */ + if(f_dst == f_src) { + /* Increase reference count on global heap object */ + if((heap_rc = H5HG_link(f_dst, dxpl_id, (H5HG_t *)&(layout_dst->u.virt.serial_list_hobjid), 1)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTMODIFY, FAIL, "unable to adjust global heap refence count") + } /* end if */ + else +#endif /* NOT_YET */ + { + /* Reset global heap id so a new heap object is created when the message + * is flushed */ + layout_dst->storage.u.virt.serial_list_hobjid.addr = HADDR_UNDEF; + layout_dst->storage.u.virt.serial_list_hobjid.idx = (size_t)0; + } /* end block/else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_delete + * + * Purpose: Delete the file space for a virtual dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_delete(H5F_t *f, hid_t dxpl_id, H5O_storage_t *storage) +{ +#ifdef NOT_YET + int heap_rc; /* Reference count of global heap object */ +#endif /* NOT_YET */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* check args */ + HDassert(f); + HDassert(storage); + HDassert(storage->type == H5D_VIRTUAL); + + /* Check for global heap block */ + if(storage->u.virt.serial_list_hobjid.addr != HADDR_UNDEF) { +#ifdef NOT_YET + /* Unlink the global heap block */ + if((heap_rc = H5HG_link(f, dxpl_id, (H5HG_t *)&(storage->u.virt.serial_list_hobjid), -1)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTMODIFY, FAIL, "unable to adjust global heap refence count") + if(heap_rc == 0) +#endif /* NOT_YET */ + /* Delete the global heap block */ + if(H5HG_remove(f, dxpl_id, (H5HG_t *)&(storage->u.virt.serial_list_hobjid)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "unable to remove heap object") + } /* end if */ + + /* Clear global heap ID in storage */ + storage->u.virt.serial_list_hobjid.addr = HADDR_UNDEF; + storage->u.virt.serial_list_hobjid.idx = 0; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_delete */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_open_source_dset + * + * Purpose: Attempts to open a source dataset. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * March 6, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_open_source_dset(const H5D_t *vdset, + H5O_storage_virtual_ent_t *virtual_ent, + H5O_storage_virtual_srcdset_t *source_dset, hid_t dxpl_id) +{ + H5F_t *src_file = NULL; /* Source file */ + hbool_t src_file_open = FALSE; /* Whether we have opened and need to close src_file */ + H5G_loc_t src_root_loc; /* Object location of source file root group */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(vdset); + HDassert(source_dset); + HDassert(!source_dset->dset); + HDassert(source_dset->file_name); + HDassert(source_dset->dset_name); + + /* Check if we need to open the source file */ + if(HDstrcmp(source_dset->file_name, ".")) { + /* Open the source file */ + if(NULL == (src_file = H5F_open(source_dset->file_name, H5F_INTENT(vdset->oloc.file) & H5F_ACC_RDWR, H5P_FILE_CREATE_DEFAULT, vdset->shared->layout.storage.u.virt.source_fapl, dxpl_id))) + H5E_clear_stack(NULL); /* Quick hack until proper support for H5Fopen with missing file is implemented */ + else + src_file_open = TRUE; + } /* end if */ + else + /* Source file is ".", use the virtual dataset's file */ + src_file = vdset->oloc.file; + + if(src_file) { + /* Set up the root group in the destination file */ + if(NULL == (src_root_loc.oloc = H5G_oloc(H5G_rootof(src_file)))) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (src_root_loc.path = H5G_nameof(H5G_rootof(src_file)))) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "unable to get path for root group") + + /* Open the source dataset */ + if(NULL == (source_dset->dset = H5D__open_name(&src_root_loc, source_dset->dset_name, vdset->shared->layout.storage.u.virt.source_dapl, dxpl_id))) { + H5E_clear_stack(NULL); /* Quick hack until proper support for H5Dopen with missing file is implemented */ + + /* Dataset does not exist */ + source_dset->dset_exists = FALSE; + } /* end if */ + else { + /* Dataset exists */ + source_dset->dset_exists = TRUE; + + /* Patch the source selection if necessary */ + if(virtual_ent->source_space_status != H5O_VIRTUAL_STATUS_CORRECT) { + if(H5S_extent_copy(virtual_ent->source_select, source_dset->dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent") + virtual_ent->source_space_status = H5O_VIRTUAL_STATUS_CORRECT; + } /* end if */ + } /* end else */ + } /* end if */ + +done: + /* Close source file */ + if(src_file_open) + if(H5F_try_close(src_file) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, FAIL, "can't close source file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_open_source_dset() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_reset_source_dset + * + * Purpose: Frees space referenced by a source dataset struct. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 20, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_reset_source_dset(H5O_storage_virtual_ent_t *virtual_ent, + H5O_storage_virtual_srcdset_t *source_dset) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(source_dset); + + /* Free dataset */ + if(source_dset->dset) { + if(H5D_close(source_dset->dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset") + source_dset->dset = NULL; + } /* end if */ + + /* Free file name */ + if(virtual_ent->parsed_source_file_name + && (source_dset->file_name + != virtual_ent->parsed_source_file_name->name_segment)) + source_dset->file_name = (char *)H5MM_xfree(source_dset->file_name); + else + HDassert((source_dset->file_name == virtual_ent->source_file_name) + || (virtual_ent->parsed_source_file_name + && (source_dset->file_name + == virtual_ent->parsed_source_file_name->name_segment)) + || !source_dset->file_name); + + /* Free dataset name */ + if(virtual_ent->parsed_source_dset_name + && (source_dset->dset_name + != virtual_ent->parsed_source_dset_name->name_segment)) + source_dset->dset_name = (char *)H5MM_xfree(source_dset->dset_name); + else + HDassert((source_dset->dset_name == virtual_ent->source_dset_name) + || (virtual_ent->parsed_source_dset_name + && (source_dset->dset_name + == virtual_ent->parsed_source_dset_name->name_segment)) + || !source_dset->dset_name); + + /* Free clipped virtual selection */ + if(source_dset->clipped_virtual_select) { + if(source_dset->clipped_virtual_select != source_dset->virtual_select) + if(H5S_close(source_dset->clipped_virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual selection") + source_dset->clipped_virtual_select = NULL; + } /* end if */ + + /* Free virtual selection */ + if(source_dset->virtual_select) { + if(H5S_close(source_dset->virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") + source_dset->virtual_select = NULL; + } /* end if */ + + /* Free clipped source selection */ + if(source_dset->clipped_source_select) { + if(source_dset->clipped_source_select != virtual_ent->source_select) + if(H5S_close(source_dset->clipped_source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source selection") + source_dset->clipped_source_select = NULL; + } /* end if */ + + /* The projected memory space should never exist when this function is + * called */ + HDassert(!source_dset->projected_mem_space); + + /* Note the lack of a done: label. This is because there are no HGOTO_ERROR + * calls. If one is added, a done: label must also be added */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_reset_source_dset() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_str_append + * + * Purpose: Appends src_len bytes of the string src to the position *p + * in the buffer *buf (allocating *buf if necessary). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 19, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_str_append(const char *src, size_t src_len, char **p, char **buf, + size_t *buf_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(src); + HDassert(src_len > 0); + HDassert(p); + HDassert(buf); + HDassert(*p >= *buf); + HDassert(buf_size); + + /* Allocate or extend buffer if necessary */ + if(!*buf) { + HDassert(!*p); + HDassert(*buf_size == 0); + + /* Allocate buffer */ + if(NULL == (*buf = (char *)H5MM_malloc(src_len + (size_t)1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate name segment struct") + *buf_size = src_len + (size_t)1; + *p = *buf; + } /* end if */ + else { + size_t p_offset = (size_t)(*p - *buf); /* Offset of p within buf */ + + /* Extend buffer if necessary */ + if((p_offset + src_len + (size_t)1) > *buf_size) { + char *tmp_buf; + size_t tmp_buf_size; + + /* Calculate new size of buffer */ + tmp_buf_size = MAX(p_offset + src_len + (size_t)1, + *buf_size * (size_t)2); + + /* Reallocate buffer */ + if(NULL == (tmp_buf = (char *)H5MM_realloc(*buf, tmp_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to reallocate name segment buffer") + *buf = tmp_buf; + *buf_size = tmp_buf_size; + *p = *buf + p_offset; + } /* end if */ + } /* end else */ + + /* Copy string to *p. Note that since src in not NULL terminated, we must + * use memcpy */ + (void)HDmemcpy(*p, src, src_len); + + /* Advance *p */ + *p += src_len; + + /* Add NULL terminator */ + **p = '\0'; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5D__virtual_str_append() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_parse_source_name + * + * Purpose: Parses a source file or dataset name. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 18, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_parse_source_name(const char *source_name, + H5O_storage_virtual_name_seg_t **parsed_name, size_t *static_strlen, + size_t *nsubs) +{ + H5O_storage_virtual_name_seg_t *tmp_parsed_name = NULL; + H5O_storage_virtual_name_seg_t **tmp_parsed_name_p = &tmp_parsed_name; + size_t tmp_static_strlen; + size_t tmp_strlen; + size_t tmp_nsubs = 0; + const char *p; + const char *pct; + char *name_seg_p = NULL; + size_t name_seg_size = 0; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(source_name); + HDassert(parsed_name); + HDassert(static_strlen); + HDassert(nsubs); + + /* Initialize p and tmp_static_strlen */ + p = source_name; + tmp_static_strlen = tmp_strlen = HDstrlen(source_name); + + /* Iterate over name */ + /* Note this will not work with UTF-8! We should support this eventually + * -NAF 5/18/2015 */ + while((pct = HDstrchr(p, '%'))) { + HDassert(pct >= p); + + /* Allocate name segment struct if necessary */ + if(!*tmp_parsed_name_p) + if(NULL == (*tmp_parsed_name_p = H5FL_CALLOC(H5O_storage_virtual_name_seg_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate name segment struct") + + /* Check for type of format specifier */ + if(pct[1] == 'b') { + /* Check for blank string before specifier */ + if(pct != p) + /* Append string to name segment */ + if(H5D__virtual_str_append(p, (size_t)(pct - p), &name_seg_p, &(*tmp_parsed_name_p)->name_segment, + &name_seg_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to append name segment") + + /* Update other variables */ + tmp_parsed_name_p = &(*tmp_parsed_name_p)->next; + tmp_static_strlen -= 2; + tmp_nsubs++; + name_seg_p = NULL; + name_seg_size = 0; + } /* end if */ + else if(pct[1] == '%') { + /* Append string to name segment (include first '%') */ + if(H5D__virtual_str_append(p, (size_t)(pct - p) + (size_t)1, &name_seg_p, &(*tmp_parsed_name_p)->name_segment, +&name_seg_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to append name segment") + + /* Update other variables */ + tmp_static_strlen -= 1; + } /* end else */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid format specifier") + + p = pct + 2; + } /* end while */ + + /* Copy last segment of name, if any, unless the parsed name was not + * allocated */ + if(tmp_parsed_name) { + HDassert(p >= source_name); + if(*p == '\0') + HDassert((size_t)(p - source_name) == tmp_strlen); + else { + HDassert((size_t)(p - source_name) < tmp_strlen); + + /* Allocate name segment struct if necessary */ + if(!*tmp_parsed_name_p) + if(NULL == (*tmp_parsed_name_p = H5FL_CALLOC(H5O_storage_virtual_name_seg_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate name segment struct") + + /* Append string to name segment */ + if(H5D__virtual_str_append(p, tmp_strlen - (size_t)(p - source_name), &name_seg_p, &(*tmp_parsed_name_p)->name_segment, + &name_seg_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to append name segment") + } /* end else */ + } /* end if */ + + /* Set return values */ + *parsed_name = tmp_parsed_name; + tmp_parsed_name = NULL; + *static_strlen = tmp_static_strlen; + *nsubs = tmp_nsubs; + +done: + if(tmp_parsed_name) { + HDassert(ret_value < 0); + H5D_virtual_free_parsed_name(tmp_parsed_name); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_parse_source_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_copy_parsed_name + * + * Purpose: Deep copies a parsed source file or dataset name. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 19, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_copy_parsed_name(H5O_storage_virtual_name_seg_t **dst, + H5O_storage_virtual_name_seg_t *src) +{ + H5O_storage_virtual_name_seg_t *tmp_dst = NULL; + H5O_storage_virtual_name_seg_t *p_src = src; + H5O_storage_virtual_name_seg_t **p_dst = &tmp_dst; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(dst); + + /* Walk over parsed name, duplicating it */ + while(p_src) { + /* Allocate name segment struct */ + if(NULL == (*p_dst = H5FL_CALLOC(H5O_storage_virtual_name_seg_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate name segment struct") + + /* Duplicate name segment */ + if(p_src->name_segment) { + if(NULL == ((*p_dst)->name_segment = HDstrdup(p_src->name_segment))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to duplicate name segment") + } /* end if */ + + /* Advance pointers */ + p_src = p_src->next; + p_dst = &(*p_dst)->next; + } /* end while */ + + /* Set dst */ + *dst = tmp_dst; + tmp_dst = NULL; + +done: + if(tmp_dst) { + HDassert(ret_value < 0); + H5D_virtual_free_parsed_name(tmp_dst); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_copy_parsed_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_free_parsed_name + * + * Purpose: Frees the provided parsed name. + * + * Return: void + * + * Programmer: Neil Fortner + * May 19, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_free_parsed_name(H5O_storage_virtual_name_seg_t *name_seg) +{ + H5O_storage_virtual_name_seg_t *next_seg; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Walk name segments, freeing them */ + while(name_seg) { + (void)H5MM_xfree(name_seg->name_segment); + next_seg = name_seg->next; + (void)H5FL_FREE(H5O_storage_virtual_name_seg_t, name_seg); + name_seg = next_seg; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_free_parsed_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_build_source_name + * + * Purpose: Builds a source file or dataset name from a parsed name. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 18, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_build_source_name(char *source_name, + const H5O_storage_virtual_name_seg_t *parsed_name, size_t static_strlen, + size_t nsubs, hsize_t blockno, char **built_name) +{ + char *tmp_name = NULL; /* Name buffer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(source_name); + HDassert(built_name); + + /* Check for static name */ + if(nsubs == 0) { + if(parsed_name) + *built_name = parsed_name->name_segment; + else + *built_name = source_name; + } /* end if */ + else { + const H5O_storage_virtual_name_seg_t *name_seg = parsed_name; + char *p; + hsize_t blockno_down = blockno; + size_t blockno_len = 1; + size_t name_len; + size_t name_len_rem; + size_t seg_len; + size_t nsubs_rem = nsubs; + + HDassert(parsed_name); + + /* Calculate length of printed block number */ + do { + blockno_down /= (hsize_t)10; + if(blockno_down == 0) + break; + blockno_len++; + } while(1); + + /* Calculate length of name buffer */ + name_len_rem = name_len = static_strlen + (nsubs * blockno_len) + (size_t)1; + + /* Allocate name buffer */ + if(NULL == (tmp_name = (char *)H5MM_malloc(name_len))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate name buffer") + p = tmp_name; + + /* Build name */ + do { + /* Add name segment */ + if(name_seg->name_segment) { + seg_len = HDstrlen(name_seg->name_segment); + HDassert(seg_len > 0); + HDassert(seg_len < name_len_rem); + HDstrncpy(p, name_seg->name_segment, name_len_rem); + name_len_rem -= seg_len; + p += seg_len; + } /* end if */ + + /* Add block number */ + if(nsubs_rem > 0) { + HDassert(blockno_len < name_len_rem); + if(HDsnprintf(p, name_len_rem, "%llu", (long long unsigned)blockno) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write block number to string") + name_len_rem -= blockno_len; + p += blockno_len; + nsubs_rem--; + } /* end if */ + + /* Advance name_seg */ + name_seg = name_seg->next; + } while(name_seg); + + /* Assign built_name */ + *built_name = tmp_name; + tmp_name = NULL; + } /* end else */ + +done: + if(tmp_name) { + HDassert(ret_value < 0); + H5MM_free(tmp_name); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_build_source_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_set_extent_unlim + * + * Purpose: Sets the extent of the virtual dataset by checking the + * extents of source datasets where an unlimited selection + * matching. Dimensions that are not unlimited in any + * virtual mapping selections are not affected. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * April 22, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) +{ + H5O_storage_virtual_t *storage; + hsize_t new_dims[H5S_MAX_RANK]; + hsize_t curr_dims[H5S_MAX_RANK]; + hsize_t clip_size; + int rank; + hbool_t changed = FALSE; /* Whether the VDS extent changed */ + size_t i, j; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(dset); + HDassert(dset->shared->layout.storage.type == H5D_VIRTUAL); + storage = &dset->shared->layout.storage.u.virt; + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); + + /* Get rank of VDS */ + if((rank = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions") + + /* Initialize new_dims to HSIZE_UNDEF */ + for(i = 0; i < (size_t)rank; i++) + new_dims[i] = HSIZE_UNDEF; + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nalloc; i++) + /* Check for unlimited dimension */ + if(storage->list[i].unlim_dim_virtual >= 0) { + /* Check for "printf" source dataset resolution */ + if(storage->list[i].unlim_dim_source >= 0 ) { + /* Non-printf mapping */ + /* Open source dataset */ + if(!storage->list[i].source_dset.dset) + if(H5D__virtual_open_source_dset(dset, &storage->list[i], &storage->list[i].source_dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + + /* Check if source dataset is open */ + if(storage->list[i].source_dset.dset) { + /* Retrieve current source dataset extent and patch mapping + */ + if(H5S_extent_copy(storage->list[i].source_select, storage->list[i].source_dset.dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent") + + /* Get source space dimenstions */ + if(H5S_get_simple_extent_dims(storage->list[i].source_select, curr_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions") + + /* Check if the source extent in the unlimited dimension + * changed since the last time the VDS extent/mapping + * was updated */ + if(curr_dims[storage->list[i].unlim_dim_source] + == storage->list[i].unlim_extent_source) + /* Use cached result for clip size */ + clip_size = storage->list[i].clip_size_virtual; + else { + /* Get size that virtual selection would be clipped to + * to match size of source selection within source + * extent */ + clip_size = H5S_hyper_get_clip_extent_match(storage->list[i].source_dset.virtual_select, storage->list[i].source_select, curr_dims[storage->list[i].unlim_dim_source], storage->view == H5D_VDS_FIRST_MISSING); + + /* If we are setting the extent by the last available + * data, clip virtual_select and source_select. Note + * that if we used the cached clip_size above or it + * happens to be the same, the virtual selection will + * already be clipped to the correct size. Likewise, + * if we used the cached clip_size the source selection + * will already be correct. */ + if(storage->view == H5D_VDS_LAST_AVAILABLE) { + if(clip_size != storage->list[i].clip_size_virtual) { + /* Close previous clipped virtual selection, if + * any */ + if(storage->list[i].source_dset.clipped_virtual_select) { + HDassert(storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select); + if(H5S_close(storage->list[i].source_dset.clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + } /* end if */ + + /* Copy virtual selection */ + if(NULL == (storage->list[i].source_dset.clipped_virtual_select = H5S_copy(storage->list[i].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Clip virtual selection */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_virtual_select, clip_size)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + } /* end if */ + + /* Close previous clipped source selection, if any + */ + if(storage->list[i].source_dset.clipped_source_select) { + HDassert(storage->list[i].source_dset.clipped_source_select + != storage->list[i].source_select); + if(H5S_close(storage->list[i].source_dset.clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + } /* end if */ + + /* Copy source selection */ + if(NULL == (storage->list[i].source_dset.clipped_source_select = H5S_copy(storage->list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Clip source selection */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_source_select, curr_dims[storage->list[i].unlim_dim_source])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + } /* end if */ + + /* Update cached values unlim_extent_source and + * clip_size_virtual */ + storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source]; + storage->list[i].clip_size_virtual = clip_size; + } /* end else */ + } /* end if */ + else + clip_size = 0; + } /* end if */ + else { + /* printf mapping */ + hsize_t first_missing = 0; /* First missing dataset in the current block of missing datasets */ + + /* Search for source datasets */ + HDassert(storage->printf_gap != HSIZE_UNDEF); + for(j = 0; j <= (storage->printf_gap + first_missing); j++) { + /* Check for running out of space in sub_dset array */ + if(j >= (hsize_t)storage->list[i].sub_dset_nalloc) { + if(storage->list[i].sub_dset_nalloc == 0) { + /* Allocate sub_dset */ + if(NULL == (storage->list[i].sub_dset = (H5O_storage_virtual_srcdset_t *)H5MM_calloc(H5D_VIRTUAL_DEF_SUB_DSET_SIZE * sizeof(H5O_storage_virtual_srcdset_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate sub dataset array") + storage->list[i].sub_dset_nalloc = H5D_VIRTUAL_DEF_SUB_DSET_SIZE; + } /* end if */ + else { + H5O_storage_virtual_srcdset_t *tmp_sub_dset; + + /* Extend sub_dset */ + if(NULL == (tmp_sub_dset = (H5O_storage_virtual_srcdset_t *)H5MM_realloc(storage->list[i].sub_dset, 2 * storage->list[i].sub_dset_nalloc * sizeof(H5O_storage_virtual_srcdset_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to extend sub dataset array") + storage->list[i].sub_dset = tmp_sub_dset; + + /* Clear new space in sub_dset */ + (void)HDmemset(&storage->list[i].sub_dset[storage->list[i].sub_dset_nalloc], 0, storage->list[i].sub_dset_nalloc * sizeof(H5O_storage_virtual_srcdset_t)); + + /* Update sub_dset_nalloc */ + storage->list[i].sub_dset_nalloc *= 2; + } /* end else */ + } /* end if */ + + /* Check if the dataset was already opened */ + if(storage->list[i].sub_dset[j].dset_exists) + first_missing = j + 1; + else { + /* Resolve file name */ + if(!storage->list[i].sub_dset[j].file_name) + if(H5D__virtual_build_source_name(storage->list[i].source_file_name, storage->list[i].parsed_source_file_name, storage->list[i].psfn_static_strlen, storage->list[i].psfn_nsubs, j, &storage->list[i].sub_dset[j].file_name) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to build source file name") + + /* Resolve dset name */ + if(!storage->list[i].sub_dset[j].dset_name) + if(H5D__virtual_build_source_name(storage->list[i].source_dset_name, storage->list[i].parsed_source_dset_name, storage->list[i].psdn_static_strlen, storage->list[i].psdn_nsubs, j, &storage->list[i].sub_dset[j].dset_name) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to build source dataset name") + + /* Resolve virtual selection for block */ + if(!storage->list[i].sub_dset[j].virtual_select) + if(NULL == (storage->list[i].sub_dset[j].virtual_select = H5S_hyper_get_unlim_block(storage->list[i].source_dset.virtual_select, j))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get block in unlimited selection") + + /* Initialize clipped selections */ + if(!storage->list[i].sub_dset[j].clipped_source_select) + storage->list[i].sub_dset[j].clipped_source_select = storage->list[i].source_select; + if(!storage->list[i].sub_dset[j].clipped_virtual_select) + storage->list[i].sub_dset[j].clipped_virtual_select = storage->list[i].sub_dset[j].virtual_select; + + /* Open source dataset */ + if(H5D__virtual_open_source_dset(dset, &storage->list[i], &storage->list[i].sub_dset[j], dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + + if(storage->list[i].sub_dset[j].dset) { + /* Update first_missing */ + first_missing = j + 1; + + /* Close source dataset so we don't have huge + * numbers of datasets open */ + if(H5D_close(storage->list[i].sub_dset[j].dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset") + storage->list[i].sub_dset[j].dset = NULL; + } /* end if */ + } /* end else */ + } /* end for */ + + /* Check if the size changed */ + if((first_missing == (hsize_t)storage->list[i].sub_dset_nused) + && (storage->list[i].clip_size_virtual != HSIZE_UNDEF)) + /* Use cached clip_size */ + clip_size = storage->list[i].clip_size_virtual; + else { + /* Check for no datasets */ + if(first_missing == 0) + /* Set clip size to 0 */ + clip_size = (hsize_t)0; + else { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + + /* Get clip size from selection */ + if(storage->view == H5D_VDS_LAST_AVAILABLE) { + /* Get bounds from last valid virtual selection */ + if(H5S_SELECT_BOUNDS(storage->list[i].sub_dset[first_missing - (hsize_t)1].virtual_select, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds") + + /* Set clip_size to bounds_end in unlimited + * dimension */ + clip_size = bounds_end[storage->list[i].unlim_dim_virtual] + + (hsize_t)1; + } /* end if */ + else { + /* Get bounds from first missing virtual selection + */ + if(H5S_SELECT_BOUNDS(storage->list[i].sub_dset[first_missing].virtual_select, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds") + + /* Set clip_size to bounds_start in unlimited + * dimension */ + clip_size = bounds_start[storage->list[i].unlim_dim_virtual]; + } /* end else */ + } /* end else */ + + /* Set sub_dset_nused and clip_size_virtual */ + storage->list[i].sub_dset_nused = (size_t)first_missing; + storage->list[i].clip_size_virtual = clip_size; + } /* end else */ + } /* end else */ + + /* Update new_dims */ + if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF) + || (storage->view == H5D_VDS_FIRST_MISSING ? (clip_size + < (hsize_t)new_dims[storage->list[i].unlim_dim_virtual]) + : (clip_size + > (hsize_t)new_dims[storage->list[i].unlim_dim_virtual]))) + new_dims[storage->list[i].unlim_dim_virtual] = clip_size; + } /* end if */ + + /* Get current VDS dimensions */ + if(H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions") + + /* Calculate new extent */ + for(i = 0; i < (size_t)rank; i++) { + if(new_dims[i] == HSIZE_UNDEF) + new_dims[i] = curr_dims[i]; + else if(new_dims[i] < storage->min_dims[i]) + new_dims[i] = storage->min_dims[i]; + if(new_dims[i] != curr_dims[i]) + changed = TRUE; + } /* end for */ + + /* Update extent if it changed */ + if(changed) { + /* Update VDS extent */ + if(H5S_set_extent(dset->shared->space, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + + /* Mark the space as dirty, for later writing to the file */ + if(H5F_INTENT(dset->oloc.file) & H5F_ACC_RDWR) + if(H5D__mark(dset, dxpl_id, H5D_MARK_SPACE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty") + } /* end if */ + + /* If we did not change the VDS dimensions, there is nothing more to update + */ + if(changed || (!storage->init && (storage->view == H5D_VDS_FIRST_MISSING))) { + /* Iterate over mappings again to update source selections and virtual + * mapping extents */ + for(i = 0; i < storage->list_nalloc; i++) { + /* If there is an unlimited dimension, we are setting extent by the + * minimum of mappings, and the virtual extent in the unlimited + * dimension has changed since the last time the VDS extent/mapping + * was updated, we must adjust the selections */ + if((storage->list[i].unlim_dim_virtual >= 0) + && (storage->view == H5D_VDS_FIRST_MISSING) + && (new_dims[storage->list[i].unlim_dim_virtual] + != storage->list[i].unlim_extent_virtual)) { + /* Check for "printf" style mapping */ + if(storage->list[i].unlim_dim_source >= 0) { + /* Non-printf mapping */ + /* Close previous clipped virtual selection, if any */ + if(storage->list[i].source_dset.clipped_virtual_select) { + HDassert(storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select); + if(H5S_close(storage->list[i].source_dset.clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + } /* end if */ + + /* Copy virtual selection */ + if(NULL == (storage->list[i].source_dset.clipped_virtual_select = H5S_copy(storage->list[i].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Clip space to virtual extent */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_virtual_select, new_dims[storage->list[i].unlim_dim_source])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Get size that source selection will be clipped to to + * match size of virtual selection */ + clip_size = H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].source_dset.clipped_virtual_select, FALSE); + + /* Check if the clip size changed */ + if(clip_size != storage->list[i].clip_size_source) { + /* Close previous clipped source selection, if any */ + if(storage->list[i].source_dset.clipped_source_select) { + HDassert(storage->list[i].source_dset.clipped_source_select + != storage->list[i].source_select); + if(H5S_close(storage->list[i].source_dset.clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + } /* end if */ + + /* Copy source selection */ + if(NULL == (storage->list[i].source_dset.clipped_source_select = H5S_copy(storage->list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Clip source selection */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_source_select, clip_size)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Update cached value clip_size_source */ + storage->list[i].clip_size_source = clip_size; + } /* end if */ + } /* end if */ + else { + /* printf mapping */ + hsize_t first_inc_block; + hbool_t partial_block; + + /* Get index of first incomplete block in virtual + * selection */ + first_inc_block = H5S_hyper_get_first_inc_block(storage->list[i].source_dset.virtual_select, new_dims[storage->list[i].unlim_dim_virtual], &partial_block); + + /* Iterate over sub datasets */ + for(j = 0; j < storage->list[i].sub_dset_nalloc; j++) { + /* Close previous clipped source selection, if any */ + if(storage->list[i].sub_dset[j].clipped_source_select + != storage->list[i].source_select) { + if(storage->list[i].sub_dset[j].clipped_source_select) + if(H5S_close(storage->list[i].sub_dset[j].clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + + /* Initialize clipped source selection to point to + * base source selection */ + storage->list[i].sub_dset[j].clipped_source_select = storage->list[i].source_select; + } /* end if */ + + /* Close previous clipped virtual selection, if any */ + if(storage->list[i].sub_dset[j].clipped_virtual_select + != storage->list[i].sub_dset[j].virtual_select) { + if(storage->list[i].sub_dset[j].clipped_virtual_select) + if(H5S_close(storage->list[i].sub_dset[j].clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + + /* Initialize clipped virtual selection to point to + * unclipped virtual selection */ + storage->list[i].sub_dset[j].clipped_virtual_select = storage->list[i].sub_dset[j].virtual_select; + } /* end if */ + + /* Only initialize clipped selections if it is a + * complete block, for incomplete blocks defer to + * H5D__virtual_pre_io() as we may not have a valid + * source extent here. For unused blocks we will never + * need clipped selections (until the extent is + * recalculated in this function). */ + if(j >= (size_t)first_inc_block) { + /* Clear clipped source and virtual selections */ + storage->list[i].sub_dset[j].clipped_source_select = NULL; + storage->list[i].sub_dset[j].clipped_virtual_select = NULL; + } /* end if */ + } /* end for */ + } /* end else */ + + /* Update cached value unlim_extent_virtual */ + storage->list[i].unlim_extent_virtual = new_dims[storage->list[i].unlim_dim_virtual]; + } /* end if */ + + /* Update top level virtual_select and clipped_virtual_select + * extents */ + if(H5S_set_extent(storage->list[i].source_dset.virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + if((storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select) + && storage->list[i].source_dset.clipped_virtual_select) + if(H5S_set_extent(storage->list[i].source_dset.clipped_virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + + /* Update sub dataset virtual_select and clipped_virtual_select + * extents */ + for(j = 0; j < storage->list[i].sub_dset_nalloc; j++) + if(storage->list[i].sub_dset[j].virtual_select) { + if(H5S_set_extent(storage->list[i].sub_dset[j].virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + if((storage->list[i].sub_dset[j].clipped_virtual_select + != storage->list[i].sub_dset[j].virtual_select) + && storage->list[i].sub_dset[j].clipped_virtual_select) + if(H5S_set_extent(storage->list[i].sub_dset[j].clipped_virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + } /* end if */ + else + HDassert(!storage->list[i].sub_dset[j].clipped_virtual_select); + } /* end for */ + } /* end if */ + + /* Mark layout as fully initialized */ + storage->init = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_set_extent_unlim() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_init_all + * + * Purpose: Finishes initializing layout in preparation for I/O. + * Only necessary if H5D__virtual_set_extent_unlim() has not + * been called yet. Initializes clipped_virtual_select and + * clipped_source_select for all mappings in this layout. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * August 10, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_init_all(const H5D_t *dset, hid_t dxpl_id) +{ + H5O_storage_virtual_t *storage; + hsize_t virtual_dims[H5S_MAX_RANK]; + hsize_t source_dims[H5S_MAX_RANK]; + hsize_t clip_size; + size_t i, j; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(dset); + HDassert(dset->shared->layout.storage.type == H5D_VIRTUAL); + storage = &dset->shared->layout.storage.u.virt; + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); + + /* Get current VDS dimensions */ + if(H5S_get_simple_extent_dims(dset->shared->space, virtual_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions") + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nalloc; i++) + /* Check for unlimited dimension */ + if(storage->list[i].unlim_dim_virtual >= 0) { + /* Check for "printf" source dataset resolution */ + if(storage->list[i].unlim_dim_source >= 0 ) { + /* Non-printf mapping */ + /* Open source dataset */ + if(!storage->list[i].source_dset.dset) + if(H5D__virtual_open_source_dset(dset, &storage->list[i], &storage->list[i].source_dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + + /* Check if source dataset is open */ + if(storage->list[i].source_dset.dset) { + /* Retrieve current source dataset extent and patch mapping + */ + if(H5S_extent_copy(storage->list[i].source_select, storage->list[i].source_dset.dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent") + + /* Get source space dimenstions */ + if(H5S_get_simple_extent_dims(storage->list[i].source_select, source_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions") + + /* Get size that source selection would be clipped to to + * match size of virtual selection */ + clip_size = H5S_hyper_get_clip_extent_match(storage->list[i].source_select, storage->list[i].source_dset.virtual_select, virtual_dims[storage->list[i].unlim_dim_virtual], FALSE); + + /* Close previous clipped virtual selection, if any */ + if(storage->list[i].source_dset.clipped_virtual_select) { + HDassert(storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select); + if(H5S_close(storage->list[i].source_dset.clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + } /* end if */ + + /* Copy virtual selection */ + if(NULL == (storage->list[i].source_dset.clipped_virtual_select = H5S_copy(storage->list[i].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Close previous clipped source selection, if any */ + if(storage->list[i].source_dset.clipped_source_select) { + HDassert(storage->list[i].source_dset.clipped_source_select + != storage->list[i].source_select); + if(H5S_close(storage->list[i].source_dset.clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + } /* end if */ + + /* Copy source selection */ + if(NULL == (storage->list[i].source_dset.clipped_source_select = H5S_copy(storage->list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Check if the clip size is within the current extent of + * the source dataset */ + if(clip_size <= source_dims[storage->list[i].unlim_dim_source]) { + /* Clip virtual selection to extent */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_virtual_select, virtual_dims[storage->list[i].unlim_dim_virtual])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Clip source selection to clip_size */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_source_select, clip_size)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + } /* end if */ + else { + /* Get size that virtual selection will be clipped to to + * match size of source selection within source extent + */ + clip_size = H5S_hyper_get_clip_extent_match(storage->list[i].source_dset.virtual_select, storage->list[i].source_select, source_dims[storage->list[i].unlim_dim_source], FALSE); + + /* Clip virtual selection to clip_size */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_virtual_select, clip_size)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Clip source selection to extent */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_source_select, source_dims[storage->list[i].unlim_dim_source])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + } /* end else */ + } /* end if */ + else { + HDassert(!storage->list[i].source_dset.clipped_virtual_select); + HDassert(!storage->list[i].source_dset.clipped_source_select); + } /* end else */ + } /* end if */ + else { + /* printf mapping */ + size_t sub_dset_max; + hbool_t partial_block; + + /* Get number of sub-source datasets in current extent */ + sub_dset_max = (size_t)H5S_hyper_get_first_inc_block(storage->list[i].source_dset.virtual_select, virtual_dims[storage->list[i].unlim_dim_virtual], &partial_block); + if(partial_block) + sub_dset_max++; + + /* Allocate or grow the sub_dset array if necessary */ + if(!storage->list[i].sub_dset) { + /* Allocate sub_dset array */ + if(NULL == (storage->list[i].sub_dset = (H5O_storage_virtual_srcdset_t *)H5MM_calloc(sub_dset_max * sizeof(H5O_storage_virtual_srcdset_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate sub dataset array") + + /* Update sub_dset_nalloc */ + storage->list[i].sub_dset_nalloc = sub_dset_max; + } /* end if */ + else if(sub_dset_max > storage->list[i].sub_dset_nalloc) { + H5O_storage_virtual_srcdset_t *tmp_sub_dset; + + /* Extend sub_dset array */ + if(NULL == (tmp_sub_dset = (H5O_storage_virtual_srcdset_t *)H5MM_realloc(storage->list[i].sub_dset, sub_dset_max * sizeof(H5O_storage_virtual_srcdset_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to extend sub dataset array") + storage->list[i].sub_dset = tmp_sub_dset; + + /* Clear new space in sub_dset */ + (void)HDmemset(&storage->list[i].sub_dset[storage->list[i].sub_dset_nalloc], 0, (sub_dset_max - storage->list[i].sub_dset_nalloc) * sizeof(H5O_storage_virtual_srcdset_t)); + + /* Update sub_dset_nalloc */ + storage->list[i].sub_dset_nalloc = sub_dset_max; + } /* end if */ + + /* Iterate over sub dsets */ + for(j = 0; j < sub_dset_max; j++) { + /* Resolve file name */ + if(!storage->list[i].sub_dset[j].file_name) + if(H5D__virtual_build_source_name(storage->list[i].source_file_name, storage->list[i].parsed_source_file_name, storage->list[i].psfn_static_strlen, storage->list[i].psfn_nsubs, j, &storage->list[i].sub_dset[j].file_name) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to build source file name") + + /* Resolve dset name */ + if(!storage->list[i].sub_dset[j].dset_name) + if(H5D__virtual_build_source_name(storage->list[i].source_dset_name, storage->list[i].parsed_source_dset_name, storage->list[i].psdn_static_strlen, storage->list[i].psdn_nsubs, j, &storage->list[i].sub_dset[j].dset_name) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to build source dataset name") + + /* Resolve virtual selection for block */ + if(!storage->list[i].sub_dset[j].virtual_select) + if(NULL == (storage->list[i].sub_dset[j].virtual_select = H5S_hyper_get_unlim_block(storage->list[i].source_dset.virtual_select, j))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get block in unlimited selection") + + /* Close previous clipped source selection, if any */ + if(storage->list[i].sub_dset[j].clipped_source_select + != storage->list[i].source_select) { + if(storage->list[i].sub_dset[j].clipped_source_select) + if(H5S_close(storage->list[i].sub_dset[j].clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + + /* Initialize clipped source selection to point to base + * source selection */ + storage->list[i].sub_dset[j].clipped_source_select = storage->list[i].source_select; + } /* end if */ + + /* Close previous clipped virtual selection, if any */ + if(storage->list[i].sub_dset[j].clipped_virtual_select + != storage->list[i].sub_dset[j].virtual_select) { + if(storage->list[i].sub_dset[j].clipped_virtual_select) + if(H5S_close(storage->list[i].sub_dset[j].clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + + /* Initialize clipped virtual selection to point to + * unclipped virtual selection */ + storage->list[i].sub_dset[j].clipped_virtual_select = storage->list[i].sub_dset[j].virtual_select; + } /* end if */ + + /* Clear clipped selections if this is a partial block, + * defer calculation of real clipped selections to + * H5D__virtual_pre_io() as we may not have a valid source + * extent here */ + if((j == (sub_dset_max - 1)) && partial_block) { + /* Clear clipped source and virtual selections */ + storage->list[i].sub_dset[j].clipped_source_select = NULL; + storage->list[i].sub_dset[j].clipped_virtual_select = NULL; + } /* end else */ + /* Note we do not need to open the source file, this will + * happen later in H5D__virtual_pre_io() */ + } /* end for */ + + /* Update sub_dset_nused */ + storage->list[i].sub_dset_nused = sub_dset_max; + } /* end else */ + } /* end if */ + else { + /* Limited mapping, just make sure the clipped selections were + * already set. Again, no need to open the source file. */ + HDassert(storage->list[i].source_dset.clipped_virtual_select); + HDassert(storage->list[i].source_dset.clipped_source_select); + } /* end else */ + + /* Mark layout as fully initialized */ + storage->init = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_init_all() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_init + * + * Purpose: Initialize the virtual layout information for a dataset. + * This is called when the dataset is initialized. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Thursday, April 30, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__virtual_init(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const H5D_t *dset, + hid_t dapl_id) +{ + H5O_storage_virtual_t *storage; /* Convenience pointer */ + H5P_genplist_t *dapl; /* Data access property list object pointer */ + hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset (unused) */ + size_t i; /* Local index variables */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(dset); + storage = &dset->shared->layout.storage.u.virt; + HDassert(storage->list || (storage->list_nused == 0)); + + /* Check that the dimensions of the VDS are large enough */ + if(H5D_virtual_check_min_dims(dset) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual dataset dimensions not large enough to contain all limited dimensions in all selections") + + /* Patch the virtual selection dataspaces. Note we always patch the space + * status because this layout could be from an old version held in the + * object header message code. We cannot update that held message because + * the layout message is constant, so just overwrite the values here (and + * invalidate other fields by setting storage->init to FALSE below). Also + * remove offset from selections. We only have to update + * source_space_status and virtual_space_status because others will be based + * on these and should therefore already have been normalized. */ + for(i = 0; i < storage->list_nused; i++) { + HDassert(storage->list[i].sub_dset_nalloc == 0); + + /* Patch extent */ + if(H5S_extent_copy(storage->list[i].source_dset.virtual_select, dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent") + storage->list[i].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT; + + /* Mark source extent as invalid */ + storage->list[i].source_space_status = H5O_VIRTUAL_STATUS_INVALID; + + /* Normalize offsets, toss out old offset values */ + if(H5S_hyper_normalize_offset(storage->list[i].source_dset.virtual_select, old_offset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") + if(H5S_hyper_normalize_offset(storage->list[i].source_select, old_offset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") + } /* end for */ + + /* Get dataset access property list */ + if(NULL == (dapl = (H5P_genplist_t *)H5I_object(dapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for dapl ID") + + /* Get view option */ + if(H5P_get(dapl, H5D_ACS_VDS_VIEW_NAME, &storage->view) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get virtual view option") + + /* Get printf gap if view is H5D_VDS_LAST_AVAILABLE, otherwise set to 0 */ + if(storage->view == H5D_VDS_LAST_AVAILABLE) { + if(H5P_get(dapl, H5D_ACS_VDS_PRINTF_GAP_NAME, &storage->printf_gap) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get virtual printf gap") + } /* end if */ + else + storage->printf_gap = (hsize_t)0; + + /* Retrieve VDS file FAPL to layout */ + if(storage->source_fapl <= 0) + if((storage->source_fapl = H5F_get_access_plist(f, FALSE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fapl") + + /* Copy DAPL to layout */ + if(storage->source_dapl <= 0) + if((storage->source_dapl = H5P_copy_plist(dapl, FALSE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dapl") + + /* Mark layout as not fully initialized (must be done prior to I/O for + * unlimited/printf selections) */ + storage->init = FALSE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_is_space_alloc + * + * Purpose: Query if space is allocated for layout + * + * Return: TRUE if space is allocated + * FALSE if it is not + * Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5D__virtual_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage) +{ + hbool_t ret_value; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Just return TRUE, since the global heap object containing the mappings is + * created when the layout message is encoded, and nothing else needs to be + * allocated for virtual datasets. This also ensures that the library never + * assumes (falsely) that no data is present in the dataset, causing errors. + */ + ret_value = TRUE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_is_space_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_pre_io + * + * Purpose: Project all virtual mappings onto mem_space, with the + * results stored in projected_mem_space for each mapping. + * Opens all source datasets if possible. The total number + * of elements is stored in tot_nelmts. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * June 3, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_pre_io(H5D_io_info_t *io_info, + H5O_storage_virtual_t *storage, const H5S_t *file_space, + const H5S_t *mem_space, hsize_t *tot_nelmts) +{ + hssize_t select_nelmts; /* Number of elements in selection */ + hsize_t bounds_start[H5S_MAX_RANK]; /* Selection bounds start */ + hsize_t bounds_end[H5S_MAX_RANK]; /* Selection bounds end */ + int rank; + hbool_t bounds_init = FALSE; /* Whether bounds_start, bounds_end, and rank are valid */ + size_t i, j, k; /* Local index variables */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(storage); + HDassert(mem_space); + HDassert(file_space); + HDassert(tot_nelmts); + + /* Initialize layout if necessary */ + if(!storage->init) + if(H5D__virtual_init_all(io_info->dset, io_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize virtual layout") + + /* Initialize tot_nelmts */ + *tot_nelmts = 0; + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nused; i++) { + /* Sanity check that the virtual space has been patched by now */ + HDassert(storage->list[i].virtual_space_status == H5O_VIRTUAL_STATUS_CORRECT); + + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + hbool_t partial_block; + + HDassert(storage->list[i].unlim_dim_virtual >= 0); + + /* Get selection bounds if necessary */ + if(!bounds_init) { + /* Get rank of VDS */ + if((rank = H5S_GET_EXTENT_NDIMS(io_info->dset->shared->space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions") + + /* Get selection bounds */ + if(H5S_SELECT_BOUNDS(file_space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds") + + /* Adjust bounds_end to represent the extent just enclosing them + * (add 1) */ + for(j = 0; j < (size_t)rank; j++) + bounds_end[j]++; + + /* Bounds are now initialized */ + bounds_init = TRUE; + } /* end if */ + + /* Get index of first block in virtual selection */ + storage->list[i].sub_dset_io_start = (size_t)H5S_hyper_get_first_inc_block(storage->list[i].source_dset.virtual_select, bounds_start[storage->list[i].unlim_dim_virtual], NULL); + + /* Get index of first block outside of virtual selection */ + storage->list[i].sub_dset_io_end = (size_t)H5S_hyper_get_first_inc_block(storage->list[i].source_dset.virtual_select, bounds_end[storage->list[i].unlim_dim_virtual], &partial_block); + if(partial_block) + storage->list[i].sub_dset_io_end++; + if(storage->list[i].sub_dset_io_end > storage->list[i].sub_dset_nused) + storage->list[i].sub_dset_io_end = storage->list[i].sub_dset_nused; + + /* Iterate over sub-source dsets */ + for(j = storage->list[i].sub_dset_io_start; + j < storage->list[i].sub_dset_io_end; j++) { + /* Check for clipped virtual selection */ + if(!storage->list[i].sub_dset[j].clipped_virtual_select) { + hsize_t start[H5S_MAX_RANK]; + /* This should only be NULL if this is a partial block */ + HDassert((j == (storage->list[i].sub_dset_io_end - 1)) + && partial_block); + + /* If the source space status is not correct, we must try to + * open the source dataset to patch it */ + if(storage->list[i].source_space_status != H5O_VIRTUAL_STATUS_CORRECT) { + HDassert(!storage->list[i].sub_dset[j].dset); + if(H5D__virtual_open_source_dset(io_info->dset, &storage->list[i], &storage->list[i].sub_dset[j], io_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + } /* end if */ + + /* If we obtained a valid source space, we must create + * clipped source and virtual selections, otherwise we + * cannot do this and we will leave them NULL. This doesn't + * hurt anything because we can't do I/O because the dataset + * must not have been found. */ + if(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT) { + hsize_t tmp_dims[H5S_MAX_RANK]; + hsize_t vbounds_end[H5S_MAX_RANK]; + + /* Get bounds of virtual selection */ + if(H5S_SELECT_BOUNDS(storage->list[i].sub_dset[j].virtual_select, tmp_dims, vbounds_end) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds") + + HDassert(bounds_init); + + /* Convert bounds to extent (add 1) */ + for(k = 0; k < (size_t)rank; k++) + vbounds_end[k]++; + + /* Temporarily set extent of virtual selection to bounds */ + if(H5S_set_extent(storage->list[i].sub_dset[j].virtual_select, vbounds_end) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + + /* Get current VDS dimensions */ + if(H5S_get_simple_extent_dims(io_info->dset->shared->space, tmp_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions") + + /* Copy virtual selection */ + if(NULL == (storage->list[i].sub_dset[j].clipped_virtual_select = H5S_copy(storage->list[i].sub_dset[j].virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Clip virtual selection to real virtual extent */ + (void)HDmemset(start, 0, sizeof(start)); + if(H5S_select_hyperslab(storage->list[i].sub_dset[j].clipped_virtual_select, H5S_SELECT_AND, start, NULL, tmp_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to clip hyperslab") + + /* Project intersection of virtual space and clipped + * virtual space onto source space (create + * clipped_source_select) */ + if(H5S_select_project_intersection(storage->list[i].sub_dset[j].virtual_select, storage->list[i].source_select, storage->list[i].sub_dset[j].clipped_virtual_select, &storage->list[i].sub_dset[j].clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") + + /* Set extents of virtual_select and + * clipped_virtual_select to virtual extent */ + if(H5S_set_extent(storage->list[i].sub_dset[j].virtual_select, tmp_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + if(H5S_set_extent(storage->list[i].sub_dset[j].clipped_virtual_select, tmp_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + } /* end if */ + } /* end if */ + + /* Only continue if we managed to obtain a + * clipped_virtual_select */ + if(storage->list[i].sub_dset[j].clipped_virtual_select) { + /* Project intersection of file space and mapping virtual space + * onto memory space */ + if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].sub_dset[j].clipped_virtual_select, &storage->list[i].sub_dset[j].projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") + + /* Check number of elements selected */ + if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(storage->list[i].sub_dset[j].projected_mem_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* Check if anything is selected */ + if(select_nelmts > (hssize_t)0) { + /* Open source dataset */ + if(!storage->list[i].sub_dset[j].dset) + /* Try to open dataset */ + if(H5D__virtual_open_source_dset(io_info->dset, &storage->list[i], &storage->list[i].sub_dset[j], io_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + + /* If the source dataset is not open, mark the selected + * elements as zero so projected_mem_space is freed */ + if(!storage->list[i].sub_dset[j].dset) + select_nelmts = (hssize_t)0; + } /* end if */ + + /* If there are not elements selected in this mapping, free + * projected_mem_space, otherwise update tot_nelmts */ + if(select_nelmts == (hssize_t)0) { + if(H5S_close(storage->list[i].sub_dset[j].projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space") + storage->list[i].sub_dset[j].projected_mem_space = NULL; + } /* end if */ + else + *tot_nelmts += (hsize_t)select_nelmts; + } /* end if */ + } /* end for */ + } /* end if */ + else { + if(storage->list[i].source_dset.clipped_virtual_select) { + /* Project intersection of file space and mapping virtual space onto + * memory space */ + if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].source_dset.clipped_virtual_select, &storage->list[i].source_dset.projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") + + /* Check number of elements selected, add to tot_nelmts */ + if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(storage->list[i].source_dset.projected_mem_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* Check if anything is selected */ + if(select_nelmts > (hssize_t)0) { + /* Open source dataset */ + if(!storage->list[i].source_dset.dset) + /* Try to open dataset */ + if(H5D__virtual_open_source_dset(io_info->dset, &storage->list[i], &storage->list[i].source_dset, io_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + + /* If the source dataset is not open, mark the selected elements + * as zero so projected_mem_space is freed */ + if(!storage->list[i].source_dset.dset) + select_nelmts = (hssize_t)0; + } /* end if */ + + /* If there are not elements selected in this mapping, free + * projected_mem_space, otherwise update tot_nelmts */ + if(select_nelmts == (hssize_t)0) { + if(H5S_close(storage->list[i].source_dset.projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space") + storage->list[i].source_dset.projected_mem_space = NULL; + } /* end if */ + else + *tot_nelmts += (hsize_t)select_nelmts; + } /* end if */ + else { + /* If there is no clipped_dim_virtual, this must be an unlimited + * selection whose dataset was not found in the last call to + * H5Dget_space(). Do not attempt to open it as this might + * affect the extent and we are not going to recalculate it + * here. */ + HDassert(storage->list[i].unlim_dim_virtual >= 0); + HDassert(!storage->list[i].source_dset.dset); + } /* end else */ + } /* end else */ + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_pre_io() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_post_io + * + * Purpose: Frees memory structures allocated by H5D__virtual_pre_io. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * June 4, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_post_io(H5O_storage_virtual_t *storage) +{ + size_t i, j; /* Local index variables */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(storage); + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nused; i++) + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + /* Iterate over sub-source dsets */ + for(j = storage->list[i].sub_dset_io_start; + j < storage->list[i].sub_dset_io_end; j++) + /* Close projected memory space */ + if(storage->list[i].sub_dset[j].projected_mem_space) { + if(H5S_close(storage->list[i].sub_dset[j].projected_mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") + storage->list[i].sub_dset[j].projected_mem_space = NULL; + } /* end if */ + } /* end if */ + else + /* Close projected memory space */ + if(storage->list[i].source_dset.projected_mem_space) { + if(H5S_close(storage->list[i].source_dset.projected_mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") + storage->list[i].source_dset.projected_mem_space = NULL; + } /* end if */ + + /* Note the lack of a done: label. This is because there are no HGOTO_ERROR + * calls. If one is added, a done: label must also be added */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_post_io() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_read_one + * + * Purpose: Read from a singe source dataset in a virtual dataset. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 15, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, + const H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset) +{ + H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(source_dset); + + /* Only perform I/O if there is a projected memory space, otherwise there + * were no elements in the projection or the source dataset could not be + * opened */ + if(source_dset->projected_mem_space) { + HDassert(source_dset->dset); + HDassert(source_dset->clipped_source_select); + + /* Project intersection of file space and mapping virtual space onto + * mapping source space */ + if(H5S_select_project_intersection(source_dset->clipped_virtual_select, source_dset->clipped_source_select, file_space, &projected_src_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto source space") + + /* Perform read on source dataset */ + if(H5D__read(source_dset->dset, type_info->dst_type_id, source_dset->projected_mem_space, projected_src_space, io_info->dxpl_id, io_info->u.rbuf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read source dataset") + + /* Close projected_src_space */ + if(H5S_close(projected_src_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected source space") + projected_src_space = NULL; + } /* end if */ + +done: + /* Release allocated resources on failure */ + if(projected_src_space) { + HDassert(ret_value < 0); + if(H5S_close(projected_src_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected source space") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_read_one() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_read + * + * Purpose: Read from a virtual dataset. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, + hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, + H5D_chunk_map_t H5_ATTR_UNUSED *fm) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + hsize_t tot_nelmts; /* Total number of elements mapped to mem_space */ + H5S_t *fill_space = NULL; /* Space to fill with fill value */ + size_t i, j; /* Local index variables */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(io_info); + HDassert(io_info->u.rbuf); + HDassert(type_info); + HDassert(mem_space); + HDassert(file_space); + + storage = &io_info->dset->shared->layout.storage.u.virt; + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); + +#ifdef H5_HAVE_PARALLEL + /* Parallel reads are not supported (yet) */ + if(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI)) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "parallel reads not supported on virtual datasets") +#endif /* H5_HAVE_PARALLEL */ + + /* Prepare for I/O operation */ + if(H5D__virtual_pre_io(io_info, storage, file_space, mem_space, &tot_nelmts) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to prepare for I/O operation") + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nused; i++) { + /* Sanity check that the virtual space has been patched by now */ + HDassert(storage->list[i].virtual_space_status == H5O_VIRTUAL_STATUS_CORRECT); + + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + /* Iterate over sub-source dsets */ + for(j = storage->list[i].sub_dset_io_start; + j < storage->list[i].sub_dset_io_end; j++) + if(H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i].sub_dset[j]) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read source dataset") + } /* end if */ + else + /* Read from source dataset */ + if(H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i].source_dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read source dataset") + } /* end for */ + + /* Fill unmapped part of buffer with fill value */ + if(tot_nelmts < nelmts) { + H5D_fill_value_t fill_status; /* Fill value status */ + + /* Check the fill value status */ + if(H5P_is_fill_value_defined(&io_info->dset->shared->dcpl_cache.fill, &fill_status) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if fill value defined") + + /* Always write fill value to memory buffer unless it is undefined */ + if(fill_status != H5D_FILL_VALUE_UNDEFINED) { + /* Start with fill space equal to memory space */ + if(NULL == (fill_space = H5S_copy(mem_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy memory selection") + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nused; i++) + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + /* Iterate over sub-source dsets */ + for(j = storage->list[i].sub_dset_io_start; + j < storage->list[i].sub_dset_io_end; j++) + if(storage->list[i].sub_dset[j].projected_mem_space) + if(H5S_select_subtract(fill_space, storage->list[i].sub_dset[j].projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to clip fill selection") + } /* end if */ + else + if(storage->list[i].source_dset.projected_mem_space) + /* Subtract projected memory space from fill space */ + if(H5S_select_subtract(fill_space, storage->list[i].source_dset.projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to clip fill selection") + + /* Write fill values to memory buffer */ + if(H5D__fill(io_info->dset->shared->dcpl_cache.fill.buf, io_info->dset->shared->type, io_info->u.rbuf, type_info->mem_type, fill_space, io_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "filling buf failed") + +#ifndef NDEBUG + /* Make sure the total number of elements written (including fill + * values) >= nelmts */ + { + hssize_t select_nelmts; /* Number of elements in selection */ + + /* Get number of elements in fill dataspace */ + if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(fill_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* Verify number of elements is correct. Note that since we + * don't check for overlap we can't assert that these are equal + */ + HDassert((tot_nelmts + (hsize_t)select_nelmts) >= nelmts); + } /* end block */ +#endif /* NDEBUG */ + } /* end if */ + } /* end if */ + +done: + /* Cleanup I/O operation */ + if(H5D__virtual_post_io(storage) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't cleanup I/O operation") + + /* Close fill space */ + if(fill_space) + if(H5S_close(fill_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close fill space") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_write_one + * + * Purpose: Write to a singe source dataset in a virtual dataset. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 15, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, + const H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset) +{ + H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(source_dset); + + /* Only perform I/O if there is a projected memory space, otherwise there + * were no elements in the projection */ + if(source_dset->projected_mem_space) { + HDassert(source_dset->dset); + HDassert(source_dset->clipped_source_select); + + /* In the future we may wish to extent this implementation to extend + * source datasets if a write to a virtual dataset goes past the current + * extent in the unlimited dimension. -NAF */ + /* Project intersection of file space and mapping virtual space onto + * mapping source space */ + if(H5S_select_project_intersection(source_dset->virtual_select, source_dset->clipped_source_select, file_space, &projected_src_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto source space") + + /* Perform write on source dataset */ + if(H5D__write(source_dset->dset, type_info->dst_type_id, source_dset->projected_mem_space, projected_src_space, io_info->dxpl_id, io_info->u.wbuf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write to source dataset") + + /* Close projected_src_space */ + if(H5S_close(projected_src_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected source space") + projected_src_space = NULL; + } /* end if */ + +done: + /* Release allocated resources on failure */ + if(projected_src_space) { + HDassert(ret_value < 0); + if(H5S_close(projected_src_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected source space") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_write_one() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_write + * + * Purpose: Write to a virtual dataset. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, + hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, + H5D_chunk_map_t H5_ATTR_UNUSED *fm) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + hsize_t tot_nelmts; /* Total number of elements mapped to mem_space */ + size_t i, j; /* Local index variables */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(io_info); + HDassert(io_info->u.wbuf); + HDassert(type_info); + HDassert(mem_space); + HDassert(file_space); + + storage = &io_info->dset->shared->layout.storage.u.virt; + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); + +#ifdef H5_HAVE_PARALLEL + /* Parallel writes are not supported (yet) */ + if(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI)) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "parallel writes not supported on virtual datasets") +#endif /* H5_HAVE_PARALLEL */ + + /* Prepare for I/O operation */ + if(H5D__virtual_pre_io(io_info, storage, file_space, mem_space, &tot_nelmts) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to prepare for I/O operation") + + /* Fail if there are unmapped parts of the selection as they would not be + * written */ + if(tot_nelmts != nelmts) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "write requested to unmapped portion of virtual dataset") + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nused; i++) { + /* Sanity check that virtual space has been patched by now */ + HDassert(storage->list[i].virtual_space_status == H5O_VIRTUAL_STATUS_CORRECT); + + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + /* Iterate over sub-source dsets */ + for(j = storage->list[i].sub_dset_io_start; + j < storage->list[i].sub_dset_io_end; j++) + if(H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i].sub_dset[j]) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write to source dataset") + } /* end if */ + else + /* Write to source dataset */ + if(H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i].source_dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write to source dataset") + } /* end for */ + +done: + /* Cleanup I/O operation */ + if(H5D__virtual_post_io(storage) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't cleanup I/O operation") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_flush + * + * Purpose: Writes all dirty data to disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_flush(H5D_t *dset, hid_t dxpl_id) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + size_t i, j; /* Local index variables */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(dset); + + storage = &dset->shared->layout.storage.u.virt; + + /* Flush only open datasets */ + for(i = 0; i < storage->list_nused; i++) + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + /* Iterate over sub-source dsets */ + for(j = 0; j < storage->list[i].sub_dset_nused; j++) + if(storage->list[i].sub_dset[j].dset) + /* Flush source dataset */ + if(H5D__flush_real(storage->list[i].sub_dset[j].dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush source dataset") + } /* end if */ + else + if(storage->list[i].source_dset.dset) + /* Flush source dataset */ + if(H5D__flush_real(storage->list[i].source_dset.dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to write to source dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_flush() */ + @@ -724,6 +724,50 @@ done: /*------------------------------------------------------------------------- + * Function: H5HG_get_obj_size + * + * Purpose: Returns the size of a global heap object. + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Neil Fortner + * Thursday, February 12, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HG_get_obj_size(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, size_t *obj_size) +{ + H5HG_heap_t *heap = NULL; /* Pointer to global heap object */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_TAG(dxpl_id, H5AC__GLOBALHEAP_TAG, FAIL) + + /* Check args */ + HDassert(f); + HDassert(hobj); + HDassert(obj_size); + + /* Load the heap */ + if(NULL == (heap = H5HG_protect(f, dxpl_id, hobj->addr, H5AC__READ_ONLY_FLAG))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap") + + HDassert(hobj->idx < heap->nused); + HDassert(heap->obj[hobj->idx].begin); + + /* Set object size */ + *obj_size = heap->obj[hobj->idx].size; + +done: + if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) +} /* end H5HG_get_obj_size() */ + + +/*------------------------------------------------------------------------- * Function: H5HG_remove * * Purpose: Removes the specified object from the global heap. diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index b090d4c..0c0aa69 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -60,6 +60,7 @@ H5_DLL herr_t H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/); H5_DLL void *H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object, size_t *buf_size/*out*/); H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust); +H5_DLL herr_t H5HG_get_obj_size(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, size_t *obj_size); H5_DLL herr_t H5HG_remove(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj); /* Support routines */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 6f4274f..daffe48 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -35,6 +35,9 @@ /* Local macros */ +/* Version # of encoded virtual dataset global heap blocks */ +#define H5O_LAYOUT_VDS_GH_ENC_VERS 0 + /* PRIVATE PROTOTYPES */ static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, @@ -101,6 +104,7 @@ H5O_layout_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED * unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p) { H5O_layout_t *mesg = NULL; + uint8_t *heap_block = NULL; unsigned u; void *ret_value = NULL; /* Return value */ @@ -115,7 +119,7 @@ H5O_layout_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED * HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") mesg->version = *p++; - if(mesg->version < H5O_LAYOUT_VERSION_1 || mesg->version > H5O_LAYOUT_VERSION_3) + if(mesg->version < H5O_LAYOUT_VERSION_1 || mesg->version > H5O_LAYOUT_VERSION_4) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message") if(mesg->version < H5O_LAYOUT_VERSION_3) { @@ -242,6 +246,147 @@ H5O_layout_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED * mesg->ops = H5D_LOPS_CHUNK; break; + case H5D_VIRTUAL: + /* Check version */ + if(mesg->version < H5O_LAYOUT_VERSION_4) + HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "invalid layout version with virtual layout") + + /* Heap information */ + H5F_addr_decode(f, &p, &(mesg->storage.u.virt.serial_list_hobjid.addr)); + UINT32DECODE(p, mesg->storage.u.virt.serial_list_hobjid.idx); + + /* Initialize other fields */ + mesg->storage.u.virt.list_nused = 0; + mesg->storage.u.virt.list = NULL; + mesg->storage.u.virt.list_nalloc = 0; + mesg->storage.u.virt.view = H5D_VDS_ERROR; + mesg->storage.u.virt.printf_gap = HSIZE_UNDEF; + mesg->storage.u.virt.source_fapl = -1; + mesg->storage.u.virt.source_dapl = -1; + mesg->storage.u.virt.init = FALSE; + + /* Decode heap block if it exists */ + if(mesg->storage.u.virt.serial_list_hobjid.addr != HADDR_UNDEF) { + const uint8_t *heap_block_p; + uint8_t heap_vers; + size_t block_size = 0; + size_t tmp_size; + hsize_t tmp_hsize; + uint32_t stored_chksum; + uint32_t computed_chksum; + size_t i; + + /* Read heap */ + if(NULL == (heap_block = (uint8_t *)H5HG_read(f, dxpl_id, &(mesg->storage.u.virt.serial_list_hobjid), NULL, &block_size))) + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "Unable to read global heap block") + + heap_block_p = (const uint8_t *)heap_block; + + /* Decode the version number of the heap block encoding */ + heap_vers = (uint8_t)*heap_block_p++; + if((uint8_t)H5O_LAYOUT_VDS_GH_ENC_VERS != heap_vers) + HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad version # of encoded VDS heap information, expected %u, got %u", (unsigned)H5O_LAYOUT_VDS_GH_ENC_VERS, (unsigned)heap_vers) + + /* Number of entries */ + H5F_DECODE_LENGTH(f, heap_block_p, tmp_hsize) + + /* Allocate entry list */ + if(NULL == (mesg->storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc((size_t)tmp_hsize * sizeof(H5O_storage_virtual_ent_t)))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate heap block") + mesg->storage.u.virt.list_nalloc = (size_t)tmp_hsize; + mesg->storage.u.virt.list_nused = (size_t)tmp_hsize; + + /* Decode each entry */ + for(i = 0; i < mesg->storage.u.virt.list_nused; i++) { + /* Source file name */ + tmp_size = HDstrlen((const char *)heap_block_p) + 1; + if(NULL == (mesg->storage.u.virt.list[i].source_file_name = (char *)H5MM_malloc(tmp_size))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate memory for source file name") + (void)HDmemcpy(mesg->storage.u.virt.list[i].source_file_name, heap_block_p, tmp_size); + heap_block_p += tmp_size; + + /* Source dataset name */ + tmp_size = HDstrlen((const char *)heap_block_p) + 1; + if(NULL == (mesg->storage.u.virt.list[i].source_dset_name = (char *)H5MM_malloc(tmp_size))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate memory for source dataset name") + (void)HDmemcpy(mesg->storage.u.virt.list[i].source_dset_name, heap_block_p, tmp_size); + heap_block_p += tmp_size; + + /* Source selection */ + if(H5S_SELECT_DESERIALIZE(&mesg->storage.u.virt.list[i].source_select, &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode source space selection") + + /* Virtual selection */ + if(H5S_SELECT_DESERIALIZE(&mesg->storage.u.virt.list[i].source_dset.virtual_select, &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode virtual space selection") + + /* Parse source file and dataset names for "printf" + * style format specifiers */ + if(H5D_virtual_parse_source_name(mesg->storage.u.virt.list[i].source_file_name, &mesg->storage.u.virt.list[i].parsed_source_file_name, &mesg->storage.u.virt.list[i].psfn_static_strlen, &mesg->storage.u.virt.list[i].psfn_nsubs) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't parse source file name") + if(H5D_virtual_parse_source_name(mesg->storage.u.virt.list[i].source_dset_name, &mesg->storage.u.virt.list[i].parsed_source_dset_name, &mesg->storage.u.virt.list[i].psdn_static_strlen, &mesg->storage.u.virt.list[i].psdn_nsubs) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't parse source dataset name") + + /* Set source names in source_dset struct */ + if((mesg->storage.u.virt.list[i].psfn_nsubs == 0) + && (mesg->storage.u.virt.list[i].psdn_nsubs == 0)) { + if(mesg->storage.u.virt.list[i].parsed_source_file_name) + mesg->storage.u.virt.list[i].source_dset.file_name = mesg->storage.u.virt.list[i].parsed_source_file_name->name_segment; + else + mesg->storage.u.virt.list[i].source_dset.file_name = mesg->storage.u.virt.list[i].source_file_name; + if(mesg->storage.u.virt.list[i].parsed_source_dset_name) + mesg->storage.u.virt.list[i].source_dset.dset_name = mesg->storage.u.virt.list[i].parsed_source_dset_name->name_segment; + else + mesg->storage.u.virt.list[i].source_dset.dset_name = mesg->storage.u.virt.list[i].source_dset_name; + } /* end if */ + + /* unlim_dim fields */ + mesg->storage.u.virt.list[i].unlim_dim_source = H5S_get_select_unlim_dim(mesg->storage.u.virt.list[i].source_select); + mesg->storage.u.virt.list[i].unlim_dim_virtual = H5S_get_select_unlim_dim(mesg->storage.u.virt.list[i].source_dset.virtual_select); + mesg->storage.u.virt.list[i].unlim_extent_source = HSIZE_UNDEF; + mesg->storage.u.virt.list[i].unlim_extent_virtual = HSIZE_UNDEF; + mesg->storage.u.virt.list[i].clip_size_source = HSIZE_UNDEF; + mesg->storage.u.virt.list[i].clip_size_virtual = HSIZE_UNDEF; + + /* Clipped selections */ + if(mesg->storage.u.virt.list[i].unlim_dim_virtual < 0) { + mesg->storage.u.virt.list[i].source_dset.clipped_source_select = mesg->storage.u.virt.list[i].source_select; + mesg->storage.u.virt.list[i].source_dset.clipped_virtual_select = mesg->storage.u.virt.list[i].source_dset.virtual_select; + } /* end if */ + + /* Check mapping for validity (do both pre and post + * checks here, since we had to allocate the entry list + * before decoding the selections anyways) */ + if(H5D_virtual_check_mapping_pre(mesg->storage.u.virt.list[i].source_dset.virtual_select, mesg->storage.u.virt.list[i].source_select, H5O_VIRTUAL_STATUS_INVALID) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid mapping selections") + if(H5D_virtual_check_mapping_post(&mesg->storage.u.virt.list[i]) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid mapping entry") + + /* Update min_dims */ + if(H5D_virtual_update_min_dims(mesg, i) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to update virtual dataset minimum dimensions") + } /* end for */ + + /* Read stored checksum */ + UINT32DECODE(heap_block_p, stored_chksum) + + /* Compute checksum */ + computed_chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for global heap block") + + /* Verify that the heap block size is correct */ + if((size_t)(heap_block_p - heap_block) != block_size) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect heap block size") + } /* end if */ + + /* Set the layout operations */ + mesg->ops = H5D_LOPS_VIRTUAL; + + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -254,8 +399,14 @@ H5O_layout_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED * done: if(ret_value == NULL) - if(mesg) + if(mesg) { + if(mesg->type == H5D_VIRTUAL) + if(H5D__virtual_reset_layout(mesg) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to reset virtual layout") mesg = H5FL_FREE(H5O_layout_t, mesg); + } /* end if */ + + heap_block = (uint8_t *)H5MM_xfree(heap_block); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_decode() */ @@ -295,6 +446,8 @@ static herr_t H5O_layout_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; + uint8_t *heap_block = NULL; + size_t *str_size = NULL; unsigned u; herr_t ret_value = SUCCEED; /* Return value */ @@ -306,7 +459,8 @@ H5O_layout_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, c HDassert(p); /* Message version */ - *p++ = (uint8_t)H5O_LAYOUT_VERSION_3; + *p++ = mesg->type == H5D_VIRTUAL ? (uint8_t)H5O_LAYOUT_VERSION_4 + : (uint8_t)H5O_LAYOUT_VERSION_3; /* Layout class */ *p++ = mesg->type; @@ -345,6 +499,109 @@ H5O_layout_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, c UINT32ENCODE(p, mesg->u.chunk.dim[u]); break; + case H5D_VIRTUAL: + /* Create heap block if it has not been created yet */ + /* Note that we assume here that the contents of the heap block + * cannot change! If this ever stops being the case we must change + * this code to allow overwrites of the heap block. -NAF */ + if((mesg->storage.u.virt.serial_list_hobjid.addr == HADDR_UNDEF) + && (mesg->storage.u.virt.list_nused > 0)) { + uint8_t *heap_block_p; + size_t block_size; + hssize_t select_serial_size; + hsize_t tmp_hsize; + uint32_t chksum; + size_t i; + + /* Allocate array for caching results of strlen */ + if(NULL == (str_size = (size_t *)H5MM_malloc(2 * mesg->storage.u.virt.list_nused *sizeof(size_t)))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate string length array") + + /* + * Calculate heap block size + */ + /* Version and number of entries */ + block_size = (size_t)1 + H5F_SIZEOF_SIZE(f); + + /* Calculate size of each entry */ + for(i = 0; i < mesg->storage.u.virt.list_nused; i++) { + HDassert(mesg->storage.u.virt.list[i].source_file_name); + HDassert(mesg->storage.u.virt.list[i].source_dset_name); + HDassert(mesg->storage.u.virt.list[i].source_select); + HDassert(mesg->storage.u.virt.list[i].source_dset.virtual_select); + + /* Source file name */ + str_size[2 * i] = HDstrlen(mesg->storage.u.virt.list[i].source_file_name) + (size_t)1; + block_size += str_size[2 * i]; + + /* Source dset name */ + str_size[(2 * i) + 1] = HDstrlen(mesg->storage.u.virt.list[i].source_dset_name) + (size_t)1; + block_size += str_size[(2 * i) + 1]; + + /* Source selection */ + if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virt.list[i].source_select)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size") + block_size += (size_t)select_serial_size; + + /* Virtual dataset selection */ + if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virt.list[i].source_dset.virtual_select)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size") + block_size += (size_t)select_serial_size; + } /* end for */ + + /* Checksum */ + block_size += 4; + + /* Allocate heap block */ + if(NULL == (heap_block = (uint8_t *)H5MM_malloc(block_size))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate heap block") + + /* + * Encode heap block + */ + heap_block_p = heap_block; + + /* Encode heap block encoding version */ + *heap_block_p++ = (uint8_t)H5O_LAYOUT_VDS_GH_ENC_VERS; + + /* Number of entries */ + tmp_hsize = (hsize_t)mesg->storage.u.virt.list_nused; + H5F_ENCODE_LENGTH(f, heap_block_p, tmp_hsize) + + /* Encode each entry */ + for(i = 0; i < mesg->storage.u.virt.list_nused; i++) { + /* Source file name */ + (void)HDmemcpy((char *)heap_block_p, mesg->storage.u.virt.list[i].source_file_name, str_size[2 * i]); + heap_block_p += str_size[2 * i]; + + /* Source dataset name */ + (void)HDmemcpy((char *)heap_block_p, mesg->storage.u.virt.list[i].source_dset_name, str_size[(2 * i) + 1]); + heap_block_p += str_size[(2 * i) + 1]; + + /* Source selection */ + if(H5S_SELECT_SERIALIZE(mesg->storage.u.virt.list[i].source_select, &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to serialize source selection") + + /* Virtual selection */ + if(H5S_SELECT_SERIALIZE(mesg->storage.u.virt.list[i].source_dset.virtual_select, &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to serialize virtual selection") + } /* end for */ + + /* Checksum */ + chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0); + UINT32ENCODE(heap_block_p, chksum) + + /* Insert block into global heap */ + if(H5HG_insert(f, H5AC_ind_dxpl_id, block_size, heap_block, &((H5O_layout_t *)mesg)->storage.u.virt.serial_list_hobjid) < 0) /* Casting away const OK --NAF */ + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to insert virtual dataset heap block") + } /* end if */ + + /* Heap information */ + H5F_addr_encode(f, &p, mesg->storage.u.virt.serial_list_hobjid.addr); + UINT32ENCODE(p, mesg->storage.u.virt.serial_list_hobjid.idx); + + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -352,6 +609,9 @@ H5O_layout_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, c } /* end switch */ done: + heap_block = (uint8_t *)H5MM_xfree(heap_block); + str_size = (size_t *)H5MM_xfree(str_size); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_encode() */ @@ -417,6 +677,11 @@ H5O_layout_copy(const void *_mesg, void *_dest) H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE); break; + case H5D_VIRTUAL: + if(H5D__virtual_copy_layout(dest) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy virtual layout") + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -488,19 +753,25 @@ static herr_t H5O_layout_reset(void *_mesg) { H5O_layout_t *mesg = (H5O_layout_t *)_mesg; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT if(mesg) { /* Free the compact storage buffer */ if(H5D_COMPACT == mesg->type) mesg->storage.u.compact.buf = H5MM_xfree(mesg->storage.u.compact.buf); + else if(H5D_VIRTUAL == mesg->type) + /* Free the virtual entry list */ + if(H5D__virtual_reset_layout(mesg) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to reset virtual layout") /* Reset the message */ mesg->type = H5D_CONTIGUOUS; } /* end if */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_reset() */ @@ -580,6 +851,12 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; + case H5D_VIRTUAL: /* Virtual dataset */ + /* Free the file space virtual dataset */ + if(H5D__virtual_delete(f, dxpl_id, &mesg->storage) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -667,6 +944,13 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, } /* end if */ break; + case H5D_VIRTUAL: + /* Copy virtual layout. Always copy so the memory fields get copied + * properly. */ + if(H5D__virtual_copy(file_dst, layout_dst, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy virtual storage") + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -766,6 +1050,26 @@ H5O_layout_debug(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, const vo "Data Size:", mesg->storage.u.compact.size); break; + case H5D_VIRTUAL: + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Type:", "Virtual"); + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, + "Global heap address:", mesg->storage.u.virt.serial_list_hobjid.addr); + HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, + "Global heap index:", mesg->storage.u.virt.serial_list_hobjid.idx); + for(u = 0; u < mesg->storage.u.virt.list_nused; u++) { + HDfprintf(stream, "%*sMapping %u:\n", indent, "", u); + HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", fwidth - 3, + "Virtual selection:", "<Not yet implemented>"); + HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", fwidth - 3, + "Source file name:", mesg->storage.u.virt.list[u].source_file_name); + HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", fwidth - 3, + "Source dataset name:", mesg->storage.u.virt.list[u].source_dset_name); + HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", fwidth - 3, + "Source selection:", "<Not yet implemented>"); + } /* end for */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index b6667e9..4586adb 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -38,6 +38,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5Fprivate.h" /* File access */ +#include "H5HGprivate.h" /* Global Heaps */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatype functions */ #include "H5Zprivate.h" /* I/O pipeline filters */ @@ -376,7 +377,8 @@ typedef struct H5O_efl_t { * for larger chunk dimensions, stores chunk indices into their own * message (the "layout index" message), adds features for compact/dense * storage of elements and/or chunk records, adds features for abbreviating - * the storage used for partial chunks on boundaries, etc. + * the storage used for partial chunks on boundaries, adds the virtual + * layout type, etc. */ #define H5O_LAYOUT_VERSION_4 4 @@ -414,12 +416,88 @@ typedef struct H5O_storage_compact_t { void *buf; /* Buffer for compact dataset */ } H5O_storage_compact_t; +typedef struct H5O_storage_virtual_srcdset_t { + /* Stored */ + struct H5S_t *virtual_select; /* Selection in the virtual dataset that is mapped to source selection */ + + /* Not stored */ + char *file_name; /* Source file name used for virtual dataset mapping */ + char *dset_name; /* Source dataset name used for virtual dataset mapping */ + struct H5S_t *clipped_source_select; /* Clipped version of source_select */ + struct H5S_t *clipped_virtual_select; /* Clipped version of virtual_select */ + struct H5D_t *dset; /* Source dataset */ + hbool_t dset_exists; /* Whether the dataset exists (was opened successfully) */ + + /* Temporary - only used during I/O operation, NULL at all other times */ + struct H5S_t *projected_mem_space; /* Selection within mem_space for this mapping */ +} H5O_storage_virtual_srcdset_t; + +typedef struct H5O_storage_virtual_name_seg_t { + char *name_segment; /* String for this name segment */ + struct H5O_storage_virtual_name_seg_t *next; /* Next name segment */ +} H5O_storage_virtual_name_seg_t; + +typedef enum H5O_virtual_space_status_t { + H5O_VIRTUAL_STATUS_INVALID = 0, /* Space extent is invalid */ + H5O_VIRTUAL_STATUS_SEL_BOUNDS, /* Space extent set to bounds of selection */ + H5O_VIRTUAL_STATUS_USER, /* Space extent provided by application */ + H5O_VIRTUAL_STATUS_CORRECT /* Space extent matches dataset */ +} H5O_virtual_space_status_t; + +typedef struct H5O_storage_virtual_ent_t { + /* Stored */ + H5O_storage_virtual_srcdset_t source_dset; /* Information about the source dataset */ + char *source_file_name; /* Original (unparsed) source file name */ + char *source_dset_name; /* Original (unparsed) source dataset name */ + struct H5S_t *source_select; /* Selection in the source dataset for mapping */ + + /* Not stored */ + H5O_storage_virtual_srcdset_t *sub_dset; /* Array of sub-source dataset info structs */ + size_t sub_dset_nalloc; /* Number of slots allocated in sub_dset */ + size_t sub_dset_nused; /* Number of slots "used" in sub_dset - essentially the farthest sub dataset in the extent */ + size_t sub_dset_io_start; /* First element in sub_dset involved in current I/O op. Field has no meaning and may be uninitialized at all other times */ + size_t sub_dset_io_end; /* First element in sub_dset outside of current I/O op. Field has no meaning and may be uninitialized at all other times */ + H5O_storage_virtual_name_seg_t *parsed_source_file_name; /* Parsed version of source_dset.file_name */ + size_t psfn_static_strlen; /* Length of parsed_source_file_name without block number substitutions */ + size_t psfn_nsubs; /* Number of block number substitutions in parsed_source_file_name */ + H5O_storage_virtual_name_seg_t *parsed_source_dset_name; /* Parsed version of source_dset.dset_name */ + size_t psdn_static_strlen; /* Length of parsed_source_dset_name without block number substitutions */ + size_t psdn_nsubs; /* Number of block number substitutions in parsed_source_dset_name */ + int unlim_dim_source; /* Unlimited dimension in source_select */ + int unlim_dim_virtual; /* Unlimited dimension in virtual_select */ + hsize_t unlim_extent_source; /* Extent of unlimited dimension in source dset last time virtual_select was patched to match selection */ + hsize_t unlim_extent_virtual; /* Extent of unlimited dimension in virtual dset last time source_select was patched to match selection */ + hsize_t clip_size_virtual; /* Size selection would be clipped to in virtual selection, ignoring other mappings, when source extent == unlim_extent_source */ + hsize_t clip_size_source; /* Size selection would be clipped to in source selection when virtual extent == unlim_extent_virtual */ + H5O_virtual_space_status_t source_space_status; /* Extent patching status of source_select */ + H5O_virtual_space_status_t virtual_space_status; /* Extent patching status of virtual_select */ +} H5O_storage_virtual_ent_t; + +typedef struct H5O_storage_virtual_t { + /* Stored in message */ + H5HG_t serial_list_hobjid; /* Global heap ID for the list of virtual mapping entries stored on disk */ + + /* Stored in heap */ + size_t list_nused; /* Number of array elements used in list */ + H5O_storage_virtual_ent_t *list; /* Array of virtual dataset mapping entries */ + + /* Not stored */ + size_t list_nalloc; /* Number of slots allocated */ + hsize_t min_dims[H5S_MAX_RANK]; /* Minimum extent of VDS (maximum of all non-unlimited selection bounds) */ + H5D_vds_view_t view; /* Method for calculating the extent of the virtual dataset with unlimited selections */ + hsize_t printf_gap; /* Maximum number of sequential missing source datasets before terminating the search for more */ + hid_t source_fapl; /* FAPL to use to open source files */ + hid_t source_dapl; /* DAPL to use to open source datasets */ + hbool_t init; /* Whether all information has been completely initialized */ +} H5O_storage_virtual_t; + typedef struct H5O_storage_t { H5D_layout_t type; /* Type of layout */ union { H5O_storage_contig_t contig; /* Information for contiguous storage */ H5O_storage_chunk_t chunk; /* Information for chunked storage */ H5O_storage_compact_t compact; /* Information for compact storage */ + H5O_storage_virtual_t virt; /* Information for virtual storage */ } u; } H5O_storage_t; diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index dd9c24d..eab9337 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -62,6 +62,16 @@ #define H5D_ACS_PREEMPT_READ_CHUNKS_DEF H5D_CHUNK_CACHE_W0_DEFAULT #define H5D_ACS_PREEMPT_READ_CHUNKS_ENC H5P__encode_double #define H5D_ACS_PREEMPT_READ_CHUNKS_DEC H5P__decode_double +/* Definitions for VDS view option */ +#define H5D_ACS_VDS_VIEW_SIZE sizeof(H5D_vds_view_t) +#define H5D_ACS_VDS_VIEW_DEF H5D_VDS_LAST_AVAILABLE +#define H5D_ACS_VDS_VIEW_ENC H5P__dacc_vds_view_enc +#define H5D_ACS_VDS_VIEW_DEC H5P__dacc_vds_view_dec +/* Definitions for VDS printf gap */ +#define H5D_ACS_VDS_PRINTF_GAP_SIZE sizeof(hsize_t) +#define H5D_ACS_VDS_PRINTF_GAP_DEF (hsize_t)0 +#define H5D_ACS_VDS_PRINTF_GAP_ENC H5P__encode_hsize_t +#define H5D_ACS_VDS_PRINTF_GAP_DEC H5P__decode_hsize_t /******************/ /* Local Typedefs */ @@ -86,6 +96,10 @@ static herr_t H5P__encode_chunk_cache_nbytes(const void *value, void **_pp, size_t *size); static herr_t H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value); +/* Property list callbacks */ +static herr_t H5P__dacc_vds_view_enc(const void *value, void **pp, size_t *size); +static herr_t H5P__dacc_vds_view_dec(const void **pp, void *value); + /*********************/ /* Package Variables */ @@ -140,6 +154,8 @@ H5P__dacc_reg_prop(H5P_genclass_t *pclass) size_t rdcc_nslots = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF; /* Default raw data chunk cache # of slots */ size_t rdcc_nbytes = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF; /* Default raw data chunk cache # of bytes */ double rdcc_w0 = H5D_ACS_PREEMPT_READ_CHUNKS_DEF; /* Default raw data chunk cache dirty ratio */ + H5D_vds_view_t virtual_view = H5D_ACS_VDS_VIEW_DEF; /* Default VDS view option */ + hsize_t printf_gap = H5D_ACS_VDS_PRINTF_GAP_DEF; /* Default VDS printf gap */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -159,6 +175,18 @@ H5P__dacc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, H5D_ACS_PREEMPT_READ_CHUNKS_ENC, H5D_ACS_PREEMPT_READ_CHUNKS_DEC, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the VDS view option */ + if(H5P_register_real(pclass, H5D_ACS_VDS_VIEW_NAME, H5D_ACS_VDS_VIEW_SIZE, &virtual_view, + NULL, NULL, NULL, H5D_ACS_VDS_VIEW_ENC, H5D_ACS_VDS_VIEW_DEC, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the VDS printf gap */ + if(H5P_register_real(pclass, H5D_ACS_VDS_PRINTF_GAP_NAME, H5D_ACS_VDS_PRINTF_GAP_SIZE, &printf_gap, + NULL, NULL, NULL, H5D_ACS_VDS_PRINTF_GAP_ENC, H5D_ACS_VDS_PRINTF_GAP_DEC, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dacc_reg_prop() */ @@ -511,3 +539,251 @@ H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5P__decode_chunk_cache_nbytes() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_virtual_view + * + * Purpose: Takes the access property list for the virtual dataset, + * dapl_id, and the flag, view, and sets the VDS view + * according to the flag value. The view will include all + * data before the first missing mapped data found if the + * flag is set to H5D_VDS_FIRST_MISSING or to include all + * available mapped data if the flag is set to + * H5D_VDS_LAST_AVAIALBLE. Missing mapped data will be + * filled with the fill value according to the VDS creation + * property settings. For VDS with unlimited mappings, the + * view defines the extent. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 4, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iDv", plist_id, view); + + /* Check argument */ + if((view != H5D_VDS_FIRST_MISSING) && (view != H5D_VDS_LAST_AVAILABLE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid bounds option") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Update property list */ + if(H5P_set(plist, H5D_ACS_VDS_VIEW_NAME, &view) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_virtual_view() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_view + * + * Purpose: Takes the access property list for the virtual dataset, + * dapl_id, and gets the flag, view, set by the + * H5Pset_virtual_view call. The possible values of view are + * H5D_VDS_FIRST_MISSING or H5D_VDS_LAST_AVAIALBLE. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 4, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*Dv", plist_id, view); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get value from property list */ + if(view) + if(H5P_get(plist, H5D_ACS_VDS_VIEW_NAME, view) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_view() */ + + +/*------------------------------------------------------------------------- + * Function: H5P__dacc_vds_view_enc + * + * Purpose: Callback routine which is called whenever the vds view + * property in the dataset access property list is encoded. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Tuesday, May 5, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dacc_vds_view_enc(const void *value, void **_pp, size_t *size) +{ + const H5D_vds_view_t *view = (const H5D_vds_view_t *)value; /* Create local alias for values */ + uint8_t **pp = (uint8_t **)_pp; + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(view); + HDassert(size); + + if(NULL != *pp) + /* Encode EDC property */ + *(*pp)++ = (uint8_t)*view; + + /* Size of EDC property */ + (*size)++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__dacc_vds_view_enc() */ + + +/*------------------------------------------------------------------------- + * Function: H5P__dacc_vds_view_dec + * + * Purpose: Callback routine which is called whenever the vds view + * property in the dataset access property list is encoded. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Tuesday, May 5, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dacc_vds_view_dec(const void **_pp, void *_value) +{ + H5D_vds_view_t *view = (H5D_vds_view_t *)_value; + const uint8_t **pp = (const uint8_t **)_pp; + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(pp); + HDassert(*pp); + HDassert(view); + + /* Decode EDC property */ + *view = (H5D_vds_view_t)*(*pp)++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__dacc_vds_view_dec() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_virtual_printf_gap + * + * Purpose: Sets the access property list for the virtual dataset, + * dapl_id, to instruct the library to stop looking for the + * mapped data stored in the files and/or datasets with the + * printf-style names after not finding gap_size files and/or + * datasets. The found source files and datasets will + * determine the extent of the unlimited VDS with the printf + * -style mappings. + * + * For example, if regularly spaced blocks of VDS are mapped + * to datasets with the names d-1, d-2, d-3, ..., d-N, ..., + * and d-2 dataset is missing and gap_size is set to 0, then + * VDS will contain only data found in d-1. If d-2 and d-3 + * are missing and gap_size is set to 2, then VDS will + * contain the data from d-1, d-3, ..., d-N, .... The blocks + * that are mapped to d-2 and d-3 will be filled according to + * the VDS fill value setting. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 21, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ih", plist_id, gap_size); + + /* Check argument */ + if(gap_size == HSIZE_UNDEF) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid printf gap size") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Update property list */ + if(H5P_set(plist, H5D_ACS_VDS_PRINTF_GAP_NAME, &gap_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_virtual_printf_gap() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_printf_gap + * + * Purpose: Gets the maximum number of missing printf-style files + * and/or datasets for determining the extent of the + * unlimited VDS, gap_size, using the access property list + * for the virtual dataset, dapl_id. The default library + * value for gap_size is 0. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * May 21, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*h", plist_id, gap_size); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get value from property list */ + if(gap_size) + if(H5P_get(plist, H5D_ACS_VDS_PRINTF_GAP_NAME, gap_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_printf_gap() */ + diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 5c64ccb..f3acfe2 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -41,7 +41,9 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* Object headers */ #include "H5Ppkg.h" /* Property lists */ +#include "H5Sprivate.h" /* Dataspaces */ #include "H5Tprivate.h" /* Datatypes */ #include "H5Zprivate.h" /* Data filters */ @@ -55,13 +57,16 @@ #define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0} #define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_IDX_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}} #define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} +#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, H5D_VDS_ERROR, HSIZE_UNDEF, -1, -1, FALSE} #ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER #define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }} #define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }} #define H5D_DEF_STORAGE_CHUNK {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }} +#define H5D_DEF_STORAGE_VIRTUAL {H5D_VIRTUAL, { .virt = H5D_DEF_STORAGE_VIRTUAL_INIT }} #define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_COMPACT} #define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CONTIG} #define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CHUNK} +#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_VIRTUAL} #else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ /* Note that the compact & chunked layout initialization values are using the * contiguous layout initialization in the union, because the contiguous @@ -71,6 +76,7 @@ #define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} #define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} #define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} +#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} #endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ /* ======== Dataset creation properties ======== */ @@ -211,10 +217,12 @@ static const H5O_efl_t H5D_def_efl_g = H5D_CRT_EXT_FILE_LIST_DEF; static const H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT; static const H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG; static const H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK; +static const H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL; #else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ static H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT; static H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG; static H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK; +static H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL; static hbool_t H5P_dcrt_def_layout_init_g = FALSE; #endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ @@ -364,8 +372,12 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size) { const H5O_layout_t *layout = (const H5O_layout_t *)value; /* Create local aliases for values */ uint8_t **pp = (uint8_t **)_pp; + uint8_t *tmp_p; + size_t tmp_size; + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_STATIC /* Sanity check */ HDassert(layout); @@ -374,31 +386,105 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size) if(NULL != *pp) { /* Encode layout type */ *(*pp)++ = (uint8_t)layout->type; + *size += sizeof(uint8_t); /* If layout is chunked, encode chunking structure */ if(H5D_CHUNKED == layout->type) { - unsigned u; /* Local index variable */ - /* Encode rank */ *(*pp)++ = (uint8_t)layout->u.chunk.ndims; + *size += sizeof(uint8_t); /* Encode chunk dims */ HDcompile_assert(sizeof(uint32_t) == sizeof(layout->u.chunk.dim[0])); - for(u = 0; u < layout->u.chunk.ndims; u++) + for(u = 0; u < (size_t)layout->u.chunk.ndims; u++) { UINT32ENCODE(*pp, layout->u.chunk.dim[u]) + *size += sizeof(uint32_t); + } /* end for */ + } /* end if */ + else if(H5D_VIRTUAL == layout->type) { + uint64_t nentries = (uint64_t)layout->storage.u.virt.list_nused; + + /* Encode number of entries */ + UINT64ENCODE(*pp, nentries) + *size += (size_t)8; + + /* Iterate over entries */ + for(u = 0; u < layout->storage.u.virt.list_nused; u++) { + /* Source file name */ + tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1; + (void)HDmemcpy(*pp, layout->storage.u.virt.list[u].source_file_name, tmp_size); + *pp += tmp_size; + *size += tmp_size; + + /* Source dataset name */ + tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1; + (void)HDmemcpy(*pp, layout->storage.u.virt.list[u].source_dset_name, tmp_size); + *pp += tmp_size; + *size += tmp_size; + + /* Source selection. Note that we are not passing the real + * allocated size because we do not know it. H5P__encode should + * have verified that the buffer is large enough for the entire + * list before we get here. */ + tmp_size = (size_t)-1; + tmp_p = *pp; + if(H5S_encode(layout->storage.u.virt.list[u].source_select, pp, &tmp_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize source selection") + *size += (size_t)(*pp - tmp_p); + + /* Virtual dataset selection. Same notes as above apply. */ + tmp_size = (size_t)-1; + tmp_p = *pp; + if(H5S_encode(layout->storage.u.virt.list[u].source_dset.virtual_select, pp, &tmp_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize virtual selection") + *size += (size_t)(*pp - tmp_p); + } /* end for */ } /* end if */ } /* end if */ - - /* Size of layout type */ - *size += sizeof(uint8_t); - - /* Size of chunk info encoding */ - if(H5D_CHUNKED == layout->type) { + else { + /* Size of layout type */ *size += sizeof(uint8_t); - *size += layout->u.chunk.ndims * sizeof(uint32_t); - } /* end if */ - FUNC_LEAVE_NOAPI(SUCCEED) + /* If layout is chunked, calculate chunking structure */ + if(H5D_CHUNKED == layout->type) { + *size += sizeof(uint8_t); + *size += layout->u.chunk.ndims * sizeof(uint32_t); + } /* end if */ + else if(H5D_VIRTUAL == layout->type) { + /* Calculate size of virtual layout info */ + /* number of entries */ + *size += (size_t)8; + + /* NULL pointer to pass to H5S_encode */ + tmp_p = NULL; + + /* Iterate over entries */ + for(u = 0; u < layout->storage.u.virt.list_nused; u++) { + /* Source file name */ + tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1; + *size += tmp_size; + + /* Source dataset name */ + tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1; + *size += tmp_size; + + /* Source selection */ + tmp_size = (size_t)0; + if(H5S_encode(layout->storage.u.virt.list[u].source_select, &tmp_p, &tmp_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize source selection") + *size += tmp_size; + + /* Virtual dataset selection */ + tmp_size = (size_t)0; + if(H5S_encode(layout->storage.u.virt.list[u].source_dset.virtual_select, &tmp_p, &tmp_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize virtual selection") + *size += tmp_size; + } /* end for */ + } /* end if */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dcrt_layout_enc() */ @@ -474,6 +560,100 @@ H5P__dcrt_layout_dec(const void **_pp, void *value) } break; + case H5D_VIRTUAL: + { + uint64_t nentries; /* Number of VDS mappings */ + + /* Decode number of entries */ + UINT64DECODE(*pp, nentries) + + if(nentries == (uint64_t)0) + /* Just use the default struct */ + layout = &H5D_def_layout_virtual_g; + else { + size_t tmp_size; + size_t u; /* Local index variable */ + + /* Initialize to default values */ + tmp_layout = H5D_def_layout_virtual_g; + + /* Allocate entry list */ + if(NULL == (tmp_layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc((size_t)nentries * sizeof(H5O_storage_virtual_ent_t)))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate heap block") + tmp_layout.storage.u.virt.list_nalloc = (size_t)nentries; + tmp_layout.storage.u.virt.list_nused = (size_t)nentries; + + /* Decode each entry */ + for(u = 0; u < (size_t)nentries; u++) { + /* Source file name */ + tmp_size = HDstrlen((const char *)*pp) + 1; + if(NULL == (tmp_layout.storage.u.virt.list[u].source_file_name = (char *)H5MM_malloc(tmp_size))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate memory for source file name") + (void)HDmemcpy(tmp_layout.storage.u.virt.list[u].source_file_name, *pp, tmp_size); + *pp += tmp_size; + + /* Source dataset name */ + tmp_size = HDstrlen((const char *)*pp) + 1; + if(NULL == (tmp_layout.storage.u.virt.list[u].source_dset_name = (char *)H5MM_malloc(tmp_size))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate memory for source dataset name") + (void)HDmemcpy(tmp_layout.storage.u.virt.list[u].source_dset_name, *pp, tmp_size); + *pp += tmp_size; + + /* Source selection */ + if(NULL == (tmp_layout.storage.u.virt.list[u].source_select = H5S_decode(pp))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode source space selection") + tmp_layout.storage.u.virt.list[u].source_space_status = H5O_VIRTUAL_STATUS_USER; + + /* Virtual selection */ + if(NULL == (tmp_layout.storage.u.virt.list[u].source_dset.virtual_select = H5S_decode(pp))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode virtual space selection") + tmp_layout.storage.u.virt.list[u].virtual_space_status = H5O_VIRTUAL_STATUS_USER; + + /* Parse source file and dataset names for "printf" + * style format specifiers */ + if(H5D_virtual_parse_source_name(tmp_layout.storage.u.virt.list[u].source_file_name, &tmp_layout.storage.u.virt.list[u].parsed_source_file_name, &tmp_layout.storage.u.virt.list[u].psfn_static_strlen, &tmp_layout.storage.u.virt.list[u].psfn_nsubs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name") + if(H5D_virtual_parse_source_name(tmp_layout.storage.u.virt.list[u].source_dset_name, &tmp_layout.storage.u.virt.list[u].parsed_source_dset_name, &tmp_layout.storage.u.virt.list[u].psdn_static_strlen, &tmp_layout.storage.u.virt.list[u].psdn_nsubs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name") + + /* Set source names in source_dset struct */ + if((tmp_layout.storage.u.virt.list[u].psfn_nsubs == 0) + && (tmp_layout.storage.u.virt.list[u].psdn_nsubs == 0)) { + if(tmp_layout.storage.u.virt.list[u].parsed_source_file_name) + tmp_layout.storage.u.virt.list[u].source_dset.file_name = tmp_layout.storage.u.virt.list[u].parsed_source_file_name->name_segment; + else + tmp_layout.storage.u.virt.list[u].source_dset.file_name = tmp_layout.storage.u.virt.list[u].source_file_name; + if(tmp_layout.storage.u.virt.list[u].parsed_source_dset_name) + tmp_layout.storage.u.virt.list[u].source_dset.dset_name = tmp_layout.storage.u.virt.list[u].parsed_source_dset_name->name_segment; + else + tmp_layout.storage.u.virt.list[u].source_dset.dset_name = tmp_layout.storage.u.virt.list[u].source_dset_name; + } /* end if */ + + /* unlim_dim fields */ + tmp_layout.storage.u.virt.list[u].unlim_dim_source = H5S_get_select_unlim_dim(tmp_layout.storage.u.virt.list[u].source_select); + tmp_layout.storage.u.virt.list[u].unlim_dim_virtual = H5S_get_select_unlim_dim(tmp_layout.storage.u.virt.list[u].source_dset.virtual_select); + tmp_layout.storage.u.virt.list[u].unlim_extent_source = HSIZE_UNDEF; + tmp_layout.storage.u.virt.list[u].unlim_extent_virtual = HSIZE_UNDEF; + tmp_layout.storage.u.virt.list[u].clip_size_source = HSIZE_UNDEF; + tmp_layout.storage.u.virt.list[u].clip_size_virtual = HSIZE_UNDEF; + + /* Clipped selections */ + if(tmp_layout.storage.u.virt.list[u].unlim_dim_virtual < 0) { + tmp_layout.storage.u.virt.list[u].source_dset.clipped_source_select = tmp_layout.storage.u.virt.list[u].source_select; + tmp_layout.storage.u.virt.list[u].source_dset.clipped_virtual_select = tmp_layout.storage.u.virt.list[u].source_dset.virtual_select; + } /* end if */ + + /* Update min_dims */ + if(H5D_virtual_update_min_dims(&tmp_layout, u) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions") + } /* end for */ + + /* Point at the newly set up struct */ + layout = &tmp_layout; + } /* end else */ + } /* end block */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -619,6 +799,51 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, } /* end case */ break; + case H5D_VIRTUAL: + { + htri_t equal; + int strcmp_ret; + size_t u; /* Local index variable */ + + /* Compare number of mappings */ + if(layout1->storage.u.virt.list_nused < layout2->storage.u.virt.list_nused) HGOTO_DONE(-1) + if(layout1->storage.u.virt.list_nused > layout2->storage.u.virt.list_nused) HGOTO_DONE(1) + + /* Iterate over mappings */ + for(u = 0; u < layout1->storage.u.virt.list_nused; u++) { + /* Compare virtual spaces. Note we cannot tell which is + * "greater", so just return 1 if different, -1 on failure. + */ + if((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1) + if(!equal) + HGOTO_DONE(1) + if((equal = H5S_select_shape_same(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1) + if(!equal) + HGOTO_DONE(1) + + /* Compare source file names */ + strcmp_ret = HDstrcmp(layout1->storage.u.virt.list[u].source_file_name, layout2->storage.u.virt.list[u].source_file_name); + if(strcmp_ret < 0) HGOTO_DONE(-1) + if(strcmp_ret > 0) HGOTO_DONE(1) + + /* Compare source dataset names */ + strcmp_ret = HDstrcmp(layout1->storage.u.virt.list[u].source_dset_name, layout2->storage.u.virt.list[u].source_dset_name); + if(strcmp_ret < 0) HGOTO_DONE(-1) + if(strcmp_ret > 0) HGOTO_DONE(1) + + /* Compare source spaces. Note we cannot tell which is + * "greater", so just return 1 if different, -1 on failure. + */ + if((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1) + if(!equal) + HGOTO_DONE(1) + if((equal = H5S_select_shape_same(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1) + if(!equal) + HGOTO_DONE(1) + } /* end for */ + } /* end block */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1545,6 +1770,7 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout) break; case H5D_CHUNKED: + case H5D_VIRTUAL: fill.alloc_time = H5D_ALLOC_TIME_INCR; break; @@ -1588,6 +1814,7 @@ H5P__init_def_layout(void) const H5O_layout_chunk_t def_layout_chunk = H5D_DEF_LAYOUT_CHUNK_INIT; const H5O_storage_compact_t def_store_compact = H5D_DEF_STORAGE_COMPACT_INIT; const H5O_storage_chunk_t def_store_chunk = H5D_DEF_STORAGE_CHUNK_INIT; + const H5O_storage_virtual_t def_store_virtual = H5D_DEF_STORAGE_VIRTUAL_INIT; FUNC_ENTER_STATIC_NOERR @@ -1597,6 +1824,8 @@ H5P__init_def_layout(void) H5D_def_layout_chunk_g.u.chunk = def_layout_chunk; H5D_def_layout_chunk_g.storage.type = H5D_CHUNKED; H5D_def_layout_chunk_g.storage.u.chunk = def_store_chunk; + H5D_def_layout_virtual_g.storage.type = H5D_VIRTUAL; + H5D_def_layout_virtual_g.storage.u.virt = def_store_virtual; /* Note that we've initialized the default values */ H5P_dcrt_def_layout_init_g = TRUE; @@ -1666,6 +1895,10 @@ H5Pset_layout(hid_t plist_id, H5D_layout_t layout_type) layout = &H5D_def_layout_chunk_g; break; + case H5D_VIRTUAL: + layout = &H5D_def_layout_virtual_g; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1871,6 +2104,515 @@ done: /*------------------------------------------------------------------------- + * Function: H5Pset_virtual + * + * Purpose: Maps elements of the virtual dataset described by the + * virtual dataspace identifier vspace_id to the elements of + * the source dataset described by the source dataset + * dataspace identifier src_space_id. The source dataset is + * identified by the name of the file where it is located, + * src_file_name, and the name of the dataset, src_dset_name. + * + * As a side effect, the layout method is changed to + * H5D_VIRTUAL. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Friday, February 13, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, + const char *src_dset_name, hid_t src_space_id) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_layout_t virtual_layout; /* Layout information for setting virtual info */ + H5S_t *vspace; /* Virtual dataset space selection */ + H5S_t *src_space; /* Source dataset space selection */ + H5O_storage_virtual_ent_t *old_list = NULL; /* List pointer previously on property list */ + H5O_storage_virtual_ent_t *ent = NULL; /* Convenience pointer to new VDS entry */ + hbool_t retrieved_layout = FALSE; /* Whether the layout has been retrieved */ + hbool_t adding_entry = FALSE; /* Whether we are in the middle of adding an entry */ + hbool_t free_list = FALSE; /* Whether to free the list of virtual entries */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "ii*s*si", dcpl_id, vspace_id, src_file_name, src_dset_name, + src_space_id); + + /* Check arguments */ + if(!src_file_name) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "source file name not provided") + if(!src_dset_name) + HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "source dataset name not provided") + if(NULL == (vspace = (H5S_t *)H5I_object_verify(vspace_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dataspace") + if(NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Check selections for validity */ + if(H5D_virtual_check_mapping_pre(vspace, src_space, H5O_VIRTUAL_STATUS_USER) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "invalid mapping selections") + +#ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER + /* If the compiler doesn't support C99 designated initializers, check if + * the default layout structs have been initialized yet or not. *ick* -QAK + */ + if(!H5P_dcrt_def_layout_init_g) + if(H5P__init_def_layout() < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't initialize default layout info") +#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the current layout */ + if(H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &virtual_layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout") + retrieved_layout = TRUE; + + /* If the layout was not already virtual, Start with default virtual layout. + * Otherwise, add the mapping to the current list. */ + if(virtual_layout.type == H5D_VIRTUAL) + /* Save old list pointer for error recovery */ + old_list = virtual_layout.storage.u.virt.list; + else { + /* Reset the old layout */ + if(H5O_msg_reset(H5O_LAYOUT_ID, &virtual_layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release layout message") + + /* Copy the default virtual layout */ + HDmemcpy(&virtual_layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g)); + + /* Sanity check */ + HDassert(virtual_layout.storage.u.virt.list_nalloc == 0); + } /* end else */ + + /* Expand list if necessary */ + if(virtual_layout.storage.u.virt.list_nused == virtual_layout.storage.u.virt.list_nalloc) { + H5O_storage_virtual_ent_t *x; /* Pointer to the new list */ + size_t new_alloc = MAX(H5D_VIRTUAL_DEF_LIST_SIZE, virtual_layout.storage.u.virt.list_nalloc * 2); + + /* Expand size of entry list */ + if(NULL == (x = (H5O_storage_virtual_ent_t *)H5MM_realloc(virtual_layout.storage.u.virt.list, new_alloc * sizeof(H5O_storage_virtual_ent_t)))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't reallocate virtual dataset mapping list") + virtual_layout.storage.u.virt.list = x; + virtual_layout.storage.u.virt.list_nalloc = new_alloc; + } /* end if */ + + /* Add virtual dataset mapping entry */ + ent = &virtual_layout.storage.u.virt.list[virtual_layout.storage.u.virt.list_nused]; + HDmemset(ent, 0, sizeof(H5O_storage_virtual_ent_t)); /* Clear before starting to set up */ + if(NULL == (ent->source_dset.virtual_select = H5S_copy(vspace, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + adding_entry = TRUE; + if(NULL == (ent->source_file_name = HDstrdup(src_file_name))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") + if(NULL == (ent->source_dset_name = HDstrdup(src_dset_name))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") + if(NULL == (ent->source_select = H5S_copy(src_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") + if(H5D_virtual_parse_source_name(ent->source_file_name, &ent->parsed_source_file_name, &ent->psfn_static_strlen, &ent->psfn_nsubs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name") + if(H5D_virtual_parse_source_name(ent->source_dset_name, &ent->parsed_source_dset_name, &ent->psdn_static_strlen, &ent->psdn_nsubs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name") + if((ent->psfn_nsubs == 0) && (ent->psdn_nsubs == 0)) { + if(ent->parsed_source_file_name) + ent->source_dset.file_name = ent->parsed_source_file_name->name_segment; + else + ent->source_dset.file_name = ent->source_file_name; + if(ent->parsed_source_dset_name) + ent->source_dset.dset_name = ent->parsed_source_dset_name->name_segment; + else + ent->source_dset.dset_name = ent->source_dset_name; + } /* end if */ + ent->unlim_dim_source = H5S_get_select_unlim_dim(src_space); + ent->unlim_dim_virtual = H5S_get_select_unlim_dim(vspace); + if(ent->unlim_dim_virtual < 0) { + ent->source_dset.clipped_source_select = ent->source_select; + ent->source_dset.clipped_virtual_select = ent->source_dset.virtual_select; + } /* end if */ + ent->unlim_extent_source = HSIZE_UNDEF; + ent->unlim_extent_virtual = HSIZE_UNDEF; + ent->clip_size_source = HSIZE_UNDEF; + ent->clip_size_virtual = HSIZE_UNDEF; + ent->source_space_status = H5O_VIRTUAL_STATUS_USER; + ent->virtual_space_status = H5O_VIRTUAL_STATUS_USER; + + /* Check entry for validity */ + if(H5D_virtual_check_mapping_post(ent) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid mapping entry") + + /* Update min_dims */ + if(H5D_virtual_update_min_dims(&virtual_layout, virtual_layout.storage.u.virt.list_nused) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions") + + /* Finish adding entry */ + virtual_layout.storage.u.virt.list_nused++; + +done: + /* Set VDS layout information in property list */ + /* (Even on faliure, so there's not a mangled layout struct in the list) */ + if(retrieved_layout) { + if(H5P_poke(plist, H5D_CRT_LAYOUT_NAME, &virtual_layout) < 0) { + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") + if(old_list != virtual_layout.storage.u.virt.list) + free_list = TRUE; + } /* end if */ + } /* end if */ + + /* Check if the entry has been partly allocated but not added to the + * property list or not included in list_nused */ + if(ret_value < 0) { + /* Free incomplete entry if present */ + if(ent) { + ent->source_file_name = (char *)H5MM_xfree(ent->source_file_name); + ent->source_dset_name = (char *)H5MM_xfree(ent->source_dset_name); + if(ent->source_dset.virtual_select && H5S_close(ent->source_dset.virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") + ent->source_dset.virtual_select = NULL; + if(ent->source_select && H5S_close(ent->source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + ent->source_select = NULL; + H5D_virtual_free_parsed_name(ent->parsed_source_file_name); + ent->parsed_source_file_name = NULL; + H5D_virtual_free_parsed_name(ent->parsed_source_dset_name); + ent->parsed_source_dset_name = NULL; + } /* end if */ + + /* Free list if necessary */ + if(free_list) + virtual_layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_xfree(virtual_layout.storage.u.virt.list); + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_virtual() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_count + * + * Purpose: Gets the number of mappings for the virtual dataset that + * has a creation property list specified by the dcpl_id + * parameter. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Friday, February 13, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_virtual_count(hid_t dcpl_id, size_t *count/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_layout_t layout; /* Layout information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", dcpl_id, count); + + if(count) { + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Retrieve the layout property */ + if(H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout") + if(H5D_VIRTUAL != layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout") + + /* Return the number of mappings */ + *count = layout.storage.u.virt.list_nused; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_count() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_vspace + * + * Purpose: Takes the dataset creation property list for the virtual + * dataset, dcpl_id, and the mapping index, index, and + * returns a dataspace identifier for the selection within + * the virtual dataset used in the mapping. + * + * Return: Returns a dataspace identifier if successful; otherwise + * returns a negative value. + * + * Programmer: Neil Fortner + * Friday, February 13, 2015 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Pget_virtual_vspace(hid_t dcpl_id, size_t index) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_layout_t layout; /* Layout information */ + H5S_t *space = NULL; /* Dataspace pointer */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("i", "iz", dcpl_id, index); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Retrieve the layout property */ + if(H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout") + if(H5D_VIRTUAL != layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout") + + /* Get the virtual space */ + if(index >= layout.storage.u.virt.list_nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") + HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); + if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Register ID */ + if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space") + +done: + /* Free space on failure */ + if((ret_value < 0) && space) + if(H5S_close(space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_vspace() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_srcspace + * + * Purpose: Takes the dataset creation property list for the virtual + * dataset, dcpl_id, and the mapping index, index, and + * returns a dataspace identifier for the selection within + * the source dataset used in the mapping. + * + * Return: Returns a dataspace identifier if successful; otherwise + * returns a negative value. + * + * Programmer: Neil Fortner + * Saturday, February 14, 2015 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_layout_t layout; /* Layout information */ + H5S_t *space = NULL; /* Dataspace pointer */ + hid_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("i", "iz", dcpl_id, index); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Retrieve the layout property */ + if(H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout") + if(H5D_VIRTUAL != layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout") + + /* Check index */ + if(index >= layout.storage.u.virt.list_nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") + HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); + + /* Attempt to open source dataset and patch extent if extent status is not + * H5O_VIRTUAL_STATUS_CORRECT? -NAF */ + /* If source space status is H5O_VIRTUAL_STATUS_INVALID, patch with bounds + * of selection */ + if((H5O_VIRTUAL_STATUS_INVALID == layout.storage.u.virt.list[index].source_space_status) + && (layout.storage.u.virt.list[index].unlim_dim_source < 0)) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + int rank; + int i; + + /* Get rank of source space */ + if((rank = H5S_GET_EXTENT_NDIMS(layout.storage.u.virt.list[index].source_select)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get source space rank") + + /* Get bounds of selection */ + if(H5S_SELECT_BOUNDS(layout.storage.u.virt.list[index].source_select, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Adjust bounds to extent */ + for(i = 0; i < rank; i++) + bounds_end[i]++; + + /* Set extent */ + if(H5S_set_extent_simple(layout.storage.u.virt.list[index].source_select, (unsigned)rank, bounds_end, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set source space extent") + + /* Update source space status */ + layout.storage.u.virt.list[index].source_space_status = H5O_VIRTUAL_STATUS_SEL_BOUNDS; + } /* end if */ + + /* Get the source space */ + if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Register ID */ + if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space") + +done: + /* Free space on failure */ + if((ret_value < 0) && space) + if(H5S_close(space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_srcspace() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_filename + * + * Purpose: Takes the dataset creation property list for the virtual + * dataset, dcpl_id, and the mapping index, index, and + * retrieves a name of a file for a source dataset used in + * the mapping. + * + * Up to size characters of the filename are returned in + * name; additional characters, if any, are not returned to + * the user application. + * + * If the length of the filename, which determines the + * required value of size, is unknown, a preliminary call to + * H5Pget_virtual_filename with the last two parameters set + * to NULL can be made. The return value of this call will + * be the size in bytes of the filename. That value, plus 1 + * for a NULL terminator, is then assigned to size for a + * second H5Pget_virtual_filename call, which will retrieve + * the actual filename. + * + * Return: Returns the length of the name if successful, otherwise + * returns a negative value. + * + * Programmer: Neil Fortner + * Saturday, February 14, 2015 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name/*out*/, + size_t size) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_layout_t layout; /* Layout information */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("Zs", "izxz", dcpl_id, index, name, size); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Retrieve the layout property */ + if(H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout") + if(H5D_VIRTUAL != layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout") + + /* Get the virtual filename */ + if(index >= layout.storage.u.virt.list_nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") + HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); + HDassert(layout.storage.u.virt.list[index].source_file_name); + if(name && (size > 0)) + (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_file_name, size); + ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_file_name); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_filename() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_dsetname + * + * Purpose: Takes the dataset creation property list for the virtual + * dataset, dcpl_id, and the mapping index, index, and + * retrieves the name of a source dataset used in the mapping. + * + * Up to size characters of the name are returned in name; + * additional characters, if any, are not returned to the + * user application. + * + * If the length of the filename, which determines the + * required value of size, is unknown, a preliminary call to + * H5Pget_virtual_dsetname with the last two parameters set + * to NULL can be made. The return value of this call will + * be the size in bytes of the filename. That value, plus 1 + * for a NULL terminator, is then assigned to size for a + * second H5Pget_virtual_dsetname call, which will retrieve + * the actual filename. + * + * Return: Returns the length of the name if successful, otherwise + * returns a negative value. + * + * Programmer: Neil Fortner + * Saturday, February 14, 2015 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name/*out*/, + size_t size) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_layout_t layout; /* Layout information */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("Zs", "izxz", dcpl_id, index, name, size); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Retrieve the layout property */ + if(H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout") + if(H5D_VIRTUAL != layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout") + + /* Get the virtual filename */ + if(index >= layout.storage.u.virt.list_nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") + HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); + HDassert(layout.storage.u.virt.list[index].source_dset_name); + if(name && (size > 0)) + (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_dset_name, size); + ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_dset_name); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_virtual_dsetname() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_external * * Purpose: Adds an external file to the list of external files. PLIST_ID @@ -2710,6 +3452,10 @@ H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time) alloc_time = H5D_ALLOC_TIME_INCR; break; + case H5D_VIRTUAL: + alloc_time = H5D_ALLOC_TIME_INCR; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index f56692c..4929621 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -354,6 +354,15 @@ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); H5_DLL H5D_layout_t H5Pget_layout(hid_t plist_id); H5_DLL herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]); H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/); +H5_DLL herr_t H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, + const char *src_file_name, const char *src_dset_name, hid_t src_space_id); +H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count/*out*/); +H5_DLL hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index); +H5_DLL hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index); +H5_DLL ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index, + char *name/*out*/, size_t size); +H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, + char *name/*out*/, size_t size); H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size); H5_DLL int H5Pget_external_count(hid_t plist_id); @@ -384,6 +393,10 @@ H5_DLL herr_t H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots/*out*/, size_t *rdcc_nbytes/*out*/, double *rdcc_w0/*out*/); +H5_DLL herr_t H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view); +H5_DLL herr_t H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view); +H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size); +H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size); /* Dataset xfer property list (DXPL) routines */ H5_DLL herr_t H5Pset_data_transform(hid_t plist_id, const char* expression); @@ -50,8 +50,6 @@ /* Local Prototypes */ /********************/ static htri_t H5S_is_simple(const H5S_t *sdim); -static herr_t H5S_encode(H5S_t *obj, unsigned char **p, size_t *nalloc); -static H5S_t *H5S_decode(const unsigned char **p); /*********************/ @@ -1575,7 +1573,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5S_encode(H5S_t *obj, unsigned char **p, size_t *nalloc) { H5F_t *f = NULL; /* Fake file structure*/ @@ -1693,7 +1691,7 @@ done: * *------------------------------------------------------------------------- */ -static H5S_t* +H5S_t* H5S_decode(const unsigned char **p) { H5F_t *f = NULL; /* Fake file structure*/ diff --git a/src/H5Sall.c b/src/H5Sall.c index b8a39cc..fb6b45f 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -40,9 +40,11 @@ static herr_t H5S_all_release(H5S_t *space); static htri_t H5S_all_is_valid(const H5S_t *space); static hssize_t H5S_all_serial_size(const H5S_t *space); static herr_t H5S_all_serialize(const H5S_t *space, uint8_t **p); -static herr_t H5S_all_deserialize(H5S_t *space, const uint8_t **p); +static herr_t H5S_all_deserialize(H5S_t *space, uint32_t version, uint8_t flags, + const uint8_t **p); static herr_t H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static herr_t H5S_all_offset(const H5S_t *space, hsize_t *off); +static int H5S__all_unlim_dim(const H5S_t *space); static htri_t H5S_all_is_contiguous(const H5S_t *space); static htri_t H5S_all_is_single(const H5S_t *space); static htri_t H5S_all_is_regular(const H5S_t *space); @@ -74,6 +76,8 @@ const H5S_select_class_t H5S_sel_all[1] = {{ H5S_all_deserialize, H5S_all_bounds, H5S_all_offset, + H5S__all_unlim_dim, + NULL, H5S_all_is_contiguous, H5S_all_is_single, H5S_all_is_regular, @@ -545,6 +549,8 @@ H5S_all_serialize(const H5S_t *space, uint8_t **p) herr_t H5S_all_deserialize(space, p) H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint32_t version IN: Selection version + uint8_t flags IN: Selection flags uint8 **p; OUT: Pointer to buffer holding serialized selection. Will be advanced to end of serialized selection. @@ -559,7 +565,8 @@ H5S_all_serialize(const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_all_deserialize(H5S_t *space, const uint8_t H5_ATTR_UNUSED **p) +H5S_all_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ATTR_UNUSED flags, + const uint8_t H5_ATTR_UNUSED **p) { herr_t ret_value = SUCCEED; /* return value */ @@ -665,6 +672,36 @@ H5S_all_offset(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset) /*-------------------------------------------------------------------------- NAME + H5S__all_unlim_dim + PURPOSE + Return unlimited dimension of selection, or -1 if none + USAGE + int H5S__all_unlim_dim(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + Unlimited dimension of selection, or -1 if none (never fails). + DESCRIPTION + Returns the index of the unlimited dimension in this selection, or -1 + if the selection has no unlimited dimension. "All" selections are + always unlimited in every dimension, though this is not reflected in + other calls, where the selection is "clipped" against the current + extent, so for consistency this function always returns -1. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5S__all_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) +{ + FUNC_ENTER_STATIC_NOERR + + FUNC_LEAVE_NOAPI(-1) +} /* end H5S__all_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_all_is_contiguous PURPOSE Check if a "all" selection is contiguous within the dataspace extent. @@ -982,6 +1019,7 @@ H5S_all_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED /* Determine the actual number of elements to use */ H5_CHECK_OVERFLOW(iter->elmt_left,hsize_t,size_t); elem_used=MIN(maxelem,(size_t)iter->elmt_left); + HDassert(elem_used > 0); /* Compute the offset in the dataset */ off[0]=iter->u.all.byte_offset; diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 10bcdd6..28cabf0 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -45,6 +45,10 @@ static herr_t H5S_hyper_generate_spans(H5S_t *space); #ifdef NEW_HYPERSLAB_API static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2); #endif /*NEW_HYPERSLAB_API*/ +static void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, + hsize_t *count, hsize_t *block, hsize_t clip_size); +static hsize_t H5S__hyper_get_clip_extent_real(const H5S_t *clip_space, + hsize_t num_slices, hbool_t incl_trail); /* Selection callbacks */ static herr_t H5S_hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); @@ -55,9 +59,13 @@ static herr_t H5S_hyper_release(H5S_t *space); static htri_t H5S_hyper_is_valid(const H5S_t *space); static hssize_t H5S_hyper_serial_size(const H5S_t *space); static herr_t H5S_hyper_serialize(const H5S_t *space, uint8_t **p); -static herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t **p); +static herr_t H5S_hyper_deserialize(H5S_t *space, uint32_t version, uint8_t flags, + const uint8_t **p); static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static herr_t H5S_hyper_offset(const H5S_t *space, hsize_t *offset); +static int H5S__hyper_unlim_dim(const H5S_t *space); +static herr_t H5S_hyper_num_elem_non_unlim(const H5S_t *space, + hsize_t *num_elem_non_unlim); static htri_t H5S_hyper_is_contiguous(const H5S_t *space); static htri_t H5S_hyper_is_single(const H5S_t *space); static htri_t H5S_hyper_is_regular(const H5S_t *space); @@ -94,6 +102,8 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S_hyper_deserialize, H5S_hyper_bounds, H5S_hyper_offset, + H5S__hyper_unlim_dim, + H5S_hyper_num_elem_non_unlim, H5S_hyper_is_contiguous, H5S_hyper_is_single, H5S_hyper_is_regular, @@ -248,6 +258,7 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) /* Check args */ HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); HDassert(iter); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); /* Initialize the number of points to iterate over */ iter->elmt_left = space->select.num_elem; @@ -1644,6 +1655,8 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection) dst_hslab->app_diminfo[u]=src_hslab->app_diminfo[u]; } /* end for */ } /* end if */ + dst_hslab->unlim_dim = src_hslab->unlim_dim; + dst_hslab->num_elem_non_unlim = src_hslab->num_elem_non_unlim; dst->select.sel_info.hslab->span_lst=src->select.sel_info.hslab->span_lst; /* Check if there is hyperslab span information to copy */ @@ -1759,6 +1772,10 @@ H5S_hyper_is_valid (const H5S_t *space) HDassert(space); + /* Check for unlimited selection */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_DONE(FALSE) + /* Check for a "regular" hyperslab selection */ if(space->select.sel_info.hslab->diminfo_valid) { const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ @@ -1863,6 +1880,7 @@ H5S_get_select_hyper_nblocks(H5S_t *space) FUNC_ENTER_NOAPI_NOINIT_NOERR HDassert(space); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); /* Check for a "regular" hyperslab selection */ if(space->select.sel_info.hslab->diminfo_valid) { @@ -1910,6 +1928,8 @@ H5Sget_select_hyper_nblocks(hid_t spaceid) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection") + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get number of blocks for unlimited selection") ret_value = (hssize_t)H5S_get_select_hyper_nblocks(space); @@ -1948,24 +1968,41 @@ H5S_hyper_serial_size(const H5S_t *space) HDassert(space); - /* Basic number of bytes required to serialize hyperslab selection: - * <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> + - * <length (4 bytes)> + <rank (4 bytes)> + <# of blocks (4 bytes)> = 24 bytes - */ - ret_value = 24; + /* Check for version (right now, an unlimited dimension is the only thing + * that would bump the version) */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + /* Version 2 */ + /* Size required is always: + * <type (4 bytes)> + <version (4 bytes)> + <flags (1 byte)> + + * <length (4 bytes)> + <rank (4 bytes)> + + * (4 (start/stride/count/block) * <rank> * <value (8 bytes)>) = + * 17 + (4 * rank * 8) bytes + */ + ret_value = (hssize_t)17 + ((hssize_t)4 * (hssize_t)space->extent.rank + * (hssize_t)8); + else { + /* Version 1 */ + /* Basic number of bytes required to serialize hyperslab selection: + * <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> + + * <length (4 bytes)> + <rank (4 bytes)> + <# of blocks (4 bytes)> + * = 24 bytes + */ + ret_value = 24; - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - /* Check each dimension */ - for(block_count = 1, u = 0; u < space->extent.rank; u++) - block_count *= space->select.sel_info.hslab->opt_diminfo[u].count; - } /* end if */ - else - /* Spin through hyperslab spans, adding 8 * rank bytes for each block */ - block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst); + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + /* Check each dimension */ + for(block_count = 1, u = 0; u < space->extent.rank; u++) + block_count *= space->select.sel_info.hslab->opt_diminfo[u].count; + } /* end if */ + else + /* Spin through hyperslab spans, adding 8 * rank bytes for each + * block */ + block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst); - H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, hssize_t); - ret_value += (hssize_t)(8 * block_count * space->extent.rank); + H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, hssize_t); + ret_value += (hssize_t)(8 * block_count * space->extent.rank); + } /* end else */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_serial_size() */ @@ -2020,8 +2057,7 @@ H5S_hyper_serialize_helper(const H5S_hyper_span_info_t *spans, end[rank]=curr->high; /* Recurse down to the next dimension */ - *p = pp; - H5S_hyper_serialize_helper(curr->down, start, end, rank + 1, p); + H5S_hyper_serialize_helper(curr->down, start, end, rank + 1, &pp); } /* end if */ else { /* Encode all the previous dimensions starting & ending points */ @@ -2079,12 +2115,14 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t **p) const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ uint8_t *pp = (*p); /* Local pointer for decoding */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ + hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */ hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */ - hsize_t temp_off; /* Offset in a given dimension */ + hsize_t temp_off; /* Offset in a given dimension */ uint8_t *lenp; /* pointer to length location for later storage */ uint32_t len = 0; /* number of bytes used */ + uint32_t version; /* Version number */ + uint8_t flags = 0; /* Flags for message */ hsize_t block_count; /* block counter for regular hyperslabs */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned ndims; /* Rank of the dataspace */ @@ -2092,15 +2130,25 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t **p) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Check args */ HDassert(space); HDassert(p); HDassert(pp); + /* Calculate version */ + if(space->select.sel_info.hslab->unlim_dim >= 0) { + version = 2; + flags |= H5S_SELECT_FLAG_UNLIM; + } /* end if */ + else + version = 1; + /* Store the preamble information */ UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(pp, (uint32_t)1); /* Store the version number */ - UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */ + UINT32ENCODE(pp, version); /* Store the version number */ + if(version >= 2) + *(pp)++ = flags; /* Store the flags */ + else + UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */ lenp = pp; /* keep the pointer to the length location for later */ pp += 4; /* skip over space for length */ @@ -2108,8 +2156,23 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t **p) UINT32ENCODE(pp, (uint32_t)space->extent.rank); len += 4; + /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ + if(flags & H5S_SELECT_FLAG_UNLIM) { + unsigned i; + + HDassert(H5S_UNLIMITED == HSIZE_UNDEF); + + /* Iterate over dimensions */ + for(i = 0; i < space->extent.rank; i++) { + /* Encode start/stride/block/count */ + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].start); + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].stride); + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].count); + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].block); + } /* end for */ + } /* end if */ /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { + else if(space->select.sel_info.hslab->diminfo_valid) { unsigned u; /* Local counting variable */ /* Set some convienence values */ @@ -2209,8 +2272,7 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t **p) len += (uint32_t)(8 * space->extent.rank * block_count); /* Encode each hyperslab in selection */ - *p = pp; - H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, p); + H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &pp); } /* end else */ /* Encode length */ @@ -2232,6 +2294,8 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t **p) herr_t H5S_hyper_deserialize(space, p) H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint32_t version IN: Selection version + uint8_t flags IN: Selection flags uint8 **p; OUT: Pointer to buffer holding serialized selection. Will be advanced to end of serialized selection. @@ -2246,10 +2310,11 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_deserialize(H5S_t *space, const uint8_t **p) +H5S_hyper_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t flags, + const uint8_t **p) { - const uint8_t *pp = (*p); /* Local pointer for decoding */ unsigned rank; /* rank of points */ + const uint8_t *pp = (*p); /* Local pointer for decoding */ size_t num_elem=0; /* number of elements in selection */ hsize_t start[H5O_LAYOUT_NDIMS]; /* hyperslab start information */ hsize_t end[H5O_LAYOUT_NDIMS]; /* hyperslab end information */ @@ -2274,32 +2339,54 @@ H5S_hyper_deserialize(H5S_t *space, const uint8_t **p) /* Deserialize slabs to select */ /* (The header and rank have already beed decoded) */ rank = space->extent.rank; /* Retrieve rank from space */ - UINT32DECODE(pp,num_elem); /* decode the number of points */ - /* Set the count & stride for all blocks */ - for(tcount=count,tstride=stride,j=0; j<rank; j++,tstride++,tcount++) { - *tcount=1; - *tstride=1; - } /* end for */ + /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ + if(flags & H5S_SELECT_FLAG_UNLIM) { + HDassert(H5S_UNLIMITED == HSIZE_UNDEF); + HDassert(version >= 2); + + /* Iterate over dimensions */ + for(i = 0; i < space->extent.rank; i++) { + /* Decode start/stride/block/count */ + UINT64DECODE(pp, start[i]); + UINT64DECODE(pp, stride[i]); + UINT64DECODE(pp, count[i]); + UINT64DECODE(pp, block[i]); + } /* end for */ - /* Retrieve the coordinates from the buffer */ - for(i=0; i<num_elem; i++) { - /* Decode the starting points */ - for(tstart=start,j=0; j<rank; j++,tstart++) - UINT32DECODE(pp, *tstart); + /* Select the hyperslab to the current selection */ + if((ret_value = H5S_select_hyperslab(space, H5S_SELECT_SET, start, stride, count, block)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") + } /* end if */ + else { + /* decode the number of points */ + UINT32DECODE(pp,num_elem); - /* Decode the ending points */ - for(tend=end,j=0; j<rank; j++,tend++) - UINT32DECODE(pp, *tend); + /* Set the count & stride for all blocks */ + for(tcount = count, tstride = stride, j = 0; j < rank; j++, tstride++, tcount++) { + *tcount=1; + *tstride=1; + } /* end for */ - /* Change the ending points into blocks */ - for(tblock=block,tstart=start,tend=end,j=0; j<rank; j++,tstart++,tend++,tblock++) - *tblock=(*tend-*tstart)+1; + /* Retrieve the coordinates from the buffer */ + for(i = 0; i < num_elem; i++) { + /* Decode the starting points */ + for(tstart=start,j=0; j<rank; j++,tstart++) + UINT32DECODE(pp, *tstart); - /* Select or add the hyperslab to the current selection */ - if((ret_value=H5S_select_hyperslab(space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") - } /* end for */ + /* Decode the ending points */ + for(tend = end, j = 0; j < rank; j++, tend++) + UINT32DECODE(pp, *tend); + + /* Change the ending points into blocks */ + for(tblock=block,tstart=start,tend=end,j=0; j<rank; j++,tstart++,tend++,tblock++) + *tblock=(*tend-*tstart)+1; + + /* Select or add the hyperslab to the current selection */ + if((ret_value=H5S_select_hyperslab(space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") + } /* end for */ + } /* end else */ /* Update decoding pointer */ *p = pp; @@ -2452,6 +2539,7 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc HDassert(space); HDassert(buf); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); /* Check for a "regular" hyperslab selection */ if(space->select.sel_info.hslab->diminfo_valid) { @@ -2475,11 +2563,19 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc */ diminfo = space->select.sel_info.hslab->opt_diminfo; else - /* - * Use the "application dimension information" to pass back to the user - * the blocks they set, not the optimized, internal information. - */ - diminfo = space->select.sel_info.hslab->app_diminfo; + if(space->select.sel_info.hslab->unlim_dim >= 0) + /* + * There is an unlimited dimension so we must use opt_diminfo as + * it has been "clipped" to the current extent. + */ + diminfo = space->select.sel_info.hslab->opt_diminfo; + else + /* + * Use the "application dimension information" to pass back to + * the user the blocks they set, not the optimized, internal + * information. + */ + diminfo = space->select.sel_info.hslab->app_diminfo; /* Build the tables of count sizes as well as the initial offset */ for(u = 0; u < ndims; u++) { @@ -2616,6 +2712,8 @@ H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_HYPERSLABS) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection") + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get blocklist for unlimited selection") /* Go get the correct number of blocks */ if(numblocks > 0) @@ -2758,7 +2856,10 @@ H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) start[i] = diminfo[i].start + (hsize_t)space->select.offset[i]; /* Compute the largest location in this dimension */ - end[i] = diminfo[i].start + diminfo[i].stride * (diminfo[i].count - 1) + (diminfo[i].block - 1) + (hsize_t)space->select.offset[i]; + if((int)i == space->select.sel_info.hslab->unlim_dim) + end[i] = H5S_UNLIMITED; + else + end[i] = diminfo[i].start + diminfo[i].stride * (diminfo[i].count - 1) + (diminfo[i].block - 1) + (hsize_t)space->select.offset[i]; } /* end for */ } /* end if */ else { @@ -2881,6 +2982,75 @@ done: /*-------------------------------------------------------------------------- NAME + H5S__hyper_unlim_dim + PURPOSE + Return unlimited dimension of selection, or -1 if none + USAGE + int H5S__hyper_unlim_dim(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + Unlimited dimension of selection, or -1 if none (never fails). + DESCRIPTION + Returns the index of the unlimited dimension of the selection, or -1 + if the selection has no unlimited dimension. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5S__hyper_unlim_dim(const H5S_t *space) +{ + FUNC_ENTER_STATIC_NOERR + + FUNC_LEAVE_NOAPI(space->select.sel_info.hslab->unlim_dim); +} /* end H5S__hyper_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_num_elem_non_unlim + PURPOSE + Return number of elements in the non-unlimited dimensions + USAGE + herr_t H5S_hyper_num_elem_non_unlim(space,num_elem_non_unlim) + H5S_t *space; IN: Dataspace pointer to check + hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Returns the number of elements in a slice through the non-unlimited + dimensions of the selection. Fails if the selection has no unlimited + dimension. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_hyper_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(space); + HDassert(num_elem_non_unlim); + + /* Get number of elements in the non-unlimited dimensions */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + *num_elem_non_unlim = space->select.sel_info.hslab->num_elem_non_unlim; + else + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection has no unlimited dimension") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_num_elem_non_unlim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_hyper_is_contiguous PURPOSE Check if a hyperslab selection is contiguous within the dataspace extent. @@ -3592,6 +3762,9 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, hsize_t *coords) /* Reset "regular" hyperslab flag */ space->select.sel_info.hslab->diminfo_valid = FALSE; + /* Set unlim_dim */ + space->select.sel_info.hslab->unlim_dim = -1; + /* Set # of elements in selection */ space->select.num_elem = 1; } /* end if */ @@ -4301,6 +4474,9 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off if(NULL == (new_space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + /* Set unlim_dim */ + new_space->select.sel_info.hslab->unlim_dim = -1; + /* Check for a "regular" hyperslab selection */ if(base_space->select.sel_info.hslab->diminfo_valid) { unsigned base_space_dim; /* Current dimension in the base dataspace */ @@ -6047,6 +6223,15 @@ H5S_hyper_generate_spans(H5S_t *space) /* Get the diminfo */ for(u=0; u<space->extent.rank; u++) { + /* Check for unlimited dimension and return error */ + /* These should be able to be converted to assertions once everything + * that calls this function checks for unlimited selections first + * (especially the new hyperslab API) -NAF */ + if(space->select.sel_info.hslab->opt_diminfo[u].count == H5S_UNLIMITED) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited count") + if(space->select.sel_info.hslab->opt_diminfo[u].block == H5S_UNLIMITED) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited block") + tmp_start[u]=space->select.sel_info.hslab->opt_diminfo[u].start; tmp_stride[u]=space->select.sel_info.hslab->opt_diminfo[u].stride; tmp_count[u]=space->select.sel_info.hslab->opt_diminfo[u].count; @@ -6334,6 +6519,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hsize_t *opt_count; /* Optimized count information */ const hsize_t *opt_block; /* Optimized block information */ unsigned u; /* Counters */ + int unlim_dim = -1; /* Unlimited dimension in selection, of -1 if none */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -6352,6 +6538,18 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if(block==NULL) block = _ones; + /* Check for unlimited dimension */ + for(u = 0; u<space->extent.rank; u++) + if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) { + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") + else { + if(count[u] == block[u] /* == H5S_UNLIMITED */) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") + unlim_dim = (int)u; + } /* end else */ + } /* end if */ + /* * Check new selection. */ @@ -6400,7 +6598,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, opt_block = int_block; for(u=0; u<space->extent.rank; u++) { /* contiguous hyperslabs have the block size equal to the stride */ - if(stride[u]==block[u]) { + if((stride[u] == block[u]) && (count[u] != H5S_UNLIMITED)) { int_count[u]=1; int_stride[u]=1; if(block[u]==1) @@ -6412,7 +6610,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if(count[u]==1) int_stride[u]=1; else { - HDassert(stride[u] > block[u]); + HDassert((stride[u] > block[u]) || ((stride[u] == block[u]) + && (count[u] == H5S_UNLIMITED))); int_stride[u]=stride[u]; } /* end else */ int_count[u]=count[u]; @@ -6421,6 +6620,32 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, } /* end for */ } /* end else */ + /* Check for operating on unlimited selection */ + if((H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS) + && (space->select.sel_info.hslab->unlim_dim >= 0) + && (op != H5S_SELECT_SET)) + { + /* Check for invalid operation */ + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") + HDassert(space->select.sel_info.hslab->diminfo_valid); + + /* Clip unlimited selection to include new selection */ + if(H5S_hyper_clip_unlim(space, + start[space->select.sel_info.hslab->unlim_dim] + + ((opt_count[space->select.sel_info.hslab->unlim_dim] + - (hsize_t)1) + * opt_stride[space->select.sel_info.hslab->unlim_dim]) + + opt_block[space->select.sel_info.hslab->unlim_dim]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* If an empty space was returned it must be "none" */ + HDassert((space->select.num_elem > (hsize_t)0) + || (space->select.type->type == H5S_SEL_NONE)); + } /* end if */ + /* Fixup operation for non-hyperslab selections */ switch(H5S_GET_SELECT_TYPE(space)) { case H5S_SEL_NONE: /* No elements selected in dataspace */ @@ -6540,16 +6765,64 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, space->select.num_elem *= (opt_count[u] * opt_block[u]); } /* end for */ + /* Save unlim_dim */ + space->select.sel_info.hslab->unlim_dim = unlim_dim; + /* Indicate that the dimension information is valid */ space->select.sel_info.hslab->diminfo_valid = TRUE; /* Indicate that there's no slab information */ space->select.sel_info.hslab->span_lst = NULL; + + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + /* Calculate num_elem_non_unlim */ + space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; + for(u = 0; u < space->extent.rank; u++) + if((int)u != unlim_dim) + space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); + + /* Set num_elem */ + if(space->select.num_elem != (hsize_t)0) + space->select.num_elem = H5S_UNLIMITED; + } /* end if */ } /* end if */ else if(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA) { /* Sanity check */ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + hsize_t tmp_count = opt_count[unlim_dim]; + hsize_t tmp_block = opt_block[unlim_dim]; + + /* Check for invalid operation */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") + + /* Get bounds of existing selection */ + if(H5S_hyper_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Patch count and block to remove unlimited and include the + * existing selection */ + H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, bounds_end[unlim_dim] + (hsize_t)1); + HDassert((tmp_count == 1) || (opt_count != _ones)); + HDassert((tmp_block == 1) || (opt_block != _ones)); + if(opt_count != _ones) { + HDassert(opt_count == int_count); + int_count[unlim_dim] = tmp_count; + } /* end if */ + if(opt_block != _ones) { + HDassert(opt_block == int_block); + int_block[unlim_dim] = tmp_block; + } /* end if */ + } /* end if */ + /* Check if there's no hyperslab span information currently */ if(NULL == space->select.sel_info.hslab->span_lst) if(H5S_hyper_generate_spans(space) < 0) @@ -6896,6 +7169,9 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, /* Allocate space for the hyperslab selection information */ if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + + /* Set unlim_dim */ + space->select.sel_info.hslab->unlim_dim = -1; } /* end if */ /* Combine tmp_space (really space) & new_space, with the result in space */ @@ -6943,6 +7219,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hsize_t *opt_count; /* Optimized count information */ const hsize_t *opt_block; /* Optimized block information */ unsigned u; /* Counters */ + int unlim_dim = -1; /* Unlimited dimension in selection, of -1 if none */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -6961,6 +7238,18 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if(block==NULL) block = _ones; + /* Check for unlimited dimension */ + for(u = 0; u<space->extent.rank; u++) + if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) { + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") + else { + if(count[u] == block[u] /* == H5S_UNLIMITED */) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") + unlim_dim = (int)u; + } /* end else */ + } /* end if */ + /* * Check new selection. */ @@ -7005,7 +7294,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, opt_block = int_block; for(u=0; u<space->extent.rank; u++) { /* contiguous hyperslabs have the block size equal to the stride */ - if(stride[u]==block[u]) { + if((stride[u] == block[u]) && (count[u] != H5S_UNLIMITED)) { int_count[u]=1; int_stride[u]=1; if(block[u]==1) @@ -7017,7 +7306,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if(count[u]==1) int_stride[u]=1; else { - HDassert(stride[u] > block[u]); + HDassert((stride[u] > block[u]) || ((stride[u] == block[u]) + && (count[u] == H5S_UNLIMITED))); int_stride[u]=stride[u]; } /* end else */ int_count[u]=count[u]; @@ -7026,6 +7316,32 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, } /* end for */ } /* end else */ + /* Check for operating on unlimited selection */ + if((H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS) + && (space->select.sel_info.hslab->unlim_dim >= 0) + && (op != H5S_SELECT_SET)) + { + /* Check for invalid operation */ + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") + HDassert(space->select.sel_info.hslab->diminfo_valid); + + /* Clip unlimited selection to include new selection */ + if(H5S_hyper_clip_unlim(space, + start[space->select.sel_info.hslab->unlim_dim] + + ((opt_count[space->select.sel_info.hslab->unlim_dim] + - (hsize_t)1) + * opt_stride[space->select.sel_info.hslab->unlim_dim]) + + opt_block[space->select.sel_info.hslab->unlim_dim]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* If an empty space was returned it must be "none" */ + HDassert((space->select.num_elem > (hsize_t)0) + || (space->select.type->type == H5S_SEL_NONE)); + } /* end if */ + /* Fixup operation for non-hyperslab selections */ switch(H5S_GET_SELECT_TYPE(space)) { case H5S_SEL_NONE: /* No elements selected in dataspace */ @@ -7136,16 +7452,64 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, space->select.num_elem*=(opt_count[u]*opt_block[u]); } /* end for */ + /* Save unlim_dim */ + space->select.sel_info.hslab->unlim_dim = unlim_dim; + /* Indicate that the dimension information is valid */ space->select.sel_info.hslab->diminfo_valid = TRUE; /* Indicate that there's no slab information */ space->select.sel_info.hslab->span_lst = NULL; + + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + /* Calculate num_elem_non_unlim */ + space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; + for(u = 0; u < space->extent.rank; u++) + if((int)u != unlim_dim) + space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); + + /* Set num_elem */ + if(space->select.num_elem != (hsize_t)0) + space->select.num_elem = H5S_UNLIMITED; + } /* end if */ } /* end if */ else if(op>=H5S_SELECT_OR && op<=H5S_SELECT_NOTA) { /* Sanity check */ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + hsize_t tmp_count = opt_count[unlim_dim]; + hsize_t tmp_block = opt_block[unlim_dim]; + + /* Check for invalid operation */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") + + /* Get bounds of existing selection */ + if(H5S_hyper_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Patch count and block to remove unlimited and include the + * existing selection */ + H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, bounds_end[unlim_dim] + (hsize_t)1); + HDassert((tmp_count == 1) || (opt_count != _ones)); + HDassert((tmp_block == 1) || (opt_block != _ones)); + if(opt_count != _ones) { + HDassert(opt_count == int_count); + int_count[unlim_dim] = tmp_count; + } /* end if */ + if(opt_block != _ones) { + HDassert(opt_block == int_block); + int_block[unlim_dim] = tmp_block; + } /* end if */ + } /* end if */ + /* Check if there's no hyperslab span information currently */ if(NULL == space->select.sel_info.hslab->span_lst) if(H5S_hyper_generate_spans(space) < 0) @@ -7351,6 +7715,9 @@ H5S_combine_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) if((new_space->select.sel_info.hslab=H5FL_CALLOC(H5S_hyper_sel_t))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab info") + /* Set unlim_dim */ + new_space->select.sel_info.hslab->unlim_dim = -1; + /* Combine space1 & space2, with the result in new_space */ if(H5S_operate_hyperslab(new_space,space1->select.sel_info.hslab->span_lst,op,space2->select.sel_info.hslab->span_lst,FALSE,&span2_owned)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, NULL, "can't clip hyperslab information") @@ -7480,6 +7847,9 @@ H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) if((space1->select.sel_info.hslab=H5FL_CALLOC(H5S_hyper_sel_t))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + /* Set unlim_dim */ + space1->select.sel_info.hslab->unlim_dim = -1; + /* Combine tmp_spans (from space1) & spans from space2, with the result in space1 */ if(H5S_operate_hyperslab(space1,tmp_spans,op,space2->select.sel_info.hslab->span_lst,FALSE,&span2_owned)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") @@ -8752,6 +9122,7 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_se HDassert(nelem); HDassert(off); HDassert(len); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); /* Check for the special case of just one H5Sselect_hyperslab call made */ if(space->select.sel_info.hslab->diminfo_valid) { @@ -8881,6 +9252,1085 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_se /*-------------------------------------------------------------------------- NAME + H5S__hyper_project_intersection + PURPOSE + Projects the intersection of of the selections of src_space and + src_intersect_space within the selection of src_space as a selection + within the selection of dst_space + USAGE + herr_t H5S__hyper_project_intersection(src_space,dst_space,src_intersect_space,proj_space) + H5S_t *src_space; IN: Selection that is mapped to dst_space, and intersected with src_intersect_space + H5S_t *dst_space; IN: Selection that is mapped to src_space, and which contains the result + H5S_t *src_intersect_space; IN: Selection whose intersection with src_space is projected to dst_space to obtain the result + H5S_t *proj_space; OUT: Will contain the result (intersection of src_intersect_space and src_space projected from src_space to dst_space) after the operation + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Projects the intersection of of the selections of src_space and + src_intersect_space within the selection of src_space as a selection + within the selection of dst_space. The result is placed in the + selection of proj_space. Note src_space, dst_space, and + src_intersect_space do not need to use hyperslab selections, but they + cannot use point selections. The result is always a hyperslab + selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, + const H5S_t *src_intersect_space, H5S_t *proj_space) +{ + hsize_t ss_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for src_space */ + size_t ss_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for src_space */ + size_t ss_nseq; /* Number of sequences for src_space */ + size_t ss_nelem; /* Number of elements for src_space */ + size_t ss_i = (size_t)0; /* Index into offset/length arrays for src_space */ + hbool_t advance_ss = FALSE; /* Whether to advance ss_i on the next iteration */ + H5S_sel_iter_t ss_iter; /* Selection iterator for src_space */ + hbool_t ss_iter_init = FALSE; /* Whether ss_iter is initialized */ + hsize_t ss_sel_off = (hsize_t)0; /* Offset within src_space selection */ + hsize_t ds_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for dst_space */ + size_t ds_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for dst_space */ + size_t ds_nseq; /* Number of sequences for dst_space */ + size_t ds_nelem; /* Number of elements for dst_space */ + size_t ds_i = (size_t)0; /* Index into offset/length arrays for dst_space */ + H5S_sel_iter_t ds_iter; /* Selection iterator for dst_space */ + hbool_t ds_iter_init = FALSE; /* Whether ds_iter is initialized */ + hsize_t ds_sel_off = (hsize_t)0; /* Offset within dst_space selection */ + hsize_t sis_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for src_intersect_space */ + size_t sis_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for src_intersect_space */ + size_t sis_nseq; /* Number of sequences for src_intersect_space */ + size_t sis_nelem; /* Number of elements for src_intersect_space */ + size_t sis_i = (size_t)0; /* Index into offset/length arrays for src_intersect_space */ + hbool_t advance_sis = FALSE; /* Whether to advance sis_i on the next iteration */ + H5S_sel_iter_t sis_iter; /* Selection iterator for src_intersect_space */ + hbool_t sis_iter_init = FALSE; /* Whether sis_iter is initialized */ + hsize_t int_sel_off; /* Offset within intersected selections (ss/sis and ds/ps) */ + size_t int_len; /* Length of segment in intersected selections */ + hsize_t proj_off; /* Segment offset in proj_space */ + size_t proj_len; /* Segment length in proj_space */ + size_t proj_len_rem; /* Remaining length in proj_space for segment */ + hsize_t proj_down_dims[H5S_MAX_RANK]; /* "Down" dimensions in proj_space */ + H5S_hyper_span_info_t *curr_span_tree[H5S_MAX_RANK]; /* Current span tree being built (in each dimension) */ + H5S_hyper_span_t *prev_span[H5S_MAX_RANK]; /* Previous span in tree (in each dimension) */ + hsize_t curr_span_up_dim[H5S_MAX_RANK]; /* "Up" dimensions for current span */ + unsigned proj_rank; /* Rank of proj_space */ + hsize_t low; /* Low value of span */ + hsize_t high; /* High value of span */ + size_t span_len; /* Length of span */ + size_t nelem; /* Number of elements returned for get_seq_list op */ + unsigned i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check parameters */ + HDassert(src_space); + HDassert(dst_space); + HDassert(src_intersect_space); + HDassert(proj_space); + + /* Assert that src_space and src_intersect_space have same extent and there + * are no point selections */ + HDassert(H5S_GET_EXTENT_NDIMS(src_space) + == H5S_GET_EXTENT_NDIMS(src_intersect_space)); + HDassert(!HDmemcmp(src_space->extent.size, src_intersect_space->extent.size, + (size_t)H5S_GET_EXTENT_NDIMS(src_space) + * sizeof(src_space->extent.size[0]))); + HDassert(H5S_GET_SELECT_TYPE(src_space) != H5S_SEL_POINTS); + HDassert(H5S_GET_SELECT_TYPE(dst_space) != H5S_SEL_POINTS); + HDassert(H5S_GET_SELECT_TYPE(src_intersect_space) != H5S_SEL_POINTS); + + /* Initialize prev_space, curr_span_tree, and curr_span_up_dim */ + for(i = 0; i < H5S_MAX_RANK; i++) { + curr_span_tree[i] = NULL; + prev_span[i] = NULL; + curr_span_up_dim[i] = (hsize_t)0; + } /* end for */ + + /* Save rank of projected space */ + proj_rank = proj_space->extent.rank; + HDassert(proj_rank > 0); + + /* Get numbers of elements */ + ss_nelem = (size_t)H5S_GET_SELECT_NPOINTS(src_space); + ds_nelem = (size_t)H5S_GET_SELECT_NPOINTS(dst_space); + sis_nelem = (size_t)H5S_GET_SELECT_NPOINTS(src_intersect_space); + HDassert(ss_nelem == ds_nelem); + + /* Calculate proj_down_dims (note loop relies on unsigned i wrapping around) + */ + if(H5VM_array_down(proj_rank, proj_space->extent.size, proj_down_dims) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't compute 'down' chunk size value") + + /* Remove current selection from proj_space */ + if(H5S_SELECT_RELEASE(proj_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + + /* If any selections are empty, skip to the end so "none" is selected */ + if((ss_nelem == 0) || (ds_nelem == 0) || (sis_nelem == 0)) + goto loop_end; + + /* Allocate space for the hyperslab selection information (note this sets + * diminfo_valid to FALSE, diminfo arrays to 0, and span list to NULL) */ + if((proj_space->select.sel_info.hslab = H5FL_CALLOC(H5S_hyper_sel_t)) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info") + + /* Set selection type */ + proj_space->select.type = H5S_sel_hyper; + + /* Set unlim_dim */ + proj_space->select.sel_info.hslab->unlim_dim = -1; + + /* Initialize source space iterator */ + if(H5S_select_iter_init(&ss_iter, src_space, (size_t)1) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") + ss_iter_init = TRUE; + + /* Get sequence list for source space */ + if(H5S_SELECT_GET_SEQ_LIST(src_space, 0u, &ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + ss_nelem -= nelem; + HDassert(ss_nseq > 0); + + /* Initialize destination space iterator */ + if(H5S_select_iter_init(&ds_iter, dst_space, (size_t)1) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") + ds_iter_init = TRUE; + + /* Get sequence list for destination space */ + if(H5S_SELECT_GET_SEQ_LIST(dst_space, 0u, &ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") + ds_nelem -= nelem; + HDassert(ds_nseq > 0); + + /* Initialize source intersect space iterator */ + if(H5S_select_iter_init(&sis_iter, src_intersect_space, (size_t)1) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") + sis_iter_init = TRUE; + + /* Get sequence list for source intersect space */ + if(H5S_SELECT_GET_SEQ_LIST(src_intersect_space, 0u, &sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + sis_nelem -= nelem; + HDassert(sis_nseq > 0); + + /* Loop until we run out of sequences in either the source or source + * intersect space */ + while(1) { + while(advance_ss || (ss_off[ss_i] + ss_len[ss_i] <= sis_off[sis_i])) { + /* Either we finished the current source sequence or the + * sequences do not intersect. Advance source space. */ + ss_sel_off += (hsize_t)ss_len[ss_i]; + if(++ss_i == ss_nseq) { + if(ss_nelem > 0) { + /* Try to grab more sequences from src_space */ + if(H5S_SELECT_GET_SEQ_LIST(src_space, 0u, &ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + HDassert(ss_len[0] > 0); + + /* Update ss_nelem */ + HDassert(nelem > 0); + HDassert(nelem <= ss_nelem); + ss_nelem -= nelem; + + /* Reset source space index */ + ss_i = 0; + } /* end if */ + else + /* There are no more sequences in src_space, so we can exit + * the loop. Use goto instead of break so we exit the outer + * loop. */ + goto loop_end; + } /* end if */ + + /* Reset advance_ss */ + advance_ss = FALSE; + } /* end if */ + if(advance_sis + || (sis_off[sis_i] + sis_len[sis_i] <= ss_off[ss_i])) { + do { + /* Either we finished the current source intersect sequence or + * the sequences do not intersect. Advance source intersect + * space. */ + if(++sis_i == sis_nseq) { + if(sis_nelem > 0) { + /* Try to grab more sequences from src_intersect_space + */ + if(H5S_SELECT_GET_SEQ_LIST(src_intersect_space, 0u, &sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + HDassert(sis_len[0] > 0); + + /* Update ss_nelem */ + HDassert(nelem > 0); + HDassert(nelem <= sis_nelem); + sis_nelem -= nelem; + + /* Reset source space index */ + sis_i = 0; + } /* end if */ + else + /* There are no more sequences in src_intersect_space, + * so we can exit the loop. Use goto instead of break + * so we exit the outer loop. */ + goto loop_end; + } /* end if */ + } while(sis_off[sis_i] + sis_len[sis_i] <= ss_off[ss_i]); + + /* Reset advance_sis */ + advance_sis = FALSE; + } /* end if */ + else { + /* Sequences intersect, add intersection to projected space */ + /* Calculate intersection sequence in terms of offset within source + * selection and advance any sequences we complete */ + if(ss_off[ss_i] >= sis_off[sis_i]) + int_sel_off = ss_sel_off; + else + int_sel_off = sis_off[sis_i] - ss_off[ss_i] + ss_sel_off; + if((ss_off[ss_i] + (hsize_t)ss_len[ss_i]) <= (sis_off[sis_i] + + (hsize_t)sis_len[sis_i])) { + int_len = (size_t)((hsize_t)ss_len[ss_i] + ss_sel_off - int_sel_off); + advance_ss = TRUE; + } /* end if */ + else + int_len = (size_t)(sis_off[sis_i] + (hsize_t)sis_len[sis_i] - ss_off[ss_i] + ss_sel_off - int_sel_off); + if((ss_off[ss_i] + (hsize_t)ss_len[ss_i]) >= (sis_off[sis_i] + + (hsize_t)sis_len[sis_i])) + advance_sis = TRUE; + + /* Project intersection sequence to destination selection */ + while(int_len > (size_t)0) { + while(ds_sel_off + (hsize_t)ds_len[ds_i] <= int_sel_off) { + /* Intersection is not projected to this destination + * sequence, advance destination space */ + ds_sel_off += (hsize_t)ds_len[ds_i]; + if(++ds_i == ds_nseq) { + HDassert(ds_nelem > 0); + + /* Try to grab more sequences from dst_space */ + if(H5S_SELECT_GET_SEQ_LIST(dst_space, 0u, &ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + HDassert(ds_len[0] > 0); + + /* Update ss_nelem */ + HDassert(nelem > 0); + HDassert(nelem <= ds_nelem); + ds_nelem -= nelem; + + /* Reset source space index */ + ds_i = 0; + } /* end if */ + } /* end while */ + + /* Add sequence to projected space */ + HDassert(ds_sel_off <= int_sel_off); + proj_off = ds_off[ds_i] + int_sel_off - ds_sel_off; + proj_len = proj_len_rem = (size_t)MIN(int_len, + (size_t)(ds_sel_off + (hsize_t)ds_len[ds_i] + - int_sel_off)); + + /* Add to span tree */ + while(proj_len_rem > (size_t)0) { + /* Check for more than one full row (in every dim) and + * append multiple spans at once? -NAF */ + /* Append spans in higher dimensions if we're going ouside + * the plane of the span currently being built (i.e. it's + * finished being built) */ + for(i = proj_rank - 1; ((i > 0) + && ((proj_off / proj_down_dims[i - 1]) + != curr_span_up_dim[i - 1])); i--) { + if(curr_span_tree[i]) { + HDassert(prev_span[i]); + + /* Append complete lower dimension span tree to + * current dimension */ + low = curr_span_up_dim[i - 1] % proj_space->extent.size[i - 1]; + if(H5S_hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], low, low, curr_span_tree[i], NULL) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + + /* Reset lower dimension's span tree and previous + * span since we just committed it and will start + * over with a new one */ + if(H5S_hyper_free_span_info(curr_span_tree[i]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free span info") + curr_span_tree[i] = NULL; + prev_span[i] = NULL; + } /* end if */ + + /* Update curr_span_up_dim */ + curr_span_up_dim[i - 1] = proj_off / proj_down_dims[i - 1]; + } /* end for */ + + /* Compute bounds for new span in lowest dimension */ + low = proj_off % proj_space->extent.size[proj_rank - 1]; + span_len = MIN(proj_len_rem, + (size_t)(proj_space->extent.size[proj_rank - 1] + - low)); + HDassert(proj_len_rem >= span_len); + high = low + (hsize_t)span_len - (hsize_t)1; + + /* Append span in lowest dimension */ + if(H5S_hyper_append_span(&prev_span[proj_rank - 1], &curr_span_tree[proj_rank - 1], low, high, NULL, NULL) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + + /* Update remaining offset and length */ + proj_off += (hsize_t)span_len; + proj_len_rem -= span_len; + } /* end while */ + + /* Update intersection sequence */ + int_sel_off += (hsize_t)proj_len; + int_len -= proj_len; + } /* end while */ + } /* end else */ + } /* end while */ + +loop_end: + /* Add remaining spans to span tree */ + for(i = proj_rank - 1; i > 0; i--) + if(curr_span_tree[i]) { + HDassert(prev_span[i]); + + /* Append remaining span tree to higher dimension */ + low = curr_span_up_dim[i - 1] % proj_space->extent.size[i - 1]; + if(H5S_hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], low, low, curr_span_tree[i], NULL) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + + /* Reset span tree */ + if(H5S_hyper_free_span_info(curr_span_tree[i]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free span info") + curr_span_tree[i] = NULL; + } /* end if */ + + /* Add span tree to proj_space */ + if(curr_span_tree[0]) { + proj_space->select.sel_info.hslab->span_lst = curr_span_tree[0]; + curr_span_tree[0] = NULL; + + /* Set the number of elements in current selection */ + proj_space->select.num_elem = H5S_hyper_spans_nelem(proj_space->select.sel_info.hslab->span_lst); + + /* Attempt to rebuild "optimized" start/stride/count/block information. + * from resulting hyperslab span tree */ + if(H5S_hyper_rebuild(proj_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't rebuild hyperslab info") + } /* end if */ + else + /* If we did not add anything to proj_space, select none instead */ + if(H5S_select_none(proj_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") + +done: + /* Release source selection iterator */ + if(ss_iter_init) + if(H5S_SELECT_ITER_RELEASE(&ss_iter) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") + + /* Release destination selection iterator */ + if(ds_iter_init) + if(H5S_SELECT_ITER_RELEASE(&ds_iter) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") + + /* Release source intersect selection iterator */ + if(sis_iter_init) + if(H5S_SELECT_ITER_RELEASE(&sis_iter) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") + + /* Cleanup on error */ + if(ret_value < 0) { + /* Remove current selection from proj_space */ + if(H5S_SELECT_RELEASE(proj_space) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + + /* Free span trees */ + for(i = 0; i < proj_rank; i++) + if(curr_span_tree[i]) { + if(H5S_hyper_free_span_info(curr_span_tree[i]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free span info") + curr_span_tree[i] = NULL; + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_project_intersection() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_subtract + PURPOSE + Subtract one hyperslab selection from another + USAGE + herr_t H5S__hyper_subtract(space,subtract_space) + H5S_t *space; IN/OUT: Selection to be operated on + H5S_t *subtract_space; IN: Selection that will be subtracted from space + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Removes any and all portions of space that are also present in + subtract_space. In essence, performs an A_NOT_B operation with the + two selections. + + Note this function basically duplicates a subset of the functionality + of H5S_select_select(). It should probably be removed when that + function is enabled. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S__hyper_subtract(H5S_t *space, H5S_t *subtract_space) +{ + H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ + H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */ + H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + HDassert(space); + HDassert(subtract_space); + + /* Check that the space selections both have span trees */ + if(space->select.sel_info.hslab->span_lst == NULL) + if(H5S_hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + if(subtract_space->select.sel_info.hslab->span_lst == NULL) + if(H5S_hyper_generate_spans(subtract_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + + /* Generate lists of spans which overlap and don't overlap */ + if(H5S_hyper_clip_spans(space->select.sel_info.hslab->span_lst, subtract_space->select.sel_info.hslab->span_lst, &a_not_b, &a_and_b, &b_not_a)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") + + /* Reset the other dataspace selection information */ + if(H5S_SELECT_RELEASE(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + + /* Allocate space for the hyperslab selection information */ + if((space->select.sel_info.hslab = H5FL_CALLOC(H5S_hyper_sel_t)) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + + /* Set unlim_dim */ + space->select.sel_info.hslab->unlim_dim = -1; + + /* Check for anything returned in a_not_b */ + if(a_not_b) { + /* Update spans in space */ + space->select.sel_info.hslab->span_lst = a_not_b; + a_not_b = NULL; + + /* Update number of elements */ + space->select.num_elem = H5S_hyper_spans_nelem(space->select.sel_info.hslab->span_lst); + + /* Attempt to rebuild "optimized" start/stride/count/block information. + * from resulting hyperslab span tree */ + if(H5S_hyper_rebuild(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't rebuild hyperslab info") + } /* end if */ + else { + H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + + /* Set number of elements */ + space->select.num_elem = 0; + + /* Allocate a span info node */ + if(NULL == (spans = H5FL_MALLOC(H5S_hyper_span_info_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") + + /* Set the reference count */ + spans->count = 1; + + /* Reset the scratch pad space */ + spans->scratch = 0; + + /* Set to empty tree */ + spans->head = NULL; + + /* Set pointer to empty span tree */ + space->select.sel_info.hslab->span_lst = spans; + } /* end if */ + +done: + /* Free span trees */ + if(a_and_b) + H5S_hyper_free_span_info(a_and_b); + if(b_not_a) + H5S_hyper_free_span_info(b_not_a); + if(a_not_b) { + HDassert(ret_value < 0); + H5S_hyper_free_span_info(b_not_a); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_subtract() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_get_clip_diminfo + PURPOSE + Calculates the count and block required to clip the specified + unlimited dimension to include clip_size. The returned selection may + extent beyond clip_size. + USAGE + void H5S__hyper_get_clip_diminfo(start,stride,count,block,clip_size) + hsize_t start; IN: Start of hyperslab in unlimited dimension + hsize_t stride; IN: Stride of hyperslab in unlimited dimension + hsize_t *count; IN/OUT: Count of hyperslab in unlimited dimension + hsize_t *block; IN/OUT: Block of hyperslab in unlimited dimension + hsize_t clip_size; IN: Extent that hyperslab will be clipped to + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + This function recalculates the internal description of the hyperslab + to make the unlimited dimension extend to the specified extent. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void +H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, + hsize_t *block, hsize_t clip_size) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Check for selection outside clip size */ + if(start >= clip_size) { + if(*block == H5S_UNLIMITED) + *block = 0; + else + *count = 0; + } /* end if */ + /* Check for single block in unlimited dimension */ + else if((*block == H5S_UNLIMITED) || (*block == stride)) { + /* Calculate actual block size for this clip size */ + *block = clip_size - start; + *count = (hsize_t)1; + } /* end if */ + else { + HDassert(*count == H5S_UNLIMITED); + + /* Calculate initial count (last block may be partial) */ + *count = (clip_size - start + stride - (hsize_t)1) / stride; + HDassert(*count > (hsize_t)0); + } /* end else */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5S_hyper_get_clip_diminfo() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_clip_unlim + PURPOSE + Clips the unlimited dimension of the hyperslab selection to the + specified size + USAGE + void H5S_hyper_clip_unlim(space,clip_size) + H5S_t *space, IN/OUT: Unlimited space to clip + hsize_t clip_size; IN: Extent that hyperslab will be clipped to + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + This function changes the unlimited selection into a limited selection + with the extent of the formerly unlimited dimension specified by + * clip_size. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this function does not take the offset into account. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) +{ + H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ + hsize_t orig_count; /* Original count in unlimited dimension */ + int orig_unlim_dim; /* Original unliminted dimension */ + H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_diminfo in unlimited dimension */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check parameters */ + HDassert(space); + hslab = space->select.sel_info.hslab; + HDassert(hslab); + HDassert(hslab->unlim_dim >= 0); + HDassert(!hslab->span_lst); + + /* Save original unlimited dimension */ + orig_unlim_dim = hslab->unlim_dim; + + diminfo = &hslab->opt_diminfo[orig_unlim_dim]; + + /* Save original count in unlimited dimension */ + orig_count = diminfo->count; + + /* Get initial diminfo */ + H5S__hyper_get_clip_diminfo(diminfo->start, diminfo->stride, &diminfo->count, &diminfo->block, clip_size); + + /* Selection is no longer unlimited */ + space->select.sel_info.hslab->unlim_dim = -1; + + /* Check for nothing returned */ + if((diminfo->block == 0) || (diminfo->count == 0)) { + /* Convert to "none" selection */ + if(H5S_select_none(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") + } /* end if */ + /* Check for single block in unlimited dimension */ + else if(orig_count == (hsize_t)1) { + /* Calculate number of elements */ + space->select.num_elem = diminfo->block * hslab->num_elem_non_unlim; + + /* Mark that opt_diminfo is valid */ + hslab->diminfo_valid = TRUE; + } /* end if */ + else { + /* Calculate number of elements */ + space->select.num_elem = diminfo->count * diminfo->block + * hslab->num_elem_non_unlim; + + /* Check if last block is partial. If superset is set, just keep the + * last block complete to speed computation. */ + HDassert(clip_size > diminfo->start); + if(((diminfo->stride * (diminfo->count - (hsize_t)1)) + diminfo->block) + > (clip_size - diminfo->start)) { + hsize_t start[H5S_MAX_RANK]; + hsize_t block[H5S_MAX_RANK]; + unsigned i; + + /* Last block is partial, need to construct compound selection */ + /* Fill start with zeros */ + HDmemset(start, 0, sizeof(start)); + + /* Set block to clip_size in unlimited dimension, H5S_MAX_SIZE in + * others so only unlimited dimension is clipped */ + for(i = 0; i < space->extent.rank; i++) + if((int)i == orig_unlim_dim) + block[i] = clip_size; + else + block[i] = H5S_MAX_SIZE; + + /* Generate span tree in selection */ + if(!hslab->span_lst) + if(H5S_hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to generate span tree") + + /* Indicate that the regular dimensions are no longer valid */ + hslab->diminfo_valid = FALSE; + + /* "And" selection with calculated block to perform clip operation + */ + if(H5S_generate_hyperslab(space, H5S_SELECT_AND, start, _ones, _ones, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") + } /* end if */ + else + /* Last block is complete, simply mark that opt_diminfo is valid */ + hslab->diminfo_valid = TRUE; + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_clip_unlim() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_get_clip_extent_real + PURPOSE + Gets the extent a space should be clipped to in order to contain the + specified number of slices in the unlimited dimension + USAGE + hsize_t H5S__hyper_get_clip_extent_real(clip_space,num_slices,incl_trail) + const H5S_t *clip_space, IN: Space that clip size will be calculated based on + hsize_t num_slizes, IN: Number of slices clip_space should contain when clipped + hbool_t incl_trail; IN: Whether to include trailing unselected space + RETURNS + Clip extent to match num_slices (never fails) + DESCRIPTION + Calculates and returns the extent that clip_space should be clipped to + (via H5S_hyper_clip_unlim) in order for it to contain num_slices + slices in the unlimited dimension. If the clipped selection would end + immediately before a section of unselected space (i.e. at the end of a + block), then if incl_trail is TRUE, the returned clip extent is + selected to include that trailing "blank" space, otherwise it is + selected to end at the end before the blank space. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this assumes the offset has been normalized. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static hsize_t +H5S__hyper_get_clip_extent_real(const H5S_t *clip_space, hsize_t num_slices, + hbool_t incl_trail) +{ + const H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_unlim_diminfo in unlimited dimension */ + hsize_t count; + hsize_t rem_slices; + hsize_t ret_value = 0; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Check parameters */ + HDassert(clip_space); + HDassert(clip_space->select.sel_info.hslab); + HDassert(clip_space->select.sel_info.hslab->unlim_dim >= 0); + + diminfo = &clip_space->select.sel_info.hslab->opt_diminfo[clip_space->select.sel_info.hslab->unlim_dim]; + + if(num_slices == 0) + ret_value = incl_trail ? diminfo->start : 0; + else if((diminfo->block == H5S_UNLIMITED) + || (diminfo->block == diminfo->stride)) + /* Unlimited block, just set the extent large enough for the block size + * to match num_slices */ + ret_value = diminfo->start + num_slices; + else { + /* Unlimited count, need to match extent so a block (possibly) gets cut + * off so the number of slices matches num_slices */ + HDassert(diminfo->count == H5S_UNLIMITED); + + /* Calculate number of complete blocks in clip_space */ + count = num_slices / diminfo->block; + + /* Calculate slices remaining */ + rem_slices = num_slices - (count * diminfo->block); + + if(rem_slices > 0) + /* Must end extent in middle of partial block (or beginning of empty + * block if include_trailing_space and rem_slices == 0) */ + ret_value = diminfo->start + (count * diminfo->stride) + rem_slices; + else { + if(incl_trail) + /* End extent just before first missing block */ + ret_value = diminfo->start + (count * diminfo->stride); + else + /* End extent at end of last block */ + ret_value = diminfo->start + ((count - (hsize_t)1) + * diminfo->stride) + diminfo->block; + } /* end else */ + } /* end else */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_get_clip_extent_real() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_get_clip_extent + PURPOSE + Gets the extent a space should be clipped to in order to contain the + same number of elements as another space + USAGE + hsize_t H5S__hyper_get_clip_extent(clip_space,match_space,incl_trail) + const H5S_t *clip_space, IN: Space that clip size will be calculated based on + const H5S_t *match_space, IN: Space containing the same number of elements as clip_space should after clipping + hbool_t incl_trail; IN: Whether to include trailing unselected space + RETURNS + Calculated clip extent (never fails) + DESCRIPTION + Calculates and returns the extent that clip_space should be clipped to + (via H5S_hyper_clip_unlim) in order for it to contain the same number + of elements as match_space. If the clipped selection would end + immediately before a section of unselected space (i.e. at the end of a + block), then if incl_trail is TRUE, the returned clip extent is + selected to include that trailing "blank" space, otherwise it is + selected to end at the end before the blank space. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this assumes the offset has been normalized. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hsize_t +H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, + hbool_t incl_trail) +{ + hsize_t num_slices; /* Number of slices in unlimited dimension */ + hsize_t ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI(0) + + /* Check parameters */ + HDassert(clip_space); + HDassert(match_space); + HDassert(clip_space->select.sel_info.hslab->unlim_dim >= 0); + + /* Check for "none" match space */ + if(match_space->select.type->type == H5S_SEL_NONE) + num_slices = (hsize_t)0; + else { + HDassert(match_space->select.type->type == H5S_SEL_HYPERSLABS); + HDassert(match_space->select.sel_info.hslab); + + /* Calculate number of slices */ + num_slices = match_space->select.num_elem + / clip_space->select.sel_info.hslab->num_elem_non_unlim; + HDassert((match_space->select.num_elem + % clip_space->select.sel_info.hslab->num_elem_non_unlim) == 0); + } /* end else */ + + /* Call "real" get_clip_extent function */ + ret_value = H5S__hyper_get_clip_extent_real(clip_space, num_slices, incl_trail); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_get_clip_extent() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_get_clip_extent_match + PURPOSE + Gets the extent a space should be clipped to in order to contain the + same number of elements as another unlimited space that has been + clipped to a different extent + USAGE + hsize_t H5S__hyper_get_clip_extent_match(clip_space,match_space,match_clip_size,incl_trail) + const H5S_t *clip_space, IN: Space that clip size will be calculated based on + const H5S_t *match_space, IN: Space that, after being clipped to match_clip_size, contains the same number of elements as clip_space should after clipping + hsize_t match_clip_size, IN: Extent match_space would be clipped to to match the number of elements in clip_space + hbool_t incl_trail; IN: Whether to include trailing unselected space + RETURNS + Calculated clip extent (never fails) + DESCRIPTION + Calculates and returns the extent that clip_space should be clipped to + (via H5S_hyper_clip_unlim) in order for it to contain the same number + of elements as match_space would have after being clipped to + match_clip_size. If the clipped selection would end immediately + before a section of unselected space (i.e. at the end of a block), + then if incl_trail is TRUE, the returned clip extent is selected to + include that trailing "blank" space, otherwise it is selected to end + at the end before the blank space. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this assumes the offset has been normalized. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hsize_t +H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, + const H5S_t *match_space, hsize_t match_clip_size, hbool_t incl_trail) +{ + const H5S_hyper_dim_t *match_diminfo; /* Convenience pointer to opt_unlim_diminfo in unlimited dimension in match_space */ + hsize_t count; /* Temporary count */ + hsize_t block; /* Temporary block */ + hsize_t num_slices; /* Number of slices in unlimited dimension */ + hsize_t ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI(0) + + /* Check parameters */ + HDassert(clip_space); + HDassert(match_space); + HDassert(clip_space->select.sel_info.hslab); + HDassert(match_space->select.sel_info.hslab); + HDassert(clip_space->select.sel_info.hslab->unlim_dim >= 0); + HDassert(match_space->select.sel_info.hslab->unlim_dim >= 0); + HDassert(clip_space->select.sel_info.hslab->num_elem_non_unlim + == match_space->select.sel_info.hslab->num_elem_non_unlim); + + match_diminfo = &match_space->select.sel_info.hslab->opt_diminfo[match_space->select.sel_info.hslab->unlim_dim]; + + /* Get initial count and block */ + count = match_diminfo->count; + block = match_diminfo->block; + H5S__hyper_get_clip_diminfo(match_diminfo->start, match_diminfo->stride, &count, &block, match_clip_size); + + /* Calculate number of slices */ + /* Check for nothing returned */ + if((block == 0) || (count == 0)) + num_slices = (hsize_t)0; + /* Check for single block in unlimited dimension */ + else if(count == (hsize_t)1) + num_slices = block; + else { + /* Calculate initial num_slices */ + num_slices = block * count; + + /* Check for partial last block */ + HDassert(match_clip_size >= match_diminfo->start); + if(((match_diminfo->stride * (count - (hsize_t)1)) + block) + > (match_clip_size - match_diminfo->start)) { + /* Subtract slices missing from last block */ + HDassert((((match_diminfo->stride * (count - (hsize_t)1)) + block) + - (match_clip_size - match_diminfo->start)) < num_slices); + num_slices -= ((match_diminfo->stride * (count - (hsize_t)1)) + + block) - (match_clip_size - match_diminfo->start); + } /* end if */ + } /* end else */ + + /* Call "real" get_clip_extent function */ + ret_value = H5S__hyper_get_clip_extent_real(clip_space, num_slices, incl_trail); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_get_clip_extent_match() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_get_unlim_block + PURPOSE + Get the nth block in the unlimited dimension + USAGE + H5S_t *H5S_hyper_get_unlim_block(space,block_index) + const H5S_t *space, IN: Space with unlimited selection + hsize_t block_index, IN: Index of block to return in unlimited dimension + hbool_t incl_trail; IN: Whether to include trailing unselected space + RETURNS + New space on success/NULL on failure. + DESCRIPTION + Returns a space containing only the block_indexth block in the + unlimited dimension on space. All blocks in all other dimensions are + preserved. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this assumes the offset has been normalized. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5S_t * +H5S_hyper_get_unlim_block(const H5S_t *space, hsize_t block_index) +{ + H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ + H5S_t *space_out = NULL; + hsize_t start[H5S_MAX_RANK]; + hsize_t stride[H5S_MAX_RANK]; + hsize_t count[H5S_MAX_RANK]; + hsize_t block[H5S_MAX_RANK]; + unsigned i; + H5S_t *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) + + /* Check parameters */ + HDassert(space); + hslab = space->select.sel_info.hslab; + HDassert(hslab); + HDassert(hslab->unlim_dim >= 0); + HDassert(hslab->opt_diminfo[hslab->unlim_dim].count == H5S_UNLIMITED); + + /* Set start to select block_indexth block in unlimited dimension and set + * count to 1 in that dimension to only select that block. Copy all other + * diminfo parameters. */ + for(i = 0; i < space->extent.rank; i++) { + if((int)i == hslab->unlim_dim){ + start[i] = hslab->opt_diminfo[i].start + (block_index + * hslab->opt_diminfo[i].stride); + count[i] = (hsize_t)1; + } /* end if */ + else { + start[i] = hslab->opt_diminfo[i].start; + count[i] = hslab->opt_diminfo[i].count; + } /* end else */ + stride[i] = hslab->opt_diminfo[i].stride; + block[i] = hslab->opt_diminfo[i].block; + } /* end for */ + + /* Create output space, copy extent */ + if(NULL == (space_out = H5S_create(H5S_SIMPLE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "unable to create output dataspace") + if(H5S_extent_copy_real(&space_out->extent, &space->extent, TRUE) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "unable to copy destination space extent") + + /* Select block as defined by start/stride/count/block computed above */ + if(H5S_select_hyperslab(space_out, H5S_SELECT_SET, start, stride, count, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "can't select hyperslab") + + /* Set return value */ + ret_value = space_out; + +done: + /* Free space on error */ + if(!ret_value) + if(space_out && H5S_close(space_out) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, NULL, "unable to release dataspace") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_get_unlim_block */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_get_first_inc_block + PURPOSE + Get the index of the first incomplete block in the specified extent + USAGE + hsize_t H5S_hyper_get_first_inc_block(space,clip_size,partial) + const H5S_t *space, IN: Space with unlimited selection + hsize_t clip_size, IN: Extent space would be clipped to + hbool_t *partial; OUT: Whether the ret_valueth block (first incomplete block) is partial + RETURNS + Index of first incomplete block in clip_size (never fails). + DESCRIPTION + Calculates and returns the index (as would be passed to + H5S_hyper_get_unlim_block()) of the first block in the unlimited + dimension of space which would be incomplete or missing when space is + clipped to clip_size. partial is set to TRUE if the first incomplete + block is partial, and FALSE if the first incomplete block is missing. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this assumes the offset has been normalized. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hsize_t +H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, + hbool_t *partial) +{ + H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ + H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_diminfo in unlimited dimension */ + hsize_t ret_value = 0; + + FUNC_ENTER_NOAPI(0) + + /* Check parameters */ + HDassert(space); + hslab = space->select.sel_info.hslab; + HDassert(hslab); + HDassert(hslab->unlim_dim >= 0); + HDassert(hslab->opt_diminfo[hslab->unlim_dim].count == H5S_UNLIMITED); + + diminfo = &hslab->opt_diminfo[hslab->unlim_dim]; + + /* Check for selection outside of clip_size */ + if(diminfo->start >= clip_size) { + ret_value = 0; + if(partial) + partial = FALSE; + } /* end if */ + else { + /* Calculate index of first incomplete block */ + ret_value = (clip_size - diminfo->start + diminfo->stride + - diminfo->block) / diminfo->stride; + + if(partial) { + /* Check for partial block */ + if((diminfo->stride * ret_value) < (clip_size - diminfo->start)) + *partial = TRUE; + else + *partial = FALSE; + } /* end if */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_get_first_inc_block */ + + +/*-------------------------------------------------------------------------- + NAME H5Sis_regular_hyperslab PURPOSE Determine if a hyperslab selection is regular diff --git a/src/H5Snone.c b/src/H5Snone.c index 19d5eed..3492325 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -41,9 +41,11 @@ static herr_t H5S_none_release(H5S_t *space); static htri_t H5S_none_is_valid(const H5S_t *space); static hssize_t H5S_none_serial_size(const H5S_t *space); static herr_t H5S_none_serialize(const H5S_t *space, uint8_t **p); -static herr_t H5S_none_deserialize(H5S_t *space, const uint8_t **p); +static herr_t H5S_none_deserialize(H5S_t *space, uint32_t version, uint8_t flags, + const uint8_t **p); static herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static herr_t H5S_none_offset(const H5S_t *space, hsize_t *off); +static int H5S__none_unlim_dim(const H5S_t *space); static htri_t H5S_none_is_contiguous(const H5S_t *space); static htri_t H5S_none_is_single(const H5S_t *space); static htri_t H5S_none_is_regular(const H5S_t *space); @@ -75,6 +77,8 @@ const H5S_select_class_t H5S_sel_none[1] = {{ H5S_none_deserialize, H5S_none_bounds, H5S_none_offset, + H5S__none_unlim_dim, + NULL, H5S_none_is_contiguous, H5S_none_is_single, H5S_none_is_regular, @@ -510,9 +514,11 @@ H5S_none_serialize(const H5S_t *space, uint8_t **p) PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_none_deserialize(space, p) + herr_t H5S_none_deserialize(space, version, flags, p) H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint32_t version IN: Selection version + uint8_t flags IN: Selection flags uint8 **p; OUT: Pointer to buffer holding serialized selection. Will be advanced to end of serialized selection. @@ -527,7 +533,8 @@ H5S_none_serialize(const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_deserialize(H5S_t *space, const uint8_t H5_ATTR_UNUSED **p) +H5S_none_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ATTR_UNUSED flags, + const uint8_t H5_ATTR_UNUSED **p) { herr_t ret_value = SUCCEED; /* return value */ @@ -618,6 +625,34 @@ H5S_none_offset(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *offse /*-------------------------------------------------------------------------- NAME + H5S__none_unlim_dim + PURPOSE + Return unlimited dimension of selection, or -1 if none + USAGE + int H5S__none_unlim_dim(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + Unlimited dimension of selection, or -1 if none (never fails). + DESCRIPTION + Returns the index of the unlimited dimension in this selection, or -1 + if the selection has no unlimited dimension. "None" selections cannot + have an unlimited dimension, so this function always returns -1. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5S__none_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) +{ + FUNC_ENTER_STATIC_NOERR + + FUNC_LEAVE_NOAPI(-1) +} /* end H5S__none_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_none_is_contiguous PURPOSE Check if a "none" selection is contiguous within the dataspace extent. diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 933de64..e57650a 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -34,6 +34,13 @@ #define H5S_VALID_MAX 0x01 #define H5S_VALID_PERM 0x02 +/* Flags for serialization of selections */ +#define H5S_SELECT_FLAG_UNLIM 0x01 +#define H5S_SELECT_FLAG_BITS (H5S_SELECT_FLAG_UNLIM) + +/* Length of stack-allocated sequences for "project intersect" routines */ +#define H5S_PROJECT_INTERSECT_NSEQS 256 + /* Initial version of the dataspace information */ #define H5O_SDSPACE_VERSION_1 1 @@ -48,6 +55,10 @@ * and 'size' callbacks for places to change when updating this. */ #define H5O_SDSPACE_VERSION_LATEST H5O_SDSPACE_VERSION_2 +/* Maximum dimension size (highest value that is not a special value e.g. + * H5S_UNLIMITED) */ +#define H5S_MAX_SIZE ((hsize_t)(hssize_t)(-2)) + /* * Dataspace extent information @@ -113,6 +124,8 @@ typedef struct { * are only used for re-gurgitating the original values used to set the * hyperslab to the application when it queries the hyperslab selection * information. */ + int unlim_dim; /* Dimension where selection is unlimited, or -1 if none */ + hsize_t num_elem_non_unlim; /* # of elements in a "slice" excluding the unlimited dimension */ H5S_hyper_span_info_t *span_lst; /* List of hyperslab span information */ } H5S_hyper_sel_t; @@ -132,11 +145,17 @@ typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space); /* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */ typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t **p); /* Method to create selection from "serialized" form (a byte sequence suitable for storing on disk) */ -typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t *space, const uint8_t **p); +typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t *space, uint32_t version, uint8_t flags, + const uint8_t **p); /* Method to determine smallest n-D bounding box containing the current selection */ typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end); /* Method to determine linear offset of initial element in selection within dataspace */ typedef herr_t (*H5S_sel_offset_func_t)(const H5S_t *space, hsize_t *offset); +/* Method to get unlimited dimension of selection (or -1 for none) */ +typedef int (*H5S_sel_unlim_dim_func_t)(const H5S_t *space); +/* Method to get the number of elements in a slice through the unlimited dimension */ +typedef herr_t (*H5S_sel_num_elem_non_unlim_func_t)(const H5S_t *space, + hsize_t *num_elem_non_unlim); /* Method to determine if current selection is contiguous */ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space); /* Method to determine if current selection is a single block */ @@ -166,6 +185,8 @@ typedef struct { H5S_sel_deserialize_func_t deserialize; /* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */ H5S_sel_bounds_func_t bounds; /* Method to determine to smallest n-D bounding box containing the current selection */ H5S_sel_offset_func_t offset; /* Method to determine linear offset of initial element in selection within dataspace */ + H5S_sel_unlim_dim_func_t unlim_dim; /* Method to get unlimited dimension of selection (or -1 for none) */ + H5S_sel_num_elem_non_unlim_func_t num_elem_non_unlim; /* Method to get the number of elements in a slice through the unlimited dimension */ H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */ H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */ H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */ @@ -249,6 +270,10 @@ H5_DLL herr_t H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max); /* Operations on selections */ +H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space, + const H5S_t *dst_space, const H5S_t *src_intersect_space, + H5S_t *proj_space); +H5_DLL herr_t H5S__hyper_subtract(H5S_t *space, H5S_t *subtract_space); /* Testing functions */ #ifdef H5S_TESTING diff --git a/src/H5Spoint.c b/src/H5Spoint.c index daee160..0f85110 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -42,9 +42,11 @@ static herr_t H5S_point_release(H5S_t *space); static htri_t H5S_point_is_valid(const H5S_t *space); static hssize_t H5S_point_serial_size(const H5S_t *space); static herr_t H5S_point_serialize(const H5S_t *space, uint8_t **p); -static herr_t H5S_point_deserialize(H5S_t *space, const uint8_t **p); +static herr_t H5S_point_deserialize(H5S_t *space, uint32_t version, uint8_t flags, + const uint8_t **p); static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static herr_t H5S_point_offset(const H5S_t *space, hsize_t *off); +static int H5S__point_unlim_dim(const H5S_t *space); static htri_t H5S_point_is_contiguous(const H5S_t *space); static htri_t H5S_point_is_single(const H5S_t *space); static htri_t H5S_point_is_regular(const H5S_t *space); @@ -76,6 +78,8 @@ const H5S_select_class_t H5S_sel_point[1] = {{ H5S_point_deserialize, H5S_point_bounds, H5S_point_offset, + H5S__point_unlim_dim, + NULL, H5S_point_is_contiguous, H5S_point_is_single, H5S_point_is_regular, @@ -882,6 +886,8 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) herr_t H5S_point_deserialize(space, p) H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint32_t version IN: Selection version + uint8_t flags IN: Selection flags uint8 **p; OUT: Pointer to buffer holding serialized selection. Will be advanced to end of serialized selection. @@ -896,7 +902,8 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_deserialize (H5S_t *space, const uint8_t **p) +H5S_point_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ATTR_UNUSED flags, + const uint8_t **p) { H5S_seloper_t op = H5S_SELECT_SET; /* Selection operation */ hsize_t *coord = NULL, *tcoord; /* Pointer to array of elements */ @@ -1197,6 +1204,35 @@ done: /*-------------------------------------------------------------------------- NAME + H5S__point_unlim_dim + PURPOSE + Return unlimited dimension of selection, or -1 if none + USAGE + int H5S__point_unlim_dim(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + Unlimited dimension of selection, or -1 if none (never fails). + DESCRIPTION + Returns the index of the unlimited dimension in this selection, or -1 + if the selection has no unlimited dimension. Currently point + selections cannot have an unlimited dimension, so this function always + returns -1. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5S__point_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) +{ + FUNC_ENTER_STATIC_NOERR + + FUNC_LEAVE_NOAPI(-1) +} /* end H5S__point_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_point_is_contiguous PURPOSE Check if a point selection is contiguous within the dataspace extent. diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index ff6955c..b00dc6b 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -220,6 +220,8 @@ H5_DLL H5S_t *H5S_create(H5S_class_t type); H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], const hsize_t maxdims[/*rank*/]); H5_DLL herr_t H5S_set_latest_version(H5S_t *ds); +H5_DLL herr_t H5S_encode(H5S_t *obj, unsigned char **p, size_t *nalloc); +H5_DLL H5S_t *H5S_decode(const unsigned char **p); H5_DLL herr_t H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream, int indent, int fwidth); #ifndef H5_NO_DEPRECATED_SYMBOLS @@ -243,6 +245,9 @@ H5_DLL htri_t H5S_select_valid(const H5S_t *space); H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space); H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset); +H5_DLL int H5S_get_select_unlim_dim(const H5S_t *space); +H5_DLL herr_t H5S_get_select_num_elem_non_unlim(const H5S_t *space, + hsize_t *num_elem_non_unlim); H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset); H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2); @@ -261,6 +266,10 @@ H5_DLL htri_t H5S_select_is_regular(const H5S_t *space); H5_DLL herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset); H5_DLL herr_t H5S_select_project_scalar(const H5S_t *space, hsize_t *offset); H5_DLL herr_t H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); +H5_DLL herr_t H5S_select_project_intersection(const H5S_t *src_space, + const H5S_t *dst_space, const H5S_t *src_intersect_space, + H5S_t **new_space_ptr); +H5_DLL herr_t H5S_select_subtract(H5S_t *space, H5S_t *subtract_space); /* Operations on all selections */ H5_DLL herr_t H5S_select_all(H5S_t *space, hbool_t rel_prev); @@ -286,6 +295,15 @@ H5_DLL htri_t H5S_hyper_intersect_block (H5S_t *space, hsize_t *start, hsize_t * H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset); H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset); H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset); +H5_DLL herr_t H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size); +H5_DLL hsize_t H5S_hyper_get_clip_extent(const H5S_t *clip_space, + const H5S_t *match_space, hbool_t incl_trail); +H5_DLL hsize_t H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, + const H5S_t *match_space, hsize_t match_clip_size, hbool_t incl_trail); +H5_DLL H5S_t *H5S_hyper_get_unlim_block(const H5S_t *space, + hsize_t block_index); +H5_DLL hsize_t H5S_hyper_get_first_inc_block(const H5S_t *space, + hsize_t clip_size, hbool_t *partial); /* Operations on selection iterators */ H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index d7a2340..d4a4d69 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -455,6 +455,8 @@ H5S_select_deserialize(H5S_t **space, const uint8_t **p) H5S_t *tmp_space = NULL; /* Pointer to actual dataspace to use, either *space or a newly allocated one */ uint32_t sel_type; /* Pointer to the selection type */ + uint32_t version; /* Version number */ + uint8_t flags = 0; /* Flags */ herr_t ret_value = FAIL; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -472,8 +474,23 @@ H5S_select_deserialize(H5S_t **space, const uint8_t **p) /* Decode selection type */ UINT32DECODE(*p, sel_type); - /* Skip over the remainder of the header */ - *p += 12; + /* Decode version */ + UINT32DECODE(*p, version); + + if(version >= (uint32_t)2) { + /* Decode flags */ + flags = *(*p)++; + + /* Check for unknown flags */ + if(flags & ~H5S_SELECT_FLAG_BITS) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "unknown flag for selection") + + /* Skip over the remainder of the header */ + *p += 4; + } /* end if */ + else + /* Skip over the remainder of the header */ + *p += 8; /* Decode and check or patch rank for point and hyperslab selections */ if((sel_type == H5S_SEL_POINTS) || (sel_type == H5S_SEL_HYPERSLABS)) { @@ -499,19 +516,19 @@ H5S_select_deserialize(H5S_t **space, const uint8_t **p) /* Make routine for selection type */ switch(sel_type) { case H5S_SEL_POINTS: /* Sequence of points selected */ - ret_value = (*H5S_sel_point->deserialize)(tmp_space, p); + ret_value = (*H5S_sel_point->deserialize)(tmp_space, version, flags, p); break; case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ - ret_value = (*H5S_sel_hyper->deserialize)(tmp_space, p); + ret_value = (*H5S_sel_hyper->deserialize)(tmp_space, version, flags, p); break; case H5S_SEL_ALL: /* Entire extent selected */ - ret_value = (*H5S_sel_all->deserialize)(tmp_space, p); + ret_value = (*H5S_sel_all->deserialize)(tmp_space, version, flags, p); break; case H5S_SEL_NONE: /* Nothing selected */ - ret_value = (*H5S_sel_none->deserialize)(tmp_space, p); + ret_value = (*H5S_sel_none->deserialize)(tmp_space, version, flags, p); break; default: @@ -673,6 +690,89 @@ H5S_get_select_offset(const H5S_t *space, hsize_t *offset) /*-------------------------------------------------------------------------- NAME + H5S_get_select_unlim_dim + PURPOSE + Gets the unlimited dimension in the selection, or -1 if there is no + unlimited dimension. + USAGE + int H5S_get_select_unlim_dim(space) + const H5S_t *space; IN: Dataspace pointer of selection to query + RETURNS + Unlimited dimension in the selection, or -1 if there is no unlimited + dimension (never fails) + DESCRIPTION + Gets the unlimited dimension in the selection, or -1 if there is no + unlimited dimension. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Currently only implemented for hyperslab selections, all others + simply return -1. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5S_get_select_unlim_dim(const H5S_t *space) +{ + herr_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Check args */ + HDassert(space); + + ret_value = (*space->select.type->unlim_dim)(space); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S_get_select_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_get_select_num_elem_non_unlim + PURPOSE + Gets the number of elements in the non-unlimited dimensions + USAGE + herr_t H5S_get_select_num_elem_non_unlim(space,num_elem_non_unlim) + H5S_t *space; IN: Dataspace pointer to check + hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Returns the number of elements in a slice through the non-unlimited + dimensions of the selection. Fails if the selection has no unlimited + dimension. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_get_select_num_elem_non_unlim(const H5S_t *space, + hsize_t *num_elem_non_unlim) +{ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(space); + HDassert(num_elem_non_unlim); + + /* Check for selection callback */ + if(!space->select.type->num_elem_non_unlim) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type has no num_elem_non_unlim callback") + + /* Make selection callback */ + if((*space->select.type->num_elem_non_unlim)(space, num_elem_non_unlim) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S_get_select_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_select_is_contiguous PURPOSE Determines if a selection is contiguous in the dataspace @@ -2114,3 +2214,189 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5S_select_fill() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_project_intersection + + PURPOSE + Projects the intersection of of the selections of src_space and + src_intersect_space within the selection of src_space as a selection + within the selection of dst_space + + USAGE + herr_t H5S_select_project_intersection(src_space,dst_space,src_intersect_space,proj_space) + H5S_t *src_space; IN: Selection that is mapped to dst_space, and intersected with src_intersect_space + H5S_t *dst_space; IN: Selection that is mapped to src_space, and which contains the result + H5S_t *src_intersect_space; IN: Selection whose intersection with src_space is projected to dst_space to obtain the result + H5S_t *proj_space; OUT: Will contain the result (intersection of src_intersect_space and src_space projected from src_space to dst_space) after the operation + + RETURNS + Non-negative on success/Negative on failure. + + DESCRIPTION + Projects the intersection of of the selections of src_space and + src_intersect_space within the selection of src_space as a selection + within the selection of dst_space. The result is placed in the + selection of proj_space. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, + const H5S_t *src_intersect_space, H5S_t **new_space_ptr) +{ + H5S_t *new_space = NULL; /* New dataspace constructed */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(src_space); + HDassert(dst_space); + HDassert(src_intersect_space); + HDassert(new_space_ptr); + + /* Create new space, using dst extent. Start with "all" selection. */ + if(NULL == (new_space = H5S_create(H5S_SIMPLE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create output dataspace") + if(H5S_extent_copy_real(&new_space->extent, &dst_space->extent, TRUE) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy destination space extent") + + /* If the intersecting space is "all", the intersection must be equal to the + * source space and the projection must be equal to the destination space */ + if(src_intersect_space->select.type->type == H5S_SEL_ALL) { + /* Copy the destination selection. */ + if(H5S_select_copy(new_space, dst_space, FALSE) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy destination space selection") + } /* end if */ + /* If any of the spaces are "none", the projection must also be "none" */ + else if((src_intersect_space->select.type->type == H5S_SEL_NONE) + || (src_space->select.type->type == H5S_SEL_NONE) + || (dst_space->select.type->type == H5S_SEL_NONE)) { + /* Change to "none" selection */ + if(H5S_select_none(new_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") + } /* end if */ + /* If any of the spaces use point selection, fall back to general algorithm + */ + else if((src_intersect_space->select.type->type == H5S_SEL_POINTS) + || (src_space->select.type->type == H5S_SEL_POINTS) + || (dst_space->select.type->type == H5S_SEL_POINTS)) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") + else { + HDassert(src_intersect_space->select.type->type == H5S_SEL_HYPERSLABS); + /* Intersecting space is hyperslab selection. Call the hyperslab + * routine to project to another hyperslab selection. */ + if(H5S__hyper_project_intersection(src_space, dst_space, src_intersect_space, new_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't project hyperslab ondot destination selection") + } /* end else */ + + /* load the address of the new space into *new_space_ptr */ + *new_space_ptr = new_space; + +done: + /* Cleanup on error */ + if(ret_value < 0) { + if(new_space && H5S_close(new_space) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S_select_project_intersection() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_select_subtract + + PURPOSE + Subtract one selection from another + + USAGE + herr_t H5S_select_subtract(space,subtract_space) + H5S_t *space; IN/OUT: Selection to be operated on + H5S_t *subtract_space; IN: Selection that will be subtracted from space + + RETURNS + Non-negative on success/Negative on failure. + + DESCRIPTION + Removes any and all portions of space that are also present in + subtract_space. In essence, performs an A_NOT_B operation with the + two selections. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(space); + HDassert(subtract_space); + + /* If either space is using the none selection, then we do not need to do + * anything */ + if((space->select.type->type != H5S_SEL_NONE) + && (subtract_space->select.type->type != H5S_SEL_NONE)) { + /* If subtract_space is using the all selection, set space to none */ + if(subtract_space->select.type->type == H5S_SEL_ALL) { + /* Change to "none" selection */ + if(H5S_select_none(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") + } /* end if */ + else { + /* Check for point selection in subtract_space, convert to + * hyperslab */ + if(subtract_space->select.type->type == H5S_SEL_POINTS) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") + + /* Check for point or all selection in space, convert to hyperslab + */ + if(space->select.type->type == H5S_SEL_ALL) { + /* Convert current "all" selection to "real" hyperslab selection */ + /* Then allow operation to proceed */ + hsize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */ + hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */ + hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */ + hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */ + unsigned i; /* Local index variable */ + + /* Fill in temporary information for the dimensions */ + for(i = 0; i < space->extent.rank; i++) { + tmp_start[i] = 0; + tmp_stride[i] = 1; + tmp_count[i] = 1; + tmp_block[i] = space->extent.size[i]; + } /* end for */ + + /* Convert to hyperslab selection */ + if(H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + } /* end if */ + else if(space->select.type->type == H5S_SEL_POINTS) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") + + HDassert(space->select.type->type == H5S_SEL_HYPERSLABS); + HDassert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS); + + /* Both spaces are now hyperslabs, perform the operation */ + if(H5S__hyper_subtract(space, subtract_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab") + } /* end else */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S_select_subtract() */ + diff --git a/src/H5trace.c b/src/H5trace.c index 41f3418..f212bef 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -523,6 +523,10 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "H5D_CHUNKED"); break; + case H5D_VIRTUAL: + fprintf(out, "H5D_VIRTUAL"); + break; + case H5D_NLAYOUTS: fprintf(out, "H5D_NLAYOUTS"); break; @@ -675,6 +679,36 @@ H5_trace(const double *returning, const char *func, const char *type, ...) } /* end else */ break; + case 'v': + if(ptr) { + if(vp) + fprintf(out, "0x%lx", (unsigned long)vp); + else + fprintf(out, "NULL"); + } /* end if */ + else { + H5D_vds_view_t view = (H5D_vds_view_t)va_arg(ap, int); + + switch(view) { + case H5D_VDS_ERROR: + fprintf(out, "H5D_VDS_ERROR"); + break; + + case H5D_VDS_FIRST_MISSING: + fprintf(out, "H5D_VDS_FIRST_MISSING"); + break; + + case H5D_VDS_LAST_AVAILABLE: + fprintf(out, "H5D_VDS_LAST_AVAILABLE"); + break; + + default: + fprintf(out, "%ld", (long)view); + break; + } /* end switch */ + } /* end else */ + break; + default: fprintf (out, "BADTYPE(D%c)", type[1]); goto error; diff --git a/src/Makefile.am b/src/Makefile.am index f63a88e..86dad23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,7 +50,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Defl.c H5Dfill.c H5Dint.c \ H5Dio.c H5Dlayout.c \ - H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \ + H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c H5Dvirtual.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c1e4ea7..f9832f3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -246,6 +246,7 @@ set (H5_TESTS cross_read freespace mf + vds farray earray btree2 diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index b3df0eb..64031eb 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -464,6 +464,7 @@ add_test ( tstint2.h5 unregister_filter_1.h5 unregister_filter_2.h5 + vds_1.h5 WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST ) diff --git a/test/Makefile.am b/test/Makefile.am index 51c8ff0..d9c53d4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -46,7 +46,7 @@ TEST_PROG= testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \ big mtime fillval mount flush1 flush2 app_ref enum \ set_extent ttsafe enc_dec_plist enc_dec_plist_cross_platform\ getname vfd ntypes dangle dtransform reserved cross_read \ - freespace mf farray earray btree2 fheap file_image unregister + freespace mf vds farray earray btree2 fheap file_image unregister # List programs to be built when testing here. error_test and err_compat are # built at the same time as the other tests, but executed by testerror.sh. @@ -150,7 +150,8 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse earray.h5 efc[0-5].h5 log_vfd_out.log \ new_multi_file_v16-r.h5 new_multi_file_v16-s.h5 \ split_get_file_image_test-m.h5 split_get_file_image_test-r.h5 \ - file_image_core_test.h5.copy unregister_filter_1.h5 unregister_filter_2.h5 + file_image_core_test.h5.copy unregister_filter_1.h5 unregister_filter_2.h5 \ + vds_virt.h5 vds_src_[0-1].h5 # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ diff --git a/test/h5test.c b/test/h5test.c index f936605..843ec35 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -96,7 +96,7 @@ static H5E_auto2_t err_func = NULL; static herr_t h5_errors(hid_t estack, void *client_data); static char * h5_fixname_real(const char *base_name, hid_t fapl, const char *suffix, - char *fullname, size_t size); + char *fullname, size_t size, hbool_t nest_printf); /*------------------------------------------------------------------------- @@ -327,7 +327,7 @@ h5_reset(void) char * h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size) { - return (h5_fixname_real(base_name, fapl, ".h5", fullname, size)); + return (h5_fixname_real(base_name, fapl, ".h5", fullname, size, FALSE)); } @@ -347,7 +347,33 @@ h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size) char * h5_fixname_no_suffix(const char *base_name, hid_t fapl, char *fullname, size_t size) { - return (h5_fixname_real(base_name, fapl, NULL, fullname, size)); + return (h5_fixname_real(base_name, fapl, NULL, fullname, size, FALSE)); +} + + +/*------------------------------------------------------------------------- + * Function: h5_fixname_printf + * + * Purpose: Same as h5_fixname but returns a filename that can be passed + * through a printf-style function once before being passed to the file + * driver. Basically, replaces all % characters used by the file + * driver with %%. + * + * Return: Success: The FULLNAME pointer. + * + * Failure: NULL if BASENAME or FULLNAME is the null + * pointer or if FULLNAME isn't large enough for + * the result. + * + * Programmer: Neil Fortner + * Wednesday, July 15, 2015 + * + *------------------------------------------------------------------------- + */ +char * +h5_fixname_printf(const char *base_name, hid_t fapl, char *fullname, size_t size) +{ + return (h5_fixname_real(base_name, fapl, ".h5", fullname, size, TRUE)); } @@ -375,7 +401,7 @@ h5_fixname_no_suffix(const char *base_name, hid_t fapl, char *fullname, size_t s */ static char * h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, - char *fullname, size_t size) + char *fullname, size_t size, hbool_t nest_printf) { const char *prefix = NULL; char *ptr, last = '\0'; @@ -396,7 +422,7 @@ h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, if(suffix) { if(H5FD_FAMILY == driver) - suffix = "%05d.h5"; + suffix = nest_printf ? "%%05d.h5" : "%05d.h5"; else if (H5FD_MULTI == driver) suffix = NULL; } diff --git a/test/h5test.h b/test/h5test.h index f949375..ca0eead 100644 --- a/test/h5test.h +++ b/test/h5test.h @@ -127,6 +127,7 @@ H5TEST_DLL void h5_clean_files(const char *base_name[], hid_t fapl); H5TEST_DLL int h5_cleanup(const char *base_name[], hid_t fapl); H5TEST_DLL char *h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size); H5TEST_DLL char *h5_fixname_no_suffix(const char *base_name, hid_t fapl, char *fullname, size_t size); +H5TEST_DLL char *h5_fixname_printf(const char *base_name, hid_t fapl, char *fullname, size_t size); H5TEST_DLL hid_t h5_fileaccess(void); H5TEST_DLL void h5_no_hwconv(void); H5TEST_DLL const char *h5_rmprefix(const char *filename); diff --git a/test/trefer.c b/test/trefer.c index df4ea76..cb0f44e 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -521,6 +521,8 @@ test_reference_region(void) uint8_t *tu8; /* Temporary pointer to uint8 data */ H5O_type_t obj_type; /* Type of object */ int i, j; /* counting variables */ + hssize_t hssize_ret; /* hssize_t return value */ + htri_t tri_ret; /* htri_t return value */ herr_t ret; /* Generic return value */ haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ hid_t dset_NA; /* Dataset id for undefined reference */ @@ -614,6 +616,24 @@ test_reference_region(void) ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); CHECK(ret, FAIL, "H5Rcreate"); + /* Select unlimited hyperslab for third reference */ + start[0] = 1; start[1] = 8; + stride[0] = 4; stride[1] = 1; + count[0] = H5S_UNLIMITED; count[1] = 1; + block[0] = 2; block[1] = 2; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + hssize_ret = H5Sget_select_npoints(sid2); + VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + + /* Store third dataset region */ + ret = H5Rcreate(&wbuf[2], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + /* Write selection to disk */ ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); @@ -805,6 +825,31 @@ test_reference_region(void) ret = H5Sclose(sid2); CHECK(ret, FAIL, "H5Sclose"); + /* Get the unlimited selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[2]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + hssize_ret = H5Sget_select_npoints(sid2); + VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + tri_ret = H5Sis_regular_hyperslab(sid2); + CHECK(tri_ret, FAIL, "H5Sis_regular_hyperslab"); + VERIFY(tri_ret, TRUE, "H5Sis_regular_hyperslab Result"); + ret = H5Sget_regular_hyperslab(sid2, start, stride, count, block); + CHECK(ret, FAIL, "H5Sget_regular_hyperslab"); + VERIFY(start[0], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(start[1], (hsize_t)8, "Hyperslab Coordinates"); + VERIFY(stride[0], (hsize_t)4, "Hyperslab Coordinates"); + VERIFY(stride[1], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(count[0], H5S_UNLIMITED, "Hyperslab Coordinates"); + VERIFY(count[1], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(block[0], (hsize_t)2, "Hyperslab Coordinates"); + VERIFY(block[1], (hsize_t)2, "Hyperslab Coordinates"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + /* Close first space */ ret = H5Sclose(sid1); CHECK(ret, FAIL, "H5Sclose"); diff --git a/test/tselect.c b/test/tselect.c index d6b1e8f..670406d 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -13230,6 +13230,439 @@ test_hyper_regular(void) /**************************************************************** ** +** test_hyper_unlim(): Tests unlimited hyperslab selections +** +****************************************************************/ +static void +test_hyper_unlim_check(hid_t sid, hsize_t *dims, hssize_t enpoints, + hssize_t enblocks, hsize_t *eblock1, hsize_t *eblock2) +{ + hid_t lim_sid; + hsize_t start[3]; + H5S_sel_type sel_type; + hssize_t npoints; + hssize_t nblocks; + hsize_t blocklist[12]; + herr_t ret; + + HDassert(enblocks <= 2); + + /* Copy sid to lim_sid */ + lim_sid = H5Scopy(sid); + CHECK(lim_sid, FAIL, "H5Scopy"); + + /* "And" lim_sid with dims to create limited selection */ + HDmemset(start, 0, sizeof(start)); + ret = H5Sselect_hyperslab(lim_sid, H5S_SELECT_AND, start, NULL, dims, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Check number of elements */ + npoints = H5Sget_select_npoints(lim_sid); + CHECK(npoints, FAIL, "H5Sget_select_npoints"); + VERIFY(npoints, enpoints, "H5Sget_select_npoints"); + + /* Get selection type */ + sel_type = H5Sget_select_type(lim_sid); + CHECK(sel_type, H5S_SEL_ERROR, "H5Sget_select_type"); + + /* Only examine blocks for hyperslab selection */ + if(sel_type == H5S_SEL_HYPERSLABS) { + /* Get number of blocks */ + nblocks = H5Sget_select_hyper_nblocks(lim_sid); + CHECK(nblocks, FAIL, "H5Sget_select_hyper_nblocks"); + VERIFY(nblocks, enblocks, "H5Sget_select_hyper_nblocks"); + + if(nblocks > 0) { + /* Get blocklist */ + ret = H5Sget_select_hyper_blocklist(lim_sid, (hsize_t)0, (hsize_t)nblocks, blocklist); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + + /* Verify blocklist */ + if(nblocks == (hssize_t)1) { + if(HDmemcmp(blocklist, eblock1, 6 * sizeof(eblock1[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + } /* end if */ + else { + HDassert(nblocks == (hssize_t)2); + if(HDmemcmp(blocklist, eblock1, 6 * sizeof(eblock1[0]))) { + if(HDmemcmp(blocklist, eblock2, 6 * sizeof(eblock2[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + if(HDmemcmp(&blocklist[6], eblock1, 6 * sizeof(eblock1[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + } /* end if */ + else + if(HDmemcmp(&blocklist[6], eblock2, 6 * sizeof(eblock2[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + } /* end else */ + } /* end if */ + } /* end if */ + else + if(sel_type != H5S_SEL_NONE) + ERROR("H5Sget_select_type"); + + /* Close the limited dataspace */ + ret = H5Sclose(lim_sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* end test_hyper_unlim_check() */ + +static void +test_hyper_unlim(void) +{ + hid_t sid; + hsize_t dims[3] = {4, 4, 7}; + hsize_t mdims[3] = {4, H5S_UNLIMITED, 7}; + hsize_t start[3] = {1, 2, 1}; + hsize_t stride[3] = {1, 1, 3}; + hsize_t count[3] = {1, 1, 2}; + hsize_t block[3] = {2, H5S_UNLIMITED, 2}; + hsize_t start2[3]; + hsize_t count2[3]; + hsize_t eblock1[6] = {1, 2, 1, 2, 3, 2}; + hsize_t eblock2[6] = {1, 2, 4, 2, 3, 5}; + hssize_t offset[3] = {0, -1, 0}; + hssize_t ssize_out; + herr_t ret; + + /* Output message about test being performed */ + MESSAGE(6, ("Testing unlimited hyperslab selections\n")); + + /* Create dataspace */ + sid = H5Screate_simple(3, dims, mdims); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Select unlimited hyperslab */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Check with unlimited dimension clipped to 4 */ + test_hyper_unlim_check(sid, dims, (hssize_t)16, (hssize_t)2, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 3 */ + dims[1] = 3; + eblock1[4] = 2; + eblock2[4] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)2, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 2 */ + dims[1] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)0, (hssize_t)0, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 1 */ + dims[1] = 1; + test_hyper_unlim_check(sid, dims, (hssize_t)0, (hssize_t)0, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 7 */ + dims[1] = 7; + eblock1[4] = 6; + eblock2[4] = 6; + test_hyper_unlim_check(sid, dims, (hssize_t)40, (hssize_t)2, eblock1, eblock2); + + /* Set offset of selection */ + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Check with adjusted offset (should not affect result) */ + test_hyper_unlim_check(sid, dims, (hssize_t)40, (hssize_t)2, eblock1, eblock2); + + /* Reset offset of selection */ + offset[1] = (hssize_t)0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* + * Now try with multiple blocks in unlimited dimension + */ + stride[1] = 3; + stride[2] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 1; + block[1] = 2; + + /* Select unlimited hyperslab */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Check with new selection */ + eblock1[1] = 2; + eblock1[4] = 3; + eblock2[1] = 5; + eblock2[2] = 1; + eblock2[4] = 6; + eblock2[5] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)16, (hssize_t)2, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 3 */ + dims[1] = 3; + eblock1[4] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)4, (hssize_t)1, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 4 */ + dims[1] = 4; + eblock1[4] = 3; + test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)1, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 5 */ + dims[1] = 5; + eblock1[4] = 3; + test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)1, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 6 */ + dims[1] = 6; + eblock1[4] = 3; + eblock2[4] = 5; + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Set offset of selection */ + offset[1] = (hssize_t)-1; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Check with adjusted offset (should not affect result) */ + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Set offset of selection */ + offset[1] = (hssize_t)3; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Check with adjusted offset (should not affect result) */ + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Reset offset of selection */ + offset[1] = (hssize_t)0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* + * Now try invalid operations + */ + H5E_BEGIN_TRY { + /* Try multiple unlimited dimensions */ + start[0] = 1; + start[1] = 2; + start[2] = 1; + stride[0] = 1; + stride[1] = 3; + stride[2] = 3; + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = H5S_UNLIMITED; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + + /* Try unlimited count and block */ + count[2] = 2; + block[1] = H5S_UNLIMITED; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + + /* Try operations with two unlimited selections */ + block[1] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + H5E_BEGIN_TRY { + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + + /* Try invalid combination operations */ + H5E_BEGIN_TRY { + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, NULL, block, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, NULL, block, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, block, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL, block, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + H5E_BEGIN_TRY { + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + + /* + * Now test valid combination operations + */ + /* unlim AND non-unlim */ + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + start2[0] = 2; + start2[1] = 2; + start2[2] = 0; + count2[0] = 5; + count2[1] = 4; + count2[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 2; + eblock1[3] = 2; + eblock1[1] = 2; + eblock1[4] = 3; + eblock1[2] = 1; + eblock1[5] = 1; + eblock2[0] = 2; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 5; + eblock2[2] = 1; + eblock2[5] = 1; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)3, (hssize_t)2, eblock1, eblock2); + + /* unlim NOTA non-unlim */ + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + start2[0] = 1; + start2[1] = 5; + start2[2] = 2; + count2[0] = 2; + count2[1] = 2; + count2[2] = 6; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 1; + eblock1[3] = 2; + eblock1[1] = 5; + eblock1[4] = 6; + eblock1[2] = 3; + eblock1[5] = 3; + eblock2[0] = 1; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 6; + eblock2[2] = 6; + eblock2[5] = 7; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* non-unlim AND unlim */ + start2[0] = 2; + start2[1] = 2; + start2[2] = 0; + count2[0] = 5; + count2[1] = 4; + count2[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 2; + eblock1[3] = 2; + eblock1[1] = 2; + eblock1[4] = 3; + eblock1[2] = 1; + eblock1[5] = 1; + eblock2[0] = 2; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 5; + eblock2[2] = 1; + eblock2[5] = 1; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)3, (hssize_t)2, eblock1, eblock2); + + /* non-unlim NOTB unlim */ + start2[0] = 1; + start2[1] = 5; + start2[2] = 2; + count2[0] = 2; + count2[1] = 2; + count2[2] = 6; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 1; + eblock1[3] = 2; + eblock1[1] = 5; + eblock1[4] = 6; + eblock1[2] = 3; + eblock1[5] = 3; + eblock2[0] = 1; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 6; + eblock2[2] = 6; + eblock2[5] = 7; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Test H5Sget_select_npoints() */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + ssize_out = H5Sget_select_npoints(sid); + VERIFY(ssize_out, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + + /* Test H5Sget_select_hyper_nblocks() */ + ssize_out = H5Sget_select_hyper_nblocks(sid); + VERIFY(ssize_out, (hssize_t)H5S_UNLIMITED, "H5Sget_select_hyper_nblocks"); + + /* Test H5Sget_select_bounds() */ + ret = H5Sget_select_bounds(sid, start2, count2); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(start2[0], start[0], "H5Sget_select_bounds"); + VERIFY(start2[1], start[1], "H5Sget_select_bounds"); + VERIFY(start2[2], start[2], "H5Sget_select_bounds"); + VERIFY(count2[0], start[0] + (stride[0] * (count[0] - (hsize_t)1)) + block[0] - (hsize_t)1, "H5Sget_select_bounds"); + VERIFY(count2[1], H5S_UNLIMITED, "H5Sget_select_bounds"); + VERIFY(count2[2], start[2] + (stride[2] * (count[2] - (hsize_t)1)) + block[2] - (hsize_t)1, "H5Sget_select_bounds"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* end test_hyper_unlim() */ + +/**************************************************************** +** ** test_select(): Main H5S selection testing routine. ** ****************************************************************/ @@ -13392,6 +13825,9 @@ test_select(void) /* Test 'regular' hyperslab query routines */ test_hyper_regular(); + /* Test unlimited hyperslab selections */ + test_hyper_unlim(); + } /* test_select() */ diff --git a/test/vds.c b/test/vds.c new file mode 100644 index 0000000..ba5fd71 --- /dev/null +++ b/test/vds.c @@ -0,0 +1,11150 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Neil Fortner <nfortne2@hdfgroup.org> + * Monday, February 16, 2015 + * + * Purpose: Tests datasets with virtual layout. + */ +#include "h5test.h" +#include "H5srcdir.h" +#include "H5Dprivate.h" /* For H5D_VIRTUAL_DEF_LIST_SIZE */ + +typedef enum { + TEST_API_BASIC, + TEST_API_COPY_PLIST, + TEST_API_ENCDEC_PLIST, + TEST_API_CREATE_DSET, + TEST_API_REOPEN_DSET, + TEST_API_REOPEN_FILE, + TEST_API_NTESTS +} test_api_config_t; + +const char *FILENAME[] = { + "vds_virt_0", + "vds_virt_1", + "vds_src_0", + "vds_src_1", + "vds%_src", + NULL +}; + +/* I/O test config flags */ +#define TEST_IO_CLOSE_SRC 0x01u +#define TEST_IO_DIFFERENT_FILE 0x02u +#define TEST_IO_REOPEN_VIRT 0x04u +#define TEST_IO_NTESTS 0x08u + +#define LIST_DOUBLE_SIZE (H5D_VIRTUAL_DEF_LIST_SIZE + 1) + +#define FILENAME_BUF_SIZE 1024 + + +/*------------------------------------------------------------------------- + * Function: vds_select_equal + * + * Purpose: Helper function to check if the selections in the two + * provided dataspaces are the same. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Neil Fortner + * Monday, March 2, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static htri_t +vds_select_equal(hid_t space1, hid_t space2) +{ + H5S_sel_type type1; + H5S_sel_type type2; + hsize_t *buf1 = NULL; + hsize_t *buf2 = NULL; + size_t i; + htri_t ret_value = TRUE; + + /* Get and compare selection types */ + if((type1 = H5Sget_select_type(space1)) < 0) + TEST_ERROR + if((type2 = H5Sget_select_type(space2)) < 0) + TEST_ERROR + if(type1 != type2) + return FALSE; + + /* Check selection type */ + switch(type1) { + case H5S_SEL_NONE: + case H5S_SEL_ALL: + break; + + case H5S_SEL_POINTS: + { + int rank1; + int rank2; + hssize_t npoints1; + hssize_t npoints2; + + /* Get and compare rank */ + if((rank1 = H5Sget_simple_extent_ndims(space1)) < 0) + TEST_ERROR + if((rank2 = H5Sget_simple_extent_ndims(space2)) < 0) + TEST_ERROR + if(rank1 != rank2) + return FALSE; + + /* Get and compare number of points */ + if((npoints1 = H5Sget_select_elem_npoints(space1)) < 0) + TEST_ERROR + if((npoints2 = H5Sget_select_elem_npoints(space2)) < 0) + TEST_ERROR + if(npoints1 != npoints2) + return FALSE; + + /* Allocate point lists. Do not return directly afer + * allocating, to make sure buffers are freed. */ + if(NULL == (buf1 = (hsize_t *)HDmalloc((size_t)rank1 * (size_t)npoints1 * sizeof(hsize_t)))) + TEST_ERROR + if(NULL == (buf2 = (hsize_t *)HDmalloc((size_t)rank1 * (size_t)npoints1 * sizeof(hsize_t)))) + TEST_ERROR + + /* Get and compare point lists */ + if(H5Sget_select_elem_pointlist(space1, (hsize_t)0, (hsize_t)npoints1, buf1) < 0) + TEST_ERROR + if(H5Sget_select_elem_pointlist(space2, (hsize_t)0, (hsize_t)npoints1, buf2) < 0) + TEST_ERROR + for(i = 0; i < ((size_t)rank1 * (size_t)npoints1); i++) + if(buf1[i] != buf2[i]) { + ret_value = FALSE; + break; + } /* end if */ + + /* Free buffers */ + HDfree(buf1); + buf1 = NULL; + HDfree(buf2); + buf2 = NULL; + } /* end block */ + + break; + + case H5S_SEL_HYPERSLABS: + { + int rank1; + int rank2; + hssize_t nblocks1; + hssize_t nblocks2; + + /* Get and compare rank */ + if((rank1 = H5Sget_simple_extent_ndims(space1)) < 0) + TEST_ERROR + if((rank2 = H5Sget_simple_extent_ndims(space2)) < 0) + TEST_ERROR + if(rank1 != rank2) + return FALSE; + + /* Get and compare number of blocks */ + if((nblocks1 = H5Sget_select_hyper_nblocks(space1)) < 0) + TEST_ERROR + if((nblocks2 = H5Sget_select_hyper_nblocks(space2)) < 0) + TEST_ERROR + if(nblocks1 != nblocks2) + return FALSE; + + /* Allocate block lists. Do not return directly afer + * allocating, to make sure buffers are freed. */ + if(NULL == (buf1 = (hsize_t *)HDmalloc((size_t)2 * (size_t)rank1 * (size_t)nblocks1 * sizeof(*buf1)))) + TEST_ERROR + if(NULL == (buf2 = (hsize_t *)HDmalloc((size_t)2 * (size_t)rank1 * (size_t)nblocks1 * sizeof(*buf2)))) + TEST_ERROR + + /* Get and compare block lists */ + if(H5Sget_select_hyper_blocklist(space1, (hsize_t)0, (hsize_t)nblocks1, buf1) < 0) + TEST_ERROR + if(H5Sget_select_hyper_blocklist(space2, (hsize_t)0, (hsize_t)nblocks1, buf2) < 0) + TEST_ERROR + for(i = 0; i < ((size_t)2 * (size_t)rank1 * (size_t)nblocks1); i++) + if(buf1[i] != buf2[i]) { + ret_value = FALSE; + break; + } /* end if */ + + /* Free buffers */ + HDfree(buf1); + buf1 = NULL; + HDfree(buf2); + buf2 = NULL; + } /* end block */ + + break; + + case H5S_SEL_ERROR: + case H5S_SEL_N: + default: + TEST_ERROR + } /* end switch */ + + return ret_value; + +error: + if(buf1) + HDfree(buf1); + if(buf2) + HDfree(buf2); + + return -1; +} /* end vds_select_equal() */ + + +/*------------------------------------------------------------------------- + * Function: vds_check_mapping + * + * Purpose: Helper function to check if the ith virtual mapping in the + * provided dcpl is the same as that described by the other + * parameters. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Neil Fortner + * Monday, March 2, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +vds_check_mapping(hid_t dcpl, size_t i, hid_t vspace, hid_t srcspace, + const char *filename, const char *dsetname) +{ + hid_t space_out = -1; + char name_out[32]; + htri_t tri_ret; + ssize_t str_len; + + HDassert(dcpl >= 0); + HDassert(vspace >= 0); + HDassert(srcspace >= 0); + HDassert(filename); + HDassert(dsetname); + + /* Check vspace */ + if((space_out = H5Pget_virtual_vspace(dcpl, i)) < 0) + TEST_ERROR + if((tri_ret = H5Sextent_equal(space_out, vspace)) < 0) + TEST_ERROR + if(!tri_ret) + TEST_ERROR + if((tri_ret = vds_select_equal(space_out, vspace)) < 0) + TEST_ERROR + if(!tri_ret) + TEST_ERROR + if(H5Sclose(space_out) < 0) + TEST_ERROR + space_out = -1; + + /* Check srcspace */ + if((space_out = H5Pget_virtual_srcspace(dcpl, i)) < 0) + TEST_ERROR + if((tri_ret = vds_select_equal(space_out, srcspace)) < 0) + TEST_ERROR + if(!tri_ret) + TEST_ERROR + if(H5Sclose(space_out) < 0) + TEST_ERROR + space_out = -1; + + /* Check filename */ + if((str_len = H5Pget_virtual_filename(dcpl, i, NULL, (size_t)0)) < 0) + TEST_ERROR + if((size_t)str_len != HDstrlen(filename)) + TEST_ERROR + HDassert((size_t)str_len < sizeof(name_out)); + if((str_len = H5Pget_virtual_filename(dcpl, i, name_out, sizeof(name_out))) < 0) + TEST_ERROR + if((size_t)str_len != HDstrlen(filename)) + TEST_ERROR + if(HDstrncmp(name_out, filename, (size_t)str_len + 1) != 0) + TEST_ERROR + + /* Check dsetname */ + if((str_len = H5Pget_virtual_dsetname(dcpl, i, NULL, (size_t)0)) < 0) + TEST_ERROR + if((size_t)str_len != HDstrlen(dsetname)) + TEST_ERROR + HDassert((size_t)str_len < sizeof(name_out)); + if((str_len = H5Pget_virtual_dsetname(dcpl, i, name_out, sizeof(name_out))) < 0) + TEST_ERROR + if((size_t)str_len != HDstrlen(dsetname)) + TEST_ERROR + if(HDstrncmp(name_out, dsetname, (size_t)str_len + 1) != 0) + TEST_ERROR + + return 0; + +error: + H5E_BEGIN_TRY { + if(space_out >= 0) + (void)H5Sclose(space_out); + } H5E_END_TRY + + return -1; +} /* end vds_check_mapping() */ + + +/*------------------------------------------------------------------------- + * Function: test_api_get_ex_dcpl + * + * Purpose: Tests API functions related to virtual datasets. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Monday, February 16, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* Helper function to get DCPL for examination depending on config */ +static int +test_api_get_ex_dcpl(test_api_config_t config, hid_t fapl, hid_t dcpl, + hid_t *ex_dcpl, hid_t vspace, char *filename, hsize_t exp_meta_size) +{ + hid_t file = -1; /* File */ + hid_t dset = -1; /* Virtual dataset */ + void *plist_buf = NULL; /* Serialized property list buffer */ + H5O_info_t oinfo; /* Object info struct */ + htri_t tri_ret; + + HDassert((config >= TEST_API_BASIC) && (config < TEST_API_NTESTS)); + HDassert(fapl >= 0); + HDassert(dcpl >= 0); + HDassert(ex_dcpl); + HDassert(*ex_dcpl < 0); + HDassert(vspace >= 0); + HDassert(filename); + + /* Take different action depending on test configuration */ + if(config >= TEST_API_CREATE_DSET) { + /* Create file and dataset */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + if((dset = H5Dcreate2(file, "vdset", H5T_NATIVE_INT, vspace, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Reopen dataset if requested */ + if(config >= TEST_API_REOPEN_DSET) { + /* Close dataset */ + if(H5Dclose(dset) < 0) + TEST_ERROR + dset = -1; + + /* Reopen file if requested */ + if(config == TEST_API_REOPEN_FILE) { + if(H5Fclose(file) < 0) + TEST_ERROR + file = -1; + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Open dataset */ + if((dset = H5Dopen2(file, "vdset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get DCPL from dataset */ + if((*ex_dcpl = H5Dget_create_plist(dset)) < 0) + TEST_ERROR + + /* Test H5Dget_offset() (just returns HADDR_UNDEF) */ + if(HADDR_UNDEF != H5Dget_offset(dset)) + TEST_ERROR + + /* Test H5Oget_info returns correct metadata size */ + if(H5Oget_info(dset, &oinfo) < 0) + TEST_ERROR + if(oinfo.meta_size.obj.index_size != (hsize_t)0) + TEST_ERROR + if(config == TEST_API_REOPEN_FILE) { + if(oinfo.meta_size.obj.heap_size != exp_meta_size) { + printf("VDS metadata size: %llu Expected: %llu\n", (long long unsigned)oinfo.meta_size.obj.heap_size, (long long unsigned)exp_meta_size); + TEST_ERROR + } /* end if */ + } /* end if */ + else + if((oinfo.meta_size.obj.heap_size != exp_meta_size) + && (oinfo.meta_size.obj.heap_size != (hsize_t)0)) + TEST_ERROR + if(oinfo.meta_size.attr.index_size != (hsize_t)0) + TEST_ERROR + if(oinfo.meta_size.attr.index_size != (hsize_t)0) + TEST_ERROR + + /* Close dataset */ + if(H5Dclose(dset) < 0) + TEST_ERROR + dset = -1; + + /* Delete dataset */ + if(H5Ldelete(file, "vdset", H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + TEST_ERROR + file = -1; + } /* end if */ + else if(config == TEST_API_COPY_PLIST) { + /* Copy property list */ + if((*ex_dcpl = H5Pcopy(dcpl)) < 0) + TEST_ERROR + } /* end if */ + else if(config == TEST_API_ENCDEC_PLIST) { + size_t plist_buf_size; + + /* Encode property list to plist_buf */ + if(H5Pencode(dcpl, NULL, &plist_buf_size) < 0) + TEST_ERROR + if(NULL == (plist_buf = HDmalloc(plist_buf_size))) + TEST_ERROR + if(H5Pencode(dcpl, plist_buf, &plist_buf_size) < 0) + TEST_ERROR + + /* Decode serialized property list to *ex_dcpl */ + if((*ex_dcpl = H5Pdecode(plist_buf)) < 0) + TEST_ERROR + + /* Free plist_buf */ + HDfree(plist_buf); + plist_buf = NULL; + } /* end if */ + else { + /* Simply copy the id to ex_dcpl and increment the ref count so ex_dcpl + * can be closed */ + if(H5Iinc_ref(dcpl) < 0) + TEST_ERROR + *ex_dcpl = dcpl; + } /* end else */ + + /* Verify examination DCPL is equal to original DCPL. Do not compare the + * plist to itselt, and do not do the comparison if we reopened the file, + * because in that case the extent of the source dset will not be corrent. + */ + if((*ex_dcpl != dcpl) && (config != TEST_API_REOPEN_FILE)) { + if((tri_ret = H5Pequal(dcpl, *ex_dcpl)) < 0) + TEST_ERROR + if(!tri_ret) + TEST_ERROR + } /* end if */ + + return 0; + +error: + H5E_BEGIN_TRY { + if(file >= 0) + (void)H5Fclose(file); + if(dset >= 0) + (void)H5Dclose(dset); + } H5E_END_TRY; + if(plist_buf) + HDfree(plist_buf); + + return -1; +} /* end test_api_get_ex_dcpl() */ + +/* Main test function */ +static int +test_api(test_api_config_t config, hid_t fapl) +{ + char filename[FILENAME_BUF_SIZE]; + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t ex_dcpl = -1; /* Temporary dcpl for examination */ + hid_t srcspace[4] = {-1, -1, -1, -1}; /* Source dataspaces */ + hid_t vspace[LIST_DOUBLE_SIZE]; /* Virtual dset dataspaces */ + const char *src_file[4] = {"src_file1", "src_file2.", "src_file3..", "src_file4..."}; /* Source file names (different lengths) */ + const char *src_dset[4] = {"src_dset1....", "src_dset2.....", "src_dset3......", "src_dset4......."}; /* Source dataset names (different lengths) */ + char tmp_filename[32]; + char tmp_dsetname[32]; + hsize_t dims[2] = {10, 20}; /* Data space current size */ + hsize_t start[2]; /* Hyperslab start */ + hsize_t stride[2]; /* Hyperslab stride */ + hsize_t count[2]; /* Hyperslab count */ + hsize_t block[2]; /* Hyperslab block */ + hsize_t coord[10]; /* Point selection array */ + size_t size_out; + herr_t ret; + unsigned i; + + /* Initialize vspace */ + for(i = 0; i < (unsigned)(sizeof(vspace) / sizeof(vspace[0])); i++) + vspace[i] = -1; + + switch(config) { + case TEST_API_BASIC: + TESTING("virtual dataset API functions") + break; + case TEST_API_COPY_PLIST: + TESTING("virtual dataset API functions with copied plists") + break; + case TEST_API_ENCDEC_PLIST: + TESTING("virtual dataset API functions with encoded and decoded plists") + break; + case TEST_API_CREATE_DSET: + TESTING("virtual dataset create") + break; + case TEST_API_REOPEN_DSET: + TESTING("virtual dataset create with reopened dataset") + break; + case TEST_API_REOPEN_FILE: + TESTING("virtual dataset create with reopened file") + break; + case TEST_API_NTESTS: + default: + TEST_ERROR + } /* end switch */ + + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + /* Create DCPL */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + + /* + * Test 1: All - all selection + */ + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all (should not be necessary, but just to be sure) */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + if(H5Sselect_all(vspace[0]) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], srcspace[0]) < 0) + TEST_ERROR + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)69) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)1) + TEST_ERROR + + /* Check that the mapping in the DCPL is correct */ + if(vds_check_mapping(ex_dcpl, (size_t)0, vspace[0], srcspace[0], src_file[0], src_dset[0]) < 0) + TEST_ERROR + + /* Close */ + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + + + /* + * Test 2: Hyper - hyper selection + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select regular hyperslab in source space */ + start[0] = 2; + start[1] = 1; + stride[0] = 3; + stride[1] = 5; + count[0] = 2; + count[1] = 3; + block[0] = 2; + block[1] = 4; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Select composite hyperslab in virtual space */ + count[0] = 1; + count[1] = 1; + block[0] = 5; + block[1] = 6; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, count, block) < 0) + TEST_ERROR + start[0] = 7; + start[1] = 0; + block[0] = 1; + block[1] = 18; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_OR, start, NULL, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], srcspace[0]) < 0) + TEST_ERROR + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)213) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)1) + TEST_ERROR + + /* Check that the mapping in the DCPL is correct */ + if(vds_check_mapping(ex_dcpl, (size_t)0, vspace[0], srcspace[0], src_file[0], src_dset[0]) < 0) + TEST_ERROR + + /* Close */ + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + + +#ifdef VDS_POINT_SELECTIONS /* VDS does not currently support point selections */ + /* + * Test 3: Point - point selection + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select points in source space */ + coord[0] = 5; + coord[1] = 15; + coord[2] = 7; + coord[3] = 19; + coord[4] = 8; + coord[5] = 0; + coord[6] = 2; + coord[7] = 14; + coord[8] = 8; + coord[9] = 18; + if(H5Sselect_elements(srcspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Select points in virtual space */ + coord[0] = 3; + coord[1] = 12; + coord[2] = 7; + coord[3] = 11; + coord[4] = 4; + coord[5] = 9; + coord[6] = 7; + coord[7] = 11; + coord[8] = 5; + coord[9] = 5; + if(H5Sselect_elements(vspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], srcspace[0]) < 0) + TEST_ERROR + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)0) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)1) + TEST_ERROR + + /* Check that the mapping in the DCPL is correct */ + if(vds_check_mapping(ex_dcpl, (size_t)0, vspace[0], srcspace[0], src_file[0], src_dset[0]) < 0) + TEST_ERROR + + /* Close */ + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + + + /* + * Test 4: Point - hyper selection + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslab in source space */ + start[0] = 2; + start[1] = 7; + count[0] = 1; + count[1] = 1; + block[0] = 1; + block[1] = 5; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, block) < 0) + TEST_ERROR + + /* Select points in virtual space */ + coord[0] = 1; + coord[1] = 1; + coord[2] = 4; + coord[3] = 17; + coord[4] = 3; + coord[5] = 9; + coord[6] = 5; + coord[7] = 13; + coord[8] = 7; + coord[9] = 16; + if(H5Sselect_elements(vspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], srcspace[0]) < 0) + TEST_ERROR + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)0) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)1) + TEST_ERROR + + /* Check that the mapping in the DCPL is correct */ + if(vds_check_mapping(ex_dcpl, (size_t)0, vspace[0], srcspace[0], src_file[0], src_dset[0]) < 0) + TEST_ERROR + + /* Close */ + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + + + /* + * Test 5: All previous mappings together + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create dataspaces */ + for(i = 0; i < 4; i++) { + /* Create source dataspace */ + if((srcspace[i] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[i] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + } /* end for */ + + /* Select all (should not be necessary, but just to be sure) */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + if(H5Sselect_all(vspace[0]) < 0) + TEST_ERROR + + /* Select regular hyperslab in source space */ + start[0] = 2; + start[1] = 1; + stride[0] = 3; + stride[1] = 5; + count[0] = 2; + count[1] = 3; + block[0] = 2; + block[1] = 4; + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Select composite hyperslab in virtual space */ + count[0] = 1; + count[1] = 1; + block[0] = 5; + block[1] = 6; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, count, block) < 0) + TEST_ERROR + start[0] = 7; + start[1] = 0; + block[0] = 1; + block[1] = 18; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_OR, start, NULL, count, block) < 0) + TEST_ERROR + + /* Select points in source space */ + coord[0] = 5; + coord[1] = 15; + coord[2] = 7; + coord[3] = 19; + coord[4] = 8; + coord[5] = 0; + coord[6] = 2; + coord[7] = 14; + coord[8] = 8; + coord[9] = 18; + if(H5Sselect_elements(srcspace[2], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Select points in virtual space */ + coord[0] = 3; + coord[1] = 12; + coord[2] = 7; + coord[3] = 11; + coord[4] = 4; + coord[5] = 9; + coord[6] = 7; + coord[7] = 11; + coord[8] = 5; + coord[9] = 5; + if(H5Sselect_elements(vspace[2], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Select hyperslab in source space */ + start[0] = 2; + start[1] = 7; + count[0] = 1; + count[1] = 1; + block[0] = 1; + block[1] = 5; + if(H5Sselect_hyperslab(srcspace[3], H5S_SELECT_SET, start, NULL, count, block) < 0) + TEST_ERROR + + /* Select points in virtual space */ + coord[0] = 1; + coord[1] = 1; + coord[2] = 4; + coord[3] = 17; + coord[4] = 3; + coord[5] = 9; + coord[6] = 5; + coord[7] = 13; + coord[8] = 7; + coord[9] = 16; + if(H5Sselect_elements(vspace[3], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + for(i = 0; i < 4; i++) + if(H5Pset_virtual(dcpl, vspace[i], src_file[i], src_dset[i], srcspace[i]) < 0) + TEST_ERROR + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)0) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)4) + TEST_ERROR + + /* Check that the mappings in the DCPL are correct */ + for(i = 0; i < 4; i++) + if(vds_check_mapping(ex_dcpl, (size_t)i, vspace[i], srcspace[i], src_file[i], src_dset[i]) < 0) + TEST_ERROR + + /* Close */ + for(i = 0; i < 4; i++) { + if(H5Sclose(srcspace[i]) < 0) + TEST_ERROR + srcspace[i] = -1; + if(H5Sclose(vspace[i]) < 0) + TEST_ERROR + vspace[i] = -1; + } /* end for */ + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + +#else /* VDS_POINT_SELECTIONS */ + + /* + * Test 3: Verify point selections fail + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select points in source space */ + coord[0] = 5; + coord[1] = 15; + coord[2] = 7; + coord[3] = 19; + coord[4] = 8; + coord[5] = 0; + coord[6] = 2; + coord[7] = 14; + coord[8] = 8; + coord[9] = 18; + if(H5Sselect_elements(srcspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Select points in virtual space */ + coord[0] = 3; + coord[1] = 12; + coord[2] = 7; + coord[3] = 11; + coord[4] = 4; + coord[5] = 9; + coord[6] = 7; + coord[7] = 11; + coord[8] = 5; + coord[9] = 5; + if(H5Sselect_elements(vspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Attempt to add virtual layout mapping */ + H5E_BEGIN_TRY { + ret = H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], srcspace[0]); + } H5E_END_TRY + if(ret >= 0) + TEST_ERROR +#endif /* VDS_POINT_SELECTIONS */ + + + /* + * Test 6: Enough Selections to trigger doubling of mapping list + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[0] = 1; + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all in source space (should not be necessary, but just to be sure) */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + + /* Init virtual space extent */ + dims[0] = LIST_DOUBLE_SIZE; + + /* Init hyperslab values */ + start[0] = 0; + start[1] = 0; + count[0] = 1; + count[1] = 1; + block[0] = 1; + block[1] = 20; + + /* Build virtual layout */ + for(i = 0; i < LIST_DOUBLE_SIZE; i++) { + /* Create virtual dataspace */ + if((vspace[i] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select row in virual dataspace */ + start[0] = (hsize_t)i; + if(H5Sselect_hyperslab(vspace[i], H5S_SELECT_SET, start, NULL, count, block) < 0) + TEST_ERROR + + /* Create file and dataset names */ + (void)HDsnprintf(tmp_filename, sizeof(tmp_filename), "src_file%u", i); + tmp_filename[sizeof(tmp_filename) - 1] = '\0'; + (void)HDsnprintf(tmp_dsetname, sizeof(tmp_dsetname), "src_dset%u", i); + tmp_dsetname[sizeof(tmp_dsetname) - 1] = '\0'; + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[i], tmp_filename, tmp_dsetname, srcspace[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)697) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)LIST_DOUBLE_SIZE) + TEST_ERROR + + /* Verify virtual layout */ + for(i = 0; i < LIST_DOUBLE_SIZE; i++) { + /* Generate source file name */ + (void)HDsnprintf(tmp_filename, sizeof(tmp_filename), "src_file%u", i); + tmp_filename[sizeof(tmp_filename) - 1] = '\0'; + + /* Generate source dset name */ + (void)HDsnprintf(tmp_dsetname, sizeof(tmp_dsetname), "src_dset%u", i); + tmp_dsetname[sizeof(tmp_dsetname) - 1] = '\0'; + + /* Check that the mapping in the DCPL is correct */ + if(vds_check_mapping(ex_dcpl, (size_t)i, vspace[i], srcspace[0], tmp_filename, tmp_dsetname) < 0) + TEST_ERROR + } /* end if */ + + /* Close */ + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + for(i = 0; i < LIST_DOUBLE_SIZE; i++) { + if(H5Sclose(vspace[i]) < 0) + TEST_ERROR + vspace[i] = -1; + } /* end for */ + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + + + /* + * Test 7: Empty VDS + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all (should not be necessary, but just to be sure) */ + if(H5Sselect_all(vspace[0]) < 0) + TEST_ERROR + + /* Get examination DCPL */ + if(test_api_get_ex_dcpl(config, fapl, dcpl, &ex_dcpl, vspace[0], filename, (hsize_t)0) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(ex_dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != (size_t)0) + TEST_ERROR + + /* Close */ + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Pclose(ex_dcpl) < 0) + TEST_ERROR + ex_dcpl = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (sizeof(srcspace) / sizeof(srcspace[0])); i++) { + if(srcspace[i] >= 0) + (void)H5Sclose(srcspace[i]); + } /* end for */ + for(i = 0; i < (sizeof(vspace) / sizeof(vspace[0])); i++) { + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(dcpl >= 0) + (void)H5Pclose(dcpl); + if(ex_dcpl >= 0) + (void)H5Pclose(ex_dcpl); + } H5E_END_TRY; + + return 1; +} /* end test_api() */ + + +/*------------------------------------------------------------------------- + * Function: test_basic_io + * + * Purpose: Tests VDS I/O without unlimited selections or + * pattern-matching file/dataset strings + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Tuesday, March 3, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_basic_io(unsigned config, hid_t fapl) +{ + char srcfilename[FILENAME_BUF_SIZE]; + char srcfilename_map[FILENAME_BUF_SIZE]; + char vfilename[FILENAME_BUF_SIZE]; + char vfilename2[FILENAME_BUF_SIZE]; + char srcfilenamepct[FILENAME_BUF_SIZE]; + char srcfilenamepct_map[FILENAME_BUF_SIZE]; + const char *srcfilenamepct_map_orig = "vds%%_src"; + hid_t srcfile[4] = {-1, -1, -1, -1}; /* Files with source dsets */ + hid_t vfile = -1; /* File with virtual dset */ + hid_t vfile2 = -1; /* File with copied virtual dset */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t srcspace[4] = {-1, -1, -1, -1}; /* Source dataspaces */ + hid_t vspace[4] = {-1, -1, -1, -1}; /* Virtual dset dataspaces */ + hid_t memspace = -1; /* Memory dataspace */ + hid_t srcdset[4] = {-1, -1, -1, -1}; /* Source datsets */ + hid_t vdset = -1; /* Virtual dataset */ + hsize_t dims[4] = {10, 26, 0, 0}; /* Data space current size */ + hsize_t start[4]; /* Hyperslab start */ + hsize_t stride[4]; /* Hyperslab stride */ + hsize_t count[4]; /* Hyperslab count */ + hsize_t block[4]; /* Hyperslab block */ + hssize_t offset[2] = {0, 0}; /* Selection offset */ + int buf[10][26]; /* Write and expected read buffer */ + int rbuf[10][26]; /* Read buffer */ + int rbuf99[9][9]; /* 9x9 Read buffer */ + int evbuf[10][26]; /* Expected VDS "buffer" */ + int erbuf[10][26]; /* Expected read buffer */ + int fill = -1; /* Fill value */ + herr_t ret; /* Generic return value */ + int i, j; + + TESTING("basic virtual dataset I/O") + + h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); + h5_fixname(FILENAME[1], fapl, vfilename2, sizeof vfilename2); + h5_fixname(FILENAME[2], fapl, srcfilename, sizeof srcfilename); + h5_fixname_printf(FILENAME[2], fapl, srcfilename_map, sizeof srcfilename_map); + h5_fixname(FILENAME[4], fapl, srcfilenamepct, sizeof srcfilenamepct); + h5_fixname_printf(srcfilenamepct_map_orig, fapl, srcfilenamepct_map, sizeof srcfilenamepct_map); + + /* Create DCPL */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* Set fill value */ + if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fill) < 0) + TEST_ERROR + + /* + * Test 1: All - all selection + */ + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all (should not be necessary, but just to be sure) */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + if(H5Sselect_all(vspace[0]) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset", srcspace[0]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source dataset */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Write data directly to source dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdset and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data through virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data through virtual dataset */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Reopen srcdset and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(srcdset[0], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* + * Test 2: 2 Source datasets, hyperslab virtual mappings, '%' in source + * dataset name, also test H5Ocopy() + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 13; + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all in source space (should not be necessary, but just to be sure) + */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + start[1] = 13; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "%%src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2%%", srcspace[0]) < 0) + TEST_ERROR + + /* Reset dims */ + dims[1] = 26; + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "%src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2%", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Write data directly to source datasets */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, vspace[1], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data through virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data through virtual dataset */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "%src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2%", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source datasets */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + if(H5Dread(srcdset[1], H5T_NATIVE_INT, vspace[1], H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Test H5Ocopy() to same file */ + /* Copy virtual dataset */ + if(H5Ocopy(vfile, "v_dset", vfile, "v_dset2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close v_dset */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data directly to source datasets */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, vspace[1], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Open v_dset2 */ + if((vdset = H5Dopen2(vfile, "v_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Read data through copied virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "%src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2%", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Only copy to a different file if the source datasets are in a different + * file */ + if(config & TEST_IO_DIFFERENT_FILE) { + /* Close v_dset2 */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + + /* Create file to copy virtual dataset to */ + if((vfile2 = H5Fcreate(vfilename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Copy virtual dataset */ + if(H5Ocopy(vfile, "v_dset", vfile2, "v_dset3", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data directly to source datasets */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, vspace[1], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen copied virtual file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile2) < 0) + TEST_ERROR + vfile2 = -1; + if((vfile2 = H5Fopen(vfilename2, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Open v_dset3 */ + if((vdset = H5Dopen2(vfile2, "v_dset3", H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Read data through copied virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "%src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2%", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Close copied virtual file */ + if(H5Fclose(vfile2) < 0) + TEST_ERROR + vfile2 = -1; + } /* end if */ + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 3: 2 Source datasets, hyperslab virtual mappings with offsets + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 13; + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all in source space (should not be necessary, but just to be sure) + */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + start[0] = 0; + start[1] = 3; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + offset[1] = -3; + if(H5Soffset_simple(vspace[0], offset) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "%%src_dset1", srcspace[0]) < 0) + TEST_ERROR + offset[1] = 10; + if(H5Soffset_simple(vspace[0], offset) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2%%", srcspace[0]) < 0) + TEST_ERROR + + /* Reset dims */ + dims[1] = 26; + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "%src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2%", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Write data directly to source datasets */ + offset[1] = -3; + if(H5Soffset_simple(vspace[0], offset) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + offset[1] = 10; + if(H5Soffset_simple(vspace[0], offset) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data through virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data through virtual dataset */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "%src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2%", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source datasets */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + offset[1] = -3; + if(H5Soffset_simple(vspace[0], offset) < 0) + TEST_ERROR + if(H5Dread(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + offset[1] = 10; + if(H5Soffset_simple(vspace[0], offset) < 0) + TEST_ERROR + if(H5Dread(srcdset[1], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* + * Test 4: 2 Source datasets, hyperslab virtual mappings on one mapping at a + * time, '%' in source file name + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 13; + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select all in source space (should not be necessary, but just to be sure) + */ + if(H5Sselect_all(srcspace[0]) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + start[1] = 13; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilenamepct_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilenamepct_map : ".", "src_dset2", srcspace[0]) < 0) + TEST_ERROR + + /* Reset dims */ + dims[1] = 26; + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilenamepct, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Write data directly to source datasets */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, vspace[1], H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read first source dataset through virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, vspace[0], vspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != (j < (int)(sizeof(buf[0]) / sizeof(buf[0][0]) / 2) + ? buf[i][j] : 0)) + TEST_ERROR + + /* Read second source dataset through virtual dataset */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(vdset, H5T_NATIVE_INT, vspace[1], vspace[1], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != (j < (int)(sizeof(buf[0]) / sizeof(buf[0][0]) / 2) + ? 0 : buf[i][j])) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write first source dataset through virtual dataset */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, vspace[0], vspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write second source dataset through virtual dataset */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, vspace[1], vspace[1], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilenamepct, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source datasets */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + if(H5Dread(srcdset[0], H5T_NATIVE_INT, vspace[0], H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + if(H5Dread(srcdset[1], H5T_NATIVE_INT, vspace[1], H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != (j < (int)(sizeof(buf[0]) / sizeof(buf[0][0]) / 2) + ? (buf[i][j] - (int)(sizeof(buf) / sizeof(buf[0][0]))) + : buf[i][j])) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 5: 2 Source datasets, hyperslab virtual mappings and selections + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create source dataspaces */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + if((srcspace[1] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslabs in source space */ + start[0] = 0; + start[1] = 0; + count[0] = 10; + count[1] = 13; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[1] = 13; + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + start[0] = 0; + start[1] = 0; + count[0] = 5; + count[1] = 26; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[0] = 5; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2", srcspace[1]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[1], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Write data directly to source datasets */ + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update evbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + evbuf[i][j] = buf[2 * i][j]; + for(/* j = 13 */; j < 26; j++) + evbuf[i][j] = buf[2 * i + 1][j - 13]; + } /* end for */ + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update evbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + evbuf[i + 5][j] = buf[2 * i][j + 13]; + for(/* j = 13 */; j < 26; j++) + evbuf[i + 5][j] = buf[2 * i + 1][j]; + } /* end for */ + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data through virtual dataset by hyperslab */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read first slice */ + if(H5Dread(vdset, H5T_NATIVE_INT, vspace[0], srcspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + erbuf[i][j] = evbuf[2 * i][j]; + for(/* j = 13 */; j < 26; j++) + erbuf[i][j] = evbuf[2 * i + 1][j - 13]; + } /* end for */ + + /* Read second slice */ + if(H5Dread(vdset, H5T_NATIVE_INT, vspace[1], srcspace[1], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + erbuf[i + 5][j] = evbuf[2 * i][j + 13]; + for(/* j = 13 */; j < 26; j++) + erbuf[i + 5][j] = evbuf[2 * i + 1][j]; + } /* end for */ + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data through virtual dataset */ + /* Write first slice */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, vspace[0], srcspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update evbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + evbuf[2 * i][j] = buf[i][j]; + for(/* j = 13 */; j < 26; j++) + evbuf[2 * i + 1][j - 13] = buf[i][j]; + } /* end for */ + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write second slice */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, vspace[1], srcspace[1], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update evbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + evbuf[2 * i][j + 13] = buf[i + 5][j]; + for(/* j = 13 */; j < 26; j++) + evbuf[2 * i + 1][j] = buf[i + 5][j]; + } /* end for */ + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source datasets */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read first dataset */ + if(H5Dread(srcdset[0], H5T_NATIVE_INT, srcspace[0], srcspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + erbuf[2 * i][j] = evbuf[i][j]; + for(/* j = 13 */; j < 26; j++) + erbuf[2 * i + 1][j - 13] = evbuf[i][j]; + } /* end for */ + + /* Read second dataset */ + if(H5Dread(srcdset[1], H5T_NATIVE_INT, srcspace[1], srcspace[1], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) { + for(j = 0; j < 13; j++) + erbuf[2 * i][j + 13] = evbuf[i + 5][j]; + for(/* j = 13 */; j < 26; j++) + erbuf[2 * i + 1][j] = evbuf[i + 5][j]; + } /* end for */ + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(srcspace[1]) < 0) + TEST_ERROR + srcspace[1] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 6: 2 Source datasets, checkerboard/stripe pattern to trigger + * sequence list refresh internally + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create memory dataspace */ + if((memspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[1] = 52; + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create source dataspace and file space for second operation (srcspace[1]) + */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + if((srcspace[1] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Reset dims */ + dims[1] = 26; + + /* Select hyperslabs (stripe) in source space and file space for second + * operation (srcspace[1]) */ + start[0] = 0; + start[1] = 0; + stride[0] = 1; + stride[1] = 2; + count[0] = 1; + count[1] = 26; + block[0] = 10; + block[1] = 1; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 1; + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Select hyperslabs (checkerboard) in virtual spaces */ + start[0] = 0; + start[1] = 0; + stride[0] = 2; + stride[1] = 2; + count[0] = 5; + count[1] = 26; + block[0] = 1; + block[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 1; + start[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_OR, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 0; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 1; + start[1] = 0; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_OR, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2", srcspace[0]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Write data directly to source datasets */ + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, srcspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i += 2) + for(j = 0; j < 26; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, srcspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 1; i < 10; i += 2) + for(j = 0; j < 26; j++) + erbuf[i][j] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data through virtual dataset by hyperslab */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read first stripe pattern */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, srcspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Read second stripe pattern */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, srcspace[1], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i += 2) + for(j = 0; j < 26; j++) { + erbuf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + erbuf[i + 1][j] -= (int)(sizeof(buf) / sizeof(buf[0][0])); + } /* end for */ + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data through virtual dataset */ + /* Write first slice */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, memspace, srcspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i += 2) + for(j = 0; j < 26; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write second slice */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, memspace, srcspace[1], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 1; i < 10; i += 2) + for(j = 0; j < 26; j++) + erbuf[i][j] = buf[i][j]; + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source datasets */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read first dataset */ + if(H5Dread(srcdset[0], H5T_NATIVE_INT, memspace, srcspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i += 2) + for(j = 0; j < 26; j++) { + erbuf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + erbuf[i + 1][j] -= (int)(sizeof(buf) / sizeof(buf[0][0])); + } /* end for */ + + /* Read second dataset */ + if(H5Dread(srcdset[1], H5T_NATIVE_INT, memspace, srcspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(srcspace[1]) < 0) + TEST_ERROR + srcspace[1] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + + /* + * Test 7: 1 Source dataset, two mappings, 4 dimensional virtual dataset + * and 3 dimensional source dataset + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create memory dataspace */ + if((memspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[0] = 3; + dims[1] = 3; + dims[2] = 3; + dims[3] = 3; + if((vspace[0] = H5Screate_simple(4, dims, NULL)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(4, dims, NULL)) < 0) + TEST_ERROR + + /* Create source dataspaces */ + dims[0] = 2; + dims[1] = 4; + dims[2] = 4; + if((srcspace[0] = H5Screate_simple(3, dims, NULL)) < 0) + TEST_ERROR + if((srcspace[1] = H5Screate_simple(3, dims, NULL)) < 0) + TEST_ERROR + + /* Reset dims */ + dims[0] = 10; + dims[1] = 26; + + /* Select hyperslabs (stripes) in source spaces */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + stride[0] = 1; + stride[1] = 2; + stride[2] = 1; + count[0] = 1; + count[1] = 2; + count[2] = 1; + block[0] = 2; + block[1] = 1; + block[2] = 4; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 1; + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Select hyperslabs (corners) in first virtual space */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + start[3] = 0; + stride[0] = 2; + stride[1] = 2; + stride[2] = 2; + stride[3] = 2; + count[0] = 2; + count[1] = 2; + count[2] = 2; + count[3] = 2; + block[0] = 1; + block[1] = 1; + block[2] = 1; + block[3] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Select hyperslabs ("+" pattern) in second virtual space */ + start[0] = 1; + start[1] = 1; + start[2] = 0; + start[3] = 0; + stride[0] = 2; + stride[1] = 2; + stride[2] = 2; + stride[3] = 2; + count[0] = 1; + count[1] = 1; + count[2] = 2; + count[3] = 2; + block[0] = 1; + block[1] = 1; + block[2] = 1; + block[3] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 0; + start[2] = 1; + count[1] = 2; + count[2] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_OR, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 0; + start[1] = 1; + count[0] = 2; + count[1] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_OR, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 1; + count[0] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_OR, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 0; + start[3] = 1; + count[1] = 2; + count[3] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_OR, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[1]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source dataset */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j; + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + count[0] = 2; + count[1] = 16; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Write data directly to source dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdset and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + count[0] = 9; + count[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Read data through virtual dataset by hyperslab */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select stripe */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + start[3] = 0; + count[0] = 3; + count[1] = 3; + count[2] = 1; + count[3] = 3; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Read first stripe pattern */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, vspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + HDmemset(erbuf, 0, sizeof(erbuf)); + for(i = 0; i < 9; i++) + for(j = 0; j < 3; j++) + erbuf[i][j] = fill; + erbuf[0][0] = buf[0][0]; + erbuf[0][2] = buf[0][1]; + erbuf[2][0] = buf[0][8]; + erbuf[2][2] = buf[0][9]; + erbuf[6][0] = buf[1][0]; + erbuf[6][2] = buf[1][1]; + erbuf[8][0] = buf[1][8]; + erbuf[8][2] = buf[1][9]; + erbuf[4][0] = buf[0][13]; + erbuf[4][2] = buf[0][14]; + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select stripe */ + start[0] = 0; + start[1] = 0; + start[2] = 1; + start[3] = 0; + count[0] = 3; + count[1] = 3; + count[2] = 1; + count[3] = 3; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 3; + count[0] = 9; + count[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Read second stripe pattern */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, vspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 9; i++) + for(j = 3; j < 6; j++) + erbuf[i][j] = fill; + erbuf[1][3] = buf[0][4]; + erbuf[1][5] = buf[0][5]; + erbuf[3][3] = buf[0][6]; + erbuf[3][4] = buf[0][7]; + erbuf[3][5] = buf[0][12]; + erbuf[4][3] = buf[0][15]; + erbuf[4][5] = buf[1][4]; + erbuf[5][3] = buf[1][7]; + erbuf[5][4] = buf[1][12]; + erbuf[5][5] = buf[1][13]; + erbuf[7][3] = buf[1][14]; + erbuf[7][5] = buf[1][15]; + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if((j >= 3) && (j < 6)) { + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != 0) + TEST_ERROR + + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select stripe */ + start[0] = 0; + start[1] = 0; + start[2] = 2; + start[3] = 0; + count[0] = 3; + count[1] = 3; + count[2] = 1; + count[3] = 3; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 6; + count[0] = 9; + count[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Read third stripe pattern */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, vspace[0], H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 9; i++) + for(j = 6; j < 9; j++) + erbuf[i][j] = fill; + erbuf[0][6] = buf[0][2]; + erbuf[0][8] = buf[0][3]; + erbuf[2][6] = buf[0][10]; + erbuf[2][8] = buf[0][11]; + erbuf[6][6] = buf[1][2]; + erbuf[6][8] = buf[1][3]; + erbuf[8][6] = buf[1][10]; + erbuf[8][8] = buf[1][11]; + erbuf[4][6] = buf[1][5]; + erbuf[4][8] = buf[1][6]; + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if((j >= 6) && (j < 9)) { + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != 0) + TEST_ERROR + + /* Now read entire VDS */ + /* Set memory space extent to 9x9, select all in order to reach part of the + * code in H5S_select_subtract() */ + dims[0] = 9; + dims[1] = 9; + if(H5Sset_extent_simple(memspace, 2, dims, NULL) < 0) + TEST_ERROR + if(H5Sselect_all(memspace) < 0) + TEST_ERROR + + /* Read third stripe pattern */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf99[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(rbuf99) / sizeof(rbuf99[0])); i++) + for(j = 0; j < (int)(sizeof(rbuf99[0]) / sizeof(rbuf99[0][0])); j++) + if(rbuf99[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Write data through virtual dataset by hyperslab */ + /* Select stripe (only select mapped elements) */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + start[3] = 0; + stride[0] = 2; + stride[1] = 2; + stride[2] = 1; + stride[3] = 2; + count[0] = 2; + count[1] = 2; + count[2] = 1; + count[3] = 2; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride ,count, NULL) < 0) + TEST_ERROR + start[0] = 1; + start[1] = 1; + start[2] = 0; + start[3] = 0; + stride[0] = 1; + stride[1] = 1; + stride[2] = 1; + stride[3] = 2; + count[0] = 1; + count[1] = 1; + count[2] = 1; + count[3] = 2; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_OR, start, stride ,count, NULL) < 0) + TEST_ERROR + + /* Reset extent of memspace, select hyperslab */ + dims[0] = 10; + dims[1] = 26; + if(H5Sset_extent_simple(memspace, 2, dims, NULL) < 0) + TEST_ERROR + start[0] = 0; + start[1] = 0; + count[0] = 1; + count[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Write data through virtual dataset by hyperslab */ + /* Write first stripe pattern */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, memspace, vspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + HDmemset(erbuf, 0, sizeof(erbuf)); + erbuf[0][0] = buf[0][0]; + erbuf[0][1] = buf[0][1]; + erbuf[0][8] = buf[0][2]; + erbuf[0][9] = buf[0][3]; + erbuf[1][0] = buf[0][6]; + erbuf[1][1] = buf[0][7]; + erbuf[1][8] = buf[0][8]; + erbuf[1][9] = buf[0][9]; + erbuf[0][13] = buf[0][4]; + erbuf[0][14] = buf[0][5]; + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Select stripe (only select mapped elements) */ + start[0] = 0; + start[1] = 1; + start[2] = 1; + start[3] = 0; + stride[0] = 1; + stride[1] = 1; + stride[2] = 1; + stride[3] = 2; + count[0] = 3; + count[1] = 1; + count[2] = 1; + count[3] = 2; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride ,count, NULL) < 0) + TEST_ERROR + start[0] = 1; + start[1] = 0; + start[2] = 1; + start[3] = 0; + stride[0] = 1; + stride[1] = 2; + stride[2] = 1; + stride[3] = 1; + count[0] = 1; + count[1] = 2; + count[2] = 1; + count[3] = 3; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_OR, start, stride ,count, NULL) < 0) + TEST_ERROR + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + count[0] = 1; + count[1] = 12; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Write second slice */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, memspace, vspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + erbuf[0][4] = buf[0][0]; + erbuf[0][5] = buf[0][1]; + erbuf[0][6] = buf[0][2]; + erbuf[0][7] = buf[0][3]; + erbuf[0][12] = buf[0][4]; + erbuf[0][15] = buf[0][5]; + erbuf[1][4] = buf[0][6]; + erbuf[1][7] = buf[0][7]; + erbuf[1][12] = buf[0][8]; + erbuf[1][13] = buf[0][9]; + erbuf[1][14] = buf[0][10]; + erbuf[1][15] = buf[0][11]; + + /* Adjust write buffer */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0])); + + /* Select stripe (only select mapped elements) */ + start[0] = 0; + start[1] = 0; + start[2] = 2; + start[3] = 0; + stride[0] = 2; + stride[1] = 2; + stride[2] = 1; + stride[3] = 2; + count[0] = 2; + count[1] = 2; + count[2] = 1; + count[3] = 2; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride ,count, NULL) < 0) + TEST_ERROR + start[0] = 1; + start[1] = 1; + start[2] = 2; + start[3] = 0; + stride[0] = 1; + stride[1] = 1; + stride[2] = 1; + stride[3] = 2; + count[0] = 1; + count[1] = 1; + count[2] = 1; + count[3] = 2; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_OR, start, stride ,count, NULL) < 0) + TEST_ERROR + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + count[0] = 1; + count[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Write third slice */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, memspace, vspace[0], H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + erbuf[0][2] = buf[0][0]; + erbuf[0][3] = buf[0][1]; + erbuf[0][10] = buf[0][2]; + erbuf[0][11] = buf[0][3]; + erbuf[1][2] = buf[0][6]; + erbuf[1][3] = buf[0][7]; + erbuf[1][10] = buf[0][8]; + erbuf[1][11] = buf[0][9]; + erbuf[1][5] = buf[0][4]; + erbuf[1][6] = buf[0][5]; + + /* Reopen srcdset and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read data directly from source dataset */ + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + count[0] = 2; + count[1] = 16; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read dataset */ + if(H5Dread(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) + for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Now try writing to whole VDS (should fail due to unmapped elements) */ + count[0] = 9; + count[1] = 9; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Dwrite(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]); + } H5E_END_TRY + if(ret >= 0) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(srcspace[1]) < 0) + TEST_ERROR + srcspace[1] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) { + if(srcdset[i] >= 0) + (void)H5Dclose(srcdset[i]); + } /* end for */ + if(vdset >= 0) + (void)H5Dclose(vdset); + for(i = 0; i < (int)(sizeof(srcfile) / sizeof(srcfile[0])); i++) { + if(srcfile[i] >= 0) + (void)H5Fclose(srcfile[i]); + } /* end for */ + if(vfile >= 0) + (void)H5Fclose(vfile); + if(vfile2 >= 0) + (void)H5Fclose(vfile2); + for(i = 0; i < (int)(sizeof(srcspace) / sizeof(srcspace[0])); i++) { + if(srcspace[i] >= 0) + (void)H5Sclose(srcspace[i]); + } /* end for */ + for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) { + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(memspace >= 0) + (void)H5Sclose(memspace); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + } H5E_END_TRY; + + return 1; +} /* end test_basic_io() */ + + +/*------------------------------------------------------------------------- + * Function: test_unlim + * + * Purpose: Tests VDS with unlimited selections + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Thursday, April 30, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_unlim(unsigned config, hid_t fapl) +{ + char srcfilename[FILENAME_BUF_SIZE]; + char srcfilename_map[FILENAME_BUF_SIZE]; + char vfilename[FILENAME_BUF_SIZE]; + hid_t srcfile[4] = {-1, -1, -1, -1}; /* Files with source dsets */ + hid_t vfile = -1; /* File with virtual dset */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t srcdcpl = -1; /* DCPL for source dset */ + hid_t dapl = -1; /* Dataset access property list */ + hid_t srcspace[4] = {-1, -1, -1, -1}; /* Source dataspaces */ + hid_t vspace[4] = {-1, -1, -1, -1}; /* Virtual dset dataspaces */ + hid_t memspace = -1; /* Memory dataspace */ + hid_t filespace = -1; /* File dataspace */ + hid_t srcdset[4] = {-1, -1, -1, -1}; /* Source datsets */ + hid_t vdset = -1; /* Virtual dataset */ + hsize_t dims[2] = {10, 10}; /* Data space current size */ + hsize_t mdims[2] = {10, 20}; /* Data space maximum size */ + hsize_t cdims[2] = {4, 4}; /* Chunk dimensions */ + hsize_t start[4]; /* Hyperslab start */ + hsize_t stride[4]; /* Hyperslab stride */ + hsize_t count[4]; /* Hyperslab count */ + hsize_t block[4]; /* Hyperslab block */ + int buf[10][20]; /* Write and expected read buffer */ + int rbuf[10][20]; /* Read buffer */ + int erbuf[10][20]; /* Expected read buffer */ + int ndims; /* Number of dimensions */ + int fill = -1; /* Fill value */ + H5D_vds_view_t virtual_view; /* Virtual view property */ + int i, j; + + TESTING("virtual dataset I/O with unlimited selections") + + h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); + h5_fixname(FILENAME[2], fapl, srcfilename, sizeof srcfilename); + h5_fixname_printf(FILENAME[2], fapl, srcfilename_map, sizeof srcfilename_map); + + /* Create DCPLs */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + if((srcdcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* Set fill value */ + if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fill) < 0) + TEST_ERROR + + /* Set chunk dimensions */ + if(H5Pset_chunk(srcdcpl, 2, cdims) < 0) + TEST_ERROR + + /* Create DAPL */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + TEST_ERROR + + /* Create memory space */ + if((memspace = H5Screate_simple(2, mdims, NULL)) < 0) + TEST_ERROR + + + /* + * Test 1: 2 Source datasets, single unlimited hyperslab virtual mappings + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[0] = 5; + mdims[0] = 5; + if((srcspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + mdims[0] = 10; + + /* Select hyperslab in source space */ + start[0] = 0; + start[1] = 0; + count[0] = 5; + count[1] = H5S_UNLIMITED; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[0] = 5; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2", srcspace[0]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write data directly to source datasets */ + /* Select hyperslab in memory */ + start[0] = 0; + count[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i + 5][j] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Test H5Pget_virtual_view() */ + if(H5Pget_virtual_view(dapl, &virtual_view) < 0) + TEST_ERROR + if(virtual_view != H5D_VDS_LAST_AVAILABLE) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_view() */ + if(H5Pget_virtual_view(dapl, &virtual_view) < 0) + TEST_ERROR + if(virtual_view != H5D_VDS_FIRST_MISSING) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[0] */ + dims[0] = 5; + dims[1] = 15; + if(H5Dset_extent(srcdset[0], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[0])) < 0) + TEST_ERROR + start[1] = 10; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING and we only extended one source dataset the + * dimensions will not have changed. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is now visible due to the change to + * H5D_VDS_LAST_AVAILABLE */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 10] = buf[i][j]; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[0] = 5; + dims[1] = 20; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[1] = 10; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i + 5][j + 10] = buf[i][j]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 20) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Now just read middle 2 rows */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + start[0] = 4; + count[0] = 2; + count[1] = 20; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, memspace, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data - algorithmically check for only 2 middle rows being + * read so we don't have to wipe out erbuf and then restore it afterwards */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if((i == 4) || (i == 5)) { + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != 0) + TEST_ERROR + + /* Now test reopening virtual dataset without calling H5Dget_space, if + * REOPEN_VIRT flag set */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Now try setting extent manually */ + /* Shrink to 18 */ + dims[1] = 18; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Shrink to 15 */ + dims[1] = 15; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + } /* end if */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now test reopening virtual dataset without calling H5Dget_space, if + * REOPEN_VIRT flag set */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now try setting extent manually */ + /* Grow to 18 */ + dims[1] = 18; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Grow to 20 */ + dims[1] = 20; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end if */ + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 2: 2 Source datasets, interleaved slices, single element wide + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[0] = 10; + dims[1] = 10; + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 5; + mdims[1] = 10; + if((srcspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + mdims[1] = 20; + + /* Select hyperslab in source space */ + start[0] = 0; + start[1] = 0; + count[0] = 10; + count[1] = H5S_UNLIMITED; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + stride[0] = 1; + stride[1] = 2; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 0; + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2", srcspace[0]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write data directly to source datasets */ + /* Select hyperslab in memory */ + count[0] = 10; + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][2 * j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][(2 * j) + 1] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[0] */ + dims[1] = 7; + if(H5Dset_extent(srcdset[0], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[0])) < 0) + TEST_ERROR + start[1] = 5; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[1] = 0; + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf to reflect only new data that is now visible under + * H5D_VDS_FIRST_MISSING (first slice) */ + for(i = 0; i < 10; i++) + erbuf[i][10] = buf[i][0]; + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING and we only extended one source dataset the + * dimension will only have changed to add one more slice. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 11) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is now visible due to the change to + * H5D_VDS_LAST_AVAILABLE (second new slice) */ + for(i = 0; i < 10; i++) + erbuf[i][12] = buf[i][1]; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 13) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[1] = 10; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[1] = 5; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[1] = 0; + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][(2 * j) + 11] = buf[i][j]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 20) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Now just read middle 2 rows */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + start[0] = 4; + count[0] = 2; + count[1] = 20; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[0] = 0; + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, memspace, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data - algorithmically check for only 2 middle rows being + * read so we don't have to wipe out erbuf and then restore it afterwards */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if((i == 4) || (i == 5)) { + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != 0) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is no longer visible due to the + * change to H5D_VDS_FIRST_MISSING */ + for(i = 0; i < 10; i++) + for(j = 15; j < 20; j += 2) + erbuf[i][j] = fill; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 14) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 3: 3 Source datasets, interleaved slices, two elements wide + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[0] = 10; + dims[1] = 10; + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[2] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspaces */ + dims[1] = 4; + mdims[1] = 8; + if((srcspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + dims[1] = 4; + mdims[1] = 6; + if((srcspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + dims[1] = 2; + mdims[1] = 6; + if((srcspace[2] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + mdims[1] = 20; + + /* Select hyperslab in source spaces */ + start[0] = 0; + start[1] = 0; + count[0] = 10; + count[1] = H5S_UNLIMITED; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(srcspace[2], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + stride[0] = 1; + stride[1] = 6; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 2; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 2; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 4; + if(H5Sselect_hyperslab(vspace[2], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 0; + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2", srcspace[1]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[2], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset3", srcspace[2]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[1], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[2] = H5Dcreate2(srcfile[0], "src_dset3", H5T_NATIVE_INT, srcspace[2], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write data directly to source datasets */ + /* Select hyperslab in memory */ + count[0] = 10; + count[1] = 4; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 2; j++) { + erbuf[i][6 * j] = buf[i][2 * j]; + erbuf[i][(6 * j) + 1] = buf[i][(2 * j) + 1]; + } /* end for */ + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 2; j++) { + erbuf[i][(6 * j) + 2] = buf[i][2 * j]; + erbuf[i][(6 * j) + 3] = buf[i][(2 * j) + 1]; + } /* end for */ + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Select hyperslab in memory */ + count[0] = 10; + count[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write third dataset */ + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) { + erbuf[i][4] = buf[i][0]; + erbuf[i][5] = buf[i][1]; + } /* end for */ + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[0] */ + dims[1] = 7; + if(H5Dset_extent(srcdset[0], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[0])) < 0) + TEST_ERROR + start[1] = 4; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[1] = 0; + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING the size will not have changed. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is now visible due to the change to + * H5D_VDS_LAST_AVAILABLE */ + for(i = 0; i < 10; i++) { + erbuf[i][12] = buf[i][0]; + erbuf[i][13] = buf[i][1]; + erbuf[i][18] = buf[i][2]; + } /* end for */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 19) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[2] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[2] = H5Dopen2(srcfile[0], "src_dset3", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[2] */ + dims[1] = 5; + if(H5Dset_extent(srcdset[2], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[2])) < 0) + TEST_ERROR + start[1] = 2; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[1] = 0; + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) { + erbuf[i][10] = buf[i][0]; + erbuf[i][11] = buf[i][1]; + erbuf[i][16] = buf[i][2]; + } /* end for */ + + /* Close srcdset[2] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that the dimensions will not have + * changed. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 19) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 14) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[1] = 6; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[1] = 4; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[1] = 0; + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) { + erbuf[i][14] = buf[i][0]; + erbuf[i][15] = buf[i][1]; + } /* end for */ + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 17) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 19) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now just read middle 2 rows */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + start[0] = 4; + count[0] = 2; + count[1] = 19; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[0] = 0; + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Verify read data - algorithmically check for only 2 middle rows being + * read */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else if((i == 4) || (i == 5)) { + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != 0) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(srcspace[1]) < 0) + TEST_ERROR + srcspace[1] = -1; + if(H5Sclose(srcspace[2]) < 0) + TEST_ERROR + srcspace[2] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 4: 2 Source datasets, offset starts + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspaces */ + dims[0] = 5; + dims[1] = 0; + mdims[0] = 5; + if((srcspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + dims[1] = 5; + if((srcspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + mdims[0] = 10; + + /* Select hyperslab in source spaces */ + start[0] = 0; + start[1] = 0; + count[0] = 5; + count[1] = H5S_UNLIMITED; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + start[1] = 10; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[0] = 5; + start[1] = 0; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset2", srcspace[1]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[1], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write data directly to second source dataset */ + /* Select hyperslab in memory */ + start[0] = 0; + start[1] = 0; + count[0] = 5; + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i + 5][j] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[0] */ + dims[0] = 5; + dims[1] = 5; + if(H5Dset_extent(srcdset[0], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[0] */ + start[0] = 0; + start[1] = 0; + count[0] = 5; + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 10] = buf[i][j]; + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(srcspace[1]) < 0) + TEST_ERROR + srcspace[1] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(srcdcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(dapl) < 0) + TEST_ERROR + dapl = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) { + if(srcdset[i] >= 0) + (void)H5Dclose(srcdset[i]); + } /* end for */ + if(vdset >= 0) + (void)H5Dclose(vdset); + for(i = 0; i < (int)(sizeof(srcfile) / sizeof(srcfile[0])); i++) { + if(srcfile[i] >= 0) + (void)H5Fclose(srcfile[i]); + } /* end for */ + if(vfile >= 0) + (void)H5Fclose(vfile); + for(i = 0; i < (int)(sizeof(srcspace) / sizeof(srcspace[0])); i++) { + if(srcspace[i] >= 0) + (void)H5Sclose(srcspace[i]); + } /* end for */ + for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) { + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(filespace >= 0) + (void)H5Sclose(filespace); + if(memspace >= 0) + (void)H5Sclose(memspace); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + if(srcdcpl >= 0) + (void)H5Pclose(srcdcpl); + if(dapl >= 0) + (void)H5Pclose(dapl); + } H5E_END_TRY; + + return 1; +} /* end test_unlim() */ + + +/*------------------------------------------------------------------------- + * Function: test_printf + * + * Purpose: Tests VDS with unlimited selections and printf style + * source dataset resolution + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Tuesday, May 26, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_printf(unsigned config, hid_t fapl) +{ + char srcfilename[FILENAME_BUF_SIZE]; + char srcfilename_map[FILENAME_BUF_SIZE]; + char srcfilename2[FILENAME_BUF_SIZE]; + char srcfilename2_map[FILENAME_BUF_SIZE]; + char vfilename[FILENAME_BUF_SIZE]; + char printf_srcfilename_map[FILENAME_BUF_SIZE]; + const char *printf_srcfilename_map_orig = "vds_src_%b"; + char srcfilenamepct[FILENAME_BUF_SIZE]; + char srcfilenamepct_map[FILENAME_BUF_SIZE]; + const char *srcfilenamepct_map_orig = "vds%%_src"; + hid_t srcfile[4] = {-1, -1, -1, -1}; /* Files with source dsets */ + hid_t vfile = -1; /* File with virtual dset */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t dapl = -1; /* Dataset access property list */ + hid_t srcspace = -1; /* Source dataspace */ + hid_t vspace[2] = {-1, -1}; /* Virtual dset dataspaces */ + hid_t memspace = -1; /* Memory dataspace */ + hid_t filespace = -1; /* File dataspace */ + hid_t srcdset[6] = {-1, -1, -1, -1, -1, -1}; /* Source datsets */ + hid_t vdset = -1; /* Virtual dataset */ + hsize_t dims[2] = {10, 0}; /* Data space current size */ + hsize_t mdims[2] = {10, 20}; /* Data space maximum size */ + hsize_t start[2] = {0, 0}; /* Hyperslab start */ + hsize_t stride[2]; /* Hyperslab stride */ + hsize_t count[2]; /* Hyperslab count */ + hsize_t block[2]; /* Hyperslab block */ + int buf[10][20]; /* Write and expected read buffer */ + int rbuf[10][20]; /* Read buffer */ + int erbuf[10][20]; /* Expected read buffer */ + int ndims; /* Number of dimensions */ + int fill = -1; /* Fill value */ + hsize_t gap_size; /* Gap size property */ + int i, j; + + TESTING("virtual dataset I/O with printf source") + + h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); + h5_fixname(FILENAME[2], fapl, srcfilename, sizeof srcfilename); + h5_fixname_printf(FILENAME[2], fapl, srcfilename_map, sizeof srcfilename_map); + h5_fixname(FILENAME[3], fapl, srcfilename2, sizeof srcfilename2); + h5_fixname_printf(FILENAME[2], fapl, srcfilename2_map, sizeof srcfilename2_map); + h5_fixname_printf(printf_srcfilename_map_orig, fapl, printf_srcfilename_map, sizeof printf_srcfilename_map); + h5_fixname(FILENAME[4], fapl, srcfilenamepct, sizeof srcfilenamepct); + h5_fixname_printf(srcfilenamepct_map_orig, fapl, srcfilenamepct_map, sizeof srcfilenamepct_map); + + /* Create DCPL */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* Set fill value */ + if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fill) < 0) + TEST_ERROR + + /* Create DAPL */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + TEST_ERROR + + /* Create memory space */ + if((memspace = H5Screate_simple(2, mdims, NULL)) < 0) + TEST_ERROR + + + /* + * Test 1: 1 Source dataset mapping, 10x5 blocks + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 5; + if((srcspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual space */ + stride[0] = 1; + stride[1] = 5; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 5; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset%b", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 2 source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 5] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 3rd source dataset */ + if((srcdset[2] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[2] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 10] = buf[i][j]; + + /* Close srcdset[2] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now try with different selections */ + count[0] = 10; + for(start[1] = (hsize_t)0; start[1] < (hsize_t)5; start[1]++) + for(count[1] = (hsize_t)1; count[1] < (hsize_t)11; count[1]++) { + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslab in file space */ + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if((j < (int)start[1]) || (j >= (int)(start[1] + count[1]))) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + } /* end for */ + start[1] = 0; + + /* Now try writing through VDS */ + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Select hyperslab in file space */ + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write data through VDS */ + if(H5Dwrite(vdset, H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset0", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[2] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Read srcdset[0] */ + count[0] = 10; + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dread(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + if(rbuf[i][j] != buf[i][j]) + TEST_ERROR + + /* Read srcdset[1] */ + if(H5Dread(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + if(rbuf[i][j] != buf[i][j + 5]) + TEST_ERROR + + /* Read srcdset[2] */ + if(H5Dread(srcdset[2], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + if(rbuf[i][j] != buf[i][j + 10]) + TEST_ERROR + + /* Close */ + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* + * Test 2: 1 Source dataset mapping, 10x1 blocks, test printf gap setting, + * '%' in source file name + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 1; + if((srcspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual space */ + stride[0] = 1; + stride[1] = 1; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilenamepct_map : ".", "src_dset%b", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilenamepct, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilenamepct, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create source datasets in a pattern with increasing gaps: + * XX-X--X---X----X */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[2] = H5Dcreate2(srcfile[0], "src_dset3", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[3] = H5Dcreate2(srcfile[0], "src_dset6", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[4] = H5Dcreate2(srcfile[0], "src_dset10", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[5] = H5Dcreate2(srcfile[0], "src_dset15", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][0] = buf[i][0]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][1] = buf[i][0]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[2] */ + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][3] = buf[i][0]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[3] */ + if(H5Dwrite(srcdset[3], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][6] = buf[i][0]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[4] */ + if(H5Dwrite(srcdset[4], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][10] = buf[i][0]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[5] */ + if(H5Dwrite(srcdset[5], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][15] = buf[i][0]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + for(i = 0; i < 6; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 2) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Test H5Pget_virtual_printf_gap() */ + if(H5Pget_virtual_printf_gap(dapl, &gap_size) < 0) + TEST_ERROR + if(gap_size != (hsize_t)0) + TEST_ERROR + + /* Close VDS and reopen with printf gap set to 1, reopen file as well if + * config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)1) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_printf_gap() */ + if(H5Pget_virtual_printf_gap(dapl, &gap_size) < 0) + TEST_ERROR + if(gap_size != (hsize_t)1) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 4) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with printf gap set to 2, reopen file as well if + * config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)2) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 7) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with printf gap set to 3, reopen file as well if + * config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)3) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 11) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with printf gap set to 4, reopen file as well if + * config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)4) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 16) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 2) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reset dapl */ + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)0) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + for(i = 0; i < 6; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* Next 2 tests are always run with a different source file, so only run if + * that config option is set (so they're not run twice with the same + * configuration) */ + if(config & TEST_IO_DIFFERENT_FILE) { + /* + * Test 3: 1 Source dataset mapping, 10x5 blocks, printf source file + */ + /* Clean up files so the source files do not exist yet */ + H5Iinc_ref(fapl); /* Prevent FAPL from being closed */ + h5_clean_files(FILENAME, fapl); + + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 5; + if((srcspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual space */ + stride[0] = 1; + stride[1] = 5; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 5; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], printf_srcfilename_map, "src_dset", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Create 2 source files, one source dataset */ + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcfile[1] = H5Fcreate(srcfilename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j] = buf[i][j]; + + /* Close srcdset and srcfiles if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(srcfile[1]) < 0) + TEST_ERROR + srcfile[1] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile[1] if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if((srcfile[1] = H5Fopen(srcfilename2, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 2nd source dataset */ + if((srcdset[1] = H5Dcreate2(srcfile[1], "src_dset", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 5] = buf[i][j]; + + /* Close srcdset[1] and srcfile[1] if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[1]) < 0) + TEST_ERROR + srcfile[1] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(srcfile[1]) < 0) + TEST_ERROR + srcfile[1] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* + * Test 4: 1 Source dataset mapping, 10x5 blocks, printf source file and + * source dset, extra %%s in source dataset name + */ + /* Clean up files so the source files do not exist yet */ + H5Iinc_ref(fapl); /* Prevent FAPL from being closed */ + h5_clean_files(FILENAME, fapl); + + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 5; + if((srcspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual space */ + stride[0] = 1; + stride[1] = 5; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 5; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], printf_srcfilename_map, "%%src%%_dset%%%b", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Create 2 source files, one source dataset */ + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dcreate2(srcfile[0], "%src%_dset%0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcfile[1] = H5Fcreate(srcfilename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j] = buf[i][j]; + + /* Close srcdset and srcfiles if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(srcfile[1]) < 0) + TEST_ERROR + srcfile[1] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile[1] if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if((srcfile[1] = H5Fopen(srcfilename2, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 2nd source dataset */ + if((srcdset[1] = H5Dcreate2(srcfile[1], "%src%_dset%1", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 5] = buf[i][j]; + + /* Close srcdset[1] and srcfile[1] if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[1]) < 0) + TEST_ERROR + srcfile[1] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + if(H5Fclose(srcfile[1]) < 0) + TEST_ERROR + srcfile[1] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + } /* end if */ + + + /* + * Test 5: 2 Source mappings, interleaved slices, single element wide, + * hyperslab selection in source, extra %%s in source dataset names + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[0] = 10; + dims[1] = 10; + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace (2 elements wide) */ + dims[1] = 2; + if((srcspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslab in source space */ + count[0] = 10; + count[1] = 1; + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + stride[0] = 1; + stride[1] = 2; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 0; + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "%bsrc_dset_a%b%%", srcspace) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset_b%b%%%%", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 2 source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "0src_dset_a0%", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset_b0%%", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + block[0] = 10; + block[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][0] = buf[i][0]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][1] = buf[i][0]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 2) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 3rd source dataset */ + if((srcdset[2] = H5Dcreate2(srcfile[0], "src_dset_b1%%", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[2] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][3] = buf[i][0]; + + /* Close srcdset[2] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 4) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Make sure that the 4th slice is no longer + * visible due to the change to H5D_VDS_FIRST_MISSING. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 2) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 4th source dataset */ + if((srcdset[3] = H5Dcreate2(srcfile[0], "2src_dset_a2%", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[3] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[3], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][4] = buf[i][0]; + + /* Close srcdset[3] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[3]) < 0) + TEST_ERROR + srcdset[3] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 2) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Make sure that the 4th slice is now visible + * due to the change to H5D_VDS_LAST_AVAILABLE. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 4) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with printf_gap set to 1, reopen file as well if + * config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)1) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Make sure that the 6th slice is now visible + * due to the change to printf_gap. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reset dapl */ + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)0) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + for(i = 0; i < 4; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 6: 2 Source mappings, side-by-side, 5x5 and 5x10 blocks + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[0] = 10; + dims[1] = 10; + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace (1 dimensional) */ + dims[0] = 50; + if((srcspace = H5Screate_simple(1, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslab in source space */ + count[0] = 25; + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + stride[0] = 1; + stride[1] = 5; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 5; + block[1] = 5; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 5; + stride[1] = 10; + block[1] = 10; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 0; + + /* Add virtual layout mappings (select ALL in source space for second + * mapping) */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset_a%b", srcspace) < 0) + TEST_ERROR + if(H5Sselect_all(srcspace) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset_b%b", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 2 source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset_a0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset_b0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + block[0] = 5; + block[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + count[0] = 25; + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + block[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Sselect_all(srcspace) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i + 5][j] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Make sure that the 4th slice is no longer + * visible due to the change to H5D_VDS_FIRST_MISSING. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 3rd source dataset */ + if((srcdset[2] = H5Dcreate2(srcfile[0], "src_dset_a1", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[2] */ + block[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 5] = buf[i][j]; + + /* Close srcdset[2] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. There should be no change. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 4th source dataset */ + if((srcdset[3] = H5Dcreate2(srcfile[0], "src_dset_a2", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[3] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[3], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 10] = buf[i][j]; + + /* Close srcdset[3] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[3]) < 0) + TEST_ERROR + srcdset[3] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now test reopening virtual dataset without calling H5Dget_space, if + * REOPEN_VIRT flag set */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now try setting extent manually */ + /* Shrink to 12 */ + dims[1] = 12; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Shrink to 10 */ + dims[1] = 12; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + } /* end if */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now test reopening virtual dataset without calling H5Dget_space, if + * REOPEN_VIRT flag set */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Now try setting extent manually */ + /* Grow to 12 */ + dims[1] = 12; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Grow to 15 */ + dims[1] = 15; + if(H5Dset_extent(vdset, dims) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + } /* end if */ + + /* Reset dapl */ + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + for(i = 0; i < 4; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 7: 1 Source dataset mapping, 10x1 blocks, test reallocating sub_dset + * array + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 1; + if((srcspace = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual space */ + stride[0] = 1; + stride[1] = 1; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilenamepct_map : ".", "src_dset%b", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilenamepct, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilenamepct, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create 1 source dataset */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + erbuf[i][0] = buf[i][0]; + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 1) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with printf gap set to 127, reopen file as well if + * config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)127) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 1) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reset dapl */ + if(H5Pset_virtual_printf_gap(dapl, (hsize_t)0) < 0) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(dapl) < 0) + TEST_ERROR + dapl = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) { + if(srcdset[i] >= 0) + (void)H5Dclose(srcdset[i]); + } /* end for */ + if(vdset >= 0) + (void)H5Dclose(vdset); + for(i = 0; i < (int)(sizeof(srcfile) / sizeof(srcfile[0])); i++) { + if(srcfile[i] >= 0) + (void)H5Fclose(srcfile[i]); + } /* end for */ + if(vfile >= 0) + (void)H5Fclose(vfile); + if(srcspace >= 0) + (void)H5Sclose(srcspace); + for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) { + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(filespace >= 0) + (void)H5Sclose(filespace); + if(memspace >= 0) + (void)H5Sclose(memspace); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + if(dapl >= 0) + (void)H5Pclose(dapl); + } H5E_END_TRY; + + return 1; +} /* end test_printf() */ + + +/*------------------------------------------------------------------------- + * Function: test_all + * + * Purpose: Tests fixed, unlimited, and printf selections in the same + * VDS + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Friday, August 14, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_all(unsigned config, hid_t fapl) +{ + char vfilename[FILENAME_BUF_SIZE]; + char srcfilename[FILENAME_BUF_SIZE]; + char srcfilename_map[FILENAME_BUF_SIZE]; + hid_t srcfile = -1; /* File with source dsets */ + hid_t vfile = -1; /* File with virtual dset */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t srcdcpl = -1; /* DCPL for source dset */ + hid_t srcspace[3] = {-1, -1, -1}; /* Source dataspaces */ + hid_t vspace[3] = {-1, -1, -1}; /* Virtual dset dataspaces */ + hid_t memspace = -1; /* Memory dataspace */ + hid_t filespace = -1; /* File dataspace */ + hid_t srcdset[5] = {-1, -1, -1, -1, -1}; /* Source datsets */ + hid_t vdset = -1; /* Virtual dataset */ + hsize_t dims[2] = {6, 6}; /* Data space current size */ + hsize_t mdims[2] = {10, 10}; /* Data space maximum size */ + hsize_t cdims[2] = {2, 2}; /* Chunk dimensions */ + hsize_t start[2]; /* Hyperslab start */ + hsize_t stride[2]; /* Hyperslab stride */ + hsize_t count[2]; /* Hyperslab count */ + hsize_t block[2]; /* Hyperslab block */ + int buf[10][10]; /* Write and expected read buffer */ + int rbuf[10][10]; /* Read buffer */ + int erbuf[10][10]; /* Expected read buffer */ + int ndims; /* Number of dimensions */ + int fill = -1; /* Fill value */ + int i, j; + + TESTING("virtual dataset I/O with mixed selection types") + + h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); + h5_fixname(FILENAME[2], fapl, srcfilename, sizeof srcfilename); + h5_fixname_printf(FILENAME[2], fapl, srcfilename_map, sizeof srcfilename_map); + + /* Create DCPLs */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + if((srcdcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* Set fill value */ + if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fill) < 0) + TEST_ERROR + + /* Set chunk dimensions */ + if(H5Pset_chunk(srcdcpl, 2, cdims) < 0) + TEST_ERROR + + /* Create memory space */ + if((memspace = H5Screate_simple(2, mdims, NULL)) < 0) + TEST_ERROR + + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create fixed mapping */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + start[0] = 3; + start[1] = 3; + count[0] = 3; + count[1] = 3; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((srcspace[0] = H5Screate_simple(2, count, NULL)) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset_fixed", srcspace[0]) < 0) + TEST_ERROR + + /* Create unlimited mapping */ + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + start[0] = 3; + start[1] = 0; + count[0] = 1; + count[1] = 1; + block[0] = H5S_UNLIMITED; + block[1] = 3; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, count, block) < 0) + TEST_ERROR + dims[0] = 0; + dims[1] = 3; + if((srcspace[1] = H5Screate_simple(2, dims, block)) < 0) + TEST_ERROR + start[0] = 0; + if(H5Sselect_hyperslab(srcspace[1], H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset_unlim", srcspace[1]) < 0) + TEST_ERROR + + /* Create printf mapping */ + if((vspace[2] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + start[0] = 0; + start[1] = 2; + stride[0] = 1; + stride[1] = 3; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 3; + block[1] = 2; + if(H5Sselect_hyperslab(vspace[2], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + if((srcspace[2] = H5Screate_simple(2, block, NULL)) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[2], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset_printf_%b", srcspace[2]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile = vfile; + if(H5Iinc_ref(srcfile) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 6) + TEST_ERROR + if(dims[1] != 6) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create fixed source dataset */ + if((srcdset[0] = H5Dcreate2(srcfile, "src_dset_fixed", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create unlimited source_dataset */ + if((srcdset[1] = H5Dcreate2(srcfile, "src_dset_unlim", H5T_NATIVE_INT, srcspace[1], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + start[0] = 0; + start[1] = 0; + block[0] = 3; + block[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 3; i++) + for(j = 0; j < 3; j++) + erbuf[i + 3][j + 3] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + for(i = 0; i < 2; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 6) + TEST_ERROR + if(dims[1] != 6) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if((i >= (int)dims[0]) || (j >= (int)dims[1])) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile, "src_dset_unlim", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[0] = 2; + dims[1] = 3; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 2; i++) + for(j = 0; j < 3; j++) + erbuf[i + 3][j] = buf[i][j]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 6) + TEST_ERROR + if(dims[1] != 6) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if((i >= (int)dims[0]) || (j >= (int)dims[1])) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create first printf source dataset */ + if((srcdset[2] = H5Dcreate2(srcfile, "src_dset_printf_0", H5T_NATIVE_INT, srcspace[2], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[2] */ + start[0] = 0; + start[1] = 0; + block[0] = 3; + block[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 3; i++) + for(j = 0; j < 2; j++) + erbuf[i][j + 2] = buf[i][j]; + + /* Close srcdset[2] srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 6) + TEST_ERROR + if(dims[1] != 6) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if((i >= (int)dims[0]) || (j >= (int)dims[1])) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile, "src_dset_unlim", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[0] = 3; + dims[1] = 3; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset[1] */ + start[0] = 0; + start[1] = 0; + block[0] = 1; + block[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[0] = 2; + start[1] = 0; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 3; i++) + erbuf[5][i] = buf[0][i]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 6) + TEST_ERROR + if(dims[1] != 6) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if((i >= (int)dims[0]) || (j >= (int)dims[1])) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create second printf source dataset, this time without using srcdcpl */ + if((srcdset[3] = H5Dcreate2(srcfile, "src_dset_printf_1", H5T_NATIVE_INT, srcspace[2], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[3] */ + start[0] = 0; + start[1] = 0; + block[0] = 3; + block[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[3], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 3; i++) + for(j = 0; j < 2; j++) + erbuf[i][j + 5] = buf[i][j]; + + /* Close srcdset[3] srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[3]) < 0) + TEST_ERROR + srcdset[3] = -1; + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 6) + TEST_ERROR + if(dims[1] != 7) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if((i >= (int)dims[0]) || (j >= (int)dims[1])) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile, "src_dset_unlim", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[0] = 7; + dims[1] = 3; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset[1] */ + start[0] = 0; + start[1] = 0; + block[0] = 4; + block[1] = 3; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[0] = 3; + start[1] = 0; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 4; i++) + for(j = 0; j < 3; j++) + erbuf[i + 6][j] = buf[i][j]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 7) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile = H5Fopen(srcfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Create third printf source dataset */ + if((srcdset[4] = H5Dcreate2(srcfile, "src_dset_printf_2", H5T_NATIVE_INT, srcspace[2], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[4] */ + start[0] = 0; + start[1] = 0; + block[0] = 3; + block[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[4], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 3; i++) + for(j = 0; j < 2; j++) + erbuf[i][j + 8] = buf[i][j]; + + /* Close srcdset[4] srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[4]) < 0) + TEST_ERROR + srcdset[4] = -1; + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 10) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + start[0] = 0; + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + for(i = 0; i < 5; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile) < 0) + TEST_ERROR + srcfile = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + for(i = 0; i < (int)(sizeof(srcspace) / sizeof(srcspace[0])); i++) { + if(H5Sclose(srcspace[i]) < 0) + TEST_ERROR + srcspace[i] = -1; + } /* end for */ + for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) { + if(H5Sclose(vspace[i]) < 0) + TEST_ERROR + vspace[i] = -1; + } /* end for */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(srcdcpl) < 0) + TEST_ERROR + srcdcpl = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) { + if(srcdset[i] >= 0) + (void)H5Dclose(srcdset[i]); + } /* end for */ + if(vdset >= 0) + (void)H5Dclose(vdset); + if(srcfile >= 0) + (void)H5Fclose(srcfile); + if(vfile >= 0) + (void)H5Fclose(vfile); + for(i = 0; i < (int)(sizeof(srcspace) / sizeof(srcspace[0])); i++) { + if(srcspace[i] >= 0) + (void)H5Sclose(srcspace[i]); + } /* end for */ + for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) { + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(filespace >= 0) + (void)H5Sclose(filespace); + if(memspace >= 0) + (void)H5Sclose(memspace); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + if(srcdcpl >= 0) + (void)H5Pclose(srcdcpl); + } H5E_END_TRY; + + return 1; +} /* end test_all() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Tests datasets with virtual layout + * + * Return: Success: exit(0) + * + * Failure: exit(1) + * + * Programmer: Neil Fortner + * Tuesday, February 17, 2015 + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + char filename[FILENAME_BUF_SIZE]; + hid_t fapl; + int test_api_config; + unsigned bit_config; + int nerrors = 0; + + /* Testing setup */ + h5_reset(); + fapl = h5_fileaccess(); + + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + for(test_api_config = (int)TEST_API_BASIC; test_api_config < (int)TEST_API_NTESTS; test_api_config++) + nerrors += test_api((test_api_config_t)test_api_config, fapl); + for(bit_config = 0; bit_config < TEST_IO_NTESTS; bit_config++) { + printf("Config: %s%s%s\n", bit_config & TEST_IO_CLOSE_SRC ? "closed source dataset, " : "", bit_config & TEST_IO_DIFFERENT_FILE ? "different source file" : "same source file", bit_config & TEST_IO_REOPEN_VIRT ? ", reopen virtual file" : ""); + nerrors += test_basic_io(bit_config, fapl); + nerrors += test_unlim(bit_config, fapl); + nerrors += test_printf(bit_config, fapl); + nerrors += test_all(bit_config, fapl); + } /* end for */ + + /* Verify symbol table messages are cached */ + nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); + + if(nerrors) + goto error; + printf("All virtual dataset tests passed.\n"); + h5_cleanup(FILENAME, fapl); + + return 0; + +error: + nerrors = MAX(1, nerrors); + printf("***** %d VIRTUAL DATASET TEST%s FAILED! *****\n", + nerrors, 1 == nerrors ? "" : "S"); + return 1; +} /* end main() */ + diff --git a/tools/h5diff/CMakeTests.cmake b/tools/h5diff/CMakeTests.cmake index c650dbe..33d0971 100644 --- a/tools/h5diff/CMakeTests.cmake +++ b/tools/h5diff/CMakeTests.cmake @@ -4,7 +4,7 @@ ### T E S T I N G ### ############################################################################## ############################################################################## - + # -------------------------------------------------------------------- # Copy all the HDF5 files from the test directory into the source directory # -------------------------------------------------------------------- @@ -50,6 +50,30 @@ ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/compounds_array_vlen2.h5 ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/non_comparables1.h5 ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/non_comparables2.h5 + # tools/testfiles/vds + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_a.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_b.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_c.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_d.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_e.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_f.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_a.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_b.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_c.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_d.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_e.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/3_1_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/3_2_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_0.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_1.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_2.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_a.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_b.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_c.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_vds.h5 ) set (LIST_OTHER_TEST_FILES @@ -231,6 +255,9 @@ ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_710.txt ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_80.txt ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_90.txt + ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_v1.txt + ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_v2.txt + ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_v3.txt ) # Make testfiles dir under build dir @@ -283,7 +310,7 @@ ARGS -E copy_if_different ${HDF5_TOOLS_H5DIFF_SOURCE_DIR}/testfiles/h5diff_104w.txt ${PROJECT_BINARY_DIR}/testfiles/h5diff_104.txt ) endif (WIN32) - + ############################################################################## ############################################################################## ### T H E T E S T S M A C R O S ### @@ -399,7 +426,7 @@ ############################################################################## # -------------------------------------------------------------------- - # test file names + # test file names # -------------------------------------------------------------------- set (FILE1 h5diff_basic1.h5) set (FILE2 h5diff_basic2.h5) @@ -425,7 +452,7 @@ set (DANGLE_LINK_FILE2 h5diff_danglelinks2.h5) set (GRP_RECURSE_FILE1 h5diff_grp_recurse1.h5) set (GRP_RECURSE_FILE2 h5diff_grp_recurse2.h5) - # group recursive - same structure via external links through files + # group recursive - same structure via external links through files set (GRP_RECURSE1_EXT h5diff_grp_recurse_ext1.h5) set (GRP_RECURSE2_EXT1 h5diff_grp_recurse_ext2-1.h5) set (GRP_RECURSE2_EXT2 h5diff_grp_recurse_ext2-2.h5) @@ -447,13 +474,20 @@ # attrs with verbose option level set (ATTR_VERBOSE_LEVEL_FILE1 h5diff_attr_v_level1.h5) set (ATTR_VERBOSE_LEVEL_FILE2 h5diff_attr_v_level2.h5) +# VDS tests + set (FILEV1 1_vds.h5) + set (FILEV2 2_vds.h5) + set (FILEV3_1 3_1_vds.h5) + set (FILEV3_2 3_2_vds.h5) + set (FILEV4 4_vds.h5) + set (FILEV5 5_vds.h5) if (HDF5_ENABLE_USING_MEMCHECKER) # Remove any output file left over from previous test run add_test ( NAME H5DIFF-clearall-objects COMMAND ${CMAKE_COMMAND} - -E remove + -E remove h5diff_10.out h5diff_10.out.err h5diff_100.out @@ -800,6 +834,12 @@ h5diff_80.out.err h5diff_90.out h5diff_90.out.err + h5diff_v1.out + h5diff_v1.out.err + h5diff_v2.out + h5diff_v2.out.err + h5diff_v3.out + h5diff_v3.out.err ) set_tests_properties (H5DIFF-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") if (NOT "${last_test}" STREQUAL "") @@ -816,13 +856,13 @@ ADD_H5_TEST (h5diff_10 0 -h) # 1.1 normal mode -ADD_H5_TEST (h5diff_11 1 ${FILE1} ${FILE2}) +ADD_H5_TEST (h5diff_11 1 ${FILE1} ${FILE2}) # 1.2 normal mode with objects ADD_H5_TEST (h5diff_12 1 ${FILE1} ${FILE2} g1/dset1 g1/dset2) # 1.3 report mode -ADD_H5_TEST (h5diff_13 1 -r ${FILE1} ${FILE2}) +ADD_H5_TEST (h5diff_13 1 -r ${FILE1} ${FILE2}) # 1.4 report mode with objects ADD_H5_TEST (h5diff_14 1 -r ${FILE1} ${FILE2} g1/dset1 g1/dset2) @@ -840,7 +880,7 @@ ADD_H5_TEST (h5diff_16_2 1 --verbose --relative=0.02 ${FILE1} ${FILE1} g1/dset7 ADD_H5_TEST (h5diff_16_3 1 -v -p 0.02 ${FILE1} ${FILE1} g1/dset9 g1/dset10) # 1.7 verbose mode -ADD_H5_TEST (h5diff_17 1 -v ${FILE1} ${FILE2}) +ADD_H5_TEST (h5diff_17 1 -v ${FILE1} ${FILE2}) # 1.7 test 32-bit INFINITY ADD_H5_TEST (h5diff_171 0 -v ${FILE1} ${FILE1} /g1/fp19 /g1/fp19_COPY) @@ -848,8 +888,8 @@ ADD_H5_TEST (h5diff_171 0 -v ${FILE1} ${FILE1} /g1/fp19 /g1/fp19_COPY) # 1.7 test 64-bit INFINITY ADD_H5_TEST (h5diff_172 0 -v ${FILE1} ${FILE1} /g1/fp20 /g1/fp20_COPY) -# 1.8 quiet mode -ADD_H5_TEST (h5diff_18 1 -q ${FILE1} ${FILE2}) +# 1.8 quiet mode +ADD_H5_TEST (h5diff_18 1 -q ${FILE1} ${FILE2}) # 1.8 -v and -q ADD_H5_TEST (h5diff_18_1 2 -v -q ${FILE1} ${FILE2}) @@ -878,7 +918,7 @@ ADD_H5_TEST (h5diff_23 0 -v ${FILE3} ${FILE3} g1 g1) ADD_H5_TEST (h5diff_24 0 -v ${FILE3} ${FILE3} t1 t1) # 2.5 -ADD_H5_TEST (h5diff_25 0 -v ${FILE3} ${FILE3} l1 l1) +ADD_H5_TEST (h5diff_25 0 -v ${FILE3} ${FILE3} l1 l1) # 2.6 ADD_H5_TEST (h5diff_26 0 -v ${FILE3} ${FILE3} g1 g2) @@ -920,7 +960,7 @@ ADD_H5_TEST (h5diff_57 0 -v ${FILE4} ${FILE4} dset7a dset7b) # 5.8 (region reference) ADD_H5_TEST (h5diff_58 1 -v ${FILE7} ${FILE8} refreg) -# test for both dset and attr with same type but with different size +# test for both dset and attr with same type but with different size # ( HDDFV-7942 ) ADD_H5_TEST (h5diff_59 0 -v ${FILE4} ${FILE4} dset11a dset11b) @@ -929,13 +969,13 @@ ADD_H5_TEST (h5diff_59 0 -v ${FILE4} ${FILE4} dset11a dset11b) # ############################################################################## # 6.0: Check if the command line number of arguments is less than 3 -ADD_H5_TEST (h5diff_600 1 ${FILE1}) +ADD_H5_TEST (h5diff_600 1 ${FILE1}) -# 6.1: Check if non-exist object name is specified +# 6.1: Check if non-exist object name is specified ADD_H5_TEST (h5diff_601 2 ${FILE1} ${FILE1} nono_obj) # ############################################################################## -# # -d +# # -d # ############################################################################## # 6.3: negative value @@ -953,7 +993,7 @@ ADD_H5_TEST (h5diff_606 1 -d 0x1 ${FILE1} ${FILE2} g1/dset3 g1/dset4) # 6.7: string ADD_H5_TEST (h5diff_607 1 -d "1" ${FILE1} ${FILE2} g1/dset3 g1/dset4) -# 6.8: use system epsilon +# 6.8: use system epsilon ADD_H5_TEST (h5diff_608 1 --use-system-epsilon ${FILE1} ${FILE2} g1/dset3 g1/dset4) # 6.9: number larger than biggest difference @@ -1032,12 +1072,12 @@ ADD_H5_TEST (h5diff_631 0 -v --use-system-epsilon ${FILE1} ${FILE1} g1/fp18 g1/f # ############################################################################## # 7. attributes # ############################################################################## -ADD_H5_TEST (h5diff_70 1 -v ${FILE5} ${FILE6}) +ADD_H5_TEST (h5diff_70 1 -v ${FILE5} ${FILE6}) # ################################################## # attrs with verbose option level # ################################################## -ADD_H5_TEST (h5diff_700 1 -v1 ${FILE5} ${FILE6}) +ADD_H5_TEST (h5diff_700 1 -v1 ${FILE5} ${FILE6}) ADD_H5_TEST (h5diff_701 1 -v2 ${FILE5} ${FILE6}) ADD_H5_TEST (h5diff_702 1 --verbose=1 ${FILE5} ${FILE6}) ADD_H5_TEST (h5diff_703 1 --verbose=2 ${FILE5} ${FILE6}) @@ -1054,7 +1094,7 @@ ADD_H5_TEST (h5diff_706 1 -v2 ${ATTR_VERBOSE_LEVEL_FILE1} ${ATTR_VERBOSE_LEVEL_F # different attr number , same attr name (intersected) ADD_H5_TEST (h5diff_707 1 -v2 ${ATTR_VERBOSE_LEVEL_FILE1} ${ATTR_VERBOSE_LEVEL_FILE2} /g2) -# different attr number , all different attr name +# different attr number , all different attr name ADD_H5_TEST (h5diff_708 1 -v2 ${ATTR_VERBOSE_LEVEL_FILE1} ${ATTR_VERBOSE_LEVEL_FILE2} /g3) # when no attributes exist in both objects @@ -1066,31 +1106,31 @@ ADD_H5_TEST (h5diff_710 1 -v2 ${ATTR_VERBOSE_LEVEL_FILE1} ${ATTR_VERBOSE_LEVEL_F # ############################################################################## # 8. all dataset datatypes # ############################################################################## -ADD_H5_TEST (h5diff_80 1 -v ${FILE7} ${FILE8}) +ADD_H5_TEST (h5diff_80 1 -v ${FILE7} ${FILE8}) # 9. compare a file with itself ADD_H5_TEST (h5diff_90 0 -v ${FILE2} ${FILE2}) # 10. read by hyperslab, print indexes -ADD_H5_TEST (h5diff_100 1 -v ${FILE9} ${FILE10}) +ADD_H5_TEST (h5diff_100 1 -v ${FILE9} ${FILE10}) # 11. floating point comparison -ADD_H5_TEST (h5diff_101 1 -v ${FILE1} ${FILE1} g1/d1 g1/d2) +ADD_H5_TEST (h5diff_101 1 -v ${FILE1} ${FILE1} g1/d1 g1/d2) -ADD_H5_TEST (h5diff_102 1 -v ${FILE1} ${FILE1} g1/fp1 g1/fp2) +ADD_H5_TEST (h5diff_102 1 -v ${FILE1} ${FILE1} g1/fp1 g1/fp2) -# with --use-system-epsilon for double value. expect less differences +# with --use-system-epsilon for double value. expect less differences ADD_H5_TEST (h5diff_103 1 -v --use-system-epsilon ${FILE1} ${FILE1} g1/d1 -g1/d2) +g1/d2) # with --use-system-epsilon for float value. expect less differences ADD_H5_TEST (h5diff_104 1 -v --use-system-epsilon ${FILE1} ${FILE1} g1/fp1 g1/fp2) # not comparable -c flag -ADD_H5_TEST (h5diff_200 0 ${FILE2} ${FILE2} g2/dset1 g2/dset2) +ADD_H5_TEST (h5diff_200 0 ${FILE2} ${FILE2} g2/dset1 g2/dset2) -ADD_H5_TEST (h5diff_201 0 -c ${FILE2} ${FILE2} g2/dset1 g2/dset2) +ADD_H5_TEST (h5diff_201 0 -c ${FILE2} ${FILE2} g2/dset1 g2/dset2) ADD_H5_TEST (h5diff_202 0 -c ${FILE2} ${FILE2} g2/dset2 g2/dset3) @@ -1106,9 +1146,9 @@ ADD_H5_TEST (h5diff_206 0 -c ${FILE2} ${FILE2} g2/dset7 g2/dset8) ADD_H5_TEST (h5diff_207 0 -c ${FILE2} ${FILE2} g2/dset8 g2/dset9) # not comparable in dataspace of zero dimension size -ADD_H5_TEST (h5diff_208 0 -c ${FILE19} ${FILE20}) +ADD_H5_TEST (h5diff_208 0 -c ${FILE19} ${FILE20}) -# non-comparable dataset with comparable attribute, and other comparable datasets. +# non-comparable dataset with comparable attribute, and other comparable datasets. # All the rest comparables should display differences. ADD_H5_TEST (h5diff_220 1 -c non_comparables1.h5 non_comparables2.h5 /g1) @@ -1221,28 +1261,28 @@ ADD_H5_TEST (h5diff_425 1 --follow-symlinks -v ${FILE17} ${FILE17} /ext_link_to_ ADD_H5_TEST (h5diff_450 1 --follow-symlinks -v ${DANGLE_LINK_FILE1} ${DANGLE_LINK_FILE2}) # dangling links --follow-symlinks and --no-dangling-links (FILE to FILE) -ADD_H5_TEST (h5diff_451 2 --follow-symlinks -v --no-dangling-links ${DANGLE_LINK_FILE1} ${DANGLE_LINK_FILE2}) +ADD_H5_TEST (h5diff_451 2 --follow-symlinks -v --no-dangling-links ${DANGLE_LINK_FILE1} ${DANGLE_LINK_FILE2}) # try --no-dangling-links without --follow-symlinks options ADD_H5_TEST (h5diff_452 2 --no-dangling-links ${FILE13} ${FILE13}) # dangling link found for soft links (FILE to FILE) -ADD_H5_TEST (h5diff_453 2 --follow-symlinks -v --no-dangling-links ${FILE13} ${FILE13}) +ADD_H5_TEST (h5diff_453 2 --follow-symlinks -v --no-dangling-links ${FILE13} ${FILE13}) # dangling link found for soft links (obj to obj) -ADD_H5_TEST (h5diff_454 2 --follow-symlinks -v --no-dangling-links ${FILE13} ${FILE13} /softlink_dset2 /softlink_noexist) +ADD_H5_TEST (h5diff_454 2 --follow-symlinks -v --no-dangling-links ${FILE13} ${FILE13} /softlink_dset2 /softlink_noexist) # dangling link found for soft links (obj to obj) Both dangle links -ADD_H5_TEST (h5diff_455 2 --follow-symlinks -v --no-dangling-links ${FILE13} ${FILE13} /softlink_noexist /softlink_noexist) +ADD_H5_TEST (h5diff_455 2 --follow-symlinks -v --no-dangling-links ${FILE13} ${FILE13} /softlink_noexist /softlink_noexist) # dangling link found for ext links (FILE to FILE) -ADD_H5_TEST (h5diff_456 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15}) +ADD_H5_TEST (h5diff_456 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15}) # dangling link found for ext links (obj to obj). target file exist -ADD_H5_TEST (h5diff_457 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15} /ext_link_dset1 /ext_link_noexist1) +ADD_H5_TEST (h5diff_457 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15} /ext_link_dset1 /ext_link_noexist1) # dangling link found for ext links (obj to obj). target file NOT exist -ADD_H5_TEST (h5diff_458 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15} /ext_link_dset1 /ext_link_noexist2) +ADD_H5_TEST (h5diff_458 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15} /ext_link_dset1 /ext_link_noexist2) # dangling link found for ext links (obj to obj). Both dangle links ADD_H5_TEST (h5diff_459 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15} /ext_link_noexist1 /ext_link_noexist2) @@ -1261,9 +1301,9 @@ ADD_H5_TEST (h5diff_468 0 -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_dan ADD_H5_TEST (h5diff_469 1 -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /ext_link2) #--------------------------------------------------- -# dangling links without follow symlink +# dangling links without follow symlink # (HDFFV-7998) -# test - soft dangle links (same and different paths), +# test - soft dangle links (same and different paths), # - external dangle links (same and different paths) ADD_H5_TEST (h5diff_471 1 -v h5diff_danglelinks1.h5 h5diff_danglelinks2.h5) ADD_H5_TEST (h5diff_472 0 -v h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link1) @@ -1275,7 +1315,7 @@ ADD_H5_TEST (h5diff_475 1 -v h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /ext_ # ############################################################################## # # test for group diff recursivly # ############################################################################## -# root +# root ADD_H5_TEST (h5diff_500 1 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} / /) ADD_H5_TEST (h5diff_501 1 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} / /) @@ -1309,7 +1349,7 @@ ADD_H5_TEST (h5diff_513 1 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /slink_gr ADD_H5_TEST (h5diff_514 1 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /slink_grp10 /slink_grp11) ############################################################################### -# Test for group recursive diff via multi-linked external links +# Test for group recursive diff via multi-linked external links # With follow-symlinks, file $GRP_RECURSE1_EXT and $GRP_RECURSE2_EXT1 should # be same with the external links. ############################################################################### @@ -1332,7 +1372,7 @@ ADD_H5_TEST (h5diff_480 0 -v --exclude-path /group1/dset3 ${EXCLUDE_FILE1_1} ${E ADD_H5_TEST (h5diff_481 1 -v ${EXCLUDE_FILE1_1} ${EXCLUDE_FILE1_2}) # -# Different structure, different names. +# Different structure, different names. # # Exclude all the different objects. Expect return - same ADD_H5_TEST (h5diff_482 0 -v --exclude-path "/group1" --exclude-path "/dset1" ${EXCLUDE_FILE2_1} ${EXCLUDE_FILE2_2}) @@ -1364,10 +1404,10 @@ ADD_H5_TEST (h5diff_530 0 -v ${COMP_VL_STRS_FILE} ${COMP_VL_STRS_FILE} /group / ADD_H5_TEST (h5diff_540 1 -v ${COMPS_ARRAY_VLEN_FILE1} ${COMPS_ARRAY_VLEN_FILE2}) # ############################################################################## -# # Test mutually exclusive options +# # Test mutually exclusive options # ############################################################################## # -# Test with -d , -p and --use-system-epsilon. +# Test with -d , -p and --use-system-epsilon. ADD_H5_TEST (h5diff_640 1 -v -d 5 -p 0.05 --use-system-epsilon ${FILE1} ${FILE2} /g1/dset3 /g1/dset4) ADD_H5_TEST (h5diff_641 1 -v -d 5 -p 0.05 ${FILE1} ${FILE2} /g1/dset3 /g1/dset4) ADD_H5_TEST (h5diff_642 1 -v -p 0.05 -d 5 ${FILE1} ${FILE2} /g1/dset3 /g1/dset4) @@ -1375,3 +1415,9 @@ ADD_H5_TEST (h5diff_643 1 -v -d 5 --use-system-epsilon ${FILE1} ${FILE2} /g1/dse ADD_H5_TEST (h5diff_644 1 -v --use-system-epsilon -d 5 ${FILE1} ${FILE2} /g1/dset3 /g1/dset4) ADD_H5_TEST (h5diff_645 1 -v -p 0.05 --use-system-epsilon ${FILE1} ${FILE2} /g1/dset3 /g1/dset4) ADD_H5_TEST (h5diff_646 1 -v --use-system-epsilon -p 0.05 ${FILE1} ${FILE2} /g1/dset3 /g1/dset4) + +# VDS +ADD_H5_TEST (h5diff_v1 0 -v ${FILEV1} ${FILEV2}) +ADD_H5_TEST (h5diff_v2 0 -r ${FILEV1} ${FILEV2}) +ADD_H5_TEST (h5diff_v3 0 -c ${FILEV1} ${FILEV2}) + diff --git a/tools/h5diff/testfiles/h5diff_v1.txt b/tools/h5diff/testfiles/h5diff_v1.txt new file mode 100644 index 0000000..31a3eae --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_v1.txt @@ -0,0 +1,18 @@ + +file1 file2 +--------------------------------------- + x x / + x x /vds_dset + +group : </> and </> +0 differences found +dataset: </vds_dset> and </vds_dset> +Not comparable: </vds_dset> or </vds_dset> is an empty dataset +Not comparable: </vds_dset> has rank 3, dimensions [5x18x8], max dimensions [18446744073709551615x18x8] +and </vds_dset> has rank 3, dimensions [6x8x14], max dimensions [18446744073709551615x8x14] +0 differences found +-------------------------------- +Some objects are not comparable +-------------------------------- +Use -c for a list of objects without details of differences. +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_v2.txt b/tools/h5diff/testfiles/h5diff_v2.txt new file mode 100644 index 0000000..aa327b1 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_v2.txt @@ -0,0 +1,7 @@ +dataset: </vds_dset> and </vds_dset> +0 differences found +-------------------------------- +Some objects are not comparable +-------------------------------- +Use -c for a list of objects. +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_v3.txt b/tools/h5diff/testfiles/h5diff_v3.txt new file mode 100644 index 0000000..8c5d2a2 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_v3.txt @@ -0,0 +1,4 @@ +Not comparable: </vds_dset> or </vds_dset> is an empty dataset +Not comparable: </vds_dset> has rank 3, dimensions [5x18x8], max dimensions [18446744073709551615x18x8] +and </vds_dset> has rank 3, dimensions [6x8x14], max dimensions [18446744073709551615x8x14] +EXIT CODE: 0 diff --git a/tools/h5diff/testh5diff.sh.in b/tools/h5diff/testh5diff.sh.in index 373558e..fec6035 100644 --- a/tools/h5diff/testh5diff.sh.in +++ b/tools/h5diff/testh5diff.sh.in @@ -120,6 +120,29 @@ $SRC_H5DIFF_TESTFILES/h5diff_attr_v_level2.h5 $SRC_H5DIFF_TESTFILES/h5diff_enum_invalid_values.h5 $SRC_H5DIFF_TESTFILES/non_comparables1.h5 $SRC_H5DIFF_TESTFILES/non_comparables2.h5 +$SRC_TOOLS_TESTFILES/vds/1_a.h5 +$SRC_TOOLS_TESTFILES/vds/1_b.h5 +$SRC_TOOLS_TESTFILES/vds/1_c.h5 +$SRC_TOOLS_TESTFILES/vds/1_d.h5 +$SRC_TOOLS_TESTFILES/vds/1_e.h5 +$SRC_TOOLS_TESTFILES/vds/1_f.h5 +$SRC_TOOLS_TESTFILES/vds/1_vds.h5 +$SRC_TOOLS_TESTFILES/vds/2_a.h5 +$SRC_TOOLS_TESTFILES/vds/2_b.h5 +$SRC_TOOLS_TESTFILES/vds/2_c.h5 +$SRC_TOOLS_TESTFILES/vds/2_d.h5 +$SRC_TOOLS_TESTFILES/vds/2_e.h5 +$SRC_TOOLS_TESTFILES/vds/2_vds.h5 +$SRC_TOOLS_TESTFILES/vds/3_1_vds.h5 +$SRC_TOOLS_TESTFILES/vds/3_2_vds.h5 +$SRC_TOOLS_TESTFILES/vds/4_0.h5 +$SRC_TOOLS_TESTFILES/vds/4_1.h5 +$SRC_TOOLS_TESTFILES/vds/4_2.h5 +$SRC_TOOLS_TESTFILES/vds/4_vds.h5 +$SRC_TOOLS_TESTFILES/vds/5_a.h5 +$SRC_TOOLS_TESTFILES/vds/5_b.h5 +$SRC_TOOLS_TESTFILES/vds/5_c.h5 +$SRC_TOOLS_TESTFILES/vds/5_vds.h5 " LIST_OTHER_TEST_FILES=" @@ -1110,6 +1133,13 @@ TOOLTEST h5diff_644.txt -v --use-system-epsilon -d 5 h5diff_basic1.h5 h5diff_bas TOOLTEST h5diff_645.txt -v -p 0.05 --use-system-epsilon h5diff_basic1.h5 h5diff_basic2.h5 /g1/dset3 /g1/dset4 TOOLTEST h5diff_646.txt -v --use-system-epsilon -p 0.05 h5diff_basic1.h5 h5diff_basic2.h5 /g1/dset3 /g1/dset4 +# ############################################################################## +# VDS tests +# ############################################################################## +TOOLTEST h5diff_v1.txt -v 1_vds.h5 2_vds.h5 +TOOLTEST h5diff_v2.txt -r 1_vds.h5 2_vds.h5 +TOOLTEST h5diff_v3.txt -c 1_vds.h5 2_vds.h5 + # ############################################################################## # # END diff --git a/tools/h5dump/CMakeLists.txt b/tools/h5dump/CMakeLists.txt index 47ba7a8..be08e2a 100644 --- a/tools/h5dump/CMakeLists.txt +++ b/tools/h5dump/CMakeLists.txt @@ -39,6 +39,8 @@ if (BUILD_TESTING) include (CMakeTestsPBITS.cmake) + include (CMakeTestsVDS.cmake) + include (CMakeTestsXML.cmake) endif (BUILD_TESTING) diff --git a/tools/h5dump/CMakeTestsVDS.cmake b/tools/h5dump/CMakeTestsVDS.cmake new file mode 100644 index 0000000..58287fa --- /dev/null +++ b/tools/h5dump/CMakeTestsVDS.cmake @@ -0,0 +1,238 @@ + +############################################################################## +############################################################################## +### T E S T I N G ### +############################################################################## +############################################################################## + + # -------------------------------------------------------------------- + # VDS + # -------------------------------------------------------------------- + #-- Copy all the HDF5 files from the test directory into the source directory + set (HDF5_REFERENCE_VDS + tvds-1.ddl + tvds-2.ddl + tvds-3_1.ddl + tvds-3_2.ddl + tvds-4.ddl + tvds-5.ddl + tvds_layout-1.ddl + tvds_layout-2.ddl + tvds_layout-3_1.ddl + tvds_layout-3_2.ddl + tvds_layout-4.ddl + tvds_layout-5.ddl + ) + set (HDF5_REFERENCE_TEST_VDS + 1_a.h5 + 1_b.h5 + 1_c.h5 + 1_d.h5 + 1_e.h5 + 1_f.h5 + 1_vds.h5 + 2_a.h5 + 2_b.h5 + 2_c.h5 + 2_d.h5 + 2_e.h5 + 2_vds.h5 + 3_1_vds.h5 + 3_2_vds.h5 + 4_0.h5 + 4_1.h5 + 4_2.h5 + 4_vds.h5 + 5_a.h5 + 5_b.h5 + 5_c.h5 + 5_vds.h5 + ) + set (HDF5_ERROR_REFERENCE_VDS + ) + + foreach (vds_h5_file ${HDF5_REFERENCE_TEST_VDS}) + GET_FILENAME_COMPONENT(fname "${vds_h5_file}" NAME) + set (dest "${PROJECT_BINARY_DIR}/testfiles/vds/${fname}") + #message (STATUS " Copying ${vds_h5_file}") + add_custom_command ( + TARGET h5dump + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/${vds_h5_file} ${dest} + ) + endforeach (vds_h5_file ${HDF5_REFERENCE_TEST_VDS}) + + + foreach (ddl_vds ${HDF5_REFERENCE_VDS}) + GET_FILENAME_COMPONENT(fname "${ddl_vds}" NAME) + set (ddldest "${PROJECT_BINARY_DIR}/testfiles/vds/${fname}") + #message (STATUS " Copying ${ddl_vds}") + add_custom_command ( + TARGET h5dump + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/${ddl_vds} ${ddldest} + ) + endforeach (ddl_vds ${HDF5_REFERENCE_VDS}) + + foreach (ddl_vds ${HDF5_ERROR_REFERENCE_VDS}) + GET_FILENAME_COMPONENT(fname "${ddl_vds}" NAME) + set (ddldest "${PROJECT_BINARY_DIR}/testfiles/vds/${fname}") + #message (STATUS " Copying ${ddl_vds}") + add_custom_command ( + TARGET h5dump + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/errfiles/${ddl_vds} ${ddldest} + ) + endforeach (ddl_vds ${HDF5_ERROR_REFERENCE_VDS}) + +############################################################################## +############################################################################## +### T H E T E S T S M A C R O S ### +############################################################################## +############################################################################## + + MACRO (ADD_H5_VDS_TEST resultfile resultcode) + # If using memchecker add tests without using scripts + if (HDF5_ENABLE_USING_MEMCHECKER) + add_test (NAME H5DUMP-${resultfile} COMMAND $<TARGET_FILE:h5dump> ${ARGN}) + set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfilesvds") + if (NOT ${resultcode} STREQUAL "0") + set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") + endif (NOT ${resultcode} STREQUAL "0") + if (NOT "${last_vds_test}" STREQUAL "") + set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_VDS_test}) + endif (NOT "${last_vds_test}" STREQUAL "") + else (HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5DUMP-${resultfile}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ${resultfile}.out ${resultfile}.out.err + ) + set_tests_properties (H5DUMP-${resultfile}-clear-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") + add_test ( + NAME H5DUMP-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$<TARGET_FILE:h5dump>" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles/vds" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.ddl" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS "H5DUMP-${resultfile}-clear-objects") + endif (HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_VDS_TEST file) + + MACRO (ADD_H5_VDS_LAYOUT resultfile resultcode) + # If using memchecker add tests without using scripts + if (HDF5_ENABLE_USING_MEMCHECKER) + add_test (NAME H5DUMP-${resultfile} COMMAND $<TARGET_FILE:h5dump> -p ${ARGN}) + set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfilesvds") + if (NOT ${resultcode} STREQUAL "0") + set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") + endif (NOT ${resultcode} STREQUAL "0") + if (NOT "${last_vds_test}" STREQUAL "") + set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_VDS_test}) + endif (NOT "${last_vds_test}" STREQUAL "") + else (HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5DUMP-${resultfile}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ${resultfile}.out ${resultfile}.out.err + ) + set_tests_properties (H5DUMP-${resultfile}-clear-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") + add_test ( + NAME H5DUMP-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$<TARGET_FILE:h5dump>" + -D "TEST_ARGS:STRING=-p;${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles/vds" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.ddl" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS "H5DUMP-${resultfile}-clear-objects") + endif (HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_VDS_LAYOUT file) + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + + if (HDF5_ENABLE_USING_MEMCHECKER) + # Remove any output file left over from previous test run + add_test ( + NAME H5DUMP_VDS-clearall-objects + COMMAND ${CMAKE_COMMAND} + -E remove + tvds-1.out + tvds-1.out.err + tvds-2.out + tvds-2.out.err + tvds-3_1.out + tvds-3_1.out.err + tvds-3_2.out + tvds-3_2.out.err + tvds-4.out + tvds-4.out.err + tvds-5.out + tvds-5.out.err + tvds_layout-1.out + tvds_layout-1.out.err + tvds_layout-2.out + tvds_layout-2.out.err + tvds_layout-3_1.out + tvds_layout-3_1.out.err + tvds_layout-3_2.out + tvds_layout-3_2.out.err + tvds_layout-4.out + tvds_layout-4.out.err + tvds_layout-5.out + tvds_layout-5.out.err + ) + set_tests_properties (H5DUMP_VDS-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") + if (NOT "${last_vds_test}" STREQUAL "") + set_tests_properties (H5DUMP_VDS-clearall-objects PROPERTIES DEPENDS ${last_vds_test}) + endif (NOT "${last_vds_test}" STREQUAL "") + set (last_VDS_test "H5DUMP_VDS-clearall-objects") + endif (HDF5_ENABLE_USING_MEMCHECKER) + +# See which filters are usable (and skip tests for filters we +# don't have). Do this by searching H5pubconf.h to see which +# filters are defined. + +# detect whether the encoder is present. + if (H5_HAVE_FILTER_DEFLATE) + set (USE_FILTER_DEFLATE "true") + endif (H5_HAVE_FILTER_DEFLATE) + + if (H5_HAVE_FILTER_SZIP) + set (USE_FILTER_SZIP "true") + endif (H5_HAVE_FILTER_SZIP) + + # Data read + if (USE_FILTER_DEFLATE) + ADD_H5_VDS_TEST (tvds-1 0 --enable-error-stack 1_vds.h5) + ADD_H5_VDS_TEST (tvds-2 0 --enable-error-stack 2_vds.h5) + ADD_H5_VDS_TEST (tvds-3_1 0 --enable-error-stack 3_1_vds.h5) + ADD_H5_VDS_TEST (tvds-3_2 0 --enable-error-stack 3_2_vds.h5) + ADD_H5_VDS_TEST (tvds-4 0 --enable-error-stack 4_vds.h5) + ADD_H5_VDS_TEST (tvds-5 0 --enable-error-stack 5_vds.h5) + endif (USE_FILTER_DEFLATE) + + # Layout read + if (USE_FILTER_DEFLATE) + ADD_H5_VDS_LAYOUT (tvds_layout-1 0 --enable-error-stack 1_vds.h5) + ADD_H5_VDS_LAYOUT (tvds_layout-2 0 --enable-error-stack 2_vds.h5) + ADD_H5_VDS_LAYOUT (tvds_layout-3_1 0 --enable-error-stack 3_1_vds.h5) + ADD_H5_VDS_LAYOUT (tvds_layout-3_2 0 --enable-error-stack 3_2_vds.h5) + ADD_H5_VDS_LAYOUT (tvds_layout-4 0 --enable-error-stack 4_vds.h5) + ADD_H5_VDS_LAYOUT (tvds_layout-5 0 --enable-error-stack 5_vds.h5) + endif (USE_FILTER_DEFLATE) diff --git a/tools/h5dump/Makefile.am b/tools/h5dump/Makefile.am index cee4801..93ba195 100644 --- a/tools/h5dump/Makefile.am +++ b/tools/h5dump/Makefile.am @@ -25,7 +25,7 @@ AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib # Test programs and scripts TEST_PROG=h5dumpgentest -TEST_SCRIPT=testh5dump.sh testh5dumppbits.sh testh5dumpxml.sh +TEST_SCRIPT=testh5dump.sh testh5dumppbits.sh testh5dumpvds.sh testh5dumpxml.sh check_PROGRAMS=$(TEST_PROG) binread check_SCRIPTS=$(TEST_SCRIPT) diff --git a/tools/h5dump/testh5dumpvds.sh.in b/tools/h5dump/testh5dumpvds.sh.in new file mode 100644 index 0000000..b15606f --- /dev/null +++ b/tools/h5dump/testh5dumpvds.sh.in @@ -0,0 +1,505 @@ +#! /bin/sh +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +# +# Tests for the h5dump tool with vds type files + +srcdir=@srcdir@ + +# Determine which filters are available +USE_FILTER_SZIP="@USE_FILTER_SZIP@" +USE_FILTER_DEFLATE="@USE_FILTER_DEFLATE@" + +TESTNAME=h5dump +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +DUMPER=h5dump # The tool name +DUMPER_BIN=`pwd`/$DUMPER # The path of the tool binary + +H5DIFF=../h5diff/h5diff # The h5diff tool name +H5DIFF_BIN=`pwd`/$H5DIFF # The path of the h5diff tool binary + +H5IMPORT=../h5import/h5import # The h5import tool name +H5IMPORT_BIN=`pwd`/$H5IMPORT # The path of the h5import tool binary + +RM='rm -rf' +CMP='cmp -s' +DIFF='diff -c' +CP='cp' +DIRNAME='dirname' +LS='ls' +AWK='awk' + +nerrors=0 +verbose=yes + +# source dirs +SRC_TOOLS="$srcdir/../" + +SRC_TOOLS_TESTFILES="$SRC_TOOLS/testfiles" +# testfiles source dirs for tools +SRC_H5LS_TESTFILES="$SRC_TOOLS_TESTFILES" +SRC_H5DUMP_TESTFILES="$SRC_TOOLS_TESTFILES" +SRC_H5DUMP_ERRORFILES="$srcdir/errfiles" +SRC_H5DIFF_TESTFILES="$SRC_TOOLS/h5diff/testfiles" +SRC_H5COPY_TESTFILES="$SRC_TOOLS/h5copy/testfiles" +SRC_H5REPACK_TESTFILES="$SRC_TOOLS/h5repack/testfiles" +SRC_H5JAM_TESTFILES="$SRC_TOOLS/h5jam/testfiles" +SRC_H5STAT_TESTFILES="$SRC_TOOLS/h5stat/testfiles" +SRC_H5IMPORT_TESTFILES="$SRC_TOOLS/h5import/testfiles" + +TEST_P_DIR=./testfiles +TESTDIR=./testfiles/vds +test -d $TEST_P_DIR || mkdir -p $TEST_P_DIR +test -d $TESTDIR || mkdir -p $TESTDIR + +###################################################################### +# test files +# -------------------------------------------------------------------- +# All the test files copy from source directory to test directory +# NOTE: Keep this framework to add/remove test files. +# Any test files from other tools can be used in this framework. +# This list are also used for checking exist. +# Comment '#' without space can be used. +# -------------------------------------------------------------------- +LIST_HDF5_TEST_FILES=" +$SRC_H5DUMP_TESTFILES/vds/1_a.h5 +$SRC_H5DUMP_TESTFILES/vds/1_b.h5 +$SRC_H5DUMP_TESTFILES/vds/1_c.h5 +$SRC_H5DUMP_TESTFILES/vds/1_d.h5 +$SRC_H5DUMP_TESTFILES/vds/1_e.h5 +$SRC_H5DUMP_TESTFILES/vds/1_f.h5 +$SRC_H5DUMP_TESTFILES/vds/1_vds.h5 +$SRC_H5DUMP_TESTFILES/vds/2_a.h5 +$SRC_H5DUMP_TESTFILES/vds/2_b.h5 +$SRC_H5DUMP_TESTFILES/vds/2_c.h5 +$SRC_H5DUMP_TESTFILES/vds/2_d.h5 +$SRC_H5DUMP_TESTFILES/vds/2_e.h5 +$SRC_H5DUMP_TESTFILES/vds/2_vds.h5 +$SRC_H5DUMP_TESTFILES/vds/3_1_vds.h5 +$SRC_H5DUMP_TESTFILES/vds/3_2_vds.h5 +$SRC_H5DUMP_TESTFILES/vds/4_0.h5 +$SRC_H5DUMP_TESTFILES/vds/4_1.h5 +$SRC_H5DUMP_TESTFILES/vds/4_2.h5 +$SRC_H5DUMP_TESTFILES/vds/4_vds.h5 +$SRC_H5DUMP_TESTFILES/vds/5_a.h5 +$SRC_H5DUMP_TESTFILES/vds/5_b.h5 +$SRC_H5DUMP_TESTFILES/vds/5_c.h5 +$SRC_H5DUMP_TESTFILES/vds/5_vds.h5 +" + +LIST_OTHER_TEST_FILES=" +$SRC_H5DUMP_TESTFILES/vds/tvds-1.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds-2.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds-3_1.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds-3_2.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds-4.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds-5.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds_layout-1.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds_layout-2.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds_layout-3_1.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds_layout-3_2.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds_layout-4.ddl +$SRC_H5DUMP_TESTFILES/vds/tvds_layout-5.ddl +" + +LIST_ERROR_TEST_FILES=" +" + +# +# copy test files and expected output files from source dirs to test dir +# +COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES $LIST_ERROR_TEST_FILES" + +COPY_TESTFILES_TO_TESTDIR() +{ + # copy test files. Used -f to make sure get a new copy + for tstfile in $COPY_TESTFILES + do + # ignore '#' comment + echo $tstfile | tr -d ' ' | grep '^#' > /dev/null + RET=$? + if [ $RET -eq 1 ]; then + # skip cp if srcdir is same as destdir + # this occurs when build/test performed in source dir and + # make cp fail + SDIR=`$DIRNAME $tstfile` + INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'` + INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'` + if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then + $CP -f $tstfile $TESTDIR + if [ $? -ne 0 ]; then + echo "Error: FAILED to copy $tstfile ." + + # Comment out this to CREATE expected file + exit $EXIT_FAILURE + fi + fi + fi + done +} + +CLEAN_TESTFILES_AND_TESTDIR() +{ + # skip rm if srcdir is same as destdir + # this occurs when build/test performed in source dir and + # make cp fail + SDIR=`$DIRNAME $tstfile` + INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'` + INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'` + if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then + $RM $TESTDIR + fi +} + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +# +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012' +} + +# Source in the output filter function definitions. +. $srcdir/../../bin/output_filter.sh + +# Run a test and print PASS or *FAIL*. If a test fails then increment +# the `nerrors' global variable and (if $verbose is set) display the +# difference between the actual output and the expected output. The +# expected output is given as the first argument to this function and +# the actual output file is calculated by replacing the `.ddl' with +# `.out'. The actual output is not removed if $HDF5_NOCLEANUP has a +# non-zero value. +# +TOOLTEST() { + expect="$TESTDIR/$1" + actual="$TESTDIR/`basename $1 .ddl`.out" + actual_err="$TESTDIR/`basename $1 .ddl`.err" + actual_sav=${actual}-sav + actual_err_sav=${actual_err}-sav + shift + + # Run test. + TESTING $DUMPER $@ + ( + cd $TESTDIR + $RUNSERIAL $DUMPER_BIN "$@" + ) >$actual 2>$actual_err + + # save actual and actual_err in case they are needed later. + cp $actual $actual_sav + STDOUT_FILTER $actual + cp $actual_err $actual_err_sav + STDERR_FILTER $actual_err + cat $actual_err >> $actual + + if [ ! -f $expect ]; then + # Create the expect file if it doesn't yet exist. + echo " CREATED" + cp $actual $expect + elif $CMP $expect $actual; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected result (*.ddl) differs from actual result (*.out)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actual_err $actual_sav $actual_err_sav $actual_ext + fi + +} + + +# same as TOOLTEST1 but compares generated file to expected output +# and compares the generated data file to the expected data file +# used for the binary tests that expect a full path in -o without -b +TOOLTEST2() { + + expectdata="$TESTDIR/$1" + expect="$TESTDIR/`basename $1 .exp`.ddl" + actualdata="$TESTDIR/`basename $1 .exp`.txt" + actual="$TESTDIR/`basename $1 .exp`.out" + actual_err="$TESTDIR/`basename $1 .exp`.err" + shift + + # Run test. + TESTING $DUMPER $@ + ( + cd $TESTDIR + $RUNSERIAL $DUMPER_BIN "$@" + ) >$actual 2>$actual_err + cat $actual_err >> $actual + + if [ ! -f $expect ]; then + # Create the expect file if it doesn't yet exist. + echo " CREATED" + cp $actual $expect + elif $CMP $expect $actual; then + if [ ! -f $expectdata ]; then + # Create the expect data file if it doesn't yet exist. + echo " CREATED" + cp $actualdata $expectdata + elif $CMP $expectdata $actualdata; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected datafile (*.exp) differs from actual datafile (*.txt)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expectdata $actualdata |sed 's/^/ /' + fi + else + echo "*FAILED*" + echo " Expected result (*.ddl) differs from actual result (*.out)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actualdata $actual_err + fi + +} + +# same as TOOLTEST but filters error stack outp +# Extract file name, line number, version and thread IDs because they may be different +TOOLTEST3() { + + expect="$TESTDIR/$1" + actual="$TESTDIR/`basename $1 .ddl`.out" + actual_err="$TESTDIR/`basename $1 .ddl`.err" + actual_ext="$TESTDIR/`basename $1 .ddl`.ext" + actual_sav=${actual}-sav + actual_err_sav=${actual_err}-sav + shift + + # Run test. + TESTING $DUMPER $@ + ( + cd $TESTDIR + $RUNSERIAL $DUMPER_BIN "$@" + ) >$actual 2>$actual_err + + # save actual and actual_err in case they are needed later. + cp $actual $actual_sav + STDOUT_FILTER $actual + cp $actual_err $actual_err_sav + STDERR_FILTER $actual_err + + # Extract file name, line number, version and thread IDs because they may be different + sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + -e 's/line [0-9]*/line (number)/' \ + -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ + -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ + -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ + -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ + $actual_err > $actual_ext + cat $actual_ext >> $actual + + if [ ! -f $expect ]; then + # Create the expect file if it doesn't yet exist. + echo " CREATED" + cp $actual $expect + elif $CMP $expect $actual; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected result (*.ddl) differs from actual result (*.out)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actual_err $actual_sav $actual_err_sav + fi + +} + +# same as TOOLTEST3 but filters error stack output and compares to an error file +# Extract file name, line number, version and thread IDs because they may be different +TOOLTEST4() { + + expect="$TESTDIR/$1" + expect_err="$TESTDIR/`basename $1 .ddl`.err" + actual="$TESTDIR/`basename $1 .ddl`.out" + actual_err="$TESTDIR/`basename $1 .ddl`.oerr" + actual_ext="$TESTDIR/`basename $1 .ddl`.ext" + actual_sav=${actual}-sav + actual_err_sav=${actual_err}-sav + shift + + # Run test. + TESTING $DUMPER $@ + ( + cd $TESTDIR + $RUNSERIAL $DUMPER_BIN "$@" + ) >$actual 2>$actual_err + + # save actual and actual_err in case they are needed later. + cp $actual $actual_sav + STDOUT_FILTER $actual + cp $actual_err $actual_err_sav + STDERR_FILTER $actual_err + + # Extract file name, line number, version and thread IDs because they may be different + sed -e 's/thread [0-9]*/thread (IDs)/' -e 's/: .*\.c /: (file name) /' \ + -e 's/line [0-9]*/line (number)/' \ + -e 's/v[1-9]*\.[0-9]*\./version (number)\./' \ + -e 's/[1-9]*\.[0-9]*\.[0-9]*[^)]*/version (number)/' \ + -e 's/H5Eget_auto[1-2]*/H5Eget_auto(1 or 2)/' \ + -e 's/H5Eset_auto[1-2]*/H5Eset_auto(1 or 2)/' \ + $actual_err > $actual_ext + #cat $actual_ext >> $actual + + if [ ! -f $expect ]; then + # Create the expect file if it doesn't yet exist. + echo " CREATED" + cp $actual $expect + elif $CMP $expect $actual; then + if $CMP $expect_err $actual_ext; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected result (*.err) differs from actual result (*.oerr)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect_err $actual_ext |sed 's/^/ /' + fi + else + echo "*FAILED*" + echo " Expected result (*.ddl) differs from actual result (*.out)" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actual_err $actual_sav $actual_err_sav + fi + +} + +# Print a "SKIP" message +SKIP() { + TESTING $DUMPER $@ + echo " -SKIP-" +} + +# Print a line-line message left justified in a field of 70 characters +# +PRINT_H5DIFF() { + SPACES=" " + echo " Running h5diff $* $SPACES" | cut -c1-70 | tr -d '\012' +} + + +# Call the h5diff tool +# +DIFFTEST() +{ + PRINT_H5DIFF $@ + ( + cd $TESTDIR + $RUNSERIAL $H5DIFF_BIN "$@" -q + ) + RET=$? + if [ $RET != 0 ] ; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + else + echo " PASSED" + fi + +} + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Verifying". +# +PRINT_H5IMPORT() { + SPACES=" " + echo " Running h5import $* $SPACES" | cut -c1-70 | tr -d '\012' +} + +# Call the h5import tool +# +IMPORTTEST() +{ + # remove the output hdf5 file if it exists + hdf5_file="$TESTDIR/$5" + if [ -f $hdf5_file ]; then + rm -f $hdf5_file + fi + + PRINT_H5IMPORT $@ + ( + cd $TESTDIR + $RUNSERIAL $H5IMPORT_BIN "$@" + ) + RET=$? + if [ $RET != 0 ] ; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + else + echo " PASSED" + fi + +} + + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## +# prepare for test +COPY_TESTFILES_TO_TESTDIR + +####### test for dataset vds ###### + + # Data read +if test $USE_FILTER_DEFLATE = "yes" ; then + TOOLTEST tvds-1.ddl --enable-error-stack 1_vds.h5 + TOOLTEST tvds-2.ddl --enable-error-stack 2_vds.h5 + TOOLTEST tvds-3_1.ddl --enable-error-stack 3_1_vds.h5 + TOOLTEST tvds-3_2.ddl --enable-error-stack 3_2_vds.h5 + TOOLTEST tvds-4.ddl --enable-error-stack 4_vds.h5 + TOOLTEST tvds-5.ddl --enable-error-stack 5_vds.h5 +fi + + # Layout read +if test $USE_FILTER_DEFLATE = "yes" ; then + TOOLTEST tvds_layout-1.ddl -p --enable-error-stack 1_vds.h5 + TOOLTEST tvds_layout-2.ddl -p --enable-error-stack 2_vds.h5 + TOOLTEST tvds_layout-3_1.ddl -p --enable-error-stack 3_1_vds.h5 + TOOLTEST tvds_layout-3_2.ddl -p --enable-error-stack 3_2_vds.h5 + TOOLTEST tvds_layout-4.ddl -p --enable-error-stack 4_vds.h5 + TOOLTEST tvds_layout-5.ddl -p --enable-error-stack 5_vds.h5 +fi + +# Clean up temporary files/directories +CLEAN_TESTFILES_AND_TESTDIR + +# Report test results and exit +if test $nerrors -eq 0 ; then + echo "All $TESTNAME tests passed." + exit $EXIT_SUCCESS +else + echo "$TESTNAME tests failed with $nerrors errors." + exit $EXIT_FAILURE +fi diff --git a/tools/h5ls/CMakeLists.txt b/tools/h5ls/CMakeLists.txt index 4e96db2..6e7f00c 100644 --- a/tools/h5ls/CMakeLists.txt +++ b/tools/h5ls/CMakeLists.txt @@ -23,6 +23,8 @@ if (BUILD_TESTING) include (CMakeTests.cmake) + include (CMakeTestsVDS.cmake) + endif (BUILD_TESTING) ############################################################################## diff --git a/tools/h5ls/CMakeTestsVDS.cmake b/tools/h5ls/CMakeTestsVDS.cmake new file mode 100644 index 0000000..1ef3f20 --- /dev/null +++ b/tools/h5ls/CMakeTestsVDS.cmake @@ -0,0 +1,149 @@ + +############################################################################## +############################################################################## +### T E S T I N G ### +############################################################################## +############################################################################## + + # -------------------------------------------------------------------- + # Copy all the test files from source directory to test directory + # -------------------------------------------------------------------- + set (LIST_HDF5_TEST_FILES + 1_a.h5 + 1_b.h5 + 1_c.h5 + 1_d.h5 + 1_e.h5 + 1_f.h5 + 1_vds.h5 + 2_a.h5 + 2_b.h5 + 2_c.h5 + 2_d.h5 + 2_e.h5 + 2_vds.h5 + 3_1_vds.h5 + 3_2_vds.h5 + 4_0.h5 + 4_1.h5 + 4_2.h5 + 4_vds.h5 + 5_a.h5 + 5_b.h5 + 5_c.h5 + 5_vds.h5 + ) + + set (LIST_OTHER_TEST_FILES + tvds-1.ls + tvds-2.ls + tvds-3_1.ls + tvds-3_2.ls + tvds-4.ls + tvds-5.ls + ) + + file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") + + # copy the list of test files + foreach (listfiles ${LIST_HDF5_TEST_FILES} ${LIST_OTHER_TEST_FILES}) + GET_FILENAME_COMPONENT(fname "${listfiles}" NAME) + set (dest "${PROJECT_BINARY_DIR}/testfiles/vds/${fname}") + #message (STATUS " Copying ${listfiles} to ${dest}") + add_custom_command ( + TARGET h5ls + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/${listfiles} ${dest} + ) + endforeach (listfiles ${LIST_HDF5_TEST_FILES} ${LIST_OTHER_TEST_FILES}) + + +############################################################################## +############################################################################## +### T H E T E S T S M A C R O S ### +############################################################################## +############################################################################## + + MACRO (ADD_H5_VDS_TEST resultfile resultcode) + # If using memchecker add tests without using scripts + if (HDF5_ENABLE_USING_MEMCHECKER) + add_test (NAME H5LS-${resultfile} COMMAND $<TARGET_FILE:h5ls> ${ARGN}) + set_tests_properties (H5LS-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") + if (${resultcode} STREQUAL "1") + set_tests_properties (H5LS-${resultfile} PROPERTIES WILL_FAIL "true") + endif (${resultcode} STREQUAL "1") + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5LS-${resultfile} PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + else (HDF5_ENABLE_USING_MEMCHECKER) + add_test ( + NAME H5LS-${resultfile}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove ./testfiles/${resultfile}.out ./testfiles/vds/${resultfile}.out.err + ) + add_test ( + NAME H5LS-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$<TARGET_FILE:h5ls>" + -D "TEST_ARGS=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles/vds" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.ls" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5LS-${resultfile} PROPERTIES DEPENDS "H5LS_VDS-${resultfile}-clear-objects") + endif (HDF5_ENABLE_USING_MEMCHECKER) + ENDMACRO (ADD_H5_VDS_TEST file) + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + + if (HDF5_ENABLE_USING_MEMCHECKER) + # Remove any output file left over from previous test run + add_test ( + NAME H5LS_VDS-clearall-objects + COMMAND ${CMAKE_COMMAND} + -E remove + tvds-1.out + tvds-1.out.err + tvds-2.out + tvds-2.out.err + tvds-3_1.out + tvds-3_1.out.err + tvds-3_2.out + tvds-3_2.out.err + tvds-4.out + tvds-4.out.err + tvds-5.out + tvds-5.out.err + tvds_layout-1.out + tvds_layout-1.out.err + tvds_layout-2.out + tvds_layout-2.out.err + tvds_layout-3_1.out + tvds_layout-3_1.out.err + tvds_layout-3_2.out + tvds_layout-3_2.out.err + tvds_layout-4.out + tvds_layout-4.out.err + tvds_layout-5.out + tvds_layout-5.out.err + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (H5LS_VDS-clearall-objects PROPERTIES DEPENDS ${last_test}) + endif (NOT "${last_test}" STREQUAL "") + set (last_test "H5LS_VDS-clearall-objects") + endif (HDF5_ENABLE_USING_MEMCHECKER) + + ADD_H5_VDS_TEST (tvds-1 0 -w80 -v -S 1_vds.h5) + ADD_H5_VDS_TEST (tvds-2 0 -w80 -v -S 2_vds.h5) + ADD_H5_VDS_TEST (tvds-3_1 0 -w80 -v -S 3_1_vds.h5) + ADD_H5_VDS_TEST (tvds-3_2 0 -w80 -v -S 3_2_vds.h5) + ADD_H5_VDS_TEST (tvds-4 0 -w80 -v -S 4_vds.h5) + ADD_H5_VDS_TEST (tvds-5 0 -w80 -v -S 5_vds.h5) + diff --git a/tools/h5ls/Makefile.am b/tools/h5ls/Makefile.am index 408ce93..54a06f1 100644 --- a/tools/h5ls/Makefile.am +++ b/tools/h5ls/Makefile.am @@ -24,7 +24,7 @@ include $(top_srcdir)/config/commence.am AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib # Test programs and scripts -TEST_SCRIPT=testh5ls.sh +TEST_SCRIPT=testh5ls.sh testh5lsvds.sh check_SCRIPTS=$(TEST_SCRIPT) SCRIPT_DEPEND=h5ls$(EXEEXT) diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index fe146c1..cce5f3d 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -1847,6 +1847,34 @@ dataset_list2(hid_t dset, const char H5_ATTR_UNUSED *name) } /* end if */ break; + case H5D_VIRTUAL: + { + char dset_name[256]; /* Dataset name */ + size_t vmaps; + + H5Pget_virtual_count(dcpl, &vmaps); + + if (vmaps) { + size_t next; + ssize_t ssize_out; + + h5tools_str_append(&buffer, " %-10s {%ld} Source {\n", "Maps:", vmaps); + for (next = 0; next < (unsigned) vmaps; next++) { + ssize_out = H5Pget_virtual_filename(dcpl, next, NULL, 0); + H5Pget_virtual_filename(dcpl, next, f_name, sizeof(f_name)); + ssize_out = H5Pget_virtual_dsetname(dcpl, next, NULL, 0); + H5Pget_virtual_dsetname(dcpl, next, dset_name, sizeof(dset_name)); + h5tools_str_append(&buffer, " %-10s ", " "); + print_string(&buffer, f_name, TRUE); + h5tools_str_append(&buffer, " "); + print_string(&buffer, dset_name, TRUE); + h5tools_str_append(&buffer, "\n"); + } + h5tools_str_append(&buffer, " %-10s}\n", " "); + } + } + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/tools/h5ls/testh5lsvds.sh.in b/tools/h5ls/testh5lsvds.sh.in new file mode 100644 index 0000000..d194992 --- /dev/null +++ b/tools/h5ls/testh5lsvds.sh.in @@ -0,0 +1,258 @@ +#! /bin/sh +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +# +# Tests for the h5ls tool + +srcdir=@srcdir@ + +TESTNAME=h5ls +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +H5LS=h5ls # The tool name +H5LS_BIN=`pwd`/$H5LS # The path of the tool binary + +RM='rm -rf' +CMP='cmp -s' +DIFF='diff -c' +CP='cp' +NLINES=20 # Max. lines of output to display if test fails +DIRNAME='dirname' +LS='ls' +AWK='awk' + +WORDS_BIGENDIAN="@WORDS_BIGENDIAN@" + +nerrors=0 +verbose=yes +h5haveexitcode=yes # default is yes + +# source dirs +SRC_TOOLS="$srcdir/.." +SRC_TOOLS_TESTFILES="$SRC_TOOLS/testfiles" + +# testfiles source dirs for tools +SRC_H5LS_TESTFILES="$SRC_TOOLS_TESTFILES" +SRC_H5DUMP_TESTFILES="$SRC_TOOLS_TESTFILES" +SRC_H5DIFF_TESTFILES="$SRC_TOOLS/h5diff/testfiles" +SRC_H5COPY_TESTFILES="$SRC_TOOLS/h5copy/testfiles" +SRC_H5REPACK_TESTFILES="$SRC_TOOLS/h5repack/testfiles" +SRC_H5JAM_TESTFILES="$SRC_TOOLS/h5jam/testfiles" +SRC_H5STAT_TESTFILES="$SRC_TOOLS/h5stat/testfiles" +SRC_H5IMPORT_TESTFILES="$SRC_TOOLS/h5import/testfiles" + +TEST_P_DIR=./testfiles +TESTDIR=./testfiles/vds +test -d $TEST_P_DIR || mkdir -p $TEST_P_DIR +test -d $TESTDIR || mkdir $TESTDIR + +###################################################################### +# test files +# -------------------------------------------------------------------- +# All the test files copy from source directory to test directory +# NOTE: Keep this framework to add/remove test files. +# Any test files from other tools can be used in this framework. +# This list are also used for checking exist. +# Comment '#' without space can be used. +# -------------------------------------------------------------------- +LIST_HDF5_TEST_FILES=" +$SRC_H5LS_TESTFILES/vds/1_a.h5 +$SRC_H5LS_TESTFILES/vds/1_b.h5 +$SRC_H5LS_TESTFILES/vds/1_c.h5 +$SRC_H5LS_TESTFILES/vds/1_d.h5 +$SRC_H5LS_TESTFILES/vds/1_e.h5 +$SRC_H5LS_TESTFILES/vds/1_f.h5 +$SRC_H5LS_TESTFILES/vds/1_vds.h5 +$SRC_H5LS_TESTFILES/vds/2_a.h5 +$SRC_H5LS_TESTFILES/vds/2_b.h5 +$SRC_H5LS_TESTFILES/vds/2_c.h5 +$SRC_H5LS_TESTFILES/vds/2_d.h5 +$SRC_H5LS_TESTFILES/vds/2_e.h5 +$SRC_H5LS_TESTFILES/vds/2_vds.h5 +$SRC_H5LS_TESTFILES/vds/3_1_vds.h5 +$SRC_H5LS_TESTFILES/vds/3_2_vds.h5 +$SRC_H5LS_TESTFILES/vds/4_0.h5 +$SRC_H5LS_TESTFILES/vds/4_1.h5 +$SRC_H5LS_TESTFILES/vds/4_2.h5 +$SRC_H5LS_TESTFILES/vds/4_vds.h5 +$SRC_H5LS_TESTFILES/vds/5_a.h5 +$SRC_H5LS_TESTFILES/vds/5_b.h5 +$SRC_H5LS_TESTFILES/vds/5_c.h5 +$SRC_H5LS_TESTFILES/vds/5_vds.h5 +" + +LIST_OTHER_TEST_FILES=" +$SRC_H5LS_TESTFILES/vds/tvds-1.ls +$SRC_H5LS_TESTFILES/vds/tvds-2.ls +$SRC_H5LS_TESTFILES/vds/tvds-3_1.ls +$SRC_H5LS_TESTFILES/vds/tvds-3_2.ls +$SRC_H5LS_TESTFILES/vds/tvds-4.ls +$SRC_H5LS_TESTFILES/vds/tvds-5.ls +" + + +# RUNSERIAL is used. Check if it can return exit code from executalbe correctly. +if [ -n "$RUNSERIAL_NOEXITCODE" ]; then + echo "***Warning*** Serial Exit Code is not passed back to shell corretly." + echo "***Warning*** Exit code checking is skipped." + h5haveexitcode=no +fi + +# +# copy test files and expected output files from source dirs to test dir +# +COPY_TESTFILES="$LIST_HDF5_TEST_FILES $LIST_OTHER_TEST_FILES" + +COPY_TESTFILES_TO_TESTDIR() +{ + # copy test files. Used -f to make sure get a new copy + for tstfile in $COPY_TESTFILES + do + # ignore '#' comment + echo $tstfile | tr -d ' ' | grep '^#' > /dev/null + RET=$? + if [ $RET -eq 1 ]; then + # skip cp if srcdir is same as destdir + # this occurs when build/test performed in source dir and + # make cp fail + SDIR=`$DIRNAME $tstfile` + INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'` + INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'` + if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then + $CP -f $tstfile $TESTDIR + if [ $? -ne 0 ]; then + echo "Error: FAILED to copy $tstfile ." + + # Comment out this to CREATE expected file + exit $EXIT_FAILURE + fi + fi + fi + done +} + +CLEAN_TESTFILES_AND_TESTDIR() +{ + # skip rm if srcdir is same as destdir + # this occurs when build/test performed in source dir and + # make cp fail + SDIR=`$DIRNAME $tstfile` + INODE_SDIR=`$LS -i -d $SDIR | $AWK -F' ' '{print $1}'` + INODE_DDIR=`$LS -i -d $TESTDIR | $AWK -F' ' '{print $1}'` + if [ "$INODE_SDIR" != "$INODE_DDIR" ]; then + $RM $TESTDIR + fi +} + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" |cut -c1-70 |tr -d '\012' +} + +# Source in the output filter function definitions. +. $srcdir/../../bin/output_filter.sh + +# Run a test and print PASS or *FAIL*. For now, if h5ls can complete +# with exit status 0, consider it pass. If a test fails then increment +# the `nerrors' global variable and (if $verbose is set) display up to $NLINS +# lines of the actual output from the tool test. The actual output is not +# removed if $HDF5_NOCLEANUP has a non-zero value. +# Arguemnts: +# $1 -- actual output filename to use +# $2 and on -- argument for the h5ls tool +TOOLTEST() { + expect="$TESTDIR/$1" + actual="$TESTDIR/`basename $1 .ls`.out" + actual_err="$TESTDIR/`basename $1 .ls`.err" + actual_sav=${actual}-sav + actual_err_sav=${actual_err}-sav + shift + retvalexpect=$1 + shift + + # Run test. + # Stderr is included in stdout so that the diff can detect + # any unexpected output from that stream too. + TESTING $H5LS $@ + ( + cd $TESTDIR + $RUNSERIAL $H5LS_BIN "$@" + ) >$actual 2>$actual_err + + exitcode=$? + # save actual and actual_err in case they are needed later. + cp $actual $actual_sav + STDOUT_FILTER $actual + cp $actual_err $actual_err_sav + STDERR_FILTER $actual_err + cat $actual_err >> $actual + if [ $h5haveexitcode = 'yes' -a $exitcode -ne $retvalexpect ]; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + if [ yes = "$verbose" ]; then + echo "test returned with exit code $exitcode" + echo "test output: (up to $NLINES lines)" + head -$NLINES $actual + echo "***end of test output***" + echo "" + fi + elif [ ! -f $expect ]; then + # Create the expect file if it doesn't yet exist. + echo " CREATED" + cp $actual $expect + elif $CMP $expect $actual; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected result differs from actual result" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual $actual_err $actual_sav $actual_err_sav + fi +} + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## +# prepare for test +COPY_TESTFILES_TO_TESTDIR + +####### test for dataset vds ###### + +TOOLTEST tvds-1.ls 0 -w80 -v -S 1_vds.h5 +TOOLTEST tvds-2.ls 0 -w80 -v -S 2_vds.h5 +TOOLTEST tvds-3_1.ls 0 -w80 -v -S 3_1_vds.h5 +TOOLTEST tvds-3_2.ls 0 -w80 -v -S 3_2_vds.h5 +TOOLTEST tvds-4.ls 0 -w80 -v -S 4_vds.h5 +TOOLTEST tvds-5.ls 0 -w80 -v -S 5_vds.h5 + +# Clean up temporary files/directories +CLEAN_TESTFILES_AND_TESTDIR + +if test $nerrors -eq 0 ; then + echo "All $TESTNAME tests passed." + exit $EXIT_SUCCESS +else + echo "$TESTNAME tests failed with $nerrors errors." + exit $EXIT_FAILURE +fi diff --git a/tools/h5repack/CMakeTests.cmake b/tools/h5repack/CMakeTests.cmake index dee97ed..caad5c1 100644 --- a/tools/h5repack/CMakeTests.cmake +++ b/tools/h5repack/CMakeTests.cmake @@ -14,14 +14,14 @@ multi family ) - + if (DIRECT_VFD) set (VFD_LIST ${VFD_LIST} direct) endif (DIRECT_VFD) MACRO (ADD_VFD_TEST vfdname resultcode) add_test ( - NAME H5REPACK-VFD-${vfdname}-h5repacktest + NAME H5REPACK-VFD-${vfdname}-h5repacktest COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$<TARGET_FILE:h5repacktest>" -D "TEST_ARGS:STRING=" @@ -37,7 +37,7 @@ set (last_test "H5REPACK-VFD-${vfdname}-h5repacktest") ENDMACRO (ADD_VFD_TEST) endif (HDF5_TEST_VFD) - + # -------------------------------------------------------------------- # Copy all the HDF5 files from the source directory into the test directory # -------------------------------------------------------------------- @@ -77,6 +77,30 @@ ${HDF5_TOOLS_SRC_DIR}/testfiles/tfamily00008.h5 ${HDF5_TOOLS_SRC_DIR}/testfiles/tfamily00009.h5 ${HDF5_TOOLS_SRC_DIR}/testfiles/tfamily00010.h5 + # tools/testfiles/vds + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_a.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_b.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_c.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_d.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_e.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_f.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/1_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_a.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_b.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_c.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_d.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_e.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/2_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/3_1_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/3_2_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_0.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_1.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_2.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/4_vds.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_a.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_b.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_c.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/vds/5_vds.h5 ) set (LIST_OTHER_TEST_FILES @@ -346,7 +370,7 @@ add_test ( NAME H5REPACK_UD-${testname}-clearall-objects COMMAND ${CMAKE_COMMAND} - -E remove + -E remove testfiles/out-${testname}.${resultfile} testfiles/${testname}.${resultfile}.out testfiles/${testname}.${resultfile}.out.err @@ -392,7 +416,7 @@ ############################################################################## # -------------------------------------------------------------------- - # test file names + # test file names # -------------------------------------------------------------------- set (INFO_FILE testfiles/h5repack.info) @@ -415,12 +439,18 @@ set (FILE18 h5repack_layout2.h5) set (FILE_REF h5repack_refs.h5) set (FILE_ATTR_REF h5repack_attr_refs.h5) - + set (FILEV1 1_vds.h5) + set (FILEV2 2_vds.h5) + set (FILEV3_1 3_1_vds.h5) + set (FILEV3_2 3_2_vds.h5) + set (FILEV4 4_vds.h5) + set (FILEV5 5_vds.h5) + # Remove any output file left over from previous test run add_test ( NAME H5REPACK-clearall-objects COMMAND ${CMAKE_COMMAND} - -E remove + -E remove ./testfiles/h5dump-help.out ./testfiles/h5repack_filters.h5-gzip_verbose_filters.out ./testfiles/h5repack_filters.h5-gzip_verbose_filters.out.err @@ -555,12 +585,41 @@ ./testfiles/out-meta_short_N.meta_short.h5 ./testfiles/out-meta_long_M.meta_long.h5 ./testfiles/out-meta_long_N.meta_long.h5 - # from the h5repacktst + ./testfiles/1_vds.h5-vds_dset_compa-v.out + ./testfiles/1_vds.h5-vds_dset_compa-v.out.err + ./testfiles/1_vds.h5-vds_dset_conti-v.out + ./testfiles/1_vds.h5-vds_dset_conti-v.out.err + ./testfiles/2_vds.h5-vds_null_compa-v.out + ./testfiles/2_vds.h5-vds_null_compa-v.out.err + ./testfiles/2_vds.h5-vds_null_conti-v.out + ./testfiles/2_vds.h5-vds_null_conti-v.out.err + ./testfiles/4_vds.h5-vds_compa-v.out + ./testfiles/4_vds.h5-vds_compa-v.out.err + ./testfiles/4_vds.h5-vds_compa_compa-v.out + ./testfiles/4_vds.h5-vds_compa_compa-v.out.err + ./testfiles/4_vds.h5-vds_compa_conti-v.out + ./testfiles/4_vds.h5-vds_compa_conti-v.out.err + ./testfiles/4_vds.h5-vds_conti-v.out + ./testfiles/4_vds.h5-vds_conti-v.out.err + ./testfiles/4_vds.h5-vds_conti_compa-v.out + ./testfiles/4_vds.h5-vds_conti_compa-v.out.err + ./testfiles/4_vds.h5-vds_conti_conti-v.out + ./testfiles/4_vds.h5-vds_conti_conti-v.out.err + ./testfiles/out-vds_compa.4_vds.h5 + ./testfiles/out-vds_compa_compa.4_vds.h5 + ./testfiles/out-vds_compa_conti.4_vds.h5 + ./testfiles/out-vds_conti.4_vds.h5 + ./testfiles/out-vds_conti_compa.4_vds.h5 + ./testfiles/out-vds_conti_conti.4_vds.h5 + ./testfiles/out-vds_dset_compa.1_vds.h5 + ./testfiles/out-vds_dset_conti.1_vds.h5 + ./testfiles/out-vds_null_compa.2_vds.h5 + ./testfiles/out-vds_null_conti.2_vds.h5 h5repack_attr.h5 h5repack_attr_out.h5 h5repack_attr_refs.h5 h5repack_big.h5 - h5repack_deflate.h5 + h5repack_deflate.h5 h5repack_deflate_out.h5 h5repack_early2.h5 h5repack_early.h5 @@ -588,7 +647,7 @@ h5repack_refs.h5 h5repack_shuffle.h5 h5repack_shuffle_out.h5 - h5repack_soffset.h5 + h5repack_soffset.h5 h5repack_soffset_out.h5 h5repack_szip.h5 h5repack_szip_out.h5 @@ -628,14 +687,14 @@ # Each run generates "<file>.out.h5" and the tool h5diff is used to # compare the input and output files # -# the tests are the same as the program h5repacktst, but run from the CLI +# the tests are the same as the program h5repacktst, but run from the CLI # # See which filters are usable (and skip tests for filters we # don't have). Do this by searching H5pubconf.h to see which # filters are defined. -# detect whether the encoder is present. +# detect whether the encoder is present. set (USE_FILTER_SZIP_ENCODER "no") if (HDF5_ENABLE_SZIP_ENCODING) set (USE_FILTER_SZIP_ENCODER ${testh5repack_detect_szip}) @@ -649,7 +708,7 @@ set (USE_FILTER_SZIP "true") endif (H5_HAVE_FILTER_SZIP) -# copy files (these files have no filters) +# copy files (these files have no filters) ADD_H5_TEST (fill "TEST" ${FILE0}) ADD_H5_TEST (objs "TEST" ${FILE1}) ADD_H5_TEST (attr "TEST" ${FILE2}) @@ -666,8 +725,8 @@ set (TESTTYPE "SKIP") endif (NOT USE_FILTER_DEFLATE) ADD_H5_TEST (gzip_individual ${TESTTYPE} ${arg}) - -# gzip for all + +# gzip for all set (arg ${FILE4} -f GZIP=1) set (TESTTYPE "TEST") if (NOT USE_FILTER_DEFLATE) @@ -681,7 +740,7 @@ if (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP) set (TESTTYPE "SKIP") endif (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP) - ADD_H5_TEST (szip_individual ${TESTTYPE} ${arg}) + ADD_H5_TEST (szip_individual ${TESTTYPE} ${arg}) # szip for all set (arg ${FILE4} -f SZIP=8,NN) @@ -689,16 +748,16 @@ if (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP) set (TESTTYPE "SKIP") endif (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP) - ADD_H5_TEST (szip_all ${TESTTYPE} ${arg}) + ADD_H5_TEST (szip_all ${TESTTYPE} ${arg}) # shuffle with individual object set (arg ${FILE4} -f dset2:SHUF -l dset2:CHUNK=20x10) - ADD_H5_TEST (shuffle_individual "TEST" ${arg}) + ADD_H5_TEST (shuffle_individual "TEST" ${arg}) # shuffle for all set (arg ${FILE4} -f SHUF) ADD_H5_TEST (shuffle_all "TEST" ${arg}) - + # fletcher32 with individual object set (arg ${FILE4} -f dset2:FLET -l dset2:CHUNK=20x10) ADD_H5_TEST (fletcher_individual "TEST" ${arg}) @@ -722,7 +781,7 @@ set (TESTTYPE "SKIP") endif (NOT USE_FILTER_DEFLATE) ADD_H5_CMP_TEST (gzip_verbose_filters "O?...ing file[^\n]+\n" ${TESTTYPE} 0 ${arg}) - + ########################################################### # the following tests assume the input files have filters ########################################################### @@ -734,7 +793,7 @@ set (TESTTYPE "SKIP") endif (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP) ADD_H5_TEST (szip_copy ${TESTTYPE} ${arg}) - + # szip remove set (arg ${FILE7} --filter=dset_szip:NONE) set (TESTTYPE "TEST") @@ -742,7 +801,7 @@ set (TESTTYPE "SKIP") endif (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP) ADD_H5_TEST (szip_remove ${TESTTYPE} ${arg}) - + # deflate copy set (arg ${FILE8}) set (TESTTYPE "TEST") @@ -758,7 +817,7 @@ set (TESTTYPE "SKIP") endif (NOT USE_FILTER_DEFLATE) ADD_H5_TEST (deflate_remove ${TESTTYPE} ${arg}) - + # shuffle copy set (arg ${FILE9}) ADD_H5_TEST (shuffle_copy "TEST" ${arg}) @@ -813,14 +872,14 @@ if (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP OR NOT USE_FILTER_DEFLATE) set (TESTTYPE "SKIP") endif (NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_SZIP OR NOT USE_FILTER_DEFLATE) - ADD_H5_TEST (deflate_convert ${TESTTYPE} ${arg}) + ADD_H5_TEST (deflate_convert ${TESTTYPE} ${arg}) set (arg ${FILE7} -f dset_szip:GZIP=1) set (TESTTYPE "TEST") if (NOT USE_FILTER_SZIP OR NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_DEFLATE) set (TESTTYPE "SKIP") endif (NOT USE_FILTER_SZIP OR NOT USE_FILTER_SZIP_ENCODER OR NOT USE_FILTER_DEFLATE) - ADD_H5_TEST (szip_convert ${TESTTYPE} ${arg}) + ADD_H5_TEST (szip_convert ${TESTTYPE} ${arg}) #limit set (arg ${FILE4} -f GZIP=1 -m 1024) @@ -836,7 +895,7 @@ if (NOT USE_FILTER_DEFLATE) set (TESTTYPE "SKIP") endif (NOT USE_FILTER_DEFLATE) - ADD_H5_TEST (deflate_file ${TESTTYPE} ${arg}) + ADD_H5_TEST (deflate_file ${TESTTYPE} ${arg}) ######################################################### # layout options (these files have no filters) @@ -865,18 +924,18 @@ ADD_H5_VERIFY_TEST (contig_small_compa "TEST" 0 ${FILE18} contig_small COMPACT -l contig_small:COMPA) ADD_H5_VERIFY_TEST (contig_small_fixed_compa "TEST" 0 ${FILE18} chunked_small_fixed COMPACT -l chunked_small_fixed:COMPA) -#--------------------------------------------------------------------------- -# Test file contains chunked datasets (need multiple dsets) with +#--------------------------------------------------------------------------- +# Test file contains chunked datasets (need multiple dsets) with # unlimited max dims. (HDFFV-7933) # Use first dset to test. #--------------------------------------------------------------------------- # chunk to chunk - specify chunk dim bigger than any current dim ADD_H5_VERIFY_TEST (chunk2chunk "TEST" 0 h5repack_layout3.h5 chunk_unlimit1 CHUNK -l chunk_unlimit1:CHUNK=100x300) -# chunk to contiguous +# chunk to contiguous ADD_H5_VERIFY_TEST (chunk2conti "TEST" 0 h5repack_layout3.h5 chunk_unlimit1 CONTI -l chunk_unlimit1:CONTI) -# chunk to compact - convert big dataset (should be > 64k) for this purpose, +# chunk to compact - convert big dataset (should be > 64k) for this purpose, # should remain as original layout (chunk) ADD_H5_VERIFY_TEST (chunk2compa "TEST" 0 h5repack_layout3.h5 chunk_unlimit1 CHUNK -l chunk_unlimit1:COMPA) @@ -884,7 +943,7 @@ # Test -f for some specific cases. Chunked dataset with unlimited max dims. # (HDFFV-8012) #-------------------------------------------------------------------------- -# - should not fail +# - should not fail # - should not change max dims from unlimit # chunk dim is bigger than dataset dim. ( dset size < 64k ) @@ -900,13 +959,13 @@ ADD_H5_TEST (error4 "TEST" h5repack_layout3.h5 -f NONE) #-------------------------------------------------------------------------- -# Test base: Convert CHUNK to CONTI for a chunked dataset with small dataset +# Test base: Convert CHUNK to CONTI for a chunked dataset with small dataset # (dset size < 64K) and with unlimited max dims on a condition as follow. # (HDFFV-8214) #-------------------------------------------------------------------------- # chunk dim is bigger than dataset dim. should succeed. ADD_H5_VERIFY_TEST (ckdim_biger "TEST" 0 h5repack_layout3.h5 chunk_unlimit2 CONTI -l chunk_unlimit2:CONTI) -# chunk dim is smaller than dataset dim. should succeed. +# chunk dim is smaller than dataset dim. should succeed. ADD_H5_VERIFY_TEST (ckdim_smaller "TEST" 0 h5repack_layout3.h5 chunk_unlimit3 CONTI -l chunk_unlimit3:CONTI) @@ -975,11 +1034,11 @@ ADD_H5_TEST (bug1814 "TEST" ${FILE_REF}) # test attribute with various references (bug1797 / HDFFV-5932) -# the references in attribute of compund or vlen datatype +# the references in attribute of compund or vlen datatype ADD_H5_TEST (HDFFV-5932 "TEST" ${FILE_ATTR_REF}) -# Add test for memory leak in attirbute. This test is verified by CTEST. -# 1. leak from vlen string +# Add test for memory leak in attirbute. This test is verified by CTEST. +# 1. leak from vlen string # 2. leak from compound type without reference member # (HDFFV-7840, ) # Note: this test is experimental for sharing test file among tools @@ -989,6 +1048,26 @@ ADD_H5_TEST_META (meta_short h5repack_layout.h5 -M 8192) ADD_H5_TEST_META (meta_long h5repack_layout.h5 --metadata_block_size=8192) +# VDS tests + +######################################################### +# layout options +######################################################### + ADD_H5_VERIFY_TEST (vds_dset_conti "TEST" 0 ${FILEV1} vds_dset CONTIGUOUS -l vds_dset:CONTI) + ADD_H5_VERIFY_TEST (vds_null_conti "TEST" 1 ${FILEV2} null CONTIGUOUS -l CONTI) + ADD_H5_VERIFY_TEST (vds_dset_compa "TEST" 0 ${FILEV1} vds_dset COMPACT -l vds_dset:COMPA) + ADD_H5_VERIFY_TEST (vds_null_compa "TEST" 1 ${FILEV2} null COMPACT -l COMPA) + +################################################################ +# layout conversions +############################################################### + ADD_H5_VERIFY_TEST (vds_compa_conti "TEST" 0 ${FILEV4} vds_dset CONTIGUOUS -l vds_dset:CONTI) + ADD_H5_VERIFY_TEST (vds_compa_compa "TEST" 0 ${FILEV4} vds_dset COMPACT -l vds_dset:COMPA) + ADD_H5_VERIFY_TEST (vds_conti_compa "TEST" 0 ${FILEV4} vds_dset COMPACT -l vds_dset:COMPA) + ADD_H5_VERIFY_TEST (vds_conti_conti "TEST" 0 ${FILEV4} vds_dset CONTIGUOUS -l vds_dset:CONTI) + ADD_H5_VERIFY_TEST (vds_compa "TEST" 0 ${FILEV4} vds_dset COMPACT -l vds_dset:COMPA) + ADD_H5_VERIFY_TEST (vds_conti "TEST" 0 ${FILEV4} vds_dset CONTIGUOUS -l vds_dset:CONTI) + ############################################################################## ### P L U G I N T E S T S ############################################################################## diff --git a/tools/h5repack/h5repack.sh.in b/tools/h5repack/h5repack.sh.in index 1796151..24298d0 100644 --- a/tools/h5repack/h5repack.sh.in +++ b/tools/h5repack/h5repack.sh.in @@ -113,6 +113,29 @@ $SRC_TOOLS_TESTFILES/tfamily00007.h5 $SRC_TOOLS_TESTFILES/tfamily00008.h5 $SRC_TOOLS_TESTFILES/tfamily00009.h5 $SRC_TOOLS_TESTFILES/tfamily00010.h5 +$SRC_TOOLS_TESTFILES/vds/1_a.h5 +$SRC_TOOLS_TESTFILES/vds/1_b.h5 +$SRC_TOOLS_TESTFILES/vds/1_c.h5 +$SRC_TOOLS_TESTFILES/vds/1_d.h5 +$SRC_TOOLS_TESTFILES/vds/1_e.h5 +$SRC_TOOLS_TESTFILES/vds/1_f.h5 +$SRC_TOOLS_TESTFILES/vds/1_vds.h5 +$SRC_TOOLS_TESTFILES/vds/2_a.h5 +$SRC_TOOLS_TESTFILES/vds/2_b.h5 +$SRC_TOOLS_TESTFILES/vds/2_c.h5 +$SRC_TOOLS_TESTFILES/vds/2_d.h5 +$SRC_TOOLS_TESTFILES/vds/2_e.h5 +$SRC_TOOLS_TESTFILES/vds/2_vds.h5 +$SRC_TOOLS_TESTFILES/vds/3_1_vds.h5 +$SRC_TOOLS_TESTFILES/vds/3_2_vds.h5 +$SRC_TOOLS_TESTFILES/vds/4_0.h5 +$SRC_TOOLS_TESTFILES/vds/4_1.h5 +$SRC_TOOLS_TESTFILES/vds/4_2.h5 +$SRC_TOOLS_TESTFILES/vds/4_vds.h5 +$SRC_TOOLS_TESTFILES/vds/5_a.h5 +$SRC_TOOLS_TESTFILES/vds/5_b.h5 +$SRC_TOOLS_TESTFILES/vds/5_c.h5 +$SRC_TOOLS_TESTFILES/vds/5_vds.h5 " LIST_OTHER_TEST_FILES=" @@ -1063,6 +1086,26 @@ TOOLTEST HDFFV-7840 h5diff_attr1.h5 TOOLTEST_META meta_short h5repack_layout.h5 -M 8192 TOOLTEST_META meta_long h5repack_layout.h5 --metadata_block_size=8192 +# VDS tests + +######################################################### +# layout options +######################################################### +VERIFY_LAYOUT_DSET vds_dset_conti 1_vds.h5 vds_dset CONTIGUOUS -l vds_dset:CONTI +VERIFY_LAYOUT_ALL vds_null_conti 2_vds.h5 CONTIGUOUS -l CONTI +VERIFY_LAYOUT_DSET vds_dset_compa 1_vds.h5 vds_dset COMPACT -l vds_dset:COMPA +VERIFY_LAYOUT_ALL vds_null_compa 2_vds.h5 COMPACT -l COMPA + +################################################################ +# layout conversions +############################################################### +VERIFY_LAYOUT_DSET vds_compa_conti 4_vds.h5 vds_dset CONTIGUOUS -l vds_dset:CONTI +VERIFY_LAYOUT_DSET vds_compa_compa 4_vds.h5 vds_dset COMPACT -l vds_dset:COMPA +VERIFY_LAYOUT_DSET vds_conti_compa 4_vds.h5 vds_dset COMPACT -l vds_dset:COMPA +VERIFY_LAYOUT_DSET vds_conti_conti 4_vds.h5 vds_dset CONTIGUOUS -l vds_dset:CONTI +VERIFY_LAYOUT_DSET vds_compa 4_vds.h5 vds_dset COMPACT -l vds_dset:COMPA +VERIFY_LAYOUT_DSET vds_conti 4_vds.h5 vds_dset CONTIGUOUS -l vds_dset:CONTI + # Clean up temporary files/directories CLEAN_TESTFILES_AND_TESTDIR diff --git a/tools/h5stat/h5stat.c b/tools/h5stat/h5stat.c index c19aba5..ac6ca23 100644 --- a/tools/h5stat/h5stat.c +++ b/tools/h5stat/h5stat.c @@ -1342,8 +1342,8 @@ print_dataset_info(const iter_t *iter) printf("Dataset layout information:\n"); for(u = 0; u < H5D_NLAYOUTS; u++) - printf("\tDataset layout counts[%s]: %lu\n", (u == 0 ? "COMPACT" : - (u == 1 ? "CONTIG" : "CHUNKED")), iter->dset_layouts[u]); + printf("\tDataset layout counts[%s]: %lu\n", (u == H5D_COMPACT ? "COMPACT" : + (u == H5D_CONTIGUOUS ? "CONTIG" : (u == H5D_CHUNKED ? "CHUNKED" : "VIRTUAL"))), iter->dset_layouts[u]); printf("\tNumber of external files : %lu\n", iter->nexternal); printf("Dataset filters information:\n"); diff --git a/tools/h5stat/testfiles/h5stat_dims1.ddl b/tools/h5stat/testfiles/h5stat_dims1.ddl index c285ea4..07b2900 100644 --- a/tools/h5stat/testfiles/h5stat_dims1.ddl +++ b/tools/h5stat/testfiles/h5stat_dims1.ddl @@ -31,6 +31,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_dims2.ddl b/tools/h5stat/testfiles/h5stat_dims2.ddl index 769749e..dbccd05 100644 --- a/tools/h5stat/testfiles/h5stat_dims2.ddl +++ b/tools/h5stat/testfiles/h5stat_dims2.ddl @@ -22,6 +22,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_filters-d.ddl b/tools/h5stat/testfiles/h5stat_filters-d.ddl index 2e0bd64..6e6dd61 100644 --- a/tools/h5stat/testfiles/h5stat_filters-d.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-d.ddl @@ -18,6 +18,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 2 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_filters-dT.ddl b/tools/h5stat/testfiles/h5stat_filters-dT.ddl index 9ef3e82..b14ca9f 100644 --- a/tools/h5stat/testfiles/h5stat_filters-dT.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-dT.ddl @@ -18,6 +18,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 2 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_filters.ddl b/tools/h5stat/testfiles/h5stat_filters.ddl index 24522cd..1a4fd72 100644 --- a/tools/h5stat/testfiles/h5stat_filters.ddl +++ b/tools/h5stat/testfiles/h5stat_filters.ddl @@ -56,6 +56,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 2 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_links2.ddl b/tools/h5stat/testfiles/h5stat_links2.ddl index 09bf937..4622884 100644 --- a/tools/h5stat/testfiles/h5stat_links2.ddl +++ b/tools/h5stat/testfiles/h5stat_links2.ddl @@ -64,6 +64,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_newgrat.ddl b/tools/h5stat/testfiles/h5stat_newgrat.ddl index 33d756b..e305f58 100644 --- a/tools/h5stat/testfiles/h5stat_newgrat.ddl +++ b/tools/h5stat/testfiles/h5stat_newgrat.ddl @@ -54,6 +54,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 1 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_numattrs2.ddl b/tools/h5stat/testfiles/h5stat_numattrs2.ddl index 1313aec..ccb23c1 100644 --- a/tools/h5stat/testfiles/h5stat_numattrs2.ddl +++ b/tools/h5stat/testfiles/h5stat_numattrs2.ddl @@ -65,6 +65,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_tsohm.ddl b/tools/h5stat/testfiles/h5stat_tsohm.ddl index 37de79b..4cf33fc 100644 --- a/tools/h5stat/testfiles/h5stat_tsohm.ddl +++ b/tools/h5stat/testfiles/h5stat_tsohm.ddl @@ -53,6 +53,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 0 Dataset layout counts[CHUNKED]: 3 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index ff7cf12..d2e3ea6 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -93,6 +93,16 @@ #define PACKED_BITS "PACKED_BITS" #define PACKED_OFFSET "OFFSET" #define PACKED_LENGTH "LENGTH" +#define VDS_VIRTUAL "VIRTUAL" +#define VDS_MAPPING "MAPPING" +#define VDS_SOURCE "SOURCE" +#define VDS_REG_HYPERSLAB "SELECTION REGULAR_HYPERSLAB" +#define VDS_IRR_HYPERSLAB "SELECTION IRREGULAR_HYPERSLAB" +#define VDS_POINT "POINT" +#define VDS_SRC_FILE "FILE" +#define VDS_SRC_DATASET "DATASET" +#define VDS_NONE "SELECTION NONE" +#define VDS_ALL "SELECTION ALL" #define BEGIN "{" #define END "}" @@ -182,6 +192,15 @@ typedef struct h5tools_dump_header_t { const char *dataspacedimbegin; const char *dataspacedimend; + const char *virtualselectionbegin; + const char *virtualselectionend; + const char *virtualselectionblockbegin; + const char *virtualselectionblockend; + const char *virtualfilenamebegin; + const char *virtualfilenameend; + const char *virtualdatasetnamebegin; + const char *virtualdatasetnameend; + } h5tools_dump_header_t; /* diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index 1e6e9d6..0d39981 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -179,6 +179,15 @@ BLOCK, /*blockbegin */ "", /*dataspacedescriptionend */ "(", /*dataspacedimbegin */ ")", /*dataspacedimend */ + +"", /*virtualselectionbegin */ +"", /*virtualselectionend */ +"{", /*virtualselectionblockbegin */ +"}", /*virtualselectionblockend */ +"\"", /*virtualfilenamebeginbegin */ +"\"", /*virtualfilenamebeginend */ +"\"", /*virtualdatasetnamebegin */ +"\"", /*virtualdtatasetnameend */ }; const h5tools_dump_header_t* h5tools_dump_header_format; @@ -216,6 +225,13 @@ void h5tools_print_dims(h5tools_str_t *buffer, hsize_t *s, int dims); void h5tools_dump_subsetting_header(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, struct subset_t *sset, int dims); +static void h5tools_print_virtual_selection(hid_t vspace, + FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols); + void h5tools_dump_init(void) { @@ -1523,6 +1539,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont /* Hyperslab info */ hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ + //hsize_t hs_count[H5S_MAX_RANK]; /* size this pass */ hsize_t hs_nelmts; /* elements in request */ /* VL data special information */ @@ -1605,9 +1622,11 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont hs_size[i] = MIN(total_size[i] - hs_offset[i], sm_size[i]); ctx->p_max_idx[i] = ctx->p_min_idx[i] + hs_size[i]; hs_nelmts *= hs_size[i]; +// hs_count[i] = 1; } H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL); +// H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_count, hs_size); H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL); } else { @@ -2844,7 +2863,78 @@ h5tools_dump_oid(FILE *stream, const h5tool_format_t *info, h5tools_str_close(&buffer); } +/*------------------------------------------------------------------------- + * Function: print_virtual_selection + * + * Purpose: Print the virtual dataset selection. + * + * Return: void + *------------------------------------------------------------------------- + */ +static void +h5tools_print_virtual_selection(hid_t vspace, + FILE *stream, const h5tool_format_t *info, + h5tools_context_t *ctx/*in,out*/, + h5tools_str_t *buffer/*string into which to render */, + hsize_t *curr_pos/*total data element position*/, + size_t ncols) +{ + switch(H5Sget_select_type(vspace)) { + case H5S_SEL_NONE: /* Nothing selected */ + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, *curr_pos, 0); + + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s", VDS_NONE); + break; + case H5S_SEL_POINTS: /* Sequence of points selected */ + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s %s ", VDS_POINT, h5tools_dump_header_format->virtualselectionblockbegin); + h5tools_str_dump_space_points(buffer, vspace, info); + h5tools_str_append(buffer, " %s", h5tools_dump_header_format->virtualselectionblockend); + break; + case H5S_SEL_HYPERSLABS: /* "New-style" hyperslab selection defined */ + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, *curr_pos, 0); + + h5tools_str_reset(buffer); + if (H5Sis_regular_hyperslab(vspace)) { + h5tools_str_append(buffer, "%s %s ", VDS_REG_HYPERSLAB, h5tools_dump_header_format->virtualselectionblockbegin); + h5tools_render_element(stream, info, ctx, buffer, curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + h5tools_str_reset(buffer); + h5tools_str_dump_space_slabs(buffer, vspace, info, ctx); + } + else { + h5tools_str_append(buffer, "%s %s ", VDS_IRR_HYPERSLAB, h5tools_dump_header_format->virtualselectionblockbegin); + h5tools_render_element(stream, info, ctx, buffer, curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, *curr_pos, 0); + + h5tools_str_reset(buffer); + h5tools_str_dump_space_blocks(buffer, vspace, info); + ctx->indent_level--; + } + h5tools_render_element(stream, info, ctx, buffer, curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, *curr_pos, 0); + + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s", h5tools_dump_header_format->virtualselectionblockend); + break; + case H5S_SEL_ALL: /* Entire extent selected */ + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, *curr_pos, 0); + h5tools_str_reset(buffer); + h5tools_str_append(buffer, "%s", VDS_ALL); + break; + default: + h5tools_str_append(buffer, "Unknown Selection"); + } + h5tools_render_element(stream, info, ctx, buffer, curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); +} /*------------------------------------------------------------------------- * Function: dump_fill_value @@ -2932,14 +3022,13 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, h5tools_str_append(&buffer, "%s %s", STORAGE_LAYOUT, BEGIN); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t)ncols, (hsize_t)0, (hsize_t)0); - ctx->indent_level++; - - ctx->need_prefix = TRUE; - h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); - stl = H5Pget_layout(dcpl_id); switch (stl) { case H5D_CHUNKED: + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "%s ", CHUNKED); @@ -3002,8 +3091,13 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, h5tools_str_append(&buffer, "SIZE " HSIZE_T_FORMAT, storage_size); } h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + ctx->indent_level--; break; case H5D_COMPACT: + ctx->indent_level++; + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "%s", COMPACT); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); @@ -3014,6 +3108,7 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "SIZE " HSIZE_T_FORMAT, storage_size); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + ctx->indent_level--; break; case H5D_CONTIGUOUS: { @@ -3025,7 +3120,11 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, * EXTERNAL_FILE *------------------------------------------------------------------------- */ + ctx->indent_level++; if (next) { + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "%s", CONTIGUOUS); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); @@ -3061,6 +3160,9 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, else { haddr_t ioffset; + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "%s", CONTIGUOUS); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); @@ -3080,8 +3182,116 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, h5tools_str_append(&buffer, "OFFSET "H5_PRINTF_HADDR_FMT, ioffset); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); } + ctx->indent_level--; } break; + + case H5D_VIRTUAL: + { + char dsetname[256]; /* virtual datset name */ + size_t vmaps; + + H5Pget_virtual_count(dcpl_id, &vmaps); + + if (vmaps) { + size_t next; + ssize_t ssize_out; + + ctx->indent_level++; + for (next = 0; next < (unsigned) vmaps; next++) { + hid_t virtual_vspace = H5Pget_virtual_vspace(dcpl_id, next); + hid_t virtual_srcspace = H5Pget_virtual_srcspace(dcpl_id, next); + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s %ld %s ", VDS_MAPPING, next, BEGIN); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + ctx->indent_level++; + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s %s", VDS_VIRTUAL, BEGIN); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + ctx->indent_level++; + + h5tools_print_virtual_selection(virtual_vspace, stream, info, ctx, &buffer, &curr_pos, (size_t) ncols); + + ctx->indent_level--; + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s", END); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s %s", VDS_SOURCE, BEGIN); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + ctx->indent_level++; + + ssize_out = H5Pget_virtual_filename(dcpl_id, next, NULL, 0); + HDassert(ssize_out > 0); + HDassert((size_t)ssize_out < sizeof(name)); + H5Pget_virtual_filename(dcpl_id, next, name, sizeof(name)); + ssize_out = H5Pget_virtual_dsetname(dcpl_id, next, NULL, 0); + HDassert(ssize_out > 0); + HDassert((size_t)ssize_out < sizeof(name)); + H5Pget_virtual_dsetname(dcpl_id, next, dsetname, sizeof(dsetname)); + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s %s", VDS_SRC_FILE, h5tools_dump_header_format->virtualfilenamebegin); + h5tools_str_append(&buffer, "%s", name); + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->virtualfilenameend); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s %s", VDS_SRC_DATASET, h5tools_dump_header_format->virtualdatasetnamebegin); + h5tools_str_append(&buffer, "%s", dsetname); + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->virtualdatasetnameend); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + h5tools_print_virtual_selection(virtual_srcspace, stream, info, ctx, &buffer, &curr_pos, (size_t) ncols); + + ctx->indent_level--; + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s", END); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + + ctx->indent_level--; + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "%s", END); + h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); + } + ctx->indent_level--; + } + } + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -3090,8 +3300,6 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, (size_t) ncols, (hsize_t) 0, (hsize_t) 0); }/*switch*/ - ctx->indent_level--; - ctx->need_prefix = TRUE; h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 9d151d0..bdb82a4 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -413,9 +413,9 @@ h5tools_str_region_prefix(h5tools_str_t *str, const h5tool_format_t *info, } /*------------------------------------------------------------------------- - * Function: h5tools_str_dump_region_blocks + * Function: h5tools_str_dump_space_slabs * - * Purpose: Prints information about a dataspace region by appending + * Purpose: Prints information about a dataspace selection by appending * the information to the specified string. * * Return: none @@ -426,19 +426,85 @@ h5tools_str_region_prefix(h5tools_str_t *str, const h5tool_format_t *info, *------------------------------------------------------------------------- */ void -h5tools_str_dump_region_blocks(h5tools_str_t *str, hid_t region, +h5tools_str_dump_space_slabs(h5tools_str_t *str, hid_t rspace, + const h5tool_format_t *info, h5tools_context_t *ctx) +{ + hsize_t start[H5S_MAX_RANK]; + hsize_t stride[H5S_MAX_RANK]; + hsize_t count[H5S_MAX_RANK]; + hsize_t block[H5S_MAX_RANK]; + int j; + int ndims = H5Sget_simple_extent_ndims(rspace); + + H5Sget_regular_hyperslab(rspace, start, stride, count, block); + + /* Print hyperslab information */ + + /* Start coordinates */ + h5tools_str_append(str, "%s%s ", info->line_indent, START); + for (j = 0; j < ndims; j++) + h5tools_str_append(str, "%s" HSIZE_T_FORMAT, j ? "," : "(", start[j]); + h5tools_str_append(str, ")"); + h5tools_str_append(str, "%s", "\n"); + h5tools_str_indent(str, info, ctx); + + /* Stride coordinates */ + h5tools_str_append(str, "%s ", STRIDE); + for (j = 0; j < ndims; j++) + h5tools_str_append(str, "%s" HSIZE_T_FORMAT, j ? "," : "(", stride[j]); + h5tools_str_append(str, ")"); + h5tools_str_append(str, "%s", "\n"); + h5tools_str_indent(str, info, ctx); + + /* Count coordinates */ + h5tools_str_append(str, "%s ", COUNT); + for (j = 0; j < ndims; j++) { + if(count[j] == H5S_UNLIMITED) + h5tools_str_append(str, "%s%s", j ? "," : "(","H5S_UNLIMITED"); + else + h5tools_str_append(str, "%s" HSIZE_T_FORMAT, j ? "," : "(", count[j]); + } + h5tools_str_append(str, ")"); + h5tools_str_append(str, "%s", "\n"); + h5tools_str_indent(str, info, ctx); + + /* Block coordinates */ + h5tools_str_append(str, "%s ", BLOCK); + for (j = 0; j < ndims; j++) { + if(block[j] == H5S_UNLIMITED) + h5tools_str_append(str, "%s%s", j ? "," : "(","H5S_UNLIMITED"); + else + h5tools_str_append(str, "%s" HSIZE_T_FORMAT, j ? "," : "(", block[j]); + } + h5tools_str_append(str, ")"); +} + +/*------------------------------------------------------------------------- + * Function: h5tools_str_dump_space_blocks + * + * Purpose: Prints information about a dataspace selection by appending + * the information to the specified string. + * + * Return: none + * + * In/Out: + * h5tools_str_t *str + *------------------------------------------------------------------------- + */ +void +h5tools_str_dump_space_blocks(h5tools_str_t *str, hid_t rspace, const h5tool_format_t *info) { hssize_t nblocks; hsize_t alloc_size; hsize_t *ptdata; - int ndims = H5Sget_simple_extent_ndims(region); + int ndims = H5Sget_simple_extent_ndims(rspace); /* - * This function fails if the region does not have blocks. + * This function fails if the rspace does not have blocks. */ H5E_BEGIN_TRY { - nblocks = H5Sget_select_hyper_nblocks(region); + nblocks = H5Sget_select_hyper_nblocks(rspace); } H5E_END_TRY; /* Print block information */ @@ -449,7 +515,7 @@ h5tools_str_dump_region_blocks(h5tools_str_t *str, hid_t region, HDassert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ ptdata = (hsize_t *)HDmalloc((size_t) alloc_size); H5_CHECK_OVERFLOW(nblocks, hssize_t, hsize_t); - H5Sget_select_hyper_blocklist(region, (hsize_t)0, (hsize_t)nblocks, ptdata); + H5Sget_select_hyper_blocklist(rspace, (hsize_t)0, (hsize_t)nblocks, ptdata); for (i = 0; i < nblocks; i++) { int j; @@ -473,32 +539,31 @@ h5tools_str_dump_region_blocks(h5tools_str_t *str, hid_t region, } /*------------------------------------------------------------------------- - * Function: h5tools_str_dump_region_points + * Function: h5tools_str_dump_space_points * - * Purpose: Prints information about a dataspace region by appending + * Purpose: Prints information about a dataspace selection by appending * the information to the specified string. * * Return: none * * In/Out: - * h5tools_context_t *ctx * h5tools_str_t *str *------------------------------------------------------------------------- */ void -h5tools_str_dump_region_points(h5tools_str_t *str, hid_t region, +h5tools_str_dump_space_points(h5tools_str_t *str, hid_t rspace, const h5tool_format_t *info) { hssize_t npoints; hsize_t alloc_size; hsize_t *ptdata; - int ndims = H5Sget_simple_extent_ndims(region); + int ndims = H5Sget_simple_extent_ndims(rspace); /* - * This function fails if the region does not have points. + * This function fails if the rspace does not have points. */ H5E_BEGIN_TRY { - npoints = H5Sget_select_elem_npoints(region); + npoints = H5Sget_select_elem_npoints(rspace); } H5E_END_TRY; /* Print point information */ @@ -509,7 +574,7 @@ h5tools_str_dump_region_points(h5tools_str_t *str, hid_t region, HDassert(alloc_size == (hsize_t) ((size_t) alloc_size)); /*check for overflow*/ ptdata = (hsize_t *)HDmalloc((size_t) alloc_size); H5_CHECK_OVERFLOW(npoints, hssize_t, hsize_t); - H5Sget_select_elem_pointlist(region, (hsize_t)0, (hsize_t)npoints, ptdata); + H5Sget_select_elem_pointlist(rspace, (hsize_t)0, (hsize_t)npoints, ptdata); for (i = 0; i < npoints; i++) { int j; @@ -1243,9 +1308,9 @@ h5tools_str_sprint_region(h5tools_str_t *str, const h5tool_format_t *info, region_type = H5Sget_select_type(region); if(region_type==H5S_SEL_POINTS) - h5tools_str_dump_region_points(str, region, info); + h5tools_str_dump_space_points(str, region, info); else - h5tools_str_dump_region_blocks(str, region, info); + h5tools_str_dump_space_blocks(str, region, info); h5tools_str_append(str, "}"); diff --git a/tools/lib/h5tools_str.h b/tools/lib/h5tools_str.h index 38697c6..6173b89 100644 --- a/tools/lib/h5tools_str.h +++ b/tools/lib/h5tools_str.h @@ -40,8 +40,9 @@ H5TOOLS_DLL char *h5tools_str_prefix(h5tools_str_t *str, const h5tool_format_ H5TOOLS_DLL char *h5tools_str_region_prefix(h5tools_str_t *str, const h5tool_format_t *info, hsize_t elmtno, hsize_t *ptdata, unsigned ndims, hsize_t max_idx[], h5tools_context_t *ctx); -H5TOOLS_DLL void h5tools_str_dump_region_blocks(h5tools_str_t *, hid_t, const h5tool_format_t *); -H5TOOLS_DLL void h5tools_str_dump_region_points(h5tools_str_t *, hid_t, const h5tool_format_t *); +H5TOOLS_DLL void h5tools_str_dump_space_slabs(h5tools_str_t *, hid_t, const h5tool_format_t *, h5tools_context_t *ctx); +H5TOOLS_DLL void h5tools_str_dump_space_blocks(h5tools_str_t *, hid_t, const h5tool_format_t *); +H5TOOLS_DLL void h5tools_str_dump_space_points(h5tools_str_t *, hid_t, const h5tool_format_t *); H5TOOLS_DLL void h5tools_str_sprint_region(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, void *vp); H5TOOLS_DLL char *h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, diff --git a/tools/misc/CMakeLists.txt b/tools/misc/CMakeLists.txt index d53cdc8..088dbdf 100644 --- a/tools/misc/CMakeLists.txt +++ b/tools/misc/CMakeLists.txt @@ -52,6 +52,9 @@ if (BUILD_TESTING) target_link_libraries (h5repart_gentest ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) set_target_properties (h5repart_gentest PROPERTIES FOLDER generator/tools) #add_test (NAME h5repart_gentest COMMAND $<TARGET_FILE:h5repart_gentest>) + + add_subdirectory (${HDF5_TOOLS_MISC_SOURCE_DIR}/vds) + endif (HDF5_BUILD_GENERATORS) add_executable (h5repart_test ${HDF5_TOOLS_MISC_SOURCE_DIR}/repart_test.c) diff --git a/tools/misc/Makefile.am b/tools/misc/Makefile.am index 53b1872..fdfe8f7 100644 --- a/tools/misc/Makefile.am +++ b/tools/misc/Makefile.am @@ -20,6 +20,8 @@ include $(top_srcdir)/config/commence.am +SUBDIRS=vds + # Include src directory AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib diff --git a/tools/misc/vds/CMakeLists.txt b/tools/misc/vds/CMakeLists.txt new file mode 100644 index 0000000..dcf883c --- /dev/null +++ b/tools/misc/vds/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required (VERSION 3.1.0) +PROJECT (HDF5_TOOLS_MISC_VDS) + +#----------------------------------------------------------------------------- +# Setup include Directories +#----------------------------------------------------------------------------- +INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) + +MACRO (ADD_H5_GENERATOR genfile) + add_executable (${genfile} ${HDF5_TOOLS_MISC_VDS_SOURCE_DIR}/${genfile}.c) + TARGET_NAMING (${genfile} STATIC) + TARGET_C_PROPERTIES (${genfile} STATIC " " " ") + target_link_libraries (${genfile} ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) + set_target_properties (${genfile} PROPERTIES FOLDER generator/tools) +ENDMACRO (ADD_H5_GENERATOR genfile) + +# generator executables +set (H5_GENERATORS + UC_1_one_dim_gen + UC_2_two_dims_gen + UC_3_gaps_gen + UC_4_printf_gen + UC_5_stride_gen +) + +foreach (gen ${H5_GENERATORS}) + ADD_H5_GENERATOR (${gen}) +endforeach (gen ${H5_GENERATORS}) diff --git a/tools/misc/vds/Makefile.am b/tools/misc/vds/Makefile.am new file mode 100644 index 0000000..f1ef80c --- /dev/null +++ b/tools/misc/vds/Makefile.am @@ -0,0 +1,38 @@ +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +## +## Makefile.am +## Run automake to generate a Makefile.in from this file. +# +# HDF5 Library Makefile(.in) +# + +include $(top_srcdir)/config/commence.am + +# Include src directory +AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib + +#test scripts and programs +TEST_PROG=UC_1_one_dim_gen UC_2_two_dims_gen UC_3_gaps_gen UC_4_printf_gen \ + UC_5_stride_gen + +check_PROGRAMS=$(TEST_PROG) + +# Temporary files. +CHECK_CLEANFILES+=*.h5 + +# All programs rely on hdf5 library and h5tools library +LDADD=$(LIBH5TOOLS) $(LIBHDF5) + +include $(top_srcdir)/config/conclude.am diff --git a/tools/misc/vds/UC_1.h b/tools/misc/vds/UC_1.h new file mode 100644 index 0000000..29df72b --- /dev/null +++ b/tools/misc/vds/UC_1.h @@ -0,0 +1,150 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef UC_1_H +#define UC_1_H + +#include "hdf5.h" + +#include "UC_common.h" + +/* + * Definitions for VDS use case 1 + * + * Datasets have a single unlimited dimension and two fixed dimensions. They + * are mapped along a single dimension in the VDS with no gaps between them. + */ + +/* virtual dataset <---> source dataset mapping and sizes + + ***************** --+ + * A * K + ***************** --+ + * * | + * B * N + * * | + ***************** --+ + * C * + ***************** + * * + * D * + * * + ***************** + * E * + ***************** + * * + * F * + * * + ***************** + + | | + +-------M-------+ + + + dim[0] + / + / + / + -----> dim[2] + | + | + | + dim[1] + + */ + + +#define UC_1_N_SOURCES 6 + +/* Dataset dimensions */ +#define UC_1_SM_HEIGHT 2 /* K */ +#define UC_1_LG_HEIGHT 4 /* N */ +#define UC_1_SM_LG_HEIGHT 6 /* SM_HEIGHT + LG_HEIGHT */ +#define UC_1_FULL_HEIGHT 18 /* (3 * K) + (3 * N) */ +#define UC_1_HALF_HEIGHT 9 +#define UC_1_WIDTH 8 /* M */ +#define UC_1_HALF_WIDTH 4 + +#define UC_1_N_MAX_PLANES H5S_UNLIMITED /* max number of planes */ +#define UC_1_N_TEST_PLANES 5 /* number of planes we write */ + +/* Dataset datatypes */ +#define UC_1_SOURCE_DATATYPE H5T_STD_I32LE +#define UC_1_VDS_DATATYPE H5T_STD_I32LE + +/* Starting size of datasets, both source and VDS */ +static hsize_t UC_1_DIMS[UC_1_N_SOURCES][RANK] = { + {0, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {0, UC_1_LG_HEIGHT, UC_1_WIDTH}, + {0, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {0, UC_1_LG_HEIGHT, UC_1_WIDTH}, + {0, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {0, UC_1_LG_HEIGHT, UC_1_WIDTH} +}; +static hsize_t UC_1_VDS_DIMS[RANK] = {0, UC_1_FULL_HEIGHT, UC_1_WIDTH}; + +/* Maximum size of datasets, both source and VDS */ +static hsize_t UC_1_MAX_DIMS[UC_1_N_SOURCES][RANK] = { + {UC_1_N_MAX_PLANES, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {UC_1_N_MAX_PLANES, UC_1_LG_HEIGHT, UC_1_WIDTH}, + {UC_1_N_MAX_PLANES, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {UC_1_N_MAX_PLANES, UC_1_LG_HEIGHT, UC_1_WIDTH}, + {UC_1_N_MAX_PLANES, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {UC_1_N_MAX_PLANES, UC_1_LG_HEIGHT, UC_1_WIDTH} +}; +static hsize_t UC_1_VDS_MAX_DIMS[RANK] = {UC_1_N_MAX_PLANES, UC_1_FULL_HEIGHT, UC_1_WIDTH}; + +/* Planes */ +static hsize_t UC_1_PLANES[UC_1_N_SOURCES][RANK] = { + {1, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {1, UC_1_LG_HEIGHT, UC_1_WIDTH}, + {1, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {1, UC_1_LG_HEIGHT, UC_1_WIDTH}, + {1, UC_1_SM_HEIGHT, UC_1_WIDTH}, + {1, UC_1_LG_HEIGHT, UC_1_WIDTH} +}; +static hsize_t UC_1_VDS_PLANE[RANK] = {1, UC_1_FULL_HEIGHT, UC_1_WIDTH}; + +/* File names for source datasets */ +static char UC_1_FILE_NAMES[UC_1_N_SOURCES][NAME_LEN] = { + {"1_a.h5"}, + {"1_b.h5"}, + {"1_c.h5"}, + {"1_d.h5"}, + {"1_e.h5"}, + {"1_f.h5"} +}; + +/* VDS file name */ +static char UC_1_VDS_FILE_NAME[NAME_LEN] = "1_vds.h5"; + +/* Dataset names */ +static char UC_1_SOURCE_DSET_NAME[NAME_LEN] = "source_dset"; +static char UC_1_SOURCE_DSET_PATH[NAME_LEN] = "/source_dset"; +static char UC_1_VDS_DSET_NAME[NAME_LEN] = "vds_dset"; + +/* Fill values */ +static hsize_t UC_1_FILL_VALUES[UC_1_N_SOURCES] = { + -1, + -2, + -3, + -4, + -5, + -6 +}; +static int UC_1_VDS_FILL_VALUE = -9; + +#endif /* UC_1_H */ + diff --git a/tools/misc/vds/UC_1_one_dim_gen.c b/tools/misc/vds/UC_1_one_dim_gen.c new file mode 100644 index 0000000..a78268b --- /dev/null +++ b/tools/misc/vds/UC_1_one_dim_gen.c @@ -0,0 +1,239 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * File/dataset generator for VDS use case 1 + * + * See the header file for a description. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "hdf5.h" + +#include "UC_common.h" +#include "UC_1.h" + + +int +main(int argc, char *argv[]) +{ + hid_t src_sid = -1; /* source dataset's dataspace ID */ + hid_t src_dcplid = -1; /* source dataset property list ID */ + + hid_t vds_sid = -1; /* VDS dataspace ID */ + hid_t vds_dcplid = -1; /* VDS dataset property list ID */ + + hid_t fid = -1; /* HDF5 file ID */ + hid_t did = -1; /* dataset ID */ + hid_t msid = -1; /* memory dataspace ID */ + hid_t fsid = -1; /* file dataspace ID */ + + hsize_t extent[RANK]; /* dataset extents */ + hsize_t start[RANK]; /* starting point for hyperslab */ + int map_start = -1; /* starting point in the VDS map */ + + int *buffer = NULL; /* data buffer */ + hsize_t count = 0; /* number of elements in a plane */ + int n_planes = -1; /* number of planes to write */ + int value = -1; /* value written to datasets */ + + int i; /* iterator */ + int j; /* iterator */ + int k; /* iterator */ + + + /* Start by creating the virtual dataset (VDS) dataspace and creation + * property list. The individual source datasets are then created + * and the VDS map (stored in the VDS property list) is updated. + */ + + /* Create VDS dcpl */ + if((vds_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_fill_value(vds_dcplid, UC_1_VDS_DATATYPE, + &UC_1_VDS_FILL_VALUE) < 0) + UC_ERROR + + /* Create VDS dataspace */ + if((vds_sid = H5Screate_simple(RANK, UC_1_VDS_DIMS, + UC_1_VDS_MAX_DIMS)) < 0) + UC_ERROR + + /************************************ + * Create source files and datasets * + ************************************/ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + map_start = 0; + + for(i = 0; i < UC_1_N_SOURCES; i++) { + + /* Create source dataset dcpl */ + if((src_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_chunk(src_dcplid, RANK, UC_1_PLANES[i]) < 0) + UC_ERROR + if(H5Pset_fill_value(src_dcplid, UC_1_SOURCE_DATATYPE, + &UC_1_FILL_VALUES[i]) < 0) + UC_ERROR + if(0 != i % 2) + if(H5Pset_deflate(src_dcplid, COMPRESSION_LEVEL) < 0) + UC_ERROR + + /* Create source file, dataspace, and dataset */ + if((fid = H5Fcreate(UC_1_FILE_NAMES[i], H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + if((src_sid = H5Screate_simple(RANK, UC_1_DIMS[i], + UC_1_MAX_DIMS[i])) < 0) + UC_ERROR + if((did = H5Dcreate2(fid, UC_1_SOURCE_DSET_NAME, + UC_1_SOURCE_DATATYPE, src_sid, + H5P_DEFAULT, src_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* Set the dataset's extent (will eventually vary with i) */ + extent[0] = UC_1_N_TEST_PLANES; + extent[1] = UC_1_PLANES[i][1]; + extent[2] = UC_1_PLANES[i][2]; + if(H5Dset_extent(did, extent) < 0) + UC_ERROR + + /* Create a data buffer that represents a plane */ + count = UC_1_PLANES[i][1] * UC_1_PLANES[i][2]; + if(NULL == (buffer = (int *)malloc(count * sizeof(int)))) + UC_ERROR + + /* Create the memory dataspace */ + if((msid = H5Screate_simple(RANK, UC_1_PLANES[i], NULL)) < 0) + UC_ERROR + + /* Get the file dataspace */ + if((fsid = H5Dget_space(did)) < 0) + UC_ERROR + + /* Write planes to the dataset, number will eventually vary with i */ + n_planes = UC_1_N_TEST_PLANES; + for(j = 0; j < n_planes; j++) { + + value = ((i + 1) * 10) + j; + for(k = 0; k < count; k++) + buffer[k] = value; + + start[0] = j; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, UC_1_PLANES[i], NULL) < 0) + UC_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, msid, fsid, H5P_DEFAULT, buffer) < 0) + UC_ERROR + + } /* end for */ + + /* set up hyperslabs for source and destination datasets */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(src_sid, H5S_SELECT_SET, start, NULL, + UC_1_MAX_DIMS[i], NULL) < 0) + UC_ERROR + start[0] = 0; + start[1] = map_start; + start[2] = 0; + if(H5Sselect_hyperslab(vds_sid, H5S_SELECT_SET, start, NULL, + UC_1_MAX_DIMS[i], NULL) < 0) + UC_ERROR + map_start += UC_1_PLANES[i][1]; + + /* Add VDS mapping */ + if(H5Pset_virtual(vds_dcplid, vds_sid, UC_1_FILE_NAMES[i], + UC_1_SOURCE_DSET_PATH, src_sid) < 0) + UC_ERROR + + /* close */ + if(H5Sclose(src_sid) < 0) + UC_ERROR + if(H5Pclose(src_dcplid) < 0) + UC_ERROR + if(H5Sclose(msid) < 0) + UC_ERROR + if(H5Sclose(fsid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + free(buffer); + + } /* end for */ + + + /******************* + * Create VDS file * + *******************/ + + /* file */ + if((fid = H5Fcreate(UC_1_VDS_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + + /* dataset */ + if((did = H5Dcreate2(fid, UC_1_VDS_DSET_NAME, UC_1_VDS_DATATYPE, vds_sid, + H5P_DEFAULT, vds_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* close */ + if(H5Pclose(vds_dcplid) < 0) + UC_ERROR + if(H5Sclose(vds_sid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + + return EXIT_SUCCESS; + +error: + + H5E_BEGIN_TRY { + if(src_sid >= 0) + (void)H5Sclose(src_sid); + if(src_dcplid >= 0) + (void)H5Pclose(src_dcplid); + if(vds_sid >= 0) + (void)H5Sclose(vds_sid); + if(vds_dcplid >= 0) + (void)H5Pclose(vds_dcplid); + if(fid >= 0) + (void)H5Fclose(fid); + if(did >= 0) + (void)H5Dclose(did); + if(msid >= 0) + (void)H5Sclose(msid); + if(fsid >= 0) + (void)H5Sclose(fsid); + if(buffer != NULL) + free(buffer); + } H5E_END_TRY + + return EXIT_FAILURE; + +} /* end main */ + diff --git a/tools/misc/vds/UC_2.h b/tools/misc/vds/UC_2.h new file mode 100644 index 0000000..3e4e4fd --- /dev/null +++ b/tools/misc/vds/UC_2.h @@ -0,0 +1,151 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef UC_2_H +#define UC_2_H + +#include "hdf5.h" + +/* + * Definitions for VDS use case 2 + * + * Datasets have a single unlimited dimension and two fixed dimensions. They + * are mapped along two dimensions in the VDS with no gaps between them. + */ + +/* virtual dataset <---> source dataset mapping and sizes + + ********************************** + * A * * + ***************** D * + * * * + * B * * + * ****************** + ***************** E * + * C * * + ********************************** + + + dim[0] + / + / + / + -----> dim[2] + | + | + | + dim[1] + + */ + +#define UC_2_N_SOURCES 5 + +/* Dataset dimensions */ +#define UC_2_A_HEIGHT 2 +#define UC_2_B_HEIGHT 4 +#define UC_2_AB_HEIGHT 6 /* For hyperslab start position */ +#define UC_2_C_HEIGHT 2 +#define UC_2_D_HEIGHT 5 +#define UC_2_E_HEIGHT 3 +#define UC_2_FULL_HEIGHT 8 /* A+B+C and D+E */ +#define UC_2_WIDTH 7 +#define UC_2_FULL_WIDTH 14 /* 2*width */ + +#define UC_2_N_PLANES_IN_SERIES 3 /* number of planes in a series of sub-images */ +#define UC_2_N_MAX_PLANES H5S_UNLIMITED /* max number of planes */ +#define UC_2_N_TEST_PLANES 6 /* number of planes we write */ + +/* Dataset datatypes */ +#define UC_2_SOURCE_DATATYPE H5T_STD_I32LE +#define UC_2_VDS_DATATYPE H5T_STD_I32LE + +/* Starting size of datasets, both source and VDS */ +static hsize_t UC_2_DIMS[UC_2_N_SOURCES][RANK] = { + {0, UC_2_A_HEIGHT, UC_2_WIDTH}, + {0, UC_2_B_HEIGHT, UC_2_WIDTH}, + {0, UC_2_C_HEIGHT, UC_2_WIDTH}, + {0, UC_2_D_HEIGHT, UC_2_WIDTH}, + {0, UC_2_E_HEIGHT, UC_2_WIDTH} +}; +static hsize_t UC_2_VDS_DIMS[RANK] = {0, UC_2_FULL_HEIGHT, UC_2_FULL_WIDTH}; + +/* Maximum size of datasets, both source and VDS */ +static hsize_t UC_2_MAX_DIMS[UC_2_N_SOURCES][RANK] = { + {UC_2_N_MAX_PLANES, UC_2_A_HEIGHT, UC_2_WIDTH}, + {UC_2_N_MAX_PLANES, UC_2_B_HEIGHT, UC_2_WIDTH}, + {UC_2_N_MAX_PLANES, UC_2_C_HEIGHT, UC_2_WIDTH}, + {UC_2_N_MAX_PLANES, UC_2_D_HEIGHT, UC_2_WIDTH}, + {UC_2_N_MAX_PLANES, UC_2_E_HEIGHT, UC_2_WIDTH} +}; +static hsize_t UC_2_VDS_MAX_DIMS[RANK] = {UC_2_N_MAX_PLANES, UC_2_FULL_HEIGHT, UC_2_FULL_WIDTH}; + +/* Positions of source datasets in the VDS */ +static hsize_t UC_2_POSITIONS[UC_2_N_SOURCES][RANK] = { + /* A */ {0, 0, 0}, + /* B */ {0, UC_2_A_HEIGHT, 0}, + /* C */ {0, UC_2_AB_HEIGHT, 0}, + /* D */ {0, 0, UC_2_WIDTH}, + /* E */ {0, UC_2_D_HEIGHT, UC_2_WIDTH} +}; + +/* Planes */ +static hsize_t UC_2_PLANES[UC_2_N_SOURCES][RANK] = { + {1, UC_2_A_HEIGHT, UC_2_WIDTH}, + {1, UC_2_B_HEIGHT, UC_2_WIDTH}, + {1, UC_2_C_HEIGHT, UC_2_WIDTH}, + {1, UC_2_D_HEIGHT, UC_2_WIDTH}, + {1, UC_2_E_HEIGHT, UC_2_WIDTH} +}; +static hsize_t UC_2_VDS_SUB_IMAGE[RANK] = {1, UC_2_FULL_HEIGHT, UC_2_WIDTH}; +static hsize_t UC_2_VDS_PLANE[RANK] = {1, UC_2_FULL_HEIGHT, UC_2_FULL_WIDTH}; + +/* Chunk dimensions */ +static hsize_t UC_2_CHUNK_DIMS[UC_2_N_SOURCES][RANK] = { + {UC_2_N_PLANES_IN_SERIES, UC_2_A_HEIGHT, UC_2_WIDTH}, + {UC_2_N_PLANES_IN_SERIES, UC_2_B_HEIGHT, UC_2_WIDTH}, + {UC_2_N_PLANES_IN_SERIES, UC_2_C_HEIGHT, UC_2_WIDTH}, + {UC_2_N_PLANES_IN_SERIES, UC_2_D_HEIGHT, UC_2_WIDTH}, + {UC_2_N_PLANES_IN_SERIES, UC_2_E_HEIGHT, UC_2_WIDTH} +}; + +/* File names for source datasets */ +static char UC_2_FILE_NAMES[UC_2_N_SOURCES][NAME_LEN] = { + {"2_a.h5"}, + {"2_b.h5"}, + {"2_c.h5"}, + {"2_d.h5"}, + {"2_e.h5"} +}; + +/* VDS file name */ +#define UC_2_VDS_FILE_NAME "2_vds.h5" + +/* Dataset names */ +#define UC_2_SOURCE_DSET_NAME "source_dset" +#define UC_2_SOURCE_DSET_PATH "/source_dset" +#define UC_2_VDS_DSET_NAME "vds_dset" + +/* Fill values */ +static hsize_t UC_2_FILL_VALUES[UC_2_N_SOURCES] = { + -1, + -2, + -3, + -4, + -5 +}; +static int UC_2_VDS_FILL_VALUE = -9; + +#endif /* UC_2_H */ + diff --git a/tools/misc/vds/UC_2_two_dims_gen.c b/tools/misc/vds/UC_2_two_dims_gen.c new file mode 100644 index 0000000..b5fd319 --- /dev/null +++ b/tools/misc/vds/UC_2_two_dims_gen.c @@ -0,0 +1,230 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * File/dataset generator for VDS use case 2 + * + * See the header file for a description. + */ + + +#include <stdlib.h> + +#include "hdf5.h" + +#include "UC_common.h" +#include "UC_2.h" + +int +main(int argc, char *argv[]) +{ + hid_t src_sid = -1; /* source dataset's dataspace ID */ + hid_t src_dcplid = -1; /* source dataset property list ID */ + + hid_t vds_sid = -1; /* VDS dataspace ID */ + hid_t vds_dcplid = -1; /* VDS dataset property list ID */ + + hid_t fid = -1; /* HDF5 file ID */ + hid_t did = -1; /* dataset ID */ + hid_t msid = -1; /* memory dataspace ID */ + hid_t fsid = -1; /* file dataspace ID */ + + hsize_t start[RANK]; /* starting point for hyperslab */ + hsize_t extent[RANK]; /* dataset extents */ + + int *buffer = NULL; /* data buffer */ + int value = -1; /* value written to datasets */ + hsize_t count = 0; /* number of elements in a plane */ + int n_planes = -1; /* number of planes to write */ + + int i; /* iterator */ + int j; /* iterator */ + int k; /* iterator */ + + + /* Start by creating the virtual dataset (VDS) dataspace and creation + * property list. The individual source datasets are then created + * and the VDS map (stored in the VDS property list) is updated. + */ + + /* Create VDS dcpl */ + if((vds_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_fill_value(vds_dcplid, UC_2_VDS_DATATYPE, + &UC_2_VDS_FILL_VALUE) < 0) + UC_ERROR + + /* Create VDS dataspace */ + if((vds_sid = H5Screate_simple(RANK, UC_2_VDS_DIMS, + UC_2_VDS_MAX_DIMS)) < 0) + UC_ERROR + + /************************************ + * Create source files and datasets * + ************************************/ + + start[0] = 0; + start[1] = 0; + start[2] = 0; + + for(i = 0; i < UC_2_N_SOURCES; i++) { + + /* source dataset dcpl */ + if((src_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_chunk(src_dcplid, RANK, UC_2_CHUNK_DIMS[i]) < 0) + UC_ERROR + if(H5Pset_fill_value(src_dcplid, UC_2_SOURCE_DATATYPE, + &UC_2_FILL_VALUES[i]) < 0) + UC_ERROR + if(H5Pset_deflate(src_dcplid, COMPRESSION_LEVEL) < 0) + UC_ERROR + + /* Create source file, dataspace, and dataset */ + if((fid = H5Fcreate(UC_2_FILE_NAMES[i], H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + if((src_sid = H5Screate_simple(RANK, UC_2_DIMS[i], + UC_2_MAX_DIMS[i])) < 0) + UC_ERROR + if((did = H5Dcreate2(fid, UC_2_SOURCE_DSET_NAME, + UC_2_SOURCE_DATATYPE, src_sid, + H5P_DEFAULT, src_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* Set the dataset's extent (will eventually vary with i) */ + extent[0] = UC_2_N_TEST_PLANES; + extent[1] = UC_2_PLANES[i][1]; + extent[2] = UC_2_PLANES[i][2]; + if(H5Dset_extent(did, extent) < 0) + UC_ERROR + + /* Create a data buffer that represents a plane */ + count = UC_2_PLANES[i][1] * UC_2_PLANES[i][2]; + if(NULL == (buffer = (int *)malloc(count * sizeof(int)))) + UC_ERROR + + /* Create the memory dataspace */ + if((msid = H5Screate_simple(RANK, UC_2_PLANES[i], NULL)) < 0) + UC_ERROR + + /* Get the file dataspace */ + if((fsid = H5Dget_space(did)) < 0) + UC_ERROR + + /* Write planes to the dataset, number will eventually vary with i */ + n_planes = UC_2_N_TEST_PLANES; + for(j = 0; j < n_planes; j++) { + + value = ((i + 1) * 10) + j; + for(k = 0; k < count; k++) + buffer[k] = value; + + start[0] = j; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, UC_2_PLANES[i], NULL) < 0) + UC_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, msid, fsid, H5P_DEFAULT, buffer) < 0) + UC_ERROR + + } /* end for */ + + /* set up hyperslabs for source and destination datasets */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(src_sid, H5S_SELECT_SET, start, NULL, + UC_2_MAX_DIMS[i], NULL) < 0) + UC_ERROR + if(H5Sselect_hyperslab(vds_sid, H5S_SELECT_SET, UC_2_POSITIONS[i], NULL, + UC_2_MAX_DIMS[i], NULL) < 0) + UC_ERROR + + /* Add VDS mapping */ + if(H5Pset_virtual(vds_dcplid, vds_sid, UC_2_FILE_NAMES[i], + UC_2_SOURCE_DSET_PATH, src_sid) < 0) + UC_ERROR + + /* close */ + if(H5Sclose(msid) < 0) + UC_ERROR + if(H5Sclose(fsid) < 0) + UC_ERROR + if(H5Sclose(src_sid) < 0) + UC_ERROR + if(H5Pclose(src_dcplid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + free(buffer); + + } /* end for */ + + /******************************* + * Create VDS file and dataset * + *******************************/ + + /* file */ + if((fid = H5Fcreate(UC_2_VDS_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + + /* dataset */ + if((did = H5Dcreate2(fid, UC_2_VDS_DSET_NAME, UC_2_VDS_DATATYPE, vds_sid, + H5P_DEFAULT, vds_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* close */ + if(H5Pclose(vds_dcplid) < 0) + UC_ERROR + if(H5Sclose(vds_sid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + + return EXIT_SUCCESS; + +error: + + H5E_BEGIN_TRY { + if(src_sid >= 0) + (void)H5Sclose(src_sid); + if(src_dcplid >= 0) + (void)H5Pclose(src_dcplid); + if(vds_sid >= 0) + (void)H5Sclose(vds_sid); + if(vds_dcplid >= 0) + (void)H5Pclose(vds_dcplid); + if(fid >= 0) + (void)H5Fclose(fid); + if(did >= 0) + (void)H5Dclose(did); + if(msid >= 0) + (void)H5Sclose(msid); + if(fsid >= 0) + (void)H5Sclose(fsid); + if(buffer != NULL) + free(buffer); + } H5E_END_TRY + + return EXIT_FAILURE; + +} /* end main() */ + diff --git a/tools/misc/vds/UC_3.h b/tools/misc/vds/UC_3.h new file mode 100644 index 0000000..a27c3cf --- /dev/null +++ b/tools/misc/vds/UC_3.h @@ -0,0 +1,78 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef UC_3_H +#define UC_3_H + +#include "hdf5.h" + +#include "UC_1.h" +#include "UC_2.h" + +/* + * Definitions for VDS use case 3 + * + * Datasets have a single unlimited dimension and one or two fixed + * dimensions (they are reused from use cases 1 and 2). In this use case, + * the datasets are mapped in the VDS with gaps between them. + */ + +/* VDS dimensions + * Height and width are large enough to encompass the + * mapped source datasets with gaps. + */ +#define UC_31_VDS_HEIGHT 25 /* full height + 7 (gaps of 1) */ +#define UC_31_VDS_WIDTH 8 /* full width + 0 (no gaps) */ +#define UC_32_VDS_HEIGHT 13 /* full height + 5 */ +#define UC_32_VDS_WIDTH 19 /* full width + 5 */ +#define UC_31_GAP 1 + +/* VDS datatypes */ +#define UC_31_VDS_DATATYPE H5T_STD_I32LE +#define UC_32_VDS_DATATYPE H5T_STD_I32LE + +/* Starting size of virtual datasets */ +static hsize_t UC_31_VDS_DIMS[RANK] = {0, UC_31_VDS_HEIGHT, UC_31_VDS_WIDTH}; +static hsize_t UC_32_VDS_DIMS[RANK] = {0, UC_32_VDS_HEIGHT, UC_32_VDS_WIDTH}; + +/* Maximum size of virtual datasets */ +static hsize_t UC_31_VDS_MAX_DIMS[RANK] = {UC_1_N_MAX_PLANES, UC_31_VDS_HEIGHT, UC_31_VDS_WIDTH}; +static hsize_t UC_32_VDS_MAX_DIMS[RANK] = {UC_2_N_MAX_PLANES, UC_32_VDS_HEIGHT, UC_32_VDS_WIDTH}; + +/* Positions of mapped source datasets */ +static hsize_t UC_32_POSITIONS[UC_2_N_SOURCES][RANK] = { + /* A */ {0, 1, 1}, + /* B */ {0, 4, 0}, + /* C */ {0, 11, 4}, + /* D */ {0, 1, 9}, + /* E */ {0, 8, 12} +}; + +/* Planes */ +static hsize_t UC_31_VDS_PLANE[RANK] = {1, UC_31_VDS_HEIGHT, UC_31_VDS_WIDTH}; +static hsize_t UC_32_VDS_PLANE[RANK] = {1, UC_32_VDS_HEIGHT, UC_32_VDS_WIDTH}; + +/* VDS file names */ +#define UC_31_VDS_FILE_NAME "3_1_vds.h5" +#define UC_32_VDS_FILE_NAME "3_2_vds.h5" + +/* Dataset name */ +#define UC_3_VDS_DSET_NAME "vds_dset" + +/* Fill value */ +static int UC_3_VDS_FILL_VALUE = -9; + +#endif /* UC_3_H */ + diff --git a/tools/misc/vds/UC_3_gaps_gen.c b/tools/misc/vds/UC_3_gaps_gen.c new file mode 100644 index 0000000..1f150c1 --- /dev/null +++ b/tools/misc/vds/UC_3_gaps_gen.c @@ -0,0 +1,255 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * File/dataset generator for VDS use case 3 + * + * See the header file for a description. + */ + +#include <stdlib.h> +#include <string.h> + +#include <hdf5.h> + +#include "UC_common.h" +#include "UC_3.h" + +/* Create the VDS that uses use case 1 files */ +herr_t +create_3_1_vds(void) +{ + hid_t src_sid = -1; /* source dataset's dataspace ID */ + hid_t vds_sid = -1; /* VDS dataspace ID */ + hid_t vds_dcplid = -1; /* VDS dataset property list ID */ + + hid_t fid = -1; /* HDF5 file ID */ + hid_t did = -1; /* dataset ID */ + + hsize_t start[RANK]; /* source starting point for hyperslab */ + hsize_t position[RANK]; /* vds mapping positions */ + + int i; /* iterator */ + + /* Create VDS dcpl */ + if((vds_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_fill_value(vds_dcplid, UC_31_VDS_DATATYPE, + &UC_3_VDS_FILL_VALUE) < 0) + UC_ERROR + + /* Create VDS dataspace */ + if((vds_sid = H5Screate_simple(RANK, UC_31_VDS_DIMS, + UC_31_VDS_MAX_DIMS)) < 0) + UC_ERROR + + /* Set starting positions */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + + position[0] = 0; + position[1] = UC_31_GAP; + position[2] = 0; + + /****************************** + * Create source-VDS mappings * + ******************************/ + for(i = 0; i < UC_1_N_SOURCES; i++) { + + if((src_sid = H5Screate_simple(RANK, UC_1_DIMS[i], + UC_1_MAX_DIMS[i])) < 0) + UC_ERROR + + /* set up hyperslabs for source and destination datasets */ + if(H5Sselect_hyperslab(src_sid, H5S_SELECT_SET, start, NULL, + UC_1_MAX_DIMS[i], NULL) < 0) + UC_ERROR + if(H5Sselect_hyperslab(vds_sid, H5S_SELECT_SET, position, + NULL, UC_1_MAX_DIMS[i], NULL) < 0) + UC_ERROR + position[1] += UC_1_DIMS[i][1] + UC_31_GAP; + + /* Add VDS mapping */ + if(H5Pset_virtual(vds_dcplid, vds_sid, UC_1_FILE_NAMES[i], + UC_1_SOURCE_DSET_PATH, src_sid) < 0) + UC_ERROR + if(H5Sclose(src_sid) < 0) + UC_ERROR + + } /* end for */ + + /******************************* + * Create VDS file and dataset * + *******************************/ + + /* file */ + if((fid = H5Fcreate(UC_31_VDS_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + + /* dataset */ + if((did = H5Dcreate2(fid, UC_3_VDS_DSET_NAME, UC_31_VDS_DATATYPE, vds_sid, + H5P_DEFAULT, vds_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* close */ + if(H5Pclose(vds_dcplid) < 0) + UC_ERROR + if(H5Sclose(vds_sid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + + return 0; + +error: + + H5E_BEGIN_TRY { + if(vds_sid >= 0) + (void)H5Sclose(vds_sid); + if(vds_dcplid >= 0) + (void)H5Pclose(vds_dcplid); + if(fid >= 0) + (void)H5Fclose(fid); + if(did >= 0) + (void)H5Dclose(did); + } H5E_END_TRY + + return -1; + +} /* end create_3_1_vds() */ + +/* Create the VDS that uses use case 2 files */ +herr_t +create_3_2_vds(void) +{ + hid_t src_sid = -1; /* source dataset's dataspace ID */ + hid_t vds_sid = -1; /* VDS dataspace ID */ + hid_t vds_dcplid = -1; /* VDS dataset property list ID */ + + hid_t fid = -1; /* HDF5 file ID */ + hid_t did = -1; /* dataset ID */ + + hsize_t start[RANK]; /* source starting point for hyperslab */ + + int i; /* iterator */ + + /* Create VDS dcpl */ + if((vds_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_fill_value(vds_dcplid, UC_32_VDS_DATATYPE, + &UC_3_VDS_FILL_VALUE) < 0) + UC_ERROR + + /* Create VDS dataspace */ + if((vds_sid = H5Screate_simple(RANK, UC_32_VDS_DIMS, + UC_32_VDS_MAX_DIMS)) < 0) + UC_ERROR + + /* Set starting positions */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + + /****************************** + * Create source-VDS mappings * + ******************************/ + for(i = 0; i < UC_2_N_SOURCES; i++) { + + if((src_sid = H5Screate_simple(RANK, UC_2_DIMS[i], + UC_2_MAX_DIMS[i])) < 0) + UC_ERROR + + /* set up hyperslabs for source and destination datasets */ + if(H5Sselect_hyperslab(src_sid, H5S_SELECT_SET, start, NULL, + UC_2_MAX_DIMS[i], NULL) < 0) + UC_ERROR + if(H5Sselect_hyperslab(vds_sid, H5S_SELECT_SET, UC_32_POSITIONS[i], + NULL, UC_2_MAX_DIMS[i], NULL) < 0) + UC_ERROR + + /* Add VDS mapping */ + if(H5Pset_virtual(vds_dcplid, vds_sid, UC_2_FILE_NAMES[i], + UC_2_SOURCE_DSET_PATH, src_sid) < 0) + UC_ERROR + if(H5Sclose(src_sid) < 0) + UC_ERROR + + } /* end for */ + + /******************************* + * Create VDS file and dataset * + *******************************/ + + /* file */ + if((fid = H5Fcreate(UC_32_VDS_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + + /* dataset */ + if((did = H5Dcreate2(fid, UC_3_VDS_DSET_NAME, UC_32_VDS_DATATYPE, vds_sid, + H5P_DEFAULT, vds_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* close */ + if(H5Pclose(vds_dcplid) < 0) + UC_ERROR + if(H5Sclose(vds_sid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + + return 0; + +error: + + H5E_BEGIN_TRY { + if(vds_sid >= 0) + (void)H5Sclose(vds_sid); + if(vds_dcplid >= 0) + (void)H5Pclose(vds_dcplid); + if(fid >= 0) + (void)H5Fclose(fid); + if(did >= 0) + (void)H5Dclose(did); + } H5E_END_TRY + + return -1; + +} /* end create_3_2_vds() */ + +int +main(int argc, char *argv[]) +{ + + if(create_3_1_vds() < 0) + UC_ERROR + + if(create_3_2_vds() < 0) + UC_ERROR + + return EXIT_SUCCESS; + +error: + + return EXIT_FAILURE; + +} /* end main() */ + diff --git a/tools/misc/vds/UC_4.h b/tools/misc/vds/UC_4.h new file mode 100644 index 0000000..ce74e63 --- /dev/null +++ b/tools/misc/vds/UC_4.h @@ -0,0 +1,86 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef UC_4_H +#define UC_4_H + +#include "hdf5.h" + +#include "UC_common.h" + +/* + * Definitions for VDS use case 4 + * + * Source datasets have three fixed dimensions. In this use case, the + * datasets are mapped consecutively in the VDS along a single dimension with + * no gaps between them. Datasets are automatically loaded using a + * printf-like format string for the file name. + */ + +/* virtual dataset <---> source dataset mapping and sizes */ + +#define UC_4_N_SOURCES 3 + +/* Dataset dimensions */ +#define UC_4_SRC_PLANES 3 +#define UC_4_HEIGHT 4 +#define UC_4_WIDTH 4 + +/* max number of planes for VDS (sources are finite) */ +#define UC_4_VDS_MAX_PLANES H5S_UNLIMITED +#define UC_4_N_TEST_PLANES 9 /* number of planes in the VDS */ + +/* Dataset datatypes */ +#define UC_4_SOURCE_DATATYPE H5T_STD_I32LE +#define UC_4_VDS_DATATYPE H5T_STD_I32LE + +/* Starting size of datasets, both source and VDS */ +static hsize_t UC_4_SOURCE_DIMS[RANK] = {0, UC_4_HEIGHT, UC_4_WIDTH}; +static hsize_t UC_4_VDS_DIMS[RANK] = {0, UC_4_HEIGHT, UC_4_WIDTH}; + +/* Max size of datasets, both source and VDS */ +static hsize_t UC_4_SOURCE_MAX_DIMS[RANK] = {UC_4_SRC_PLANES, UC_4_HEIGHT, UC_4_WIDTH}; +static hsize_t UC_4_VDS_MAX_DIMS[RANK] = {UC_4_VDS_MAX_PLANES, UC_4_HEIGHT, UC_4_WIDTH}; + +/* Planes (both source and VDS) */ +static hsize_t UC_4_PLANE[RANK] = {1, UC_4_HEIGHT, UC_4_WIDTH}; + +/* File names for source datasets */ +static char UC_4_FILE_NAMES[UC_4_N_SOURCES][NAME_LEN] = { + {"4_0.h5"}, + {"4_1.h5"}, + {"4_2.h5"} +}; +static char UC_4_MAPPING_FILE_NAME[NAME_LEN] = "4_%b.h5"; + +/* VDS file name */ +static char UC_4_VDS_FILE_NAME[NAME_LEN] = "4_vds.h5"; + +/* Dataset names */ +static char UC_4_SOURCE_DSET_NAME[NAME_LEN] = "source_dset"; +static char UC_4_SOURCE_DSET_PATH[NAME_LEN] = "/source_dset"; +static char UC_4_VDS_DSET_NAME[NAME_LEN] = "vds_dset"; + +/* Fill values */ +static hsize_t UC_4_FILL_VALUES[UC_4_N_SOURCES] = { + -1, + -2, + -3 +}; +static int UC_4_VDS_FILL_VALUE = -9; + +#endif /* UC_4_H */ + + diff --git a/tools/misc/vds/UC_4_printf_gen.c b/tools/misc/vds/UC_4_printf_gen.c new file mode 100644 index 0000000..c8e111a --- /dev/null +++ b/tools/misc/vds/UC_4_printf_gen.c @@ -0,0 +1,219 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * File/dataset generator for VDS use case 4 + * + * See the header file for a description. + */ + +#include <stdlib.h> + +#include <hdf5.h> + +#include "UC_common.h" +#include "UC_4.h" + +int +main(int argc, char *argv[]) +{ + hid_t src_sid = -1; /* source dataset's dataspace ID */ + hid_t src_dcplid = -1; /* source dataset property list ID */ + + hid_t vds_sid = -1; /* VDS dataspace ID */ + hid_t vds_dcplid = -1; /* VDS dataset property list ID */ + + hid_t fid = -1; /* HDF5 file ID */ + hid_t did = -1; /* dataset ID */ + hid_t msid = -1; /* memory dataspace ID */ + hid_t fsid = -1; /* file dataspace ID */ + + /* Hyperslab arrays */ + hsize_t start[RANK] = {0, 0, 0}; + hsize_t count[RANK] = {H5S_UNLIMITED, 1, 1}; + + int *buffer = NULL; /* data buffer */ + int value = -1; /* value written to datasets */ + + hsize_t n = 0; /* number of elements in a plane */ + + int i; /* iterator */ + int j; /* iterator */ + int k; /* iterator */ + + /************************************ + * Create source files and datasets * + ************************************/ + + /* Create source dataspace ID */ + if((src_sid = H5Screate_simple(RANK, UC_4_SOURCE_DIMS, + UC_4_SOURCE_MAX_DIMS)) < 0) + UC_ERROR + if(H5Sselect_hyperslab(src_sid, H5S_SELECT_SET, start, NULL, + UC_4_SOURCE_MAX_DIMS, NULL) < 0) + UC_ERROR + + /* Create source files and datasets */ + for(i = 0; i < UC_4_N_SOURCES; i++) { + + /* source dataset dcpl */ + if((src_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_chunk(src_dcplid, RANK, UC_4_PLANE) < 0) + UC_ERROR + if(H5Pset_fill_value(src_dcplid, UC_4_SOURCE_DATATYPE, + &UC_4_FILL_VALUES[i]) < 0) + UC_ERROR + if(H5Pset_deflate(src_dcplid, COMPRESSION_LEVEL) < 0) + UC_ERROR + + /* Create source file and dataset */ + if((fid = H5Fcreate(UC_4_FILE_NAMES[i], H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + if((did = H5Dcreate2(fid, UC_4_SOURCE_DSET_NAME, + UC_4_SOURCE_DATATYPE, src_sid, + H5P_DEFAULT, src_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* Set the dataset's extent */ + if(H5Dset_extent(did, UC_4_SOURCE_MAX_DIMS) < 0) + UC_ERROR + + /* Create a data buffer that represents a plane */ + n = UC_4_PLANE[1] * UC_4_PLANE[2]; + if(NULL == (buffer = (int *)malloc(n * sizeof(int)))) + UC_ERROR + + /* Create the memory dataspace */ + if((msid = H5Screate_simple(RANK, UC_4_PLANE, NULL)) < 0) + UC_ERROR + + /* Get the file dataspace */ + if((fsid = H5Dget_space(did)) < 0) + UC_ERROR + + /* Write planes to the dataset */ + for(j = 0; j < UC_4_SRC_PLANES; j++) { + + value = ((i + 1) * 10) + j; + for(k = 0; k < n; k++) + buffer[k] = value; + + start[0] = j; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, UC_4_PLANE, NULL) < 0) + UC_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, msid, fsid, H5P_DEFAULT, buffer) < 0) + UC_ERROR + + } /* end for */ + + /* close */ + if(H5Sclose(msid) < 0) + UC_ERROR + if(H5Sclose(fsid) < 0) + UC_ERROR + if(H5Pclose(src_dcplid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + free(buffer); + + } /* end for */ + + /******************* + * Create VDS file * + *******************/ + + /* Create file */ + if((fid = H5Fcreate(UC_4_VDS_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + + /* Create VDS dcpl */ + if((vds_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_fill_value(vds_dcplid, UC_4_VDS_DATATYPE, + &UC_4_VDS_FILL_VALUE) < 0) + UC_ERROR + + /* Create VDS dataspace */ + if((vds_sid = H5Screate_simple(RANK, UC_4_VDS_DIMS, + UC_4_VDS_MAX_DIMS)) < 0) + UC_ERROR + start[0] = 0; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(vds_sid, H5S_SELECT_SET, start, + UC_4_SOURCE_MAX_DIMS, count, UC_4_SOURCE_MAX_DIMS) < 0) + UC_ERROR + + /* Add VDS mapping - The mapped file name uses a printf-like + * naming scheme that automatically maps new files. + */ + if(H5Pset_virtual(vds_dcplid, vds_sid, UC_4_MAPPING_FILE_NAME, + UC_4_SOURCE_DSET_PATH, src_sid) < 0) + UC_ERROR + + /* Create dataset */ + if((did = H5Dcreate2(fid, UC_4_VDS_DSET_NAME, UC_4_VDS_DATATYPE, vds_sid, + H5P_DEFAULT, vds_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* close */ + if(H5Sclose(src_sid) < 0) + UC_ERROR + if(H5Pclose(vds_dcplid) < 0) + UC_ERROR + if(H5Sclose(vds_sid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + + return EXIT_SUCCESS; + +error: + + H5E_BEGIN_TRY { + if(src_sid >= 0) + (void)H5Sclose(src_sid); + if(src_dcplid >= 0) + (void)H5Pclose(src_dcplid); + if(vds_sid >= 0) + (void)H5Sclose(vds_sid); + if(vds_dcplid >= 0) + (void)H5Pclose(vds_dcplid); + if(fid >= 0) + (void)H5Fclose(fid); + if(did >= 0) + (void)H5Dclose(did); + if(msid >= 0) + (void)H5Sclose(msid); + if(fsid >= 0) + (void)H5Sclose(fsid); + if(buffer != NULL) + free(buffer); + } H5E_END_TRY + + return EXIT_FAILURE; + +} /* end main() */ + diff --git a/tools/misc/vds/UC_5.h b/tools/misc/vds/UC_5.h new file mode 100644 index 0000000..b22b177 --- /dev/null +++ b/tools/misc/vds/UC_5.h @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef UC_5_H +#define UC_5_H + +#include <hdf5.h> + +#include "UC_common.h" + +/* + * Definitions for VDS use case 5 + * + * Source datasets have one unlimited dimension and two fixed dimensions. In + * this use case, the datasets are mapped in the VDS so that alternating + * planes in the source are interleaved in the VDS. + */ + +/* virtual dataset <---> source dataset mapping and sizes */ + +#define UC_5_N_SOURCES 3 + +/* Dataset dimensions */ +#define UC_5_SRC_PLANES 3 +#define UC_5_HEIGHT 4 +#define UC_5_WIDTH 4 + +/* max number of planes for datasets */ +#define UC_5_MAX_PLANES H5S_UNLIMITED +#define UC_5_N_TEST_PLANES 9 /* number of planes in VDS */ + +/* Dataset datatypes */ +#define UC_5_SOURCE_DATATYPE H5T_STD_I32LE +#define UC_5_VDS_DATATYPE H5T_STD_I32LE + +/* Starting size of datasets, both source and VDS */ +static hsize_t UC_5_SOURCE_DIMS[RANK] = {0, UC_5_HEIGHT, UC_5_WIDTH}; +static hsize_t UC_5_VDS_DIMS[RANK] = {0, UC_5_HEIGHT, UC_5_WIDTH}; + +/* Max size of datasets, both source and VDS */ +static hsize_t UC_5_SOURCE_MAX_DIMS[RANK] = {UC_5_MAX_PLANES, UC_5_HEIGHT, UC_5_WIDTH}; +static hsize_t UC_5_VDS_MAX_DIMS[RANK] = {UC_5_MAX_PLANES, UC_5_HEIGHT, UC_5_WIDTH}; + +/* Planes (both source and VDS) */ +static hsize_t UC_5_PLANE[RANK] = {1, UC_5_HEIGHT, UC_5_WIDTH}; + +/* File names for source datasets */ +static char UC_5_FILE_NAMES[UC_5_N_SOURCES][NAME_LEN] = { + {"5_a.h5"}, + {"5_b.h5"}, + {"5_c.h5"} +}; + +/* VDS file name */ +static char UC_5_VDS_FILE_NAME[NAME_LEN] = "5_vds.h5"; + +/* Dataset names */ +static char UC_5_SOURCE_DSET_NAME[NAME_LEN] = "source_dset"; +static char UC_5_SOURCE_DSET_PATH[NAME_LEN] = "/source_dset"; +static char UC_5_VDS_DSET_NAME[NAME_LEN] = "vds_dset"; + +/* Fill values */ +static hsize_t UC_5_FILL_VALUES[UC_5_N_SOURCES] = { + -1, + -2, + -3 +}; +static int UC_5_VDS_FILL_VALUE = -9; + +#endif /* UC_5_H */ + diff --git a/tools/misc/vds/UC_5_stride_gen.c b/tools/misc/vds/UC_5_stride_gen.c new file mode 100644 index 0000000..984aadc --- /dev/null +++ b/tools/misc/vds/UC_5_stride_gen.c @@ -0,0 +1,243 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * File/dataset generator for VDS use case 5 + * + * See the header file for a description. + */ + +#include <stdlib.h> + +#include <hdf5.h> + +#include "UC_common.h" +#include "UC_5.h" + +int +main(int argc, char *argv[]) +{ + hid_t src_sid = -1; /* source dataset's dataspace ID */ + hid_t src_dcplid = -1; /* source dataset property list ID */ + + hid_t vds_sid = -1; /* VDS dataspace ID */ + hid_t vds_dcplid = -1; /* VDS dataset property list ID */ + + hid_t fid = -1; /* HDF5 file ID */ + hid_t did = -1; /* dataset ID */ + hid_t msid = -1; /* memory dataspace ID */ + hid_t fsid = -1; /* file dataspace ID */ + + hsize_t extent[RANK]; /* source dataset extents */ + hsize_t start[RANK]; /* starting point for hyperslab */ + hsize_t stride[RANK]; /* hypserslab stride */ + hsize_t count[RANK]; /* hypserslab count */ + int map_start = -1; /* starting point in the VDS map */ + + int *buffer = NULL; /* data buffer */ + int value = -1; /* value written to datasets */ + + hsize_t n = 0; /* number of elements in a plane */ + + int i; /* iterator */ + int j; /* iterator */ + int k; /* iterator */ + + /* Start by creating the virtual dataset (VDS) dataspace and creation + * property list. The individual source datasets are then created + * and the VDS map (stored in the VDS property list) is updated. + */ + + /* Create VDS dcpl */ + if((vds_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_fill_value(vds_dcplid, UC_5_VDS_DATATYPE, + &UC_5_VDS_FILL_VALUE) < 0) + UC_ERROR + + /* Create VDS dataspace */ + if((vds_sid = H5Screate_simple(RANK, UC_5_VDS_DIMS, + UC_5_VDS_MAX_DIMS)) < 0) + UC_ERROR + + /********************************* + * Map source files and datasets * + *********************************/ + + /* Hyperslab array setup */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + map_start = 0; + + stride[0] = UC_5_N_SOURCES; + stride[1] = 1; + stride[2] = 1; + + count[0] = H5S_UNLIMITED; + count[1] = 1; + count[2] = 1; + + extent[0] = UC_5_SRC_PLANES; + extent[1] = UC_5_HEIGHT; + extent[2] = UC_5_WIDTH; + + for(i = 0; i < UC_5_N_SOURCES; i++) { + + /* source dataset dcpl */ + if((src_dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + UC_ERROR + if(H5Pset_chunk(src_dcplid, RANK, UC_5_PLANE) < 0) + UC_ERROR + if(H5Pset_fill_value(src_dcplid, UC_5_SOURCE_DATATYPE, + &UC_5_FILL_VALUES[i]) < 0) + UC_ERROR + if(H5Pset_deflate(src_dcplid, COMPRESSION_LEVEL) < 0) + UC_ERROR + + /* Create source file, dataspace, and dataset */ + if((fid = H5Fcreate(UC_5_FILE_NAMES[i], H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + if((src_sid = H5Screate_simple(RANK, UC_5_SOURCE_DIMS, + UC_5_SOURCE_MAX_DIMS)) < 0) + UC_ERROR + if((did = H5Dcreate2(fid, UC_5_SOURCE_DSET_NAME, + UC_5_SOURCE_DATATYPE, src_sid, + H5P_DEFAULT, src_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* Set the dataset's extent */ + if(H5Dset_extent(did, extent) < 0) + UC_ERROR + + /* Create a data buffer that represents a plane */ + n = UC_5_PLANE[1] * UC_5_PLANE[2]; + if(NULL == (buffer = (int *)malloc(n * sizeof(int)))) + UC_ERROR + + /* Create the memory dataspace */ + if((msid = H5Screate_simple(RANK, UC_5_PLANE, NULL)) < 0) + UC_ERROR + + /* Get the file dataspace */ + if((fsid = H5Dget_space(did)) < 0) + UC_ERROR + + /* Write planes to the dataset */ + for(j = 0; j < UC_5_SRC_PLANES; j++) { + + value = ((i + 1) * 10) + j; + for(k = 0; k < n; k++) + buffer[k] = value; + + start[0] = j; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, UC_5_PLANE, NULL) < 0) + UC_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, msid, fsid, H5P_DEFAULT, buffer) < 0) + UC_ERROR + + } /* end for */ + + /* set up hyperslabs for source and destination datasets */ + start[0] = 0; + start[1] = 0; + start[2] = 0; + if(H5Sselect_hyperslab(src_sid, H5S_SELECT_SET, start, NULL, + UC_5_SOURCE_MAX_DIMS, NULL) < 0) + UC_ERROR + start[0] = map_start; + if(H5Sselect_hyperslab(vds_sid, H5S_SELECT_SET, start, stride, + count, UC_5_PLANE) < 0) + UC_ERROR + map_start += 1; + + /* Add VDS mapping */ + if(H5Pset_virtual(vds_dcplid, vds_sid, UC_5_FILE_NAMES[i], + UC_5_SOURCE_DSET_PATH, src_sid) < 0) + UC_ERROR + + /* close */ + if(H5Sclose(msid) < 0) + UC_ERROR + if(H5Sclose(fsid) < 0) + UC_ERROR + if(H5Sclose(src_sid) < 0) + UC_ERROR + if(H5Pclose(src_dcplid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + free(buffer); + + } /* end for */ + + /******************* + * Create VDS file * + *******************/ + + /* file */ + if((fid = H5Fcreate(UC_5_VDS_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + UC_ERROR + + /* dataset */ + if((did = H5Dcreate2(fid, UC_5_VDS_DSET_NAME, UC_5_VDS_DATATYPE, vds_sid, + H5P_DEFAULT, vds_dcplid, H5P_DEFAULT)) < 0) + UC_ERROR + + /* close */ + if(H5Pclose(vds_dcplid) < 0) + UC_ERROR + if(H5Sclose(vds_sid) < 0) + UC_ERROR + if(H5Dclose(did) < 0) + UC_ERROR + if(H5Fclose(fid) < 0) + UC_ERROR + + return EXIT_SUCCESS; + +error: + + H5E_BEGIN_TRY { + if(src_sid >= 0) + (void)H5Sclose(src_sid); + if(src_dcplid >= 0) + (void)H5Pclose(src_dcplid); + if(vds_sid >= 0) + (void)H5Sclose(vds_sid); + if(vds_dcplid >= 0) + (void)H5Pclose(vds_dcplid); + if(fid >= 0) + (void)H5Fclose(fid); + if(did >= 0) + (void)H5Dclose(did); + if(msid >= 0) + (void)H5Sclose(msid); + if(fsid >= 0) + (void)H5Sclose(fsid); + if(buffer != NULL) + free(buffer); + } H5E_END_TRY + + return EXIT_FAILURE; + +} /* end main() */ + diff --git a/tools/misc/vds/UC_common.h b/tools/misc/vds/UC_common.h new file mode 100644 index 0000000..0e61016 --- /dev/null +++ b/tools/misc/vds/UC_common.h @@ -0,0 +1,41 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef USE_CASE_COMMON_H +#define USE_CASE_COMMON_H + +/****************************************** + * Symbols used across multiple use cases * + ******************************************/ + +/* All datasets are 3D */ +#define RANK 3 + +/* Lengths of string identifiers (file, dataset names, etc.) */ +#define NAME_LEN 32 + +/* Compression level */ +#define COMPRESSION_LEVEL 7 + +/* Booleans */ +#define TRUE 1 +#define FALSE 0 + +/* Testing macros */ +#define AT() printf (" at %s:%d in %s()...\n", __FILE__, __LINE__, __func__); +#define UC_ERROR {puts("*ERROR*"); fflush(stdout); AT(); goto error;} + +#endif /* USE_CASE_COMMON_H */ + diff --git a/tools/testfiles/vds/1_a.h5 b/tools/testfiles/vds/1_a.h5 Binary files differnew file mode 100644 index 0000000..953d33d --- /dev/null +++ b/tools/testfiles/vds/1_a.h5 diff --git a/tools/testfiles/vds/1_b.h5 b/tools/testfiles/vds/1_b.h5 Binary files differnew file mode 100644 index 0000000..6ba95e6 --- /dev/null +++ b/tools/testfiles/vds/1_b.h5 diff --git a/tools/testfiles/vds/1_c.h5 b/tools/testfiles/vds/1_c.h5 Binary files differnew file mode 100644 index 0000000..4bcebbd --- /dev/null +++ b/tools/testfiles/vds/1_c.h5 diff --git a/tools/testfiles/vds/1_d.h5 b/tools/testfiles/vds/1_d.h5 Binary files differnew file mode 100644 index 0000000..9c2d795 --- /dev/null +++ b/tools/testfiles/vds/1_d.h5 diff --git a/tools/testfiles/vds/1_e.h5 b/tools/testfiles/vds/1_e.h5 Binary files differnew file mode 100644 index 0000000..4f7aa7b --- /dev/null +++ b/tools/testfiles/vds/1_e.h5 diff --git a/tools/testfiles/vds/1_f.h5 b/tools/testfiles/vds/1_f.h5 Binary files differnew file mode 100644 index 0000000..62e86bc --- /dev/null +++ b/tools/testfiles/vds/1_f.h5 diff --git a/tools/testfiles/vds/1_vds.h5 b/tools/testfiles/vds/1_vds.h5 Binary files differnew file mode 100644 index 0000000..707a37f --- /dev/null +++ b/tools/testfiles/vds/1_vds.h5 diff --git a/tools/testfiles/vds/2_a.h5 b/tools/testfiles/vds/2_a.h5 Binary files differnew file mode 100644 index 0000000..5227e9e --- /dev/null +++ b/tools/testfiles/vds/2_a.h5 diff --git a/tools/testfiles/vds/2_b.h5 b/tools/testfiles/vds/2_b.h5 Binary files differnew file mode 100644 index 0000000..34723a3 --- /dev/null +++ b/tools/testfiles/vds/2_b.h5 diff --git a/tools/testfiles/vds/2_c.h5 b/tools/testfiles/vds/2_c.h5 Binary files differnew file mode 100644 index 0000000..d2252fc --- /dev/null +++ b/tools/testfiles/vds/2_c.h5 diff --git a/tools/testfiles/vds/2_d.h5 b/tools/testfiles/vds/2_d.h5 Binary files differnew file mode 100644 index 0000000..6880c2e --- /dev/null +++ b/tools/testfiles/vds/2_d.h5 diff --git a/tools/testfiles/vds/2_e.h5 b/tools/testfiles/vds/2_e.h5 Binary files differnew file mode 100644 index 0000000..81ffacc --- /dev/null +++ b/tools/testfiles/vds/2_e.h5 diff --git a/tools/testfiles/vds/2_vds.h5 b/tools/testfiles/vds/2_vds.h5 Binary files differnew file mode 100644 index 0000000..cbef59c --- /dev/null +++ b/tools/testfiles/vds/2_vds.h5 diff --git a/tools/testfiles/vds/3_1_vds.h5 b/tools/testfiles/vds/3_1_vds.h5 Binary files differnew file mode 100644 index 0000000..e66e4c7 --- /dev/null +++ b/tools/testfiles/vds/3_1_vds.h5 diff --git a/tools/testfiles/vds/3_2_vds.h5 b/tools/testfiles/vds/3_2_vds.h5 Binary files differnew file mode 100644 index 0000000..a19dab5 --- /dev/null +++ b/tools/testfiles/vds/3_2_vds.h5 diff --git a/tools/testfiles/vds/4_0.h5 b/tools/testfiles/vds/4_0.h5 Binary files differnew file mode 100644 index 0000000..5e71d20 --- /dev/null +++ b/tools/testfiles/vds/4_0.h5 diff --git a/tools/testfiles/vds/4_1.h5 b/tools/testfiles/vds/4_1.h5 Binary files differnew file mode 100644 index 0000000..edad46e --- /dev/null +++ b/tools/testfiles/vds/4_1.h5 diff --git a/tools/testfiles/vds/4_2.h5 b/tools/testfiles/vds/4_2.h5 Binary files differnew file mode 100644 index 0000000..a82b012 --- /dev/null +++ b/tools/testfiles/vds/4_2.h5 diff --git a/tools/testfiles/vds/4_vds.h5 b/tools/testfiles/vds/4_vds.h5 Binary files differnew file mode 100644 index 0000000..64c2288 --- /dev/null +++ b/tools/testfiles/vds/4_vds.h5 diff --git a/tools/testfiles/vds/5_a.h5 b/tools/testfiles/vds/5_a.h5 Binary files differnew file mode 100644 index 0000000..e8ea552 --- /dev/null +++ b/tools/testfiles/vds/5_a.h5 diff --git a/tools/testfiles/vds/5_b.h5 b/tools/testfiles/vds/5_b.h5 Binary files differnew file mode 100644 index 0000000..6da7cf5 --- /dev/null +++ b/tools/testfiles/vds/5_b.h5 diff --git a/tools/testfiles/vds/5_c.h5 b/tools/testfiles/vds/5_c.h5 Binary files differnew file mode 100644 index 0000000..3e3bc61 --- /dev/null +++ b/tools/testfiles/vds/5_c.h5 diff --git a/tools/testfiles/vds/5_vds.h5 b/tools/testfiles/vds/5_vds.h5 Binary files differnew file mode 100644 index 0000000..379485e --- /dev/null +++ b/tools/testfiles/vds/5_vds.h5 diff --git a/tools/testfiles/vds/tvds-1.ddl b/tools/testfiles/vds/tvds-1.ddl new file mode 100644 index 0000000..47fd413 --- /dev/null +++ b/tools/testfiles/vds/tvds-1.ddl @@ -0,0 +1,100 @@ +HDF5 "1_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 5, 18, 8 ) / ( H5S_UNLIMITED, 18, 8 ) } + DATA { + (0,0,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,1,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,2,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,3,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,6,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,7,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,8,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,9,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,10,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,11,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,12,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,13,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,14,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,15,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,16,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,17,0): 60, 60, 60, 60, 60, 60, 60, 60, + (1,0,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,1,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,2,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,3,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,6,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,7,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,8,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,9,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,10,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,11,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,12,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,13,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,14,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,15,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,16,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,17,0): 61, 61, 61, 61, 61, 61, 61, 61, + (2,0,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,1,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,2,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,3,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,6,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,7,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,8,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,9,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,10,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,11,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,12,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,13,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,14,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,15,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,16,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,17,0): 62, 62, 62, 62, 62, 62, 62, 62, + (3,0,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,1,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,2,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,3,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,6,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,7,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,8,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,9,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,10,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,11,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,12,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,13,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,14,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,15,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,16,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,17,0): 63, 63, 63, 63, 63, 63, 63, 63, + (4,0,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,1,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,2,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,3,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,6,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,7,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,8,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,9,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,10,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,11,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,12,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,13,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,14,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,15,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,16,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,17,0): 64, 64, 64, 64, 64, 64, 64, 64 + } + } +} +} diff --git a/tools/testfiles/vds/tvds-1.ls b/tools/testfiles/vds/tvds-1.ls new file mode 100644 index 0000000..61c9e46 --- /dev/null +++ b/tools/testfiles/vds/tvds-1.ls @@ -0,0 +1,14 @@ +Opened "1_vds.h5" with sec2 driver. +vds_dset Dataset {5/Inf, 18/18, 8/8} + Location: 1:800 + Links: 1 + Maps: {6} Source { + 1_a.h5 /source_dset + 1_b.h5 /source_dset + 1_c.h5 /source_dset + 1_d.h5 /source_dset + 1_e.h5 /source_dset + 1_f.h5 /source_dset + } + Storage: 2880 logical bytes, 0 allocated bytes + Type: 32-bit little-endian integer diff --git a/tools/testfiles/vds/tvds-2.ddl b/tools/testfiles/vds/tvds-2.ddl new file mode 100644 index 0000000..5f2ae16 --- /dev/null +++ b/tools/testfiles/vds/tvds-2.ddl @@ -0,0 +1,58 @@ +HDF5 "2_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 6, 8, 14 ) / ( H5S_UNLIMITED, 8, 14 ) } + DATA { + (0,0,0): 10, 10, 10, 10, 10, 10, 10, 40, 40, 40, 40, 40, 40, 40, + (0,1,0): 10, 10, 10, 10, 10, 10, 10, 40, 40, 40, 40, 40, 40, 40, + (0,2,0): 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, + (0,3,0): 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, 50, 50, 50, 50, 50, 50, 50, + (0,6,0): 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, + (0,7,0): 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, + (1,0,0): 11, 11, 11, 11, 11, 11, 11, 41, 41, 41, 41, 41, 41, 41, + (1,1,0): 11, 11, 11, 11, 11, 11, 11, 41, 41, 41, 41, 41, 41, 41, + (1,2,0): 21, 21, 21, 21, 21, 21, 21, 41, 41, 41, 41, 41, 41, 41, + (1,3,0): 21, 21, 21, 21, 21, 21, 21, 41, 41, 41, 41, 41, 41, 41, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, 41, 41, 41, 41, 41, 41, 41, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, 51, 51, 51, 51, 51, 51, 51, + (1,6,0): 31, 31, 31, 31, 31, 31, 31, 51, 51, 51, 51, 51, 51, 51, + (1,7,0): 31, 31, 31, 31, 31, 31, 31, 51, 51, 51, 51, 51, 51, 51, + (2,0,0): 12, 12, 12, 12, 12, 12, 12, 42, 42, 42, 42, 42, 42, 42, + (2,1,0): 12, 12, 12, 12, 12, 12, 12, 42, 42, 42, 42, 42, 42, 42, + (2,2,0): 22, 22, 22, 22, 22, 22, 22, 42, 42, 42, 42, 42, 42, 42, + (2,3,0): 22, 22, 22, 22, 22, 22, 22, 42, 42, 42, 42, 42, 42, 42, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, 42, 42, 42, 42, 42, 42, 42, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, 52, 52, 52, 52, 52, 52, 52, + (2,6,0): 32, 32, 32, 32, 32, 32, 32, 52, 52, 52, 52, 52, 52, 52, + (2,7,0): 32, 32, 32, 32, 32, 32, 32, 52, 52, 52, 52, 52, 52, 52, + (3,0,0): 13, 13, 13, 13, 13, 13, 13, 43, 43, 43, 43, 43, 43, 43, + (3,1,0): 13, 13, 13, 13, 13, 13, 13, 43, 43, 43, 43, 43, 43, 43, + (3,2,0): 23, 23, 23, 23, 23, 23, 23, 43, 43, 43, 43, 43, 43, 43, + (3,3,0): 23, 23, 23, 23, 23, 23, 23, 43, 43, 43, 43, 43, 43, 43, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, 43, 43, 43, 43, 43, 43, 43, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, 53, 53, 53, 53, 53, 53, 53, + (3,6,0): 33, 33, 33, 33, 33, 33, 33, 53, 53, 53, 53, 53, 53, 53, + (3,7,0): 33, 33, 33, 33, 33, 33, 33, 53, 53, 53, 53, 53, 53, 53, + (4,0,0): 14, 14, 14, 14, 14, 14, 14, 44, 44, 44, 44, 44, 44, 44, + (4,1,0): 14, 14, 14, 14, 14, 14, 14, 44, 44, 44, 44, 44, 44, 44, + (4,2,0): 24, 24, 24, 24, 24, 24, 24, 44, 44, 44, 44, 44, 44, 44, + (4,3,0): 24, 24, 24, 24, 24, 24, 24, 44, 44, 44, 44, 44, 44, 44, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, 44, 44, 44, 44, 44, 44, 44, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, + (4,6,0): 34, 34, 34, 34, 34, 34, 34, 54, 54, 54, 54, 54, 54, 54, + (4,7,0): 34, 34, 34, 34, 34, 34, 34, 54, 54, 54, 54, 54, 54, 54, + (5,0,0): 15, 15, 15, 15, 15, 15, 15, 45, 45, 45, 45, 45, 45, 45, + (5,1,0): 15, 15, 15, 15, 15, 15, 15, 45, 45, 45, 45, 45, 45, 45, + (5,2,0): 25, 25, 25, 25, 25, 25, 25, 45, 45, 45, 45, 45, 45, 45, + (5,3,0): 25, 25, 25, 25, 25, 25, 25, 45, 45, 45, 45, 45, 45, 45, + (5,4,0): 25, 25, 25, 25, 25, 25, 25, 45, 45, 45, 45, 45, 45, 45, + (5,5,0): 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, + (5,6,0): 35, 35, 35, 35, 35, 35, 35, 55, 55, 55, 55, 55, 55, 55, + (5,7,0): 35, 35, 35, 35, 35, 35, 35, 55, 55, 55, 55, 55, 55, 55 + } + } +} +} diff --git a/tools/testfiles/vds/tvds-2.ls b/tools/testfiles/vds/tvds-2.ls new file mode 100644 index 0000000..49fe05f --- /dev/null +++ b/tools/testfiles/vds/tvds-2.ls @@ -0,0 +1,13 @@ +Opened "2_vds.h5" with sec2 driver. +vds_dset Dataset {6/Inf, 8/8, 14/14} + Location: 1:800 + Links: 1 + Maps: {5} Source { + 2_a.h5 /source_dset + 2_b.h5 /source_dset + 2_c.h5 /source_dset + 2_d.h5 /source_dset + 2_e.h5 /source_dset + } + Storage: 2688 logical bytes, 0 allocated bytes + Type: 32-bit little-endian integer diff --git a/tools/testfiles/vds/tvds-3_1.ddl b/tools/testfiles/vds/tvds-3_1.ddl new file mode 100644 index 0000000..7d7d8b6 --- /dev/null +++ b/tools/testfiles/vds/tvds-3_1.ddl @@ -0,0 +1,135 @@ +HDF5 "3_1_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 5, 25, 8 ) / ( H5S_UNLIMITED, 25, 8 ) } + DATA { + (0,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,1,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,2,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,6,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,7,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,9,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,10,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,12,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,13,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,14,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,15,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,17,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,18,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,20,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,21,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,22,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,23,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,1,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,2,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,6,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,7,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,9,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,10,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,12,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,13,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,14,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,15,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,17,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,18,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,20,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,21,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,22,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,23,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,1,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,2,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,6,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,7,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,9,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,10,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,12,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,13,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,14,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,15,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,17,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,18,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,20,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,21,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,22,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,23,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,1,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,2,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,6,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,7,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,9,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,10,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,12,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,13,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,14,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,15,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,17,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,18,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,20,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,21,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,22,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,23,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,1,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,2,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,6,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,7,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,9,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,10,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,12,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,13,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,14,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,15,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,17,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,18,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,20,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,21,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,22,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,23,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,24,0): -9, -9, -9, -9, -9, -9, -9, -9 + } + } +} +} diff --git a/tools/testfiles/vds/tvds-3_1.ls b/tools/testfiles/vds/tvds-3_1.ls new file mode 100644 index 0000000..fe24002 --- /dev/null +++ b/tools/testfiles/vds/tvds-3_1.ls @@ -0,0 +1,14 @@ +Opened "3_1_vds.h5" with sec2 driver. +vds_dset Dataset {5/Inf, 25/25, 8/8} + Location: 1:800 + Links: 1 + Maps: {6} Source { + 1_a.h5 /source_dset + 1_b.h5 /source_dset + 1_c.h5 /source_dset + 1_d.h5 /source_dset + 1_e.h5 /source_dset + 1_f.h5 /source_dset + } + Storage: 4000 logical bytes, 0 allocated bytes + Type: 32-bit little-endian integer diff --git a/tools/testfiles/vds/tvds-3_2.ddl b/tools/testfiles/vds/tvds-3_2.ddl new file mode 100644 index 0000000..baec6f0 --- /dev/null +++ b/tools/testfiles/vds/tvds-3_2.ddl @@ -0,0 +1,166 @@ +HDF5 "3_2_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 6, 13, 19 ) / ( H5S_UNLIMITED, 13, 19 ) } + DATA { + (0,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (0,0,15): -9, -9, -9, -9, + (0,1,0): -9, 10, 10, 10, 10, 10, 10, 10, -9, 40, 40, 40, 40, 40, 40, + (0,1,15): 40, -9, -9, -9, + (0,2,0): -9, 10, 10, 10, 10, 10, 10, 10, -9, 40, 40, 40, 40, 40, 40, + (0,2,15): 40, -9, -9, -9, + (0,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 40, 40, 40, 40, 40, 40, + (0,3,15): 40, -9, -9, -9, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, 40, 40, 40, 40, 40, 40, + (0,4,15): 40, -9, -9, -9, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, 40, 40, 40, 40, 40, 40, + (0,5,15): 40, -9, -9, -9, + (0,6,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, -9, -9, -9, -9, -9, -9, + (0,6,15): -9, -9, -9, -9, + (0,7,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, -9, -9, -9, -9, -9, -9, + (0,7,15): -9, -9, -9, -9, + (0,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 50, 50, 50, + (0,8,15): 50, 50, 50, 50, + (0,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 50, 50, 50, + (0,9,15): 50, 50, 50, 50, + (0,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 50, 50, 50, + (0,10,15): 50, 50, 50, 50, + (0,11,0): -9, -9, -9, -9, 30, 30, 30, 30, 30, 30, 30, -9, -9, -9, -9, + (0,11,15): -9, -9, -9, -9, + (0,12,0): -9, -9, -9, -9, 30, 30, 30, 30, 30, 30, 30, -9, -9, -9, -9, + (0,12,15): -9, -9, -9, -9, + (1,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (1,0,15): -9, -9, -9, -9, + (1,1,0): -9, 11, 11, 11, 11, 11, 11, 11, -9, 41, 41, 41, 41, 41, 41, + (1,1,15): 41, -9, -9, -9, + (1,2,0): -9, 11, 11, 11, 11, 11, 11, 11, -9, 41, 41, 41, 41, 41, 41, + (1,2,15): 41, -9, -9, -9, + (1,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 41, 41, 41, 41, 41, 41, + (1,3,15): 41, -9, -9, -9, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, 41, 41, 41, 41, 41, 41, + (1,4,15): 41, -9, -9, -9, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, 41, 41, 41, 41, 41, 41, + (1,5,15): 41, -9, -9, -9, + (1,6,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, -9, -9, -9, -9, -9, -9, + (1,6,15): -9, -9, -9, -9, + (1,7,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, -9, -9, -9, -9, -9, -9, + (1,7,15): -9, -9, -9, -9, + (1,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 51, 51, 51, + (1,8,15): 51, 51, 51, 51, + (1,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 51, 51, 51, + (1,9,15): 51, 51, 51, 51, + (1,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 51, 51, 51, + (1,10,15): 51, 51, 51, 51, + (1,11,0): -9, -9, -9, -9, 31, 31, 31, 31, 31, 31, 31, -9, -9, -9, -9, + (1,11,15): -9, -9, -9, -9, + (1,12,0): -9, -9, -9, -9, 31, 31, 31, 31, 31, 31, 31, -9, -9, -9, -9, + (1,12,15): -9, -9, -9, -9, + (2,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (2,0,15): -9, -9, -9, -9, + (2,1,0): -9, 12, 12, 12, 12, 12, 12, 12, -9, 42, 42, 42, 42, 42, 42, + (2,1,15): 42, -9, -9, -9, + (2,2,0): -9, 12, 12, 12, 12, 12, 12, 12, -9, 42, 42, 42, 42, 42, 42, + (2,2,15): 42, -9, -9, -9, + (2,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 42, 42, 42, 42, 42, 42, + (2,3,15): 42, -9, -9, -9, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, 42, 42, 42, 42, 42, 42, + (2,4,15): 42, -9, -9, -9, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, 42, 42, 42, 42, 42, 42, + (2,5,15): 42, -9, -9, -9, + (2,6,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, -9, -9, -9, -9, -9, -9, + (2,6,15): -9, -9, -9, -9, + (2,7,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, -9, -9, -9, -9, -9, -9, + (2,7,15): -9, -9, -9, -9, + (2,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 52, 52, 52, + (2,8,15): 52, 52, 52, 52, + (2,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 52, 52, 52, + (2,9,15): 52, 52, 52, 52, + (2,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 52, 52, 52, + (2,10,15): 52, 52, 52, 52, + (2,11,0): -9, -9, -9, -9, 32, 32, 32, 32, 32, 32, 32, -9, -9, -9, -9, + (2,11,15): -9, -9, -9, -9, + (2,12,0): -9, -9, -9, -9, 32, 32, 32, 32, 32, 32, 32, -9, -9, -9, -9, + (2,12,15): -9, -9, -9, -9, + (3,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (3,0,15): -9, -9, -9, -9, + (3,1,0): -9, 13, 13, 13, 13, 13, 13, 13, -9, 43, 43, 43, 43, 43, 43, + (3,1,15): 43, -9, -9, -9, + (3,2,0): -9, 13, 13, 13, 13, 13, 13, 13, -9, 43, 43, 43, 43, 43, 43, + (3,2,15): 43, -9, -9, -9, + (3,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 43, 43, 43, 43, 43, 43, + (3,3,15): 43, -9, -9, -9, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, 43, 43, 43, 43, 43, 43, + (3,4,15): 43, -9, -9, -9, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, 43, 43, 43, 43, 43, 43, + (3,5,15): 43, -9, -9, -9, + (3,6,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, -9, -9, -9, -9, -9, -9, + (3,6,15): -9, -9, -9, -9, + (3,7,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, -9, -9, -9, -9, -9, -9, + (3,7,15): -9, -9, -9, -9, + (3,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 53, 53, 53, + (3,8,15): 53, 53, 53, 53, + (3,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 53, 53, 53, + (3,9,15): 53, 53, 53, 53, + (3,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 53, 53, 53, + (3,10,15): 53, 53, 53, 53, + (3,11,0): -9, -9, -9, -9, 33, 33, 33, 33, 33, 33, 33, -9, -9, -9, -9, + (3,11,15): -9, -9, -9, -9, + (3,12,0): -9, -9, -9, -9, 33, 33, 33, 33, 33, 33, 33, -9, -9, -9, -9, + (3,12,15): -9, -9, -9, -9, + (4,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (4,0,15): -9, -9, -9, -9, + (4,1,0): -9, 14, 14, 14, 14, 14, 14, 14, -9, 44, 44, 44, 44, 44, 44, + (4,1,15): 44, -9, -9, -9, + (4,2,0): -9, 14, 14, 14, 14, 14, 14, 14, -9, 44, 44, 44, 44, 44, 44, + (4,2,15): 44, -9, -9, -9, + (4,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 44, 44, 44, 44, 44, 44, + (4,3,15): 44, -9, -9, -9, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, 44, 44, 44, 44, 44, 44, + (4,4,15): 44, -9, -9, -9, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, 44, 44, 44, 44, 44, 44, + (4,5,15): 44, -9, -9, -9, + (4,6,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, -9, -9, -9, -9, -9, -9, + (4,6,15): -9, -9, -9, -9, + (4,7,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, -9, -9, -9, -9, -9, -9, + (4,7,15): -9, -9, -9, -9, + (4,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 54, 54, 54, + (4,8,15): 54, 54, 54, 54, + (4,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 54, 54, 54, + (4,9,15): 54, 54, 54, 54, + (4,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 54, 54, 54, + (4,10,15): 54, 54, 54, 54, + (4,11,0): -9, -9, -9, -9, 34, 34, 34, 34, 34, 34, 34, -9, -9, -9, -9, + (4,11,15): -9, -9, -9, -9, + (4,12,0): -9, -9, -9, -9, 34, 34, 34, 34, 34, 34, 34, -9, -9, -9, -9, + (4,12,15): -9, -9, -9, -9, + (5,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (5,0,15): -9, -9, -9, -9, + (5,1,0): -9, 15, 15, 15, 15, 15, 15, 15, -9, 45, 45, 45, 45, 45, 45, + (5,1,15): 45, -9, -9, -9, + (5,2,0): -9, 15, 15, 15, 15, 15, 15, 15, -9, 45, 45, 45, 45, 45, 45, + (5,2,15): 45, -9, -9, -9, + (5,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 45, 45, 45, 45, 45, 45, + (5,3,15): 45, -9, -9, -9, + (5,4,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, 45, 45, 45, 45, 45, 45, + (5,4,15): 45, -9, -9, -9, + (5,5,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, 45, 45, 45, 45, 45, 45, + (5,5,15): 45, -9, -9, -9, + (5,6,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, -9, -9, -9, -9, -9, -9, + (5,6,15): -9, -9, -9, -9, + (5,7,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, -9, -9, -9, -9, -9, -9, + (5,7,15): -9, -9, -9, -9, + (5,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 55, 55, 55, + (5,8,15): 55, 55, 55, 55, + (5,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 55, 55, 55, + (5,9,15): 55, 55, 55, 55, + (5,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 55, 55, 55, + (5,10,15): 55, 55, 55, 55, + (5,11,0): -9, -9, -9, -9, 35, 35, 35, 35, 35, 35, 35, -9, -9, -9, -9, + (5,11,15): -9, -9, -9, -9, + (5,12,0): -9, -9, -9, -9, 35, 35, 35, 35, 35, 35, 35, -9, -9, -9, -9, + (5,12,15): -9, -9, -9, -9 + } + } +} +} diff --git a/tools/testfiles/vds/tvds-3_2.ls b/tools/testfiles/vds/tvds-3_2.ls new file mode 100644 index 0000000..a4ad84f --- /dev/null +++ b/tools/testfiles/vds/tvds-3_2.ls @@ -0,0 +1,13 @@ +Opened "3_2_vds.h5" with sec2 driver. +vds_dset Dataset {6/Inf, 13/13, 19/19} + Location: 1:800 + Links: 1 + Maps: {5} Source { + 2_a.h5 /source_dset + 2_b.h5 /source_dset + 2_c.h5 /source_dset + 2_d.h5 /source_dset + 2_e.h5 /source_dset + } + Storage: 5928 logical bytes, 0 allocated bytes + Type: 32-bit little-endian integer diff --git a/tools/testfiles/vds/tvds-4.ddl b/tools/testfiles/vds/tvds-4.ddl new file mode 100644 index 0000000..1832724 --- /dev/null +++ b/tools/testfiles/vds/tvds-4.ddl @@ -0,0 +1,46 @@ +HDF5 "4_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 9, 4, 4 ) / ( H5S_UNLIMITED, 4, 4 ) } + DATA { + (0,0,0): 10, 10, 10, 10, + (0,1,0): 10, 10, 10, 10, + (0,2,0): 10, 10, 10, 10, + (0,3,0): 10, 10, 10, 10, + (1,0,0): 11, 11, 11, 11, + (1,1,0): 11, 11, 11, 11, + (1,2,0): 11, 11, 11, 11, + (1,3,0): 11, 11, 11, 11, + (2,0,0): 12, 12, 12, 12, + (2,1,0): 12, 12, 12, 12, + (2,2,0): 12, 12, 12, 12, + (2,3,0): 12, 12, 12, 12, + (3,0,0): 20, 20, 20, 20, + (3,1,0): 20, 20, 20, 20, + (3,2,0): 20, 20, 20, 20, + (3,3,0): 20, 20, 20, 20, + (4,0,0): 21, 21, 21, 21, + (4,1,0): 21, 21, 21, 21, + (4,2,0): 21, 21, 21, 21, + (4,3,0): 21, 21, 21, 21, + (5,0,0): 22, 22, 22, 22, + (5,1,0): 22, 22, 22, 22, + (5,2,0): 22, 22, 22, 22, + (5,3,0): 22, 22, 22, 22, + (6,0,0): 30, 30, 30, 30, + (6,1,0): 30, 30, 30, 30, + (6,2,0): 30, 30, 30, 30, + (6,3,0): 30, 30, 30, 30, + (7,0,0): 31, 31, 31, 31, + (7,1,0): 31, 31, 31, 31, + (7,2,0): 31, 31, 31, 31, + (7,3,0): 31, 31, 31, 31, + (8,0,0): 32, 32, 32, 32, + (8,1,0): 32, 32, 32, 32, + (8,2,0): 32, 32, 32, 32, + (8,3,0): 32, 32, 32, 32 + } + } +} +} diff --git a/tools/testfiles/vds/tvds-4.ls b/tools/testfiles/vds/tvds-4.ls new file mode 100644 index 0000000..176529b --- /dev/null +++ b/tools/testfiles/vds/tvds-4.ls @@ -0,0 +1,9 @@ +Opened "4_vds.h5" with sec2 driver. +vds_dset Dataset {9/Inf, 4/4, 4/4} + Location: 1:800 + Links: 1 + Maps: {1} Source { + 4_%b.h5 /source_dset + } + Storage: 576 logical bytes, 0 allocated bytes + Type: 32-bit little-endian integer diff --git a/tools/testfiles/vds/tvds-5.ddl b/tools/testfiles/vds/tvds-5.ddl new file mode 100644 index 0000000..f59017b --- /dev/null +++ b/tools/testfiles/vds/tvds-5.ddl @@ -0,0 +1,46 @@ +HDF5 "5_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 9, 4, 4 ) / ( H5S_UNLIMITED, 4, 4 ) } + DATA { + (0,0,0): 10, 10, 10, 10, + (0,1,0): 10, 10, 10, 10, + (0,2,0): 10, 10, 10, 10, + (0,3,0): 10, 10, 10, 10, + (1,0,0): 20, 20, 20, 20, + (1,1,0): 20, 20, 20, 20, + (1,2,0): 20, 20, 20, 20, + (1,3,0): 20, 20, 20, 20, + (2,0,0): 30, 30, 30, 30, + (2,1,0): 30, 30, 30, 30, + (2,2,0): 30, 30, 30, 30, + (2,3,0): 30, 30, 30, 30, + (3,0,0): 11, 11, 11, 11, + (3,1,0): 11, 11, 11, 11, + (3,2,0): 11, 11, 11, 11, + (3,3,0): 11, 11, 11, 11, + (4,0,0): 21, 21, 21, 21, + (4,1,0): 21, 21, 21, 21, + (4,2,0): 21, 21, 21, 21, + (4,3,0): 21, 21, 21, 21, + (5,0,0): 31, 31, 31, 31, + (5,1,0): 31, 31, 31, 31, + (5,2,0): 31, 31, 31, 31, + (5,3,0): 31, 31, 31, 31, + (6,0,0): 12, 12, 12, 12, + (6,1,0): 12, 12, 12, 12, + (6,2,0): 12, 12, 12, 12, + (6,3,0): 12, 12, 12, 12, + (7,0,0): 22, 22, 22, 22, + (7,1,0): 22, 22, 22, 22, + (7,2,0): 22, 22, 22, 22, + (7,3,0): 22, 22, 22, 22, + (8,0,0): 32, 32, 32, 32, + (8,1,0): 32, 32, 32, 32, + (8,2,0): 32, 32, 32, 32, + (8,3,0): 32, 32, 32, 32 + } + } +} +} diff --git a/tools/testfiles/vds/tvds-5.ls b/tools/testfiles/vds/tvds-5.ls new file mode 100644 index 0000000..5f98e84 --- /dev/null +++ b/tools/testfiles/vds/tvds-5.ls @@ -0,0 +1,11 @@ +Opened "5_vds.h5" with sec2 driver. +vds_dset Dataset {9/Inf, 4/4, 4/4} + Location: 1:800 + Links: 1 + Maps: {3} Source { + 5_a.h5 /source_dset + 5_b.h5 /source_dset + 5_c.h5 /source_dset + } + Storage: 576 logical bytes, 0 allocated bytes + Type: 32-bit little-endian integer diff --git a/tools/testfiles/vds/tvds_layout-1.ddl b/tools/testfiles/vds/tvds_layout-1.ddl new file mode 100644 index 0000000..5d8a62c --- /dev/null +++ b/tools/testfiles/vds/tvds_layout-1.ddl @@ -0,0 +1,232 @@ +HDF5 "1_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 5, 18, 8 ) / ( H5S_UNLIMITED, 18, 8 ) } + STORAGE_LAYOUT { + MAPPING 0 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + SOURCE { + FILE "1_a.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + } + MAPPING 1 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,2,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + SOURCE { + FILE "1_b.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + } + MAPPING 2 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,6,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + SOURCE { + FILE "1_c.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + } + MAPPING 3 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,8,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + SOURCE { + FILE "1_d.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + } + MAPPING 4 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,12,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + SOURCE { + FILE "1_e.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + } + MAPPING 5 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,14,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + SOURCE { + FILE "1_f.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + } + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE -9 + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_INCR + } + DATA { + (0,0,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,1,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,2,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,3,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,6,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,7,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,8,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,9,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,10,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,11,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,12,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,13,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,14,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,15,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,16,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,17,0): 60, 60, 60, 60, 60, 60, 60, 60, + (1,0,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,1,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,2,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,3,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,6,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,7,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,8,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,9,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,10,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,11,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,12,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,13,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,14,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,15,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,16,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,17,0): 61, 61, 61, 61, 61, 61, 61, 61, + (2,0,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,1,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,2,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,3,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,6,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,7,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,8,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,9,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,10,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,11,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,12,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,13,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,14,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,15,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,16,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,17,0): 62, 62, 62, 62, 62, 62, 62, 62, + (3,0,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,1,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,2,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,3,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,6,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,7,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,8,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,9,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,10,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,11,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,12,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,13,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,14,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,15,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,16,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,17,0): 63, 63, 63, 63, 63, 63, 63, 63, + (4,0,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,1,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,2,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,3,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,6,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,7,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,8,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,9,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,10,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,11,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,12,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,13,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,14,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,15,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,16,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,17,0): 64, 64, 64, 64, 64, 64, 64, 64 + } + } +} +} diff --git a/tools/testfiles/vds/tvds_layout-2.ddl b/tools/testfiles/vds/tvds_layout-2.ddl new file mode 100644 index 0000000..af6b718 --- /dev/null +++ b/tools/testfiles/vds/tvds_layout-2.ddl @@ -0,0 +1,170 @@ +HDF5 "2_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 6, 8, 14 ) / ( H5S_UNLIMITED, 8, 14 ) } + STORAGE_LAYOUT { + MAPPING 0 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + SOURCE { + FILE "2_a.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + } + MAPPING 1 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,2,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,7) + } + } + SOURCE { + FILE "2_b.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,7) + } + } + } + MAPPING 2 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,6,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + SOURCE { + FILE "2_c.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + } + MAPPING 3 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,0,7) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,5,7) + } + } + SOURCE { + FILE "2_d.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,5,7) + } + } + } + MAPPING 4 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,5,7) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,3,7) + } + } + SOURCE { + FILE "2_e.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,3,7) + } + } + } + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE -9 + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_INCR + } + DATA { + (0,0,0): 10, 10, 10, 10, 10, 10, 10, 40, 40, 40, 40, 40, 40, 40, + (0,1,0): 10, 10, 10, 10, 10, 10, 10, 40, 40, 40, 40, 40, 40, 40, + (0,2,0): 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, + (0,3,0): 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, 40, 40, 40, 40, 40, 40, 40, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, 50, 50, 50, 50, 50, 50, 50, + (0,6,0): 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, + (0,7,0): 30, 30, 30, 30, 30, 30, 30, 50, 50, 50, 50, 50, 50, 50, + (1,0,0): 11, 11, 11, 11, 11, 11, 11, 41, 41, 41, 41, 41, 41, 41, + (1,1,0): 11, 11, 11, 11, 11, 11, 11, 41, 41, 41, 41, 41, 41, 41, + (1,2,0): 21, 21, 21, 21, 21, 21, 21, 41, 41, 41, 41, 41, 41, 41, + (1,3,0): 21, 21, 21, 21, 21, 21, 21, 41, 41, 41, 41, 41, 41, 41, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, 41, 41, 41, 41, 41, 41, 41, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, 51, 51, 51, 51, 51, 51, 51, + (1,6,0): 31, 31, 31, 31, 31, 31, 31, 51, 51, 51, 51, 51, 51, 51, + (1,7,0): 31, 31, 31, 31, 31, 31, 31, 51, 51, 51, 51, 51, 51, 51, + (2,0,0): 12, 12, 12, 12, 12, 12, 12, 42, 42, 42, 42, 42, 42, 42, + (2,1,0): 12, 12, 12, 12, 12, 12, 12, 42, 42, 42, 42, 42, 42, 42, + (2,2,0): 22, 22, 22, 22, 22, 22, 22, 42, 42, 42, 42, 42, 42, 42, + (2,3,0): 22, 22, 22, 22, 22, 22, 22, 42, 42, 42, 42, 42, 42, 42, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, 42, 42, 42, 42, 42, 42, 42, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, 52, 52, 52, 52, 52, 52, 52, + (2,6,0): 32, 32, 32, 32, 32, 32, 32, 52, 52, 52, 52, 52, 52, 52, + (2,7,0): 32, 32, 32, 32, 32, 32, 32, 52, 52, 52, 52, 52, 52, 52, + (3,0,0): 13, 13, 13, 13, 13, 13, 13, 43, 43, 43, 43, 43, 43, 43, + (3,1,0): 13, 13, 13, 13, 13, 13, 13, 43, 43, 43, 43, 43, 43, 43, + (3,2,0): 23, 23, 23, 23, 23, 23, 23, 43, 43, 43, 43, 43, 43, 43, + (3,3,0): 23, 23, 23, 23, 23, 23, 23, 43, 43, 43, 43, 43, 43, 43, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, 43, 43, 43, 43, 43, 43, 43, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, 53, 53, 53, 53, 53, 53, 53, + (3,6,0): 33, 33, 33, 33, 33, 33, 33, 53, 53, 53, 53, 53, 53, 53, + (3,7,0): 33, 33, 33, 33, 33, 33, 33, 53, 53, 53, 53, 53, 53, 53, + (4,0,0): 14, 14, 14, 14, 14, 14, 14, 44, 44, 44, 44, 44, 44, 44, + (4,1,0): 14, 14, 14, 14, 14, 14, 14, 44, 44, 44, 44, 44, 44, 44, + (4,2,0): 24, 24, 24, 24, 24, 24, 24, 44, 44, 44, 44, 44, 44, 44, + (4,3,0): 24, 24, 24, 24, 24, 24, 24, 44, 44, 44, 44, 44, 44, 44, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, 44, 44, 44, 44, 44, 44, 44, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, + (4,6,0): 34, 34, 34, 34, 34, 34, 34, 54, 54, 54, 54, 54, 54, 54, + (4,7,0): 34, 34, 34, 34, 34, 34, 34, 54, 54, 54, 54, 54, 54, 54, + (5,0,0): 15, 15, 15, 15, 15, 15, 15, 45, 45, 45, 45, 45, 45, 45, + (5,1,0): 15, 15, 15, 15, 15, 15, 15, 45, 45, 45, 45, 45, 45, 45, + (5,2,0): 25, 25, 25, 25, 25, 25, 25, 45, 45, 45, 45, 45, 45, 45, + (5,3,0): 25, 25, 25, 25, 25, 25, 25, 45, 45, 45, 45, 45, 45, 45, + (5,4,0): 25, 25, 25, 25, 25, 25, 25, 45, 45, 45, 45, 45, 45, 45, + (5,5,0): 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, + (5,6,0): 35, 35, 35, 35, 35, 35, 35, 55, 55, 55, 55, 55, 55, 55, + (5,7,0): 35, 35, 35, 35, 35, 35, 35, 55, 55, 55, 55, 55, 55, 55 + } + } +} +} diff --git a/tools/testfiles/vds/tvds_layout-3_1.ddl b/tools/testfiles/vds/tvds_layout-3_1.ddl new file mode 100644 index 0000000..968327d --- /dev/null +++ b/tools/testfiles/vds/tvds_layout-3_1.ddl @@ -0,0 +1,267 @@ +HDF5 "3_1_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 5, 25, 8 ) / ( H5S_UNLIMITED, 25, 8 ) } + STORAGE_LAYOUT { + MAPPING 0 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,1,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + SOURCE { + FILE "1_a.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + } + MAPPING 1 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,4,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + SOURCE { + FILE "1_b.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + } + MAPPING 2 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,9,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + SOURCE { + FILE "1_c.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + } + MAPPING 3 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,12,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + SOURCE { + FILE "1_d.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + } + MAPPING 4 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,17,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + SOURCE { + FILE "1_e.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,8) + } + } + } + MAPPING 5 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,20,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + SOURCE { + FILE "1_f.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,8) + } + } + } + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE -9 + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_INCR + } + DATA { + (0,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,1,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,2,0): 10, 10, 10, 10, 10, 10, 10, 10, + (0,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,6,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,7,0): 20, 20, 20, 20, 20, 20, 20, 20, + (0,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,9,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,10,0): 30, 30, 30, 30, 30, 30, 30, 30, + (0,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,12,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,13,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,14,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,15,0): 40, 40, 40, 40, 40, 40, 40, 40, + (0,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,17,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,18,0): 50, 50, 50, 50, 50, 50, 50, 50, + (0,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (0,20,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,21,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,22,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,23,0): 60, 60, 60, 60, 60, 60, 60, 60, + (0,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,1,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,2,0): 11, 11, 11, 11, 11, 11, 11, 11, + (1,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,6,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,7,0): 21, 21, 21, 21, 21, 21, 21, 21, + (1,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,9,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,10,0): 31, 31, 31, 31, 31, 31, 31, 31, + (1,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,12,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,13,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,14,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,15,0): 41, 41, 41, 41, 41, 41, 41, 41, + (1,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,17,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,18,0): 51, 51, 51, 51, 51, 51, 51, 51, + (1,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (1,20,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,21,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,22,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,23,0): 61, 61, 61, 61, 61, 61, 61, 61, + (1,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,1,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,2,0): 12, 12, 12, 12, 12, 12, 12, 12, + (2,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,6,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,7,0): 22, 22, 22, 22, 22, 22, 22, 22, + (2,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,9,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,10,0): 32, 32, 32, 32, 32, 32, 32, 32, + (2,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,12,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,13,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,14,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,15,0): 42, 42, 42, 42, 42, 42, 42, 42, + (2,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,17,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,18,0): 52, 52, 52, 52, 52, 52, 52, 52, + (2,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (2,20,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,21,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,22,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,23,0): 62, 62, 62, 62, 62, 62, 62, 62, + (2,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,1,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,2,0): 13, 13, 13, 13, 13, 13, 13, 13, + (3,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,6,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,7,0): 23, 23, 23, 23, 23, 23, 23, 23, + (3,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,9,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,10,0): 33, 33, 33, 33, 33, 33, 33, 33, + (3,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,12,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,13,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,14,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,15,0): 43, 43, 43, 43, 43, 43, 43, 43, + (3,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,17,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,18,0): 53, 53, 53, 53, 53, 53, 53, 53, + (3,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (3,20,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,21,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,22,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,23,0): 63, 63, 63, 63, 63, 63, 63, 63, + (3,24,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,0,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,1,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,2,0): 14, 14, 14, 14, 14, 14, 14, 14, + (4,3,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,6,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,7,0): 24, 24, 24, 24, 24, 24, 24, 24, + (4,8,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,9,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,10,0): 34, 34, 34, 34, 34, 34, 34, 34, + (4,11,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,12,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,13,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,14,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,15,0): 44, 44, 44, 44, 44, 44, 44, 44, + (4,16,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,17,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,18,0): 54, 54, 54, 54, 54, 54, 54, 54, + (4,19,0): -9, -9, -9, -9, -9, -9, -9, -9, + (4,20,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,21,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,22,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,23,0): 64, 64, 64, 64, 64, 64, 64, 64, + (4,24,0): -9, -9, -9, -9, -9, -9, -9, -9 + } + } +} +} diff --git a/tools/testfiles/vds/tvds_layout-3_2.ddl b/tools/testfiles/vds/tvds_layout-3_2.ddl new file mode 100644 index 0000000..7e14ec2 --- /dev/null +++ b/tools/testfiles/vds/tvds_layout-3_2.ddl @@ -0,0 +1,278 @@ +HDF5 "3_2_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 6, 13, 19 ) / ( H5S_UNLIMITED, 13, 19 ) } + STORAGE_LAYOUT { + MAPPING 0 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,1,1) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + SOURCE { + FILE "2_a.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + } + MAPPING 1 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,4,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,7) + } + } + SOURCE { + FILE "2_b.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,7) + } + } + } + MAPPING 2 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,11,4) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + SOURCE { + FILE "2_c.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,2,7) + } + } + } + MAPPING 3 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,1,9) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,5,7) + } + } + SOURCE { + FILE "2_d.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,5,7) + } + } + } + MAPPING 4 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,8,12) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,3,7) + } + } + SOURCE { + FILE "2_e.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,3,7) + } + } + } + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE -9 + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_INCR + } + DATA { + (0,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (0,0,15): -9, -9, -9, -9, + (0,1,0): -9, 10, 10, 10, 10, 10, 10, 10, -9, 40, 40, 40, 40, 40, 40, + (0,1,15): 40, -9, -9, -9, + (0,2,0): -9, 10, 10, 10, 10, 10, 10, 10, -9, 40, 40, 40, 40, 40, 40, + (0,2,15): 40, -9, -9, -9, + (0,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 40, 40, 40, 40, 40, 40, + (0,3,15): 40, -9, -9, -9, + (0,4,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, 40, 40, 40, 40, 40, 40, + (0,4,15): 40, -9, -9, -9, + (0,5,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, 40, 40, 40, 40, 40, 40, + (0,5,15): 40, -9, -9, -9, + (0,6,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, -9, -9, -9, -9, -9, -9, + (0,6,15): -9, -9, -9, -9, + (0,7,0): 20, 20, 20, 20, 20, 20, 20, -9, -9, -9, -9, -9, -9, -9, -9, + (0,7,15): -9, -9, -9, -9, + (0,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 50, 50, 50, + (0,8,15): 50, 50, 50, 50, + (0,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 50, 50, 50, + (0,9,15): 50, 50, 50, 50, + (0,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 50, 50, 50, + (0,10,15): 50, 50, 50, 50, + (0,11,0): -9, -9, -9, -9, 30, 30, 30, 30, 30, 30, 30, -9, -9, -9, -9, + (0,11,15): -9, -9, -9, -9, + (0,12,0): -9, -9, -9, -9, 30, 30, 30, 30, 30, 30, 30, -9, -9, -9, -9, + (0,12,15): -9, -9, -9, -9, + (1,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (1,0,15): -9, -9, -9, -9, + (1,1,0): -9, 11, 11, 11, 11, 11, 11, 11, -9, 41, 41, 41, 41, 41, 41, + (1,1,15): 41, -9, -9, -9, + (1,2,0): -9, 11, 11, 11, 11, 11, 11, 11, -9, 41, 41, 41, 41, 41, 41, + (1,2,15): 41, -9, -9, -9, + (1,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 41, 41, 41, 41, 41, 41, + (1,3,15): 41, -9, -9, -9, + (1,4,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, 41, 41, 41, 41, 41, 41, + (1,4,15): 41, -9, -9, -9, + (1,5,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, 41, 41, 41, 41, 41, 41, + (1,5,15): 41, -9, -9, -9, + (1,6,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, -9, -9, -9, -9, -9, -9, + (1,6,15): -9, -9, -9, -9, + (1,7,0): 21, 21, 21, 21, 21, 21, 21, -9, -9, -9, -9, -9, -9, -9, -9, + (1,7,15): -9, -9, -9, -9, + (1,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 51, 51, 51, + (1,8,15): 51, 51, 51, 51, + (1,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 51, 51, 51, + (1,9,15): 51, 51, 51, 51, + (1,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 51, 51, 51, + (1,10,15): 51, 51, 51, 51, + (1,11,0): -9, -9, -9, -9, 31, 31, 31, 31, 31, 31, 31, -9, -9, -9, -9, + (1,11,15): -9, -9, -9, -9, + (1,12,0): -9, -9, -9, -9, 31, 31, 31, 31, 31, 31, 31, -9, -9, -9, -9, + (1,12,15): -9, -9, -9, -9, + (2,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (2,0,15): -9, -9, -9, -9, + (2,1,0): -9, 12, 12, 12, 12, 12, 12, 12, -9, 42, 42, 42, 42, 42, 42, + (2,1,15): 42, -9, -9, -9, + (2,2,0): -9, 12, 12, 12, 12, 12, 12, 12, -9, 42, 42, 42, 42, 42, 42, + (2,2,15): 42, -9, -9, -9, + (2,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 42, 42, 42, 42, 42, 42, + (2,3,15): 42, -9, -9, -9, + (2,4,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, 42, 42, 42, 42, 42, 42, + (2,4,15): 42, -9, -9, -9, + (2,5,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, 42, 42, 42, 42, 42, 42, + (2,5,15): 42, -9, -9, -9, + (2,6,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, -9, -9, -9, -9, -9, -9, + (2,6,15): -9, -9, -9, -9, + (2,7,0): 22, 22, 22, 22, 22, 22, 22, -9, -9, -9, -9, -9, -9, -9, -9, + (2,7,15): -9, -9, -9, -9, + (2,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 52, 52, 52, + (2,8,15): 52, 52, 52, 52, + (2,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 52, 52, 52, + (2,9,15): 52, 52, 52, 52, + (2,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 52, 52, 52, + (2,10,15): 52, 52, 52, 52, + (2,11,0): -9, -9, -9, -9, 32, 32, 32, 32, 32, 32, 32, -9, -9, -9, -9, + (2,11,15): -9, -9, -9, -9, + (2,12,0): -9, -9, -9, -9, 32, 32, 32, 32, 32, 32, 32, -9, -9, -9, -9, + (2,12,15): -9, -9, -9, -9, + (3,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (3,0,15): -9, -9, -9, -9, + (3,1,0): -9, 13, 13, 13, 13, 13, 13, 13, -9, 43, 43, 43, 43, 43, 43, + (3,1,15): 43, -9, -9, -9, + (3,2,0): -9, 13, 13, 13, 13, 13, 13, 13, -9, 43, 43, 43, 43, 43, 43, + (3,2,15): 43, -9, -9, -9, + (3,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 43, 43, 43, 43, 43, 43, + (3,3,15): 43, -9, -9, -9, + (3,4,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, 43, 43, 43, 43, 43, 43, + (3,4,15): 43, -9, -9, -9, + (3,5,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, 43, 43, 43, 43, 43, 43, + (3,5,15): 43, -9, -9, -9, + (3,6,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, -9, -9, -9, -9, -9, -9, + (3,6,15): -9, -9, -9, -9, + (3,7,0): 23, 23, 23, 23, 23, 23, 23, -9, -9, -9, -9, -9, -9, -9, -9, + (3,7,15): -9, -9, -9, -9, + (3,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 53, 53, 53, + (3,8,15): 53, 53, 53, 53, + (3,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 53, 53, 53, + (3,9,15): 53, 53, 53, 53, + (3,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 53, 53, 53, + (3,10,15): 53, 53, 53, 53, + (3,11,0): -9, -9, -9, -9, 33, 33, 33, 33, 33, 33, 33, -9, -9, -9, -9, + (3,11,15): -9, -9, -9, -9, + (3,12,0): -9, -9, -9, -9, 33, 33, 33, 33, 33, 33, 33, -9, -9, -9, -9, + (3,12,15): -9, -9, -9, -9, + (4,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (4,0,15): -9, -9, -9, -9, + (4,1,0): -9, 14, 14, 14, 14, 14, 14, 14, -9, 44, 44, 44, 44, 44, 44, + (4,1,15): 44, -9, -9, -9, + (4,2,0): -9, 14, 14, 14, 14, 14, 14, 14, -9, 44, 44, 44, 44, 44, 44, + (4,2,15): 44, -9, -9, -9, + (4,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 44, 44, 44, 44, 44, 44, + (4,3,15): 44, -9, -9, -9, + (4,4,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, 44, 44, 44, 44, 44, 44, + (4,4,15): 44, -9, -9, -9, + (4,5,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, 44, 44, 44, 44, 44, 44, + (4,5,15): 44, -9, -9, -9, + (4,6,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, -9, -9, -9, -9, -9, -9, + (4,6,15): -9, -9, -9, -9, + (4,7,0): 24, 24, 24, 24, 24, 24, 24, -9, -9, -9, -9, -9, -9, -9, -9, + (4,7,15): -9, -9, -9, -9, + (4,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 54, 54, 54, + (4,8,15): 54, 54, 54, 54, + (4,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 54, 54, 54, + (4,9,15): 54, 54, 54, 54, + (4,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 54, 54, 54, + (4,10,15): 54, 54, 54, 54, + (4,11,0): -9, -9, -9, -9, 34, 34, 34, 34, 34, 34, 34, -9, -9, -9, -9, + (4,11,15): -9, -9, -9, -9, + (4,12,0): -9, -9, -9, -9, 34, 34, 34, 34, 34, 34, 34, -9, -9, -9, -9, + (4,12,15): -9, -9, -9, -9, + (5,0,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + (5,0,15): -9, -9, -9, -9, + (5,1,0): -9, 15, 15, 15, 15, 15, 15, 15, -9, 45, 45, 45, 45, 45, 45, + (5,1,15): 45, -9, -9, -9, + (5,2,0): -9, 15, 15, 15, 15, 15, 15, 15, -9, 45, 45, 45, 45, 45, 45, + (5,2,15): 45, -9, -9, -9, + (5,3,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, 45, 45, 45, 45, 45, 45, + (5,3,15): 45, -9, -9, -9, + (5,4,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, 45, 45, 45, 45, 45, 45, + (5,4,15): 45, -9, -9, -9, + (5,5,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, 45, 45, 45, 45, 45, 45, + (5,5,15): 45, -9, -9, -9, + (5,6,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, -9, -9, -9, -9, -9, -9, + (5,6,15): -9, -9, -9, -9, + (5,7,0): 25, 25, 25, 25, 25, 25, 25, -9, -9, -9, -9, -9, -9, -9, -9, + (5,7,15): -9, -9, -9, -9, + (5,8,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 55, 55, 55, + (5,8,15): 55, 55, 55, 55, + (5,9,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 55, 55, 55, + (5,9,15): 55, 55, 55, 55, + (5,10,0): -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 55, 55, 55, + (5,10,15): 55, 55, 55, 55, + (5,11,0): -9, -9, -9, -9, 35, 35, 35, 35, 35, 35, 35, -9, -9, -9, -9, + (5,11,15): -9, -9, -9, -9, + (5,12,0): -9, -9, -9, -9, 35, 35, 35, 35, 35, 35, 35, -9, -9, -9, -9, + (5,12,15): -9, -9, -9, -9 + } + } +} +} diff --git a/tools/testfiles/vds/tvds_layout-4.ddl b/tools/testfiles/vds/tvds_layout-4.ddl new file mode 100644 index 0000000..018644e --- /dev/null +++ b/tools/testfiles/vds/tvds_layout-4.ddl @@ -0,0 +1,78 @@ +HDF5 "4_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 9, 4, 4 ) / ( H5S_UNLIMITED, 4, 4 ) } + STORAGE_LAYOUT { + MAPPING 0 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (3,1,1) + COUNT (H5S_UNLIMITED,1,1) + BLOCK (3,4,4) + } + } + SOURCE { + FILE "4_%b.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (3,4,4) + } + } + } + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE -9 + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_INCR + } + DATA { + (0,0,0): 10, 10, 10, 10, + (0,1,0): 10, 10, 10, 10, + (0,2,0): 10, 10, 10, 10, + (0,3,0): 10, 10, 10, 10, + (1,0,0): 11, 11, 11, 11, + (1,1,0): 11, 11, 11, 11, + (1,2,0): 11, 11, 11, 11, + (1,3,0): 11, 11, 11, 11, + (2,0,0): 12, 12, 12, 12, + (2,1,0): 12, 12, 12, 12, + (2,2,0): 12, 12, 12, 12, + (2,3,0): 12, 12, 12, 12, + (3,0,0): 20, 20, 20, 20, + (3,1,0): 20, 20, 20, 20, + (3,2,0): 20, 20, 20, 20, + (3,3,0): 20, 20, 20, 20, + (4,0,0): 21, 21, 21, 21, + (4,1,0): 21, 21, 21, 21, + (4,2,0): 21, 21, 21, 21, + (4,3,0): 21, 21, 21, 21, + (5,0,0): 22, 22, 22, 22, + (5,1,0): 22, 22, 22, 22, + (5,2,0): 22, 22, 22, 22, + (5,3,0): 22, 22, 22, 22, + (6,0,0): 30, 30, 30, 30, + (6,1,0): 30, 30, 30, 30, + (6,2,0): 30, 30, 30, 30, + (6,3,0): 30, 30, 30, 30, + (7,0,0): 31, 31, 31, 31, + (7,1,0): 31, 31, 31, 31, + (7,2,0): 31, 31, 31, 31, + (7,3,0): 31, 31, 31, 31, + (8,0,0): 32, 32, 32, 32, + (8,1,0): 32, 32, 32, 32, + (8,2,0): 32, 32, 32, 32, + (8,3,0): 32, 32, 32, 32 + } + } +} +} diff --git a/tools/testfiles/vds/tvds_layout-5.ddl b/tools/testfiles/vds/tvds_layout-5.ddl new file mode 100644 index 0000000..b43629a --- /dev/null +++ b/tools/testfiles/vds/tvds_layout-5.ddl @@ -0,0 +1,118 @@ +HDF5 "5_vds.h5" { +GROUP "/" { + DATASET "vds_dset" { + DATATYPE H5T_STD_I32LE + DATASPACE SIMPLE { ( 9, 4, 4 ) / ( H5S_UNLIMITED, 4, 4 ) } + STORAGE_LAYOUT { + MAPPING 0 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (3,1,1) + COUNT (H5S_UNLIMITED,1,1) + BLOCK (1,4,4) + } + } + SOURCE { + FILE "5_a.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,4) + } + } + } + MAPPING 1 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (1,0,0) + STRIDE (3,1,1) + COUNT (H5S_UNLIMITED,1,1) + BLOCK (1,4,4) + } + } + SOURCE { + FILE "5_b.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,4) + } + } + } + MAPPING 2 { + VIRTUAL { + SELECTION REGULAR_HYPERSLAB { + START (2,0,0) + STRIDE (3,1,1) + COUNT (H5S_UNLIMITED,1,1) + BLOCK (1,4,4) + } + } + SOURCE { + FILE "5_c.h5" + DATASET "/source_dset" + SELECTION REGULAR_HYPERSLAB { + START (0,0,0) + STRIDE (1,1,1) + COUNT (1,1,1) + BLOCK (H5S_UNLIMITED,4,4) + } + } + } + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE -9 + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_INCR + } + DATA { + (0,0,0): 10, 10, 10, 10, + (0,1,0): 10, 10, 10, 10, + (0,2,0): 10, 10, 10, 10, + (0,3,0): 10, 10, 10, 10, + (1,0,0): 20, 20, 20, 20, + (1,1,0): 20, 20, 20, 20, + (1,2,0): 20, 20, 20, 20, + (1,3,0): 20, 20, 20, 20, + (2,0,0): 30, 30, 30, 30, + (2,1,0): 30, 30, 30, 30, + (2,2,0): 30, 30, 30, 30, + (2,3,0): 30, 30, 30, 30, + (3,0,0): 11, 11, 11, 11, + (3,1,0): 11, 11, 11, 11, + (3,2,0): 11, 11, 11, 11, + (3,3,0): 11, 11, 11, 11, + (4,0,0): 21, 21, 21, 21, + (4,1,0): 21, 21, 21, 21, + (4,2,0): 21, 21, 21, 21, + (4,3,0): 21, 21, 21, 21, + (5,0,0): 31, 31, 31, 31, + (5,1,0): 31, 31, 31, 31, + (5,2,0): 31, 31, 31, 31, + (5,3,0): 31, 31, 31, 31, + (6,0,0): 12, 12, 12, 12, + (6,1,0): 12, 12, 12, 12, + (6,2,0): 12, 12, 12, 12, + (6,3,0): 12, 12, 12, 12, + (7,0,0): 22, 22, 22, 22, + (7,1,0): 22, 22, 22, 22, + (7,2,0): 22, 22, 22, 22, + (7,3,0): 22, 22, 22, 22, + (8,0,0): 32, 32, 32, 32, + (8,1,0): 32, 32, 32, 32, + (8,2,0): 32, 32, 32, 32, + (8,3,0): 32, 32, 32, 32 + } + } +} +} |