diff options
-rw-r--r-- | src/H5Ddeprec.c | 2 | ||||
-rw-r--r-- | src/H5Dlayout.c | 13 | ||||
-rw-r--r-- | src/H5Dvirtual.c | 69 | ||||
-rw-r--r-- | src/H5Pdcpl.c | 2 | ||||
-rw-r--r-- | src/H5Sall.c | 1 | ||||
-rw-r--r-- | src/H5Shyper.c | 309 | ||||
-rw-r--r-- | src/H5Spkg.h | 6 | ||||
-rw-r--r-- | src/H5Sselect.c | 28 |
8 files changed, 279 insertions, 151 deletions
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 021c8df..63df5b7 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -255,7 +255,7 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Dopen1() */ -#error + /*------------------------------------------------------------------------- * Function: H5Dextend diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index fea57fe..87e1bc8 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -454,12 +454,13 @@ 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 */ + /* Patch the virtual selection dataspaces if necessary */ 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; + 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; @@ -473,7 +474,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 cbcb97b..3d957a2 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -141,7 +141,7 @@ H5D__virtual_copy_layout(H5O_layout_t *layout) 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 */ + /* 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))) @@ -155,6 +155,9 @@ H5D__virtual_copy_layout(H5O_layout_t *layout) 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 { @@ -356,7 +359,7 @@ H5D__virtual_construct(H5F_t UNUSED *f, H5D_t *dset) FUNC_ENTER_STATIC - HDassert(dataset->shared->layout.storage.u.virt.list || (dataset->shared->layout.storage.u.virt.list_nused == 0)); + 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++) { @@ -386,14 +389,13 @@ done: *------------------------------------------------------------------------- */ hbool_t -H5D__virtual_is_space_alloc(const H5O_storage_t *storage) +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 if the global - * heap block has been allocated. VDSINC */ + /* 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) @@ -463,8 +465,7 @@ 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); + /* 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 @@ -478,28 +479,36 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Only perform I/O if there are any elements */ if(nelmts > 0) { - /* Open source dataset, fail if cannot open */ + /* Open source dataset */ if(!storage->list[i].source_dset) { + /* Try to open dataset */ 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) - /* Fill with fill value */ - HDassert(0 && "Not yet implemented...");//VDSINC - } /* end if */ - /* 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") + if(opened_dset) + /* Sanity check that the source space has been patched by now */ + HDassert(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + } /* end if */ - /* 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; + /* Check if source dataset is open */ + if(storage->list[i].source_dset) { + /* 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 */ @@ -563,8 +572,7 @@ 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); + /* 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 @@ -580,13 +588,18 @@ 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? + //VDSINC check all source datasets before any I/O 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") + + /* Sanity check that source space has been patched by now */ + HDassert(storage->list[i].source_space_status == H5O_VIRTUAL_STATUS_CORRECT); } /* end if */ + /* 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) @@ -671,4 +684,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/H5Pdcpl.c b/src/H5Pdcpl.c index 3739be6..b9b4653 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -1702,7 +1702,7 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pset_virtual() */ -#error + /*------------------------------------------------------------------------- * Function: H5Pget_virtual_count 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 b62184a..c64f1c9 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) @@ -8892,27 +8894,42 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_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; + 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 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_i; + 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 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_i; + 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; @@ -8924,36 +8941,41 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *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? */ + /* Assert that src_space and src_intersect_space have same extent and there + * are no point selections? */ - /* Initialize prev_space and curr_span_tree */ + /* 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) */ - proj_down_dims[proj_rank - 1] = proj_space->extend.size[proj_rank - 1]; + proj_down_dims[proj_rank - 1] = proj_space->extent.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]; + proj_down_dims[i] = proj_space->extent.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") + 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, NULL, "can't allocate hyperslab info") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") /* Set selection type */ proj_space->select.type = H5S_sel_hyper; @@ -8964,8 +8986,9 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, 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) + 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) @@ -8973,8 +8996,9 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, 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) + 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) @@ -8982,125 +9006,166 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, 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) + 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; /* 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]) { + if(advance_ss || (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 { + if(ss_nelem > 0) { HDassert(0 && "Checking code coverage..."); //VDSINC + /* 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; - } //VDSINC + } /* end if */ + else + /* There are no more sequences in src_space, so we can + * exit the loop */ + break; } /* end if */ + + /* Reset advance_ss */ + advance_ss = FALSE; } /* end if */ - else if(sis_off[sis_i] + sis_len[sis_i] <= ss_off[ss_i]) { + else if(advance_sis + || (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 + 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; - } //VDSINC + } /* end if */ + else + /* There are no more sequences in src_intersect_space, + * so we can exit the loop */ + break; } /* end if */ + + /* Reset advance_sis */ + advance_sis = FALSE; } /* 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 + /* Calculate intersection sequence and advance any sequences we + * complete */ + if(ss_off[ss_i] >= sis_off[sis_i]) int_sel_off = ss_sel_off; - } //VDSINC - else { - HDassert(0 && "Checking code coverage..."); //VDSINC + else 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); + 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)(ss_off[ss_i] + (hsize_t)ss_len[ss_i] - int_sel_off); + advance_ss = TRUE; + } /* end if */ + else + int_len = (size_t)(sis_off[sis_i] + (hsize_t)sis_len[sis_i] - 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 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) + HDassert(0 && "Checking code coverage..."); //VDSINC + HDassert(sis_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") - if(sis_nseq == 0) - break; - else { - HDassert(0 && "Checking code coverage..."); //VDSINC - sis_i = 0; - } //VDSINC + 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 = (size_t)((hsize_t)ds_len[ds_i] + ds_sel_off - - int_sel_off); + proj_len = proj_len_rem = MIN(int_len, (size_t)(ds_sel_off + + (hsize_t)ds_len[ds_i] - int_sel_off + (hsize_t)1)); /* Add to span tree */ - while(proj_len > (size_t)0) { + 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 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") + && ((proj_off / proj_down_dims[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 */ - /* 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; + /* Update curr_span_dim */ + curr_span_dim[i - 1] = proj_off / proj_down_dims[i]; } /* 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]); + 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 += high - low; - proj_len -= (size_t)(high - low); + proj_off += (hsize_t)span_len; + proj_len_rem -= span_len; } /* end while */ /* Update intersection sequence */ @@ -9111,27 +9176,75 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, } /* 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--) { + 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) + 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 */ + /* 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; - prev_span[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; - /* Add span tree to proj_space VDSINC */ - /* If we did not add anything to proj_space, select none instead VDSINC */ + /* 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 { + HDassert(0 && "Checking code coverage..."); //VDSINC + /* 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") + } /* end else */ + + +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() */ /*-------------------------------------------------------------------------- diff --git a/src/H5Spkg.h b/src/H5Spkg.h index f5511fb..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 @@ -249,6 +252,9 @@ 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/H5Sselect.c b/src/H5Sselect.c index 24ec7bb..ed384e5 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -2128,6 +2128,7 @@ 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 */ + unsigned i; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -2144,6 +2145,11 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, 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 */ + for(i = 0; i < new_space->extent.rank; i++) + new_space->select.offset[i] = 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) { @@ -2163,26 +2169,14 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, */ 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)) { + || (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); - - HDassert(0 && "Not yet implemented...");//VDSINC - } /* end else */ + /* 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 */ |