diff options
-rw-r--r-- | src/H5Ddeprec.c | 48 | ||||
-rw-r--r-- | src/H5Dio.c | 2 | ||||
-rw-r--r-- | src/H5Dlayout.c | 7 | ||||
-rw-r--r-- | src/H5Dvirtual.c | 44 | ||||
-rw-r--r-- | src/H5Oprivate.h | 9 | ||||
-rw-r--r-- | src/H5Pdcpl.c | 7 | ||||
-rw-r--r-- | src/H5Shyper.c | 275 | ||||
-rw-r--r-- | src/H5Sselect.c | 74 | ||||
-rw-r--r-- | test/vds.c | 155 |
9 files changed, 535 insertions, 86 deletions
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 04cf032..021c8df 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_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_dxpl_id; /* dxpl to use to open datset */ + hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE2("i", "i*s", loc_id, name); @@ -245,45 +240,22 @@ 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() */ - +#error /*------------------------------------------------------------------------- * Function: H5Dextend diff --git a/src/H5Dio.c b/src/H5Dio.c index 296e529..5ec1db4 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -616,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 4da0443..fea57fe 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -455,9 +455,12 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t HDassert(dataset->shared->layout.storage.u.virt.list || (dataset->shared->layout.storage.u.virt.list_nused == 0)); /* Patch the virtual selection dataspaces */ - for(i = 0; i < dataset->shared->layout.storage.u.virt.list_nused; i++) + for(i = 0; i < dataset->shared->layout.storage.u.virt.list_nused; i++) { + HDassert(dataset->shared->layout.storage.u.virt.list[i].virtual_space_status == H5O_VIRTUAL_STATUS_INVALID); 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 for */ } /* end block */ break; @@ -470,7 +473,7 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__layout_oh_read() */ - +#error /*------------------------------------------------------------------------- * Function: H5D__layout_oh_write diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index ac7af54..cbcb97b 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -228,7 +228,15 @@ H5D__virtual_open_source_dset(const H5D_t *vdset, 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") @@ -341,13 +349,25 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__virtual_construct(H5F_t UNUSED *f, H5D_t UNUSED *dset) +H5D__virtual_construct(H5F_t UNUSED *f, H5D_t *dset) { - FUNC_ENTER_STATIC_NOERR + size_t i; + herr_t ret_value = SUCCEED; - /* No-op for now VDSINC */ + FUNC_ENTER_STATIC - FUNC_LEAVE_NOAPI(SUCCEED) + HDassert(dataset->shared->layout.storage.u.virt.list || (dataset->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() */ @@ -443,6 +463,10 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Iterate over mappings */ for(i = 0; i < storage->list_nused; i++) { + /* Sanity check that both spaces have been patched by now */ + HDassert(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + 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) @@ -459,7 +483,8 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, if((opened_dset = 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(!opened_dset) - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "did not open source dataset") + /* Fill with fill value */ + HDassert(0 && "Not yet implemented...");//VDSINC } /* end if */ /* Project intersection of file space and mapping virtual space onto @@ -538,12 +563,16 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Iterate over mappings */ for(i = 0; i < storage->list_nused; i++) { + /* Sanity check that both spaces have been patched by now */ + HDassert(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + 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 */ + /* 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") @@ -551,6 +580,7 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, if(nelmts > 0) { /* Open source dataset, fail if cannot open */ if(!storage->list[i].source_dset) { + //VDSINC check all source datasets before any I/O. Also for read? if((opened_dset = 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(!opened_dset) @@ -641,4 +671,4 @@ H5D__virtual_copy(H5F_t UNUSED *f_src, const H5O_storage_virtual_t UNUSED *stora FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5D__virtual_copy() */ - +#error diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index ac8d02f..7c69a01 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -412,6 +412,13 @@ 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 */ @@ -421,6 +428,8 @@ typedef struct H5O_storage_virtual_ent_t { /* 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 { diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 9c5833d..3739be6 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -1615,7 +1615,8 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, 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 overlaping virtual spaces + //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 @@ -1668,6 +1669,8 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, 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; @@ -1699,7 +1702,7 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pset_virtual() */ - +#error /*------------------------------------------------------------------------- * Function: H5Pget_virtual_count diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 9b1562f..b62184a 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -8794,7 +8794,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 +8863,279 @@ 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_i; + H5S_sel_iter_t ss_iter; + hbool_t ss_iter_init = FALSE; + hsize_t ss_sel_off; + hsize_t ds_off[H5S_PROJECT_INTERSECT_NSEQS]; + size_t ds_len[H5S_PROJECT_INTERSECT_NSEQS]; + size_t ds_nseq; + size_t ds_i; + H5S_sel_iter_t ds_iter; + hbool_t ds_iter_init = FALSE; + hsize_t ds_sel_off; + hsize_t sis_off[H5S_PROJECT_INTERSECT_NSEQS]; + size_t sis_len[H5S_PROJECT_INTERSECT_NSEQS]; + size_t sis_nseq; + size_t sis_i; + H5S_sel_iter_t sis_iter; + hbool_t sis_iter_init = FALSE; + 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]; + unsigned proj_rank; + 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 dst_space have same # of elements in selection, + * src_space and src_intersect_space have same extent, and no point + * selections? */ + + /* Initialize prev_space and curr_span_tree */ + for(i = 0; i < H5S_MAX_RANK; i++) { + curr_span_tree[i] = NULL; + prev_span[i] = NULL; + } /* end for */ + + /* Save rank of projected space */ + proj_rank = proj_space->extent.rank; + HDassert(proj_rank > 0); + + /* Calculate proj_down_dims (note loop relies on unsigned i wrapping around) + */ + proj_down_dims[proj_rank - 1] = proj_space->extend.size[proj_rank - 1]; + if(proj_rank > 1) + for(i = proj_rank - 2; i < proj_rank; i--) + proj_down_dims[i] = proj_space->extend.size[i] * proj_down_dims[i + 1]; + + /* Init, get sequence lists, loop, etc VDSINC */ + /* Remove current selection from proj_space */ + if(H5S_SELECT_RELEASE(proj_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab") + + /* 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, NULL, "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, (size_t)-1, &ss_nseq, &nelem, ss_off, ss_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + + /* 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, (size_t)-1, &ds_nseq, &nelem, ds_off, ds_len) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") + + /* 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, (size_t)-1, &sis_nseq, &nelem, sis_off, sis_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + + /* Make sure all sequences are non-empty */ + if((ss_nseq > 0) && (ds_nseq > 0) && (sis_nseq > 0)) { + /* Loop until we run out of sequences in either the source or source + * intersect space */ + while(1) { + if(ss_off[ss_i] + ss_len[ss_i] <= sis_off[sis_i]) { + /* Sequences do not intersect, advance source space */ + ss_sel_off += (hsize_t)ss_len[ss_i]; + if(++ss_i == ss_nseq) { + /* Try to grab more sequences from src_space. If there are + * no more then we are done, otherwise reset the source + * space index. */ + if(H5S_SELECT_GET_SEQ_LIST(src_space, 0u, &ss_iter, H5S_PROJECT_INTERSECT_NSEQS, (size_t)-1, &ss_nseq, &nelem, ss_off, ss_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + if(ss_nseq == 0) + break; + else { + HDassert(0 && "Checking code coverage..."); //VDSINC + ss_i = 0; + } //VDSINC + } /* end if */ + } /* end if */ + else if(sis_off[sis_i] + sis_len[sis_i] <= ss_off[ss_i]) { + if(++sis_i == sis_nseq) { + /* Try to grab more sequences from src_intersect_space. If + * there are no more then we are done, otherwise reset the + * source intersect space index. */ + if(H5S_SELECT_GET_SEQ_LIST(src_intersect_space, 0u, &sis_iter, H5S_PROJECT_INTERSECT_NSEQS, (size_t)-1, &sis_nseq, &nelem, sis_off, sis_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + if(sis_nseq == 0) + break; + else { + HDassert(0 && "Checking code coverage..."); //VDSINC + sis_i = 0; + } //VDSINC + } /* end if */ + } /* end if */ + else { + /* Sequences intersect, add intersection to projected space */ + /* Calculate intersection sequence */ + if(ss_off[ss_i] >= sis_off[sis_i]) { + HDassert(0 && "Checking code coverage..."); //VDSINC + int_sel_off = ss_sel_off; + } //VDSINC + else { + HDassert(0 && "Checking code coverage..."); //VDSINC + int_sel_off = sis_off[sis_i] - ss_off[ss_i] + ss_sel_off; + } //VDSINC + int_len = (size_t)(MIN(ss_off[ss_i] + (hsize_t)ss_len[ss_i], + sis_off[sis_i] + (hsize_t)sis_len[sis_i]) - tmp_off); + + /* Project to destination */ + while(int_len > (size_t)0) { + while(ds_sel_off + (hsize_t)ds_len[ds_i] <= int_sel_off) { + HDassert(0 && "Checking code coverage..."); //VDSINC + /* 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) { + /* Try to grab more sequences from dst_space. If + * there are no more then we are done, otherwise + * reset the destination space index. */ + if(H5S_SELECT_GET_SEQ_LIST(dst_space, 0u, H5S_sel_iter_t *iter, H5S_PROJECT_INTERSECT_NSEQS, (size_t)-1, &sis_nseq, &nelem, sis_off, sis_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") + if(sis_nseq == 0) + break; + else { + HDassert(0 && "Checking code coverage..."); //VDSINC + sis_i = 0; + } //VDSINC + } /* 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 = (size_t)((hsize_t)ds_len[ds_i] + ds_sel_off + - int_sel_off); + + /* Add to span tree */ + while(proj_len > (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 plan of the span currently being built + * (i.e. they're finished being built) */ + for(i = proj_rank - 1; ((i > 0) + && ((up_dim = proj_off / proj_down_dims[i]) + != curr_span_dim[i - 1]) + && curr_span_tree[i]); + i--) { + HDassert(0 && "Checking code coverage..."); //VDSINC + /* Append complete lower dimension span tree to + * current dimension */ + if(H5S_hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], up_dim, up_dim, 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 */ + curr_span_tree[i] = NULL; + prev_span[i] = NULL; + } /* end for */ + + /* Compute bounds for new span in lowest dimension */ + low = proj_off % proj_down_dims[proj_rank - 1]; + high = MAX(low + (hsize_t)proj_len, + proj_space->extent.size[proj_rank - 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 += high - low; + proj_len -= (size_t)(high - low); + } /* end while */ + + /* Update intersection sequence */ + int_sel_off += (hsize_t)proj_len; + int_len -= proj_len; + } /* end while */ + } /* end else */ + } /* end while */ + } /* end if */ + + /* Back off proj_off by 1 so it's guaranteed to point to the right dimension + * for the current span tree in every rank except the lowest */ + proj_off--; + + /* Add remaining spans to span tree */ + for(i = proj_rank - 1; i > 0; i--) { + if(curr_span_tree[i]) { + HDassert(prev_span[i]); + up_dim = proj_off / proj_down_dims[i]; + /* Append remaining span tree to higher dimension */ + if(H5S_hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], up_dim, up_dim, 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 */ + curr_span_tree[i] = NULL; + prev_span[i] = NULL; + + + /* Add span tree to proj_space VDSINC */ + /* If we did not add anything to proj_space, select none instead VDSINC */ + + +/*-------------------------------------------------------------------------- + NAME H5Sis_regular_hyperslab PURPOSE Determine if a hyperslab selection is regular diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 4085e7f..24ec7bb 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -2138,48 +2138,52 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HDassert(src_intersect_space); HDassert(new_space_ptr); - /* Create new space, using dst extent. Start wil "all" selection. */ + /* 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") - /* Check intersecting space's selection type */ - switch(src_intersect_space->select.type->type) { - case H5S_SEL_NONE: - /* Since the intersecting space is "none", the intersection has no - * selection and so does the projection. Change to "none" selection - */ - if(H5S_select_none(new_space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") - - break; - - case H5S_SEL_POINTS: - HDassert(0 && "Not yet implemented...");//VDSINC - - break; + /* 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. If source space is set to + * all, use simpler algorithm, otherwise use general hyperslab algorithm + * (in either case if the destination space is al; the hyperslab + * routines will convert the destination selection to a span tree to use + * the same algorithm as with hyperslabs). */ + if(dst_space->select.type->type == H5S_SEL_ALL) { + HDassert(0 && "Checking code coverage...");//VDSINC + /* Project src_intersect_space onto dst_space selection */ + if(H5S_hyper_project_to_hs(src_intersect_space, dst_space, new_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't project hyperslab ondot destination selection") + } /* end if */ + else { + HDassert(dst_space->select.type->type == H5S_SEL_HYPERSLABS); - case H5S_SEL_HYPERSLABS: HDassert(0 && "Not yet implemented...");//VDSINC - - break; - - case H5S_SEL_ALL: - /* Since the intersecting space is "all", the intersection must be - * equal to the source space and the projection must be equal to the - * destination space. 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") - - break; - - case H5S_SEL_ERROR: - case H5S_SEL_N: - default: - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "invalid source dataspace selection type") - } /* end switch */ + } /* end else */ + } /* end else */ /* load the address of the new space into *new_space_ptr */ *new_space_ptr = new_space; @@ -42,6 +42,7 @@ const char *FILENAME[] = { #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) @@ -1133,6 +1134,160 @@ test_basic_io(unsigned config, hid_t fapl) 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] = 10; + 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] = 10; + 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] = 20; + + /* 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 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; + } /* 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 if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + 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; + + /* Close */ if(H5Pclose(dcpl) < 0) TEST_ERROR |