diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2015-03-18 21:53:49 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2015-03-18 21:53:49 (GMT) |
commit | 4cfe53284bb6c3f7f57ff70af6ceb7396683aaa4 (patch) | |
tree | a9660134778d77babb6adb93286015836044ddb5 /src | |
parent | 424826d0dd492cb734e166b7154e2db456f6a13a (diff) | |
download | hdf5-4cfe53284bb6c3f7f57ff70af6ceb7396683aaa4.zip hdf5-4cfe53284bb6c3f7f57ff70af6ceb7396683aaa4.tar.gz hdf5-4cfe53284bb6c3f7f57ff70af6ceb7396683aaa4.tar.bz2 |
[svn-r26476] Add support for I/O in all cases with fixed size datasets and no point
selections.
Add source dataspace extent patching (should allow closing the source file).
Note fill values and various other features are not yet supported.
Note there are still some code coverage assertions in the selection matching
algorithm - if you hit these try taking them out.
Note make check still fails in h5dump test (unrelated to this checkin).
Tested: ummon
Diffstat (limited to 'src')
-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 */ |