diff options
62 files changed, 6591 insertions, 214 deletions
@@ -1,4 +1,4 @@ -# + # Copyright by The HDF Group. # Copyright by the Board of Trustees of the University of Illinois. # All rights reserved. @@ -146,6 +146,12 @@ ./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/testh5cc.sh.in ./examples/README @@ -611,6 +617,7 @@ ./src/H5Dscatgath.c ./src/H5Dselect.c ./src/H5Dtest.c +./src/H5Dvirtual.c ./src/H5E.c ./src/H5Edefin.h ./src/H5Edeprec.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1f33f04..f22e355 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -10,20 +10,20 @@ add_definitions (${HDF_EXTRA_C_FLAGS}) # Define Sources #----------------------------------------------------------------------------- set (examples - h5_crtdat - h5_rdwt - h5_crtatt - h5_crtgrp - h5_crtgrpar - h5_crtgrpd - h5_cmprss - h5_extend - h5_subset h5_write h5_read h5_extend_write h5_chunk_read h5_compound + h5_crtgrpar + h5_crtgrpd + h5_subset + h5_cmprss + h5_crtdat + h5_rdwt + h5_crtatt + h5_extend + h5_crtgrp h5_group h5_select h5_attribute @@ -34,6 +34,12 @@ 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 ) foreach (example ${examples}) diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index 5a756c8..2d1a828 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -42,6 +42,12 @@ blue/prefix_target.h5 red/prefix_target.h5 u2w/u2w_target.h5 + vds.h5 + vds-excalibur.h5 + vds-exclim.h5 + vds-percival.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..b67a788 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -37,7 +37,8 @@ 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 TEST_SCRIPT=testh5cc.sh TEST_EXAMPLES_SCRIPT=$(INSTALL_SCRIPT_FILES) @@ -48,7 +49,8 @@ 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 @@ -117,6 +119,12 @@ 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 if BUILD_SHARED_SZIP_CONDITIONAL LD_LIBRARY_PATH=$(LL_PATH) diff --git a/examples/Makefile.in b/examples/Makefile.in index 5d76be3..9a57439 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -615,7 +615,8 @@ 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 TEST_SCRIPT = testh5cc.sh TEST_EXAMPLES_SCRIPT = $(INSTALL_SCRIPT_FILES) @@ -627,7 +628,8 @@ 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 # The external link examples demonstrate how to use paths; they need @@ -1080,6 +1082,12 @@ 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 # How to create EXAMPLEDIR if it doesn't already exist $(EXAMPLEDIR): diff --git a/examples/h5_vds-eiger.c b/examples/h5_vds-eiger.c new file mode 100644 index 0000000..93b39b2 --- /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-%0b.h5", "/A", src_space); + + + + /* Create a virtual dataset */ + dset = H5Dcreate (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 = H5Dopen (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", 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..509b3e1 --- /dev/null +++ b/examples/h5_vds-exc.c @@ -0,0 +1,215 @@ +/************************************************************ + + 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. + * + */ + 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 block[1] */ + block[1] = n; + /* + * Build the mappings for B, D and F source datasets. + * + */ + 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 = H5Dcreate (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 = H5Dopen (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", 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"); + } + 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..af39c55 --- /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 = H5Dcreate (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 = H5Dopen (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", 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.c b/examples/h5_vds-percival.c new file mode 100644 index 0000000..ba9e13f --- /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 = H5Dcreate (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 = H5Dcreate (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 = H5Dopen (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", 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..e4b0018 --- /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 = H5Dcreate (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 = H5Dcreate (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 = H5Dopen (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 %d\n", 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..7e128db --- /dev/null +++ b/examples/h5_vds.c @@ -0,0 +1,257 @@ +/************************************************************ + + 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 = H5Dcreate (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 = H5Dcreate (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 = H5Dopen (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 %d\n", 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); + } + /* EIP Initialize read buffer with -2 since fille values for VDS are not implemented yet */ + for (i=0; i<VDSDIM0; i++) { + for (j=0; j<VDSDIM1; j++) + rdata[i][j] = -2; + } + + /* + * 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..fe19bc8 100644 --- a/examples/run-c-ex.sh.in +++ b/examples/run-c-ex.sh.in @@ -125,7 +125,19 @@ 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 &&\ + rm h5_vds); then EXIT_VALUE=${EXIT_SUCCESS} else EXIT_VALUE=${EXIT_FAILURE} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 68f7847..ba345fa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -116,6 +116,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 @@ -323,14 +323,9 @@ hid_t H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) { H5D_t *dset = NULL; - H5G_loc_t loc; /* Object location of group */ - H5G_loc_t dset_loc; /* Object location of dataset */ - H5G_name_t path; /* Dataset group hier. path */ - H5O_loc_t oloc; /* Dataset object location */ - H5O_type_t obj_type; /* Type of object at location */ - hbool_t loc_found = FALSE; /* Location at 'name' found */ - hid_t dxpl_id = H5AC_ind_dxpl_id; /* dxpl to use to open datset */ - hid_t ret_value; + H5G_loc_t loc; /* Object location of group */ + hid_t dxpl_id = H5AC_ind_dxpl_id; /* dxpl to use to open datset */ + hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*si", loc_id, name, dapl_id); @@ -348,41 +343,18 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") - /* Set up dataset location to fill in */ - dset_loc.oloc = &oloc; - dset_loc.path = &path; - H5G_loc_reset(&dset_loc); - - /* Find the dataset object */ - if(H5G_loc_find(&loc, name, &dset_loc, dapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found") - loc_found = TRUE; - - /* Check that the object found is the correct type */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_DATASET) - HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset") - /* Open the dataset */ - if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset") + if(NULL == (dset = H5D__open_name(&loc, name, dapl_id, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") /* Register an atom for the dataset */ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom") done: - if(ret_value < 0) { - if(dset) { - if(H5D_close(dset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - } /* end if */ - else { - if(loc_found && H5G_loc_free(&dset_loc) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't free location") - } /* end else */ - } /* end if */ + if(ret_value < 0) + if(dset && H5D_close(dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dopen2() */ diff --git a/src/H5Ddbg.c b/src/H5Ddbg.c index 4e934f2..7e1d884 100644 --- a/src/H5Ddbg.c +++ b/src/H5Ddbg.c @@ -116,6 +116,8 @@ H5Ddebug(hid_t dset_id) (void)H5D__chunk_dump_index(dset, H5AC_ind_dxpl_id, stdout); else if(H5D_CONTIGUOUS == dset->shared->layout.type) HDfprintf(stdout, " %-10s %a\n", "Address:", dset->shared->layout.storage.u.contig.addr); + else if(H5D_VIRTUAL == dset->shared->layout.type) + HDassert(0 && "Not yet implemented...");//VDSINC done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 0b2fee6..f4bde4b 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -226,15 +226,10 @@ hid_t H5Dopen1(hid_t loc_id, const char *name) { H5D_t *dset = NULL; - H5G_loc_t loc; /* Object location of group */ - H5G_loc_t dset_loc; /* Object location of dataset */ - H5G_name_t path; /* Dataset group hier. path */ - H5O_loc_t oloc; /* Dataset object location */ - H5O_type_t obj_type; /* Type of object at location */ - hbool_t loc_found = FALSE; /* Location at 'name' found */ - hid_t dapl_id = H5P_DATASET_ACCESS_DEFAULT; /* dapl to use to open dataset */ - hid_t dxpl_id = H5AC_ind_dxpl_id; /* dxpl to use to open datset */ - hid_t ret_value; + H5G_loc_t loc; /* Object location of group */ + hid_t dapl_id = H5P_DATASET_ACCESS_DEFAULT; /* dapl to use to open dataset */ + hid_t dxpl_id = H5AC_ind_dxpl_id; /* dxpl to use to open datset */ + hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE2("i", "i*s", loc_id, name); @@ -245,41 +240,18 @@ H5Dopen1(hid_t loc_id, const char *name) if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - /* Set up dataset location to fill in */ - dset_loc.oloc = &oloc; - dset_loc.path = &path; - H5G_loc_reset(&dset_loc); - - /* Find the dataset object */ - if(H5G_loc_find(&loc, name, &dset_loc, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found") - loc_found = TRUE; - - /* Check that the object found is the correct type */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_DATASET) - HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset") - /* Open the dataset */ - if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset") + if(NULL == (dset = H5D__open_name(&loc, name, dapl_id, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") /* Register an atom for the dataset */ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom") done: - if(ret_value < 0) { - if(dset != NULL) { - if(H5D_close(dset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - } /* end if */ - else { - if(loc_found && H5G_loc_free(&dset_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - } /* end else */ - } /* end if */ + if(ret_value < 0) + if(dset && H5D_close(dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dopen1() */ diff --git a/src/H5Dint.c b/src/H5Dint.c index 8e1fcec..a36b8b3 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1105,6 +1105,69 @@ done: } /* end H5D__create() */ +/*------------------------------------------------------------------------- + * Function: H5D__open_name + * + * Purpose: Opens an existing dataset by name. + * + * Return: Success: Ptr to a new dataset. + * Failure: NULL + * + * Programmer: Neil Fortner + * Friday, March 6, 2015 + * + *------------------------------------------------------------------------- + */ +H5D_t * +H5D__open_name(const H5G_loc_t *loc, const char *name, hid_t dapl_id, + hid_t dxpl_id) +{ + H5D_t *dset = NULL; + H5G_loc_t dset_loc; /* Object location of dataset */ + H5G_name_t path; /* Dataset group hier. path */ + H5O_loc_t oloc; /* Dataset object location */ + H5O_type_t obj_type; /* Type of object at location */ + hbool_t loc_found = FALSE; /* Location at 'name' found */ + H5D_t *ret_value; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check args */ + HDassert(loc); + HDassert(name); + + /* Set up dataset location to fill in */ + dset_loc.oloc = &oloc; + dset_loc.path = &path; + H5G_loc_reset(&dset_loc); + + /* Find the dataset object */ + if(H5G_loc_find(loc, name, &dset_loc, dapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found") + loc_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get object type") + if(obj_type != H5O_TYPE_DATASET) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, NULL, "not a dataset") + + /* Open the dataset */ + if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't open dataset") + + /* Set return value */ + ret_value = dset; + +done: + if(!ret_value) + if(loc_found && H5G_loc_free(&dset_loc) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, NULL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__open_name() */ + + /* *------------------------------------------------------------------------- * Function: H5D_open @@ -1299,6 +1362,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: @@ -1313,7 +1380,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 */ @@ -1443,6 +1511,23 @@ H5D_close(H5D_t *dataset) dataset->shared->layout.storage.u.compact.buf = H5MM_xfree(dataset->shared->layout.storage.u.compact.buf); break; + case H5D_VIRTUAL: + { + size_t i; + + 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++) + if(dataset->shared->layout.storage.u.virt.list[i].source_dset) { + HDassert(dataset->shared->layout.storage.u.virt.list[i].source_dset != dataset); + if(H5D_close(dataset->shared->layout.storage.u.virt.list[i].source_dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset") + dataset->shared->layout.storage.u.virt.list[i].source_dset = NULL; + } /* end if */ + } /* end block */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1687,6 +1772,10 @@ 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 for now VDSINC */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1806,6 +1895,9 @@ H5D__init_storage(const H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[], break; } /* end block */ + case H5D_VIRTUAL: + /* No-op for now VDSINC */ + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1862,6 +1954,10 @@ 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 until private data is implemented VDSINC */ + *storage_size = 0; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1898,6 +1994,8 @@ H5D__get_offset(const H5D_t *dset) HDassert(dset); switch(dset->shared->layout.type) { + case H5D_VIRTUAL: + HDassert(0 && "checking code coverage...");//VDSINC case H5D_CHUNKED: case H5D_COMPACT: break; diff --git a/src/H5Dio.c b/src/H5Dio.c index 1c77d93..d21612a 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); @@ -586,7 +583,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) { @@ -619,7 +616,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 d7d7b88..87e1bc8 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: @@ -439,6 +448,23 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t case H5D_COMPACT: break; + case H5D_VIRTUAL: + { + size_t i; + + HDassert(dataset->shared->layout.storage.u.virt.list || (dataset->shared->layout.storage.u.virt.list_nused == 0)); + + /* Patch the virtual selection dataspaces if necessary */ + for(i = 0; i < dataset->shared->layout.storage.u.virt.list_nused; i++) { + if(dataset->shared->layout.storage.u.virt.list[i].virtual_space_status != H5O_VIRTUAL_STATUS_CORRECT) { + if(H5S_extent_copy(dataset->shared->layout.storage.u.virt.list[i].virtual_select, dataset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent") + dataset->shared->layout.storage.u.virt.list[i].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT; + } /* end if */ + } /* end for */ + } /* end block */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Doh.c b/src/H5Doh.c index abf76d0..39a270f 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -398,6 +398,18 @@ 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 && H5D__virtual_is_space_alloc(&layout.storage)) { + size_t virtual_heap_size; + /* Need to write a test for this. No assert here for now because the + * code is reached by h5_verify_cached_stabs() but it is not properly + * tested. VDSINC */ + /* 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 06cc2c0..1e5038b 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -173,11 +173,15 @@ typedef struct { hbool_t *dirty; /* Pointer to dirty flag to mark */ } H5D_compact_storage_t; +typedef struct { +} H5D_virtual_storage_t; /* Either fill out or remove VDSINC */ + typedef union H5D_storage_t { H5D_contig_storage_t contig; /* Contiguous information for dataset */ H5D_chunk_storage_t chunk; /* Chunk information for dataset */ H5D_compact_storage_t compact; /* Compact information for dataset */ H5O_efl_t efl; /* External file list information for dataset */ + H5D_virtual_storage_t virt; /* Virtual dataset information */ } H5D_storage_t; /* Typedef for raw data I/O operation info */ @@ -515,6 +519,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]; @@ -531,6 +536,8 @@ H5_DLL H5D_t *H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, H5_DLL H5D_t *H5D__create_named(const H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id); +H5_DLL H5D_t *H5D__open_name(const H5G_loc_t *loc, const char *name, + hid_t dapl_id, hid_t dxpl_id); H5_DLL herr_t H5D__get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id); H5_DLL herr_t H5D__alloc_storage(const H5D_t *dset, hid_t dxpl_id, H5D_time_alloc_t time_alloc, @@ -553,6 +560,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, @@ -648,6 +658,16 @@ 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_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, + const H5O_storage_virtual_t *storage_src, H5F_t *f_dst, + H5O_storage_virtual_t *storage_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, + hid_t dxpl_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 0b8b76f..b2d88ee 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -106,6 +106,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 */ diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 1b5fed7..a08ea3d 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 */ diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c new file mode 100644 index 0000000..3643c53 --- /dev/null +++ b/src/H5Dvirtual.c @@ -0,0 +1,687 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: + * VDSINC + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5D_PACKAGE /* Suppress error about including H5Dpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Dpkg.h" /* Dataset functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* Files */ +#include "H5Gprivate.h" /* Groups */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5Sprivate.h" /* Dataspaces */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Layout operation callbacks */ +static herr_t H5D__virtual_construct(H5F_t *f, H5D_t *dset); +static herr_t H5D__virtual_io_init(const 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 *cm); +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, hid_t dxpl_id); + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Contiguous storage layout I/O ops */ +const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{ + H5D__virtual_construct, + NULL, + H5D__virtual_is_space_alloc, + H5D__virtual_io_init, + H5D__virtual_read, + H5D__virtual_write, +#ifdef H5_HAVE_PARALLEL + H5D__virtual_collective_read, //VDSINC + H5D__virtual_collective_write, //VDSINC +#endif /* H5_HAVE_PARALLEL */ + NULL, + NULL, + H5D__virtual_flush, + NULL +}}; + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * 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; + size_t i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(layout); + HDassert(layout->type == H5D_VIRTUAL); + + if(layout->storage.u.virt.list_nused > 0) { + HDassert(layout->storage.u.virt.list); + + /* Save original entry list for use as the "source" */ + orig_list = layout->storage.u.virt.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_NOSPACE, 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 to NULL */ + for(i = 0; i < layout->storage.u.virt.list_nused; i++) { + 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") + 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") + if(NULL == (layout->storage.u.virt.list[i].virtual_select + = H5S_copy(orig_list[i].virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + layout->storage.u.virt.list[i].source_dset = NULL; + 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 { + HDassert(0 && "checking code coverage...");//VDSINC + /* 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 */ + +done: + /* Release allocated resources on failure */ + if((ret_value < 0) && orig_list + && (orig_list != layout->storage.u.virt.list)) + 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_open_source_dset + * + * Purpose: Attempts to open a source dataset. + * + * Return: TRUE: Source dataset opened + * FALSE: Source dataset not opened + * Negative: Error + * + * 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, 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(virtual_ent); + HDassert(!virtual_ent->source_dset); + + /* Get dapl and fapl from current (virtual dataset) location? VDSINC */ + /* Write code to check if these exist and return without opening dset + * otherwise VDSINC */ + + /* Check if we need to open the source file */ + if(HDstrcmp(virtual_ent->source_file_name, ".")) { + /* Open the source file */ + if(NULL == (src_file = H5F_open(virtual_ent->source_file_name, H5F_INTENT(vdset->oloc.file) & H5F_ACC_RDWR, H5P_FILE_CREATE_DEFAULT, H5P_FILE_ACCESS_DEFAULT, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENFILE, FAIL, "unable to open source file") + src_file_open = TRUE; + } /* end if */ + else + /* Source file is ".", use the virtual dataset's file */ + src_file = vdset->oloc.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 == (virtual_ent->source_dset = H5D__open_name(&src_root_loc, virtual_ent->source_dset_name, H5P_DATASET_ACCESS_DEFAULT, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + + /* Patch the source selection if necessary */ + if(virtual_ent->source_space_status != H5O_VIRTUAL_STATUS_CORRECT) { + if(H5S_extent_copy(virtual_ent->source_select, virtual_ent->source_dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent") + virtual_ent->source_space_status = H5O_VIRTUAL_STATUS_CORRECT; + } /* 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_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; + 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. */ + for(i = 0; i < layout->storage.u.virt.list_nused; i++) { + layout->storage.u.virt.list[i].source_file_name = (char *)H5MM_xfree(layout->storage.u.virt.list[i].source_file_name); + layout->storage.u.virt.list[i].source_dset_name = (char *)H5MM_xfree(layout->storage.u.virt.list[i].source_dset_name); + if(layout->storage.u.virt.list[i].source_select + && H5S_close(layout->storage.u.virt.list[i].source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + layout->storage.u.virt.list[i].source_select = NULL; + if(layout->storage.u.virt.list[i].virtual_select + && H5S_close(layout->storage.u.virt.list[i].virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") + layout->storage.u.virt.list[i].virtual_select = NULL; + /* Close dataset here? VDSINC */ + } /* end for */ + + /* Free the list */ + layout->storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_xfree(layout->storage.u.virt.list); + + /* 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_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) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* check args */ + HDassert(f); + HDassert(storage); + HDassert(storage->type == H5D_VIRTUAL); + + /* Need to add stuff for private data here VDSINC */ + + /* 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_WRITEERROR, FAIL, "Unable to remove heap object") + + /* 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_construct + * + * Purpose: Constructs new virtual layout information for dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Monday, February 2, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_construct(H5F_t UNUSED *f, H5D_t *dset) +{ + size_t i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(dset->shared->layout.storage.u.virt.list || (dset->shared->layout.storage.u.virt.list_nused == 0)); + + /* Patch the virtual selection dataspaces */ + for(i = 0; i < dset->shared->layout.storage.u.virt.list_nused; i++) { + HDassert(dset->shared->layout.storage.u.virt.list[i].virtual_space_status == H5O_VIRTUAL_STATUS_USER); + if(H5S_extent_copy(dset->shared->layout.storage.u.virt.list[i].virtual_select, dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent") + dset->shared->layout.storage.u.virt.list[i].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT; + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_construct() */ + + +/*------------------------------------------------------------------------- + * 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 UNUSED *storage) +{ + hbool_t ret_value; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Need to decide what to do here. For now just return TRUE VDSINC */ + ret_value = TRUE;//storage->u.virt.serial_list_hobjid.addr != HADDR_UNDEF; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_is_space_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__virtual_io_init + * + * Purpose: Performs initialization before any sort of I/O on the raw data + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 6, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__virtual_io_init(const H5D_io_info_t UNUSED *io_info, const H5D_type_info_t UNUSED *type_info, + hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space, + H5D_chunk_map_t UNUSED *cm) +{ + FUNC_ENTER_STATIC_NOERR + + /* No-op for now. Delete if we never add anything here. VDSINC */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D__virtual_io_init() */ + + +/*------------------------------------------------------------------------- + * 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 UNUSED nelmts, const H5S_t *file_space, const H5S_t *mem_space, + H5D_chunk_map_t UNUSED *fm) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + H5S_t *projected_mem_space = NULL; /* Memory space for selection in a single mapping */ + H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */ + hssize_t select_nelmts; /* Number of elements in selection */ + size_t i; /* Local index variable */ + 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; + + /* 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); + + /* Project intersection of file space and mapping virtual space onto + * memory space */ + if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].virtual_select, &projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") + + /* Get number of elements in projected dataspace */ + if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(projected_mem_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* Only perform I/O if there are any elements */ + if(select_nelmts > 0) { + /* Open source dataset */ + if(!storage->list[i].source_dset) + /* Try to open dataset */ + if(H5D__virtual_open_source_dset(io_info->dset, &storage->list[i], io_info->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) { + /* Sanity check that the source space has been patched by now */ + HDassert(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + + /* Project intersection of file space and mapping virtual space onto + * mapping source space */ + if(H5S_select_project_intersection(storage->list[i].virtual_select, storage->list[i].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(storage->list[i].source_dset, type_info->dst_type_id, 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 */ + else + /* We do not have a source dataset open, fill with fill value */ + HDassert(0 && "Not yet implemented...");//VDSINC + } /* end if */ + + /* Close projected_mem_space */ + if(H5S_close(projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space") + projected_mem_space = NULL; + } /* end for */ + + /* Fill unmapped part of buffer with fill value. Keep track of total number + * elements written to memory buffer and assert that it == nelmts */ + +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 */ + if(projected_mem_space) { + HDassert(ret_value < 0); + if(H5S_close(projected_mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_read() */ + + +/*------------------------------------------------------------------------- + * 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 UNUSED nelmts, const H5S_t *file_space, const H5S_t *mem_space, + H5D_chunk_map_t UNUSED *fm) +{ + H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */ + H5S_t *projected_mem_space = NULL; /* Memory space for selection in a single mapping */ + H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */ + hssize_t select_nelmts; /* Number of elements in selection */ + size_t i; /* Local index variable */ + 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; + + /* 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); + + /* Project intersection of file space and mapping virtual space onto + * memory space */ + if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].virtual_select, &projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") + + /* Get number of elements in projected dataspace */ + if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(projected_mem_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* Only perform I/O if there are any elements */ + if(select_nelmts > 0) { + /* Open source dataset, fail if cannot open */ + if(!storage->list[i].source_dset) { + //VDSINC check all source datasets before any I/O + if(H5D__virtual_open_source_dset(io_info->dset, &storage->list[i], io_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + if(!storage->list[i].source_dset) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "did not open source dataset") + } /* end if */ + + /* Sanity check that source space has been patched by now */ + HDassert(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + + /* Extend source dataset if necessary and there is an unlimited + * dimension VDSINC */ + /* Project intersection of file space and mapping virtual space onto + * mapping source space */ + if(H5S_select_project_intersection(storage->list[i].virtual_select, storage->list[i].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__write(storage->list[i].source_dset, type_info->dst_type_id, 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 */ + + /* Close projected_mem_space */ + if(H5S_close(projected_mem_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space") + projected_mem_space = NULL; + } /* end for */ + +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 */ + if(projected_mem_space) { + HDassert(ret_value < 0); + if(H5S_close(projected_mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space") + } /* end if */ + + 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 UNUSED *dset, hid_t UNUSED dxpl_id) +{ + FUNC_ENTER_STATIC_NOERR + + /* Flush only open datasets */ + /* No-op for now VDSINC */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D__virtual_flush() */ + + +/*------------------------------------------------------------------------- + * 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 UNUSED *f_src, const H5O_storage_virtual_t UNUSED *storage_src, + H5F_t UNUSED *f_dst, H5O_storage_virtual_t UNUSED *storage_dst, H5T_t UNUSED *dt_src, + H5O_copy_t UNUSED *cpy_info, hid_t UNUSED dxpl_id) +{ + FUNC_ENTER_PACKAGE_NOERR + + HDassert(0 && "Not yet implemented...");//VDSINC + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D__virtual_copy() */ + @@ -718,6 +718,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))) + 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 3765c47..ad0da76 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 d58ad61..ac5219d 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -96,10 +96,11 @@ H5FL_DEFINE(H5O_layout_t); *------------------------------------------------------------------------- */ static void * -H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, +H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p) { H5O_layout_t *mesg = NULL; + uint8_t *heap_block = NULL; unsigned u; void *ret_value; /* Return value */ @@ -241,6 +242,86 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, mesg->ops = H5D_LOPS_CHUNK; break; + case H5D_VIRTUAL: + /* 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; + + /* Decode heap block if it exists */ + if(mesg->storage.u.virt.serial_list_hobjid.addr != HADDR_UNDEF) { + const uint8_t *heap_block_p; + 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; + + /* 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].virtual_select), &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode virtual space selection") + } /* 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: @@ -253,8 +334,14 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, 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() */ @@ -294,6 +381,8 @@ static herr_t H5O_layout_encode(H5F_t *f, hbool_t 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 */ @@ -344,6 +433,109 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi 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 + */ + /* Number of entries */ + block_size = 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].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].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; + + /* 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)HDstrcpy((char *)heap_block_p, mesg->storage.u.virt.list[i].source_file_name); + heap_block_p += str_size[2 * i]; + + /* Source dataset name */ + (void)HDstrcpy((char *)heap_block_p, mesg->storage.u.virt.list[i].source_dset_name); + 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].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 */ + /* Casting away const OK --NAF */ + if(H5HG_insert(f, H5AC_ind_dxpl_id, block_size, heap_block, &((H5O_layout_t *)mesg)->storage.u.virt.serial_list_hobjid) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to insert virtual dataset heap block") + } /* end if */ + + HDassert((mesg->storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC + + /* 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: @@ -351,6 +543,9 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi } /* 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() */ @@ -403,6 +598,11 @@ H5O_layout_copy(const void *_mesg, void *_dest) if(dest->type == H5D_CHUNKED && dest->storage.u.chunk.ops) H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE); + /* Deep copy the entry list for virtual datasets */ + if(mesg->type == H5D_VIRTUAL) + if(H5D__virtual_copy_layout(dest) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy virtual layout") + /* Set return value */ ret_value = dest; @@ -468,19 +668,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() */ @@ -560,6 +766,13 @@ 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 */ + HDassert(0 && "checking code coverage...");//VDSINC + /* 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: @@ -647,6 +860,10 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, } /* end if */ break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -746,6 +963,11 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, "Data Size:", mesg->storage.u.compact.size); break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index e3a2d33..7c69a01 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -37,6 +37,7 @@ /* Private headers needed by this file */ #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 */ @@ -372,7 +373,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 @@ -410,12 +412,45 @@ typedef struct H5O_storage_compact_t { void *buf; /* Buffer for compact dataset */ } H5O_storage_compact_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 */ + char *source_file_name; /* Source file name used for virtual dataset mapping */ + char *source_dset_name; /* Source dataset name used for virtual dataset mapping */ + struct H5S_t *source_select; /* Selection in the source dataset for mapping */ + struct H5S_t *virtual_select; /* Selection in the virtual dataset that is mapped to source_select */ + + /* Not stored */ + struct H5D_t *source_dset; /* Source dataset */ + 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 */ +} 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/H5Osdspace.c b/src/H5Osdspace.c index 875cd56..5e47ad1 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -312,7 +312,7 @@ H5O_sdspace_copy(const void *_mesg, void *_dest) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy extent information */ - if(H5S_extent_copy(dest, mesg, TRUE) < 0) + if(H5S_extent_copy_real(dest, mesg, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent") /* Set return value */ @@ -467,7 +467,7 @@ H5O_sdspace_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src, HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "dataspace extent allocation failed") /* Create a copy of the dataspace extent */ - if(H5S_extent_copy(udata->src_space_extent, src_space_extent, TRUE) < 0) + if(H5S_extent_copy_real(udata->src_space_extent, src_space_extent, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy extent") } /* end if */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 949cefa..b9b4653 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -41,6 +41,7 @@ #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 "H5Tprivate.h" /* Datatypes */ #include "H5Zpkg.h" /* Data filters */ @@ -55,13 +56,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} #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_CHUNKED, { .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 +75,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_CHUNKED, 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 ======== */ @@ -79,7 +84,9 @@ #define H5D_CRT_LAYOUT_DEF H5D_DEF_LAYOUT_CONTIG #define H5D_CRT_LAYOUT_ENC H5P__dcrt_layout_enc #define H5D_CRT_LAYOUT_DEC H5P__dcrt_layout_dec +#define H5D_CRT_LAYOUT_DEL H5P__dcrt_layout_del #define H5D_CRT_LAYOUT_CMP H5P__dcrt_layout_cmp +#define H5D_CRT_LAYOUT_CLOSE H5P__dcrt_layout_close /* Definitions for fill value. size=0 means fill value will be 0 as * library default; size=-1 means fill value is undefined. */ #define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t) @@ -128,7 +135,9 @@ static herr_t H5P__dcrt_close(hid_t dxpl_id, void *close_data); /* Property callbacks */ static herr_t H5P__dcrt_layout_enc(const void *value, void **pp, size_t *size); static herr_t H5P__dcrt_layout_dec(const void **pp, void *value); +static herr_t H5P__dcrt_layout_del(hid_t prop_id, const char *name, size_t size, void *value); static int H5P__dcrt_layout_cmp(const void *value1, const void *value2, size_t size); +static herr_t H5P__dcrt_layout_close(const char *name, size_t size, void *value); static herr_t H5P__fill_value_enc(const void *value, void **pp, size_t *size); static herr_t H5P__fill_value_dec(const void **pp, void *value); static herr_t H5P__dcrt_ext_file_list_enc(const void *value, void **pp, size_t *size); @@ -183,10 +192,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_CHUNK; static hbool_t H5P_dcrt_def_layout_init_g = FALSE; #endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ @@ -213,7 +224,7 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass) /* Register the storage layout property */ if(H5P_register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &H5D_def_layout_g, NULL, NULL, NULL, H5D_CRT_LAYOUT_ENC, H5D_CRT_LAYOUT_DEC, - NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0) + H5D_CRT_LAYOUT_DEL, NULL, H5D_CRT_LAYOUT_CMP, H5D_CRT_LAYOUT_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the fill value property */ @@ -314,6 +325,11 @@ H5P__dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) dst_layout.storage.u.chunk.ops = NULL; break; + case H5D_VIRTUAL: + dst_layout.storage.u.virt.serial_list_hobjid.addr = HADDR_UNDEF; + dst_layout.storage.u.virt.serial_list_hobjid.idx = 0; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -444,6 +460,9 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size) for(u = 0; u < layout->u.chunk.ndims; u++) UINT32ENCODE(*pp, layout->u.chunk.dim[u]) } /* end if */ + else if(H5D_VIRTUAL == layout->type) { + HDassert(0 && "Not yet implemented...");//VDSINC + } /* end else */ } /* end if */ /* Size of layout type */ @@ -531,6 +550,10 @@ H5P__dcrt_layout_dec(const void **_pp, void *value) } break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -546,6 +569,39 @@ done: /*------------------------------------------------------------------------- + * Function: H5P__dcrt_layout_del + * + * Purpose: Frees memory used to store the layout property + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Tuesday, Feb 10, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dcrt_layout_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(value); + + /* Reset the old layout */ + if(((H5O_layout_t *)value)->type == H5D_VIRTUAL) /* Temp hack until proper fix is in trunk */ + if(H5O_msg_reset(H5O_LAYOUT_ID, value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release layout message") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__dcrt_layout_del() */ + + +/*------------------------------------------------------------------------- * Function: H5P__dcrt_layout_cmp * * Purpose: Callback routine which is called whenever the layout @@ -605,6 +661,10 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t UNUSED s } /* end case */ break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -617,6 +677,39 @@ done: /*------------------------------------------------------------------------- + * Function: H5P__dcrt_layout_close + * + * Purpose: Frees memory used to store the layout property + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Tuesday, Feb 10, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dcrt_layout_close(const char UNUSED *name, size_t UNUSED size, void *value) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(value); + + /* Reset the old layout */ + if(((H5O_layout_t *)value)->type == H5D_VIRTUAL) /* Temp hack until proper fix is in trunk */ + if(H5O_msg_reset(H5O_LAYOUT_ID, value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release layout message") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__dcrt_layout_close() */ + + +/*------------------------------------------------------------------------- * Function: H5P__fill_value_enc * * Purpose: Callback routine which is called whenever the fill value @@ -1110,6 +1203,7 @@ done: static herr_t H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout) { + H5O_layout_t old_layout; /* Layout propertry already on list */ unsigned alloc_time_state; /* State of allocation time property */ herr_t ret_value = SUCCEED; /* return value */ @@ -1141,6 +1235,10 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout) fill.alloc_time = H5D_ALLOC_TIME_INCR; break; + case H5D_VIRTUAL: + fill.alloc_time = H5D_ALLOC_TIME_INCR; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1152,6 +1250,14 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time") } /* end if */ + /* Get the old layout */ + if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &old_layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout") + + /* Reset the old layout before overwriting it */ + if(H5O_msg_reset(H5O_LAYOUT_ID, &old_layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release layout message") + /* Set layout value */ if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, layout) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout") @@ -1167,7 +1273,8 @@ done: * * Purpose: Set the default layout information for the various types of * dataset layouts - * + + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol @@ -1181,6 +1288,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 @@ -1188,6 +1296,7 @@ H5P__init_def_layout(void) H5D_def_layout_compact_g.storage.u.compact = def_store_compact; H5D_def_layout_chunk_g.u.chunk = def_layout_chunk; H5D_def_layout_chunk_g.storage.u.chunk = def_store_chunk; + 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; @@ -1257,6 +1366,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: @@ -1462,6 +1575,380 @@ done: /*------------------------------------------------------------------------- + * Function: H5Pset_virtual + * + * Purpose: VDSINC + * + * 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 layout; /* Layout information for setting chunk info */ + H5S_t *vspace; /* Virtual dataset space selection */ + H5S_t *src_space; /* Source dataset space selection */ + hbool_t new_layout = FALSE; /* Whether we are adding a new virtual layout message to plist */ + hbool_t adding_entry = FALSE; /* Whether we are in the middle of adding an entry */ + 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_ARGS, H5E_BADVALUE, FAIL, "source file name not provided") + if(!src_dset_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "source dataset name not provided") + if(NULL == (vspace = (H5S_t *)H5I_object_verify(vspace_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + if(NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + //VDSINC add check for overlapping virtual spaces and same number of + // elements in vspace and src_space + +#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_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout") + + /* If the layout was not already virtual, Start with default virtual layout. + * Otherwise, add the mapping to the current list. */ + if(layout.type != H5D_VIRTUAL) { + new_layout = TRUE; + HDmemcpy(&layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g)); + } /* end if */ + + /* Expand list if necessary */ + if(layout.storage.u.virt.list_nalloc == 0) { + /* Allocate initial entry list */ + if(NULL == (layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(H5D_VIRTUAL_DEF_LIST_SIZE * sizeof(H5O_storage_virtual_ent_t)))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't allocate virtual dataset mapping list") + layout.storage.u.virt.list_nalloc = H5D_VIRTUAL_DEF_LIST_SIZE; + } /* end if */ + else if(layout.storage.u.virt.list_nused + == layout.storage.u.virt.list_nalloc) { + HDassert((layout.storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC + /* Double size of entry list. Make sure to zero out new memory. */ + if(NULL == (layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_realloc(layout.storage.u.virt.list, (size_t)2 * layout.storage.u.virt.list_nalloc * sizeof(H5O_storage_virtual_ent_t)))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't reallocate virtual dataset mapping list") + (void)HDmemset(layout.storage.u.virt.list + layout.storage.u.virt.list_nalloc, 0, layout.storage.u.virt.list_nalloc * sizeof(H5O_storage_virtual_ent_t)); + layout.storage.u.virt.list_nalloc *= (size_t)2; + } /* end if */ + + /* Add virtual dataset mapping entry */ + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name = HDstrdup(src_file_name))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") + adding_entry = TRUE; + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name = HDstrdup(src_dset_name))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select = H5S_copy(src_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select = H5S_copy(vspace, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_space_status = H5O_VIRTUAL_STATUS_USER; + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_space_status = H5O_VIRTUAL_STATUS_USER; + layout.storage.u.virt.list_nused++; + adding_entry = FALSE; + + /* Set chunk information in property list. If we are adding a new layout, + * use H5P__set_layout so other fields are initialized properly. If we are + * extending the layout, just use H5P_set directly so we don't mess with + * anything else. */ + if(new_layout) { + if(H5P__set_layout(plist, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") + } /* end if */ + else + if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") + +done: + if(adding_entry) { + HDassert(ret_value < 0); + + /* Free incomplete entry */ + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name = (char *)H5MM_xfree(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name); + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name = (char *)H5MM_xfree(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name); + if(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select + && H5S_close(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select = NULL; + HDassert(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select == NULL); + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_virtual() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_virtual_count + * + * Purpose: VDSINC + * + * 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_get(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: VDSINC + * + * Return: VDSINC + * + * 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_get(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].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: VDSINC + * + * Return: VDSINC + * + * 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; /* 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_get(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_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: VDSINC + * + * Return: VDSINC + * + * 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_get(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: VDSINC + * + * Return: VDSINC + * + * 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_get(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 @@ -2302,6 +2789,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..c1c6f17 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); @@ -479,7 +479,40 @@ H5Sextent_copy(hid_t dst_id,hid_t src_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") /* Copy */ - if(H5S_extent_copy(&(dst->extent), &(src->extent), TRUE) < 0) + if(H5S_extent_copy(dst, src) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy extent") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Sextent_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5S_extent_copy + * + * Purpose: Copies a dataspace extent + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Monday, February 23, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_extent_copy(H5S_t *dst, const H5S_t *src) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(dst); + HDassert(src); + + /* Copy extent */ + if(H5S_extent_copy_real(&(dst->extent), &(src->extent), TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy extent") /* If the selection is 'all', update the number of elements selected in the @@ -489,12 +522,12 @@ H5Sextent_copy(hid_t dst_id,hid_t src_id) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sextent_copy() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_extent_copy() */ /*------------------------------------------------------------------------- - * Function: H5S_extent_copy + * Function: H5S_extent_copy_real * * Purpose: Copies a dataspace extent * @@ -508,7 +541,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max) +H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max) { unsigned u; herr_t ret_value = SUCCEED; /* Return value */ @@ -561,7 +594,7 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_extent_copy() */ +} /* end H5S_extent_copy_real() */ /*------------------------------------------------------------------------- @@ -597,7 +630,7 @@ H5S_copy(const H5S_t *src, hbool_t share_selection, hbool_t copy_max) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the source dataspace's extent */ - if(H5S_extent_copy(&(dst->extent), &(src->extent), copy_max) < 0) + if(H5S_extent_copy_real(&(dst->extent), &(src->extent), copy_max) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent") /* Copy the source dataspace's selection */ diff --git a/src/H5Sall.c b/src/H5Sall.c index 1105915..bbb2935 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -976,6 +976,7 @@ H5S_all_get_seq_list(const H5S_t UNUSED *space, unsigned UNUSED flags, H5S_sel_i /* 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 9b1562f..51194f9 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -3193,13 +3193,15 @@ H5S_hyper_release(H5S_t *space) space->select.num_elem = 0; /* Release irregular hyperslab information */ - if(space->select.sel_info.hslab->span_lst != NULL) { - if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - } /* end if */ + if(space->select.sel_info.hslab) { + if(space->select.sel_info.hslab->span_lst != NULL) { + if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + } /* end if */ - /* Release space for the hyperslab selection information */ - space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); + /* Release space for the hyperslab selection information */ + space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -8794,7 +8796,7 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t /* Make certain that we don't write too many */ actual_elem = MIN3(leftover, (size_t)iter->elmt_left, maxelem); - /* initialize row sizes for each dimension */ + /* Initialize row sizes for each dimension */ elem_size = iter->elmt_size; for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { slab[i] = acc; @@ -8863,6 +8865,395 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t /*-------------------------------------------------------------------------- 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 + VDSINC + 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]; + size_t ss_len[H5S_PROJECT_INTERSECT_NSEQS]; + size_t ss_nseq; + size_t ss_nelem; + size_t ss_i = (size_t)0; + hbool_t advance_ss = FALSE; + H5S_sel_iter_t ss_iter; + hbool_t ss_iter_init = FALSE; + hsize_t ss_sel_off = (hsize_t)0; + hsize_t ds_off[H5S_PROJECT_INTERSECT_NSEQS]; + size_t ds_len[H5S_PROJECT_INTERSECT_NSEQS]; + size_t ds_nseq; + size_t ds_nelem; + size_t ds_i = (size_t)0; + H5S_sel_iter_t ds_iter; + hbool_t ds_iter_init = FALSE; + hsize_t ds_sel_off = (hsize_t)0; + hsize_t sis_off[H5S_PROJECT_INTERSECT_NSEQS]; + size_t sis_len[H5S_PROJECT_INTERSECT_NSEQS]; + size_t sis_nseq; + size_t sis_nelem; + size_t sis_i = (size_t)0; + hbool_t advance_sis = FALSE; + H5S_sel_iter_t sis_iter; + hbool_t sis_iter_init = FALSE; + hsize_t int_sel_off; + size_t int_len; + hsize_t proj_off; + size_t proj_len; + size_t proj_len_rem; + hsize_t proj_down_dims[H5S_MAX_RANK]; + H5S_hyper_span_info_t *curr_span_tree[H5S_MAX_RANK]; + H5S_hyper_span_t *prev_span[H5S_MAX_RANK]; + hsize_t curr_span_dim[H5S_MAX_RANK]; + unsigned proj_rank; + hsize_t low; + hsize_t high; + size_t span_len; + size_t nelem; + unsigned i; + herr_t ret_value = SUCCEED; + + 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? */ + + /* Initialize prev_space, curr_span_tree, and curr_span_dim */ + for(i = 0; i < H5S_MAX_RANK; i++) { + curr_span_tree[i] = NULL; + prev_span[i] = NULL; + curr_span_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") + + /* 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_NOSPACE, FAIL, "can't allocate hyperslab info") + + /* Set selection type */ + proj_space->select.type = H5S_sel_hyper; + + /* 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; + + /* 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; + + /* 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; + + /* If any sequences are empty, skip the main loop */ + if((ss_nseq == 0) || (ds_nseq == 0) || (sis_nseq == 0)) + goto loop_end; + + /* 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]) + % proj_space->extent.size[i]) + != curr_span_dim[i - 1])); i--) { + if(curr_span_tree[i]) { + HDassert(prev_span[i]); + + /* Append complete lower dimension span tree to + * current dimension */ + if(H5S_hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], curr_span_dim[i - 1], curr_span_dim[i - 1], curr_span_tree[i], NULL) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 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_dim */ + curr_span_dim[i - 1] = (proj_off / proj_down_dims[i - 1]) % proj_space->extent.size[i]; + } /* 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_NOSPACE, 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 */ + if(H5S_hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], curr_span_dim[i - 1], curr_span_dim[i - 1], curr_span_tree[i], NULL) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 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 H5Sis_regular_hyperslab PURPOSE Determine if a hyperslab selection is regular diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 5f84717..8613fd7 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -34,6 +34,9 @@ #define H5S_VALID_MAX 0x01 #define H5S_VALID_PERM 0x02 +/* 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 @@ -245,10 +248,13 @@ H5_DLLVAR const H5S_select_class_t H5S_sel_point[1]; /* Extent functions */ H5_DLL herr_t H5S_extent_release(H5S_extent_t *extent); -H5_DLL herr_t H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src, +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); /* Testing functions */ #ifdef H5S_TESTING diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 7b7b8c6..6ce2821 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -204,6 +204,7 @@ H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size); H5_DLL hsize_t H5S_extent_nelem(const H5S_extent_t *ext); H5_DLL int H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[]); H5_DLL htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2); +H5_DLL herr_t H5S_extent_copy(H5S_t *dst, const H5S_t *src); /* Operations on selections */ H5_DLL herr_t H5S_select_deserialize(H5S_t **space, const uint8_t **p); @@ -234,6 +235,9 @@ 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); /* Operations on all selections */ H5_DLL herr_t H5S_select_all(H5S_t *space, hbool_t rel_prev); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index a4f13d7..b62186b 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -2101,3 +2101,92 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5S_select_fill() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_project_intersection + + PURPOSE + VDSINC + + USAGE + VDSINC + + RETURNS + Non-negative on success/Negative on failure. + + DESCRIPTION + VDSINC + + 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") + + /* Set offset to zeros */ + (void)HDmemset(new_space->select.offset, 0, (size_t)new_space->extent.rank * sizeof(new_space->select.offset[0])); + new_space->select.offset_changed = FALSE; + + /* 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)) + HDassert(0 && "Not yet implemented...");//VDSINC + 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() */ + diff --git a/src/H5trace.c b/src/H5trace.c index 6634a2a..de2b969 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -524,6 +524,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; diff --git a/src/Makefile.am b/src/Makefile.am index 2df095e..fb981c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,7 +48,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 \ - H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \ + H5Dmpio.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/src/Makefile.in b/src/Makefile.in index aa7bed3..a2a461a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -156,50 +156,51 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Dbtree.lo H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo \ H5Ddeprec.lo H5Defl.lo H5Dfill.lo H5Dint.lo H5Dio.lo \ H5Dlayout.lo H5Dmpio.lo H5Doh.lo H5Dscatgath.lo H5Dselect.lo \ - H5Dtest.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo \ - H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo \ - H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \ - H5F.lo H5Fint.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo H5Fdeprec.lo \ - H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ - H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \ - H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \ - H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5FD.lo \ - H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo \ - H5FDmpi.lo H5FDmpio.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \ - H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ - H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo \ - H5Gcache.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \ - H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \ - H5Goh.lo H5Groot.lo H5Gstab.lo H5Gtest.lo H5Gtraverse.lo \ - H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \ - H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \ - H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \ - H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HGquery.lo \ - H5HL.lo H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo \ - H5Itest.lo H5L.lo H5Lexternal.lo H5lib_settings.lo H5MF.lo \ - H5MFaggr.lo H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo \ - H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ - H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ - H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo \ - H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Ofsinfo.lo H5Oginfo.lo \ - H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ - H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ - H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \ - H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \ - H5Pdxpl.lo H5Pencdec.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo \ - H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ - H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5PL.lo H5R.lo \ - H5Rdeprec.lo H5UC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo \ - H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \ - H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo \ - H5SMmessage.lo H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo \ - H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ - H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo H5Tfields.lo H5Tfixed.lo \ - H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo H5Toh.lo \ - H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo \ - H5Tvisit.lo H5Tvlen.lo H5TS.lo H5VM.lo H5WB.lo H5Z.lo \ - H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ - H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo + H5Dtest.lo H5Dvirtual.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo \ + H5EAcache.lo H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo \ + H5EAhdr.lo H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo \ + H5EAtest.lo H5F.lo H5Fint.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo \ + H5Fdeprec.lo H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo \ + H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo \ + H5Fsuper_cache.lo H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo \ + H5FAdblock.lo H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo \ + H5FAtest.lo H5FD.lo H5FDcore.lo H5FDdirect.lo H5FDfamily.lo \ + H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo H5FDmulti.lo \ + H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo \ + H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ + H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ + H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ + H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \ + H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ + H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ + H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ + H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ + H5HGcache.lo H5HGdbg.lo H5HGquery.lo H5HL.lo H5HLcache.lo \ + H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5Itest.lo H5L.lo \ + H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \ + H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ + H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ + H5Obtreek.lo H5Ocache.lo H5Ochunk.lo H5Ocont.lo H5Ocopy.lo \ + H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \ + H5Ofsinfo.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo \ + H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo \ + H5Orefcount.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \ + H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo H5Pacpl.lo \ + H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pencdec.lo \ + H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ + H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \ + H5Ptest.lo H5PL.lo H5R.lo H5Rdeprec.lo H5UC.lo H5RS.lo H5S.lo \ + H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ + H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \ + H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo H5SMtest.lo H5ST.lo \ + H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo \ + H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo \ + H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo \ + H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \ + H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo \ + H5VM.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \ + H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \ + H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -746,7 +747,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 \ - H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \ + H5Dmpio.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 \ @@ -997,6 +998,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dscatgath.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dselect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dtest.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dvirtual.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5E.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EA.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAcache.Plo@am__quote@ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 55b3c44..950b7cf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -209,6 +209,7 @@ set (H5_TESTS cross_read freespace mf + vds farray earray btree2 diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 92e4574..c630501 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -330,6 +330,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 b5ebcf3..e45fbd3 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_with_endianess\ 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_[1-2].h5 # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ diff --git a/test/Makefile.in b/test/Makefile.in index 8b36650..3204bd3 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -194,9 +194,9 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \ enc_dec_plist_with_endianess$(EXEEXT) getname$(EXEEXT) \ vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \ dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \ - freespace$(EXEEXT) mf$(EXEEXT) farray$(EXEEXT) earray$(EXEEXT) \ - btree2$(EXEEXT) fheap$(EXEEXT) file_image$(EXEEXT) \ - unregister$(EXEEXT) + freespace$(EXEEXT) mf$(EXEEXT) vds$(EXEEXT) farray$(EXEEXT) \ + earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT) \ + file_image$(EXEEXT) unregister$(EXEEXT) @HAVE_SHARED_CONDITIONAL_TRUE@am__EXEEXT_2 = plugin$(EXEEXT) am__EXEEXT_3 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \ gen_cross$(EXEEXT) gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \ @@ -519,6 +519,10 @@ unregister_SOURCES = unregister.c unregister_OBJECTS = unregister.$(OBJEXT) unregister_LDADD = $(LDADD) unregister_DEPENDENCIES = libh5test.la $(LIBHDF5) +vds_SOURCES = vds.c +vds_OBJECTS = vds.$(OBJEXT) +vds_LDADD = $(LDADD) +vds_DEPENDENCIES = libh5test.la $(LIBHDF5) vfd_SOURCES = vfd.c vfd_OBJECTS = vfd.$(OBJEXT) vfd_LDADD = $(LDADD) @@ -574,7 +578,7 @@ SOURCES = $(libdynlib1_la_SOURCES) $(libdynlib2_la_SOURCES) \ mount.c mtime.c ntypes.c objcopy.c ohdr.c plugin.c pool.c \ reserved.c set_extent.c space_overflow.c stab.c \ tcheck_version.c $(testhdf5_SOURCES) testmeta.c \ - $(ttsafe_SOURCES) unlink.c unregister.c vfd.c + $(ttsafe_SOURCES) unlink.c unregister.c vds.c vfd.c DIST_SOURCES = $(am__libdynlib1_la_SOURCES_DIST) \ $(am__libdynlib2_la_SOURCES_DIST) \ $(am__libdynlib3_la_SOURCES_DIST) $(libh5test_la_SOURCES) \ @@ -593,7 +597,7 @@ DIST_SOURCES = $(am__libdynlib1_la_SOURCES_DIST) \ mount.c mtime.c ntypes.c objcopy.c ohdr.c plugin.c pool.c \ reserved.c set_extent.c space_overflow.c stab.c \ tcheck_version.c $(testhdf5_SOURCES) testmeta.c \ - $(ttsafe_SOURCES) unlink.c unregister.c vfd.c + $(ttsafe_SOURCES) unlink.c unregister.c vds.c vfd.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -1091,7 +1095,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog *.clog2 accum.h5 \ 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 + unregister_filter_1.h5 unregister_filter_2.h5 vds_[1-2].h5 # Test script for error_test and err_compat TEST_SCRIPT = testerror.sh testlibinfo.sh testcheck_version.sh \ @@ -1113,7 +1117,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_with_endianess\ 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 # These programs generate test files for the tests. They don't need to be @@ -1599,6 +1603,10 @@ unregister$(EXEEXT): $(unregister_OBJECTS) $(unregister_DEPENDENCIES) $(EXTRA_un @rm -f unregister$(EXEEXT) $(AM_V_CCLD)$(LINK) $(unregister_OBJECTS) $(unregister_LDADD) $(LIBS) +vds$(EXEEXT): $(vds_OBJECTS) $(vds_DEPENDENCIES) $(EXTRA_vds_DEPENDENCIES) + @rm -f vds$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(vds_OBJECTS) $(vds_LDADD) $(LIBS) + vfd$(EXEEXT): $(vfd_OBJECTS) $(vfd_DEPENDENCIES) $(EXTRA_vfd_DEPENDENCIES) @rm -f vfd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vfd_OBJECTS) $(vfd_LDADD) $(LIBS) @@ -1718,6 +1726,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvltypes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unregister.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vfd.Po@am__quote@ .c.o: @@ -2244,6 +2253,13 @@ mf.log: mf$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +vds.log: vds$(EXEEXT) + @p='vds$(EXEEXT)'; \ + b='vds'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) farray.log: farray$(EXEEXT) @p='farray$(EXEEXT)'; \ b='farray'; \ diff --git a/test/vds.c b/test/vds.c new file mode 100644 index 0000000..abb52fc --- /dev/null +++ b/test/vds.c @@ -0,0 +1,2604 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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_CREATE_DSET, + TEST_API_REOPEN_DSET, + TEST_API_REOPEN_FILE, + TEST_API_NTESTS +} test_api_config_t; + +const char *FILENAME[] = { + "vds_1", + "vds_2", + NULL +}; + +/* I/O test config flags */ +#define TEST_IO_CLOSE_SRC 0x01u +#define TEST_IO_DIFFERENT_FILE 0x02u +#define TEST_IO_NTESTS 0x04u +//VDSINC add close source, virtual file + +#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 + * + * 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) +{ + hid_t file = -1; /* File */ + hid_t dset = -1; /* Virtual dataset */ + + 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_RDONLY, 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 + + /* Close dataset and file */ + if(H5Dclose(dset) < 0) + TEST_ERROR + dset = -1; + 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 { + /* 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 */ + + return 0; + +error: + H5E_BEGIN_TRY { + if(file >= 0) + (void)H5Fclose(file); + if(dset >= 0) + (void)H5Dclose(dset); + } H5E_END_TRY; + + 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[4] = {10, 20, 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 */ + hsize_t coord[10]; /* Point selection array */ + size_t size_out; + 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_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) < 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) < 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 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) < 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) < 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) < 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; + + + /* + * 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) < 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; + + + /* 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 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 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[2] = {10, 26}; /* 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 */ + hsize_t coord[10]; /* Point selection array */ + int buf[10][26]; /* Write and expecte read buffer */ + int rbuf[10][26]; /* Read buffer */ + int evbuf[10][26]; /* Expected VDS "buffer" */ + int erbuf[10][26]; /* Expected read buffer */ + int i, j; + + TESTING("basic virtual dataset I/O") + + h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); + h5_fixname(FILENAME[1], fapl, srcfilename, sizeof srcfilename); + + /* 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], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "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 */ + + /* 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, H5P_DEFAULT)) < 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 + 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 + */ + /* 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 : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "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 */ + + /* 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, H5P_DEFAULT)) < 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 + + /* 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 + 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 on one mapping at a + * time + */ + /* 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 : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "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 */ + + /* 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(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 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 + 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 4: 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 : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "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 */ + + /* 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, H5P_DEFAULT)) < 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 + 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 5: 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 : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "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 */ + + /* 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, H5P_DEFAULT)) < 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 + 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 6: 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 : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "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 */ + + /* 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] = 3; + count[1] = 9; + 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)); + erbuf[0][0] = buf[0][0]; + erbuf[0][2] = buf[0][1]; + erbuf[0][6] = buf[0][8]; + erbuf[0][8] = buf[0][9]; + erbuf[2][0] = buf[1][0]; + erbuf[2][2] = buf[1][1]; + erbuf[2][6] = buf[1][8]; + erbuf[2][8] = buf[1][9]; + erbuf[1][3] = buf[0][13]; + erbuf[1][5] = 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 + + /* Read second 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)); + erbuf[0][3] = buf[0][4]; + erbuf[0][5] = buf[0][5]; + erbuf[1][0] = buf[0][6]; + erbuf[1][1] = buf[0][7]; + erbuf[1][2] = buf[0][12]; + erbuf[1][3] = buf[0][15]; + erbuf[1][5] = buf[1][4]; + erbuf[1][6] = buf[1][7]; + erbuf[1][7] = buf[1][12]; + erbuf[1][8] = buf[1][13]; + erbuf[2][3] = buf[1][14]; + erbuf[2][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(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] = 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 + + /* Read third 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)); + erbuf[0][0] = buf[0][2]; + erbuf[0][2] = buf[0][3]; + erbuf[0][6] = buf[0][10]; + erbuf[0][8] = buf[0][11]; + erbuf[2][0] = buf[1][2]; + erbuf[2][2] = buf[1][3]; + erbuf[2][6] = buf[1][10]; + erbuf[2][8] = buf[1][11]; + erbuf[1][3] = buf[1][5]; + erbuf[1][5] = 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(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 by hyperslab */ + /* 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 + + /* 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][2]; + erbuf[0][8] = buf[0][6]; + erbuf[0][9] = buf[0][8]; + erbuf[1][0] = buf[2][0]; + erbuf[1][1] = buf[2][2]; + erbuf[1][8] = buf[2][6]; + erbuf[1][9] = buf[2][8]; + erbuf[0][13] = buf[1][3]; + erbuf[0][14] = buf[1][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 */ + 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 + + /* 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][3]; + erbuf[0][5] = buf[0][5]; + erbuf[0][6] = buf[1][0]; + erbuf[0][7] = buf[1][1]; + erbuf[0][12] = buf[1][2]; + erbuf[0][15] = buf[1][3]; + erbuf[1][4] = buf[1][5]; + erbuf[1][7] = buf[1][6]; + erbuf[1][12] = buf[1][7]; + erbuf[1][13] = buf[1][8]; + erbuf[1][14] = buf[2][3]; + erbuf[1][15] = buf[2][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 */ + 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 + + /* 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][2]; + erbuf[0][10] = buf[0][6]; + erbuf[0][11] = buf[0][8]; + erbuf[1][2] = buf[2][0]; + erbuf[1][3] = buf[2][2]; + erbuf[1][10] = buf[2][6]; + erbuf[1][11] = buf[2][8]; + erbuf[1][5] = buf[1][3]; + erbuf[1][6] = buf[1][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, H5P_DEFAULT)) < 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 + + /* 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 + 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); + 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: 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\n", bit_config & TEST_IO_CLOSE_SRC ? "closed source dataset, " : "", bit_config & TEST_IO_DIFFERENT_FILE ? "different source file" : "same source file"); + nerrors += test_basic_io(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; +} + diff --git a/tools/h5dump/errfiles/tdset-2.err b/tools/h5dump/errfiles/tdset-2.err index d9b92f3..775351e 100644 --- a/tools/h5dump/errfiles/tdset-2.err +++ b/tools/h5dump/errfiles/tdset-2.err @@ -1,17 +1,20 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): not found + #000: (file name) line (number) in H5Dopen2(): unable to open dataset + major: Dataset + minor: Can't open object + #001: (file name) line (number) in H5D__open_name(): not found major: Dataset minor: Object not found - #001: (file name) line (number) in H5G_loc_find(): can't find object + #002: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found - #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + #003: (file name) line (number) in H5G_traverse(): internal path traversal failed major: Symbol table minor: Object not found - #003: (file name) line (number) in H5G_traverse_real(): traversal operator failed + #004: (file name) line (number) in H5G_traverse_real(): traversal operator failed major: Symbol table minor: Callback failed - #004: (file name) line (number) in H5G_loc_find_cb(): object 'dset3' doesn't exist + #005: (file name) line (number) in H5G_loc_find_cb(): object 'dset3' doesn't exist major: Symbol table minor: Object not found HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): diff --git a/tools/h5dump/errfiles/tperror.err b/tools/h5dump/errfiles/tperror.err index 19a7a73..29f9e7f 100644 --- a/tools/h5dump/errfiles/tperror.err +++ b/tools/h5dump/errfiles/tperror.err @@ -1,17 +1,20 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): not found + #000: (file name) line (number) in H5Dopen2(): unable to open dataset + major: Dataset + minor: Can't open object + #001: (file name) line (number) in H5D__open_name(): not found major: Dataset minor: Object not found - #001: (file name) line (number) in H5G_loc_find(): can't find object + #002: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found - #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + #003: (file name) line (number) in H5G_traverse(): internal path traversal failed major: Symbol table minor: Object not found - #003: (file name) line (number) in H5G_traverse_real(): traversal operator failed + #004: (file name) line (number) in H5G_traverse_real(): traversal operator failed major: Symbol table minor: Callback failed - #004: (file name) line (number) in H5G_loc_find_cb(): object 'bogus' doesn't exist + #005: (file name) line (number) in H5G_loc_find_cb(): object 'bogus' doesn't exist major: Symbol table minor: Object not found HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): diff --git a/tools/h5dump/errfiles/tslink-D.err b/tools/h5dump/errfiles/tslink-D.err index b98e324..924e9cf 100644 --- a/tools/h5dump/errfiles/tslink-D.err +++ b/tools/h5dump/errfiles/tslink-D.err @@ -1,25 +1,28 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): - #000: (file name) line (number) in H5Dopen2(): not found + #000: (file name) line (number) in H5Dopen2(): unable to open dataset + major: Dataset + minor: Can't open object + #001: (file name) line (number) in H5D__open_name(): not found major: Dataset minor: Object not found - #001: (file name) line (number) in H5G_loc_find(): can't find object + #002: (file name) line (number) in H5G_loc_find(): can't find object major: Symbol table minor: Object not found - #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + #003: (file name) line (number) in H5G_traverse(): internal path traversal failed major: Symbol table minor: Object not found - #003: (file name) line (number) in H5G_traverse_real(): special link traversal failed + #004: (file name) line (number) in H5G_traverse_real(): special link traversal failed major: Links minor: Link traversal failure - #004: (file name) line (number) in H5G__traverse_special(): symbolic link traversal failed + #005: (file name) line (number) in H5G__traverse_special(): symbolic link traversal failed major: Links minor: Link traversal failure - #005: (file name) line (number) in H5G_traverse_slink(): unable to follow symbolic link + #006: (file name) line (number) in H5G_traverse_slink(): unable to follow symbolic link major: Symbol table minor: Object not found - #006: (file name) line (number) in H5G_traverse_real(): traversal operator failed + #007: (file name) line (number) in H5G_traverse_real(): traversal operator failed major: Symbol table minor: Callback failed - #007: (file name) line (number) in H5G_traverse_slink_cb(): component not found + #008: (file name) line (number) in H5G_traverse_slink_cb(): component not found major: Symbol table minor: Object not found diff --git a/tools/h5stat/h5stat.c b/tools/h5stat/h5stat.c index e9fa0fa..1310fd5 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 d6c3720..6512f9b 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -81,7 +81,7 @@ #define FLETCHER32 "CHECKSUM FLETCHER32" #define SZIP "COMPRESSION SZIP" #define NBIT "COMPRESSION NBIT" -#define SCALEOFFSET "COMPRESSION SCALEOFFSET" +#define SCALEOFFSET "COMPRESSION SCALEOFFSET" #define SCALEOFFSET_MINBIT "MIN BITS" #define STORAGE_LAYOUT "STORAGE_LAYOUT" #define CONTIGUOUS "CONTIGUOUS" @@ -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 26cac47..29a6d68 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,14 @@ 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); +void h5tools_print_virtual_selection(hid_t vspace, hid_t dcpl_id, size_t index, + 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, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter); + void h5tools_dump_init(void) { @@ -2841,7 +2858,61 @@ 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 + *------------------------------------------------------------------------- + */ +void +h5tools_print_virtual_selection(hid_t vspace, hid_t dcpl_id, size_t index, + 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, hsize_t region_elmt_counter/*element counter*/, + hsize_t elmt_counter) +{ + 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 */ + h5tools_str_reset(buffer); + if (H5Sis_regular_hyperslab(vspace)) { + h5tools_str_append(buffer, "%s %s ", VDS_REG_HYPERSLAB, h5tools_dump_header_format->virtualselectionblockbegin); + 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_str_dump_space_blocks(buffer, vspace, info); + } + 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 @@ -3080,6 +3151,115 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, } } break; + case H5D_VIRTUAL: + { + 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, dcpl_id, next, 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->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); + H5Pget_virtual_filename(dcpl_id, next, name, sizeof(name)); + ssize_out = H5Pget_virtual_dsetname(dcpl_id, next, NULL, 0); + 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, dcpl_id, next, 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--; + + ctx->need_prefix = TRUE; + h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); + +/*EIP + 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); + } + break; default: h5tools_str_reset(&buffer); h5tools_str_append(&buffer, "%s", "Unknown layout"); diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 2603984..4381df8 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -412,9 +412,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 @@ -425,19 +425,89 @@ 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 */ + h5tools_str_append(str, "%s", "\n"); + h5tools_str_indent(str, info, ctx); + + /* Start coordinates */ + h5tools_str_append(str, "%s ", 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, ")"); + h5tools_str_append(str, "%s", "\n"); + h5tools_str_indent(str, info, ctx); +} + +/*------------------------------------------------------------------------- + * 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 */ @@ -448,7 +518,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 +543,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 +578,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; @@ -1237,9 +1306,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, |