From 9786fe2f6158cd13c5e1837dee58f99dcda8f58c Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 11 Jun 2015 23:26:53 -0500 Subject: [svn-r27192] Improve support for printf selections (support partial blocks with H5_VDS_FIRST_MISSING) Add test for this Rework VDS code to not depend on unlimited selections having a "clipped" state in preparation for removing the clipped state from unlimited selections. Other bug fixes/cleanup Tested: Kubuntu 64 (home computer) --- src/H5Dpkg.h | 4 - src/H5Dvirtual.c | 564 +++++++++++++++++++++++++------------------ src/H5Olayout.c | 6 + src/H5Oprivate.h | 3 + src/H5Pdcpl.c | 7 +- src/H5Shyper.c | 84 ++++++- src/H5Sprivate.h | 2 + test/vds.c | 713 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 8 files changed, 1115 insertions(+), 268 deletions(-) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 6af79e9..44441c4 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -171,15 +171,11 @@ typedef struct { hbool_t *dirty; /* Pointer to dirty flag to mark */ } H5D_compact_storage_t; -typedef struct { -} H5D_virtual_storage_t; /* Either fill out or remove VDSINC */ - typedef union H5D_storage_t { H5D_contig_storage_t contig; /* Contiguous information for dataset */ H5D_chunk_storage_t chunk; /* Chunk information for dataset */ H5D_compact_storage_t compact; /* Compact information for dataset */ H5O_efl_t efl; /* External file list information for dataset */ - H5D_virtual_storage_t virt; /* Virtual dataset information */ } H5D_storage_t; /* Typedef for raw data I/O operation info */ diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 0fc96cf..bfd4e0c 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -85,11 +85,9 @@ static herr_t H5D__virtual_build_source_name(char *source_name, size_t nsubs, hsize_t blockno, char **built_name); static herr_t H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, const H5S_t *file_space, - H5O_storage_virtual_ent_t *virtual_ent, H5O_storage_virtual_srcdset_t *source_dset); static herr_t H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, const H5S_t *file_space, - H5O_storage_virtual_ent_t *virtual_ent, H5O_storage_virtual_srcdset_t *source_dset); static herr_t H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, const H5S_t *file_space, @@ -242,6 +240,10 @@ H5D__virtual_copy_layout(H5O_layout_t *layout) if(NULL == (layout->storage.u.virt.list[i].source_select = H5S_copy(orig_list[i].source_select, FALSE, TRUE))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + if(orig_list[i].unlim_dim_virtual < 0) { + layout->storage.u.virt.list[i].source_dset.clipped_source_select = layout->storage.u.virt.list[i].source_select; + layout->storage.u.virt.list[i].source_dset.clipped_virtual_select = layout->storage.u.virt.list[i].source_dset.virtual_select; + } /* end if */ if(H5D__virtual_copy_parsed_name(&layout->storage.u.virt.list[i].parsed_source_file_name, orig_list[i].parsed_source_file_name) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy parsed source file name") layout->storage.u.virt.list[i].psfn_static_strlen = orig_list[i].psfn_static_strlen; @@ -267,6 +269,9 @@ H5D__virtual_copy_layout(H5O_layout_t *layout) layout->storage.u.virt.list_nalloc = 0; } /* end else */ + /* New layout is not fully initialized */ + layout->storage.u.virt.init = FALSE; + done: /* Release allocated resources on failure */ if((ret_value < 0) && orig_list @@ -313,17 +318,17 @@ H5D__virtual_reset_layout(H5O_layout_t *layout) if(H5D__virtual_reset_source_dset(&layout->storage.u.virt.list[i], &layout->storage.u.virt.list[i].source_dset) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset source dataset") - /* Free source_select */ - if(layout->storage.u.virt.list[i].source_select) - if(H5S_close(layout->storage.u.virt.list[i].source_select) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") - /* Free sub_dset */ for(j = 0; j < layout->storage.u.virt.list[i].sub_dset_nalloc; j++) if(H5D__virtual_reset_source_dset(&layout->storage.u.virt.list[i], &layout->storage.u.virt.list[i].sub_dset[j]) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset source dataset") layout->storage.u.virt.list[i].sub_dset = (H5O_storage_virtual_srcdset_t *)H5MM_xfree(layout->storage.u.virt.list[i].sub_dset); + /* Free source_select */ + if(layout->storage.u.virt.list[i].source_select) + if(H5S_close(layout->storage.u.virt.list[i].source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + /* Free parsed_source_file_name */ H5D_virtual_free_parsed_name(layout->storage.u.virt.list[i].parsed_source_file_name); @@ -337,6 +342,9 @@ H5D__virtual_reset_layout(H5O_layout_t *layout) layout->storage.u.virt.list_nused = (size_t)0; (void)HDmemset(layout->storage.u.virt.min_dims, 0, sizeof(layout->storage.u.virt.min_dims)); + /* The list is no longer initialized */ + layout->storage.u.virt.init = FALSE; + /* Note the lack of a done: label. This is because there are no HGOTO_ERROR * calls. If one is added, a done: label must also be added */ FUNC_LEAVE_NOAPI(ret_value) @@ -496,6 +504,14 @@ H5D__virtual_reset_source_dset(H5O_storage_virtual_ent_t *virtual_ent, || virtual_ent->parsed_source_dset_name) source_dset->dset_name = (char *)H5MM_xfree(source_dset->dset_name); + /* Free clipped virtual selection */ + if(source_dset->clipped_virtual_select) { + if(source_dset->clipped_virtual_select != source_dset->virtual_select) + if(H5S_close(source_dset->clipped_virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual selection") + source_dset->clipped_virtual_select = NULL; + } /* end if */ + /* Free virtual selection */ if(source_dset->virtual_select) { if(H5S_close(source_dset->virtual_select) < 0) @@ -503,10 +519,20 @@ H5D__virtual_reset_source_dset(H5O_storage_virtual_ent_t *virtual_ent, source_dset->virtual_select = NULL; } /* end if */ + /* Free clipped source selection */ + if(source_dset->clipped_source_select) { + if(source_dset->clipped_source_select != virtual_ent->source_select) + if(H5S_close(source_dset->clipped_source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source selection") + source_dset->clipped_source_select = NULL; + } /* end if */ + /* The projected memory space should never exist when this function is * called */ HDassert(!source_dset->projected_mem_space); + /* Note the lack of a done: label. This is because there are no HGOTO_ERROR + * calls. If one is added, a done: label must also be added */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_reset_source_dset() */ @@ -919,7 +945,8 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) hsize_t clip_size; int rank; hbool_t changed = FALSE; /* Whether the VDS extent changed */ - size_t i, j; + H5S_t *tmp_space = NULL; /* Temporary dataspace */ + size_t i, j, k; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -943,8 +970,106 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) /* Check for unlimited dimension */ if(storage->list[i].unlim_dim_virtual >= 0) { /* Check for "printf" source dataset resolution */ - if(storage->list[i].parsed_source_file_name - || storage->list[i].parsed_source_dset_name) { + if(storage->list[i].unlim_dim_source >= 0 ) { + /* Non-printf mapping */ + /* Open source dataset */ + if(!storage->list[i].source_dset.dset) + if(H5D__virtual_open_source_dset(dset, &storage->list[i], &storage->list[i].source_dset, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") + + /* Check if source dataset is open */ + if(storage->list[i].source_dset.dset) { + /* Retrieve current source dataset extent and patch mapping + */ + if(H5S_extent_copy(storage->list[i].source_select, storage->list[i].source_dset.dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent") + + /* Get source space dimenstions */ + if(H5S_get_simple_extent_dims(storage->list[i].source_select, curr_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions") + + /* Check if the source extent in the unlimited dimension + * changed since the last time the VDS extent/mapping + * was updated */ + if(curr_dims[storage->list[i].unlim_dim_source] + == storage->list[i].unlim_extent_source) + /* Use cached result for clip size */ + clip_size = storage->list[i].clip_size_virtual; + else { + /* Copy source mapping */ + if(NULL == (tmp_space = H5S_copy(storage->list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Clip temporary source space to source extent */ + if(H5S_hyper_clip_unlim(tmp_space, curr_dims[storage->list[i].unlim_dim_source])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Get size that virtual selection would be clipped to + * to match size of source selection */ + if(H5S_hyper_get_clip_extent(storage->list[i].source_dset.virtual_select, tmp_space, &clip_size, storage->view == H5D_VDS_FIRST_MISSING) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") + + /* Close tmp_space */ + if(H5S_close(tmp_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + tmp_space = NULL; + + /* If we are setting the extent by the last available + * data, clip virtual_select and source_select. Note + * that if we used the cached clip_size above or it + * happens to be the same, the virtual selection will + * already be clipped to the correct size. Likewise, + * if we used the cached clip_size the source selection + * will already be correct. */ + if(storage->view == H5D_VDS_LAST_AVAILABLE) { + if(clip_size != storage->list[i].clip_size_virtual) { + /* Close previous clipped virtual selection, if + * any */ + if(storage->list[i].source_dset.clipped_virtual_select) { + HDassert(storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select); + if(H5S_close(storage->list[i].source_dset.clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + } /* end if */ + + /* Copy virtual selection */ + if(NULL == (storage->list[i].source_dset.clipped_virtual_select = H5S_copy(storage->list[i].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Clip virtual selection */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_virtual_select, clip_size)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + } /* end if */ + + /* Close previous clipped source selection, if any + */ + if(storage->list[i].source_dset.clipped_source_select) { + HDassert(storage->list[i].source_dset.clipped_source_select + != storage->list[i].source_select); + if(H5S_close(storage->list[i].source_dset.clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + } /* end if */ + + /* Copy source selection */ + if(NULL == (storage->list[i].source_dset.clipped_source_select = H5S_copy(storage->list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") + + /* Clip source selection */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_source_select, curr_dims[storage->list[i].unlim_dim_source])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + } /* end if */ + + /* Update cached values unlim_extent_source and + * clip_size_virtual */ + storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source]; + storage->list[i].clip_size_virtual = clip_size; + } /* end else */ + } /* end if */ + else + clip_size = 0; + } /* end if */ + else { + /* printf mapping */ hsize_t first_missing = 0; /* First missing dataset in the current block of missing datasets */ /* Search for source datasets */ @@ -993,6 +1118,12 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) if(NULL == (storage->list[i].sub_dset[j].virtual_select = H5S_hyper_get_unlim_block(storage->list[i].source_dset.virtual_select, j))) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get block in unlimited selection") + /* Initialize clipped selections */ + if(!storage->list[i].sub_dset[j].clipped_source_select) + storage->list[i].sub_dset[j].clipped_source_select = storage->list[i].source_select; + if(!storage->list[i].sub_dset[j].clipped_virtual_select) + storage->list[i].sub_dset[j].clipped_virtual_select = storage->list[i].sub_dset[j].virtual_select; + /* Open source dataset */ if(H5D__virtual_open_source_dset(dset, &storage->list[i], &storage->list[i].sub_dset[j], dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") @@ -1040,68 +1171,10 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) } /* end else */ } /* end else */ - /* Clip entry root virtual select (virtual_select for all - * sub dsets) if we are setting the extent by the last - * available data. Note that if we used the cached - * clip_size above, the selection will already be clipped to - * the correct size. */ - if(storage->view == H5D_VDS_LAST_AVAILABLE) - if(H5S_hyper_clip_unlim(storage->list[i].source_dset.virtual_select, clip_size)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") - /* Set sub_dset_nused and clip_size_virtual */ storage->list[i].sub_dset_nused = (size_t)first_missing; storage->list[i].clip_size_virtual = clip_size; } /* end else */ - } /* end if */ - else { - HDassert(storage->list[i].unlim_dim_source >= 0); - - /* Open source dataset */ - if(!storage->list[i].source_dset.dset) - if(H5D__virtual_open_source_dset(dset, &storage->list[i], &storage->list[i].source_dset, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset") - - /* Check if source dataset is open */ - if(storage->list[i].source_dset.dset) { - /* Retrieve current source dataset extent and patch mapping. - * Note this will clip the source selection to the extent. */ - if(H5S_extent_copy(storage->list[i].source_select, storage->list[i].source_dset.dset->shared->space) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent") - - /* Get source space dimenstions */ - if(H5S_get_simple_extent_dims(storage->list[i].source_select, curr_dims, NULL) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions") - - /* Check if the source extent in the unlimited dimension - * changed since the last time the VDS extent/mapping - * was updated */ - if(curr_dims[storage->list[i].unlim_dim_source] - == storage->list[i].unlim_extent_source) - /* Use cached result for clip size */ - clip_size = storage->list[i].clip_size_virtual; - else { - /* Get size that virtual selection would be clipped to - * to match size of source selection */ - if(H5S_hyper_get_clip_extent(storage->list[i].source_dset.virtual_select, storage->list[i].source_select, &clip_size, storage->view == H5D_VDS_FIRST_MISSING) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") - - /* If we are setting the extent by the last available data, - * clip virtual_select. Note that if we used the cached - * clip_size above, the selection will already be clipped to - * the correct size. */ - if(storage->view == H5D_VDS_LAST_AVAILABLE) - if(H5S_hyper_clip_unlim(storage->list[i].source_dset.virtual_select, clip_size)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") - - /* Update cached values unlim_extent_source and - * clip_size_virtual */ - storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source]; - storage->list[i].clip_size_virtual = clip_size; - } /* end else */ - } /* end if */ - else - clip_size = 0; } /* end else */ /* Update new_dims */ @@ -1129,77 +1202,184 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) changed = TRUE; } /* end for */ - /* If we did not change the VDS dimensions and we are setting the extent by - * maximum, there is nothing more to update */ - if(changed || (storage->view == H5D_VDS_FIRST_MISSING)) { + /* If we did not change the VDS dimensions, there is nothing more to update + */ + if(changed || (!storage->init && (storage->view == H5D_VDS_FIRST_MISSING))) { /* Update VDS extent */ - if(changed) - if(H5S_set_extent(dset->shared->space, new_dims) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + if(H5S_set_extent(dset->shared->space, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") /* Iterate over mappings again to update source selections and virtual * mapping extents */ for(i = 0; i < storage->list_nalloc; i++) { - /* Update virtual mapping extent. Note this function does not clip - * the selection. */ - if(changed) { - /* Update top level virtual_select */ - if(H5S_set_extent(storage->list[i].source_dset.virtual_select, new_dims) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") - - /* Update sub dataset virtual_selects */ - for(j = 0; j < storage->list[i].sub_dset_nalloc; j++) - if(storage->list[i].sub_dset[j].virtual_select) - if(H5S_set_extent(storage->list[i].sub_dset[j].virtual_select, new_dims) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") - } /* end if */ + /* If there is an unlimited dimension, we are setting extent by the + * minimum of mappings, and the virtual extent in the unlimited + * dimension has changed since the last time the VDS extent/mapping + * was updated, we must adjust the selections */ + if((storage->list[i].unlim_dim_virtual >= 0) + && (storage->view == H5D_VDS_FIRST_MISSING) + && (new_dims[storage->list[i].unlim_dim_virtual] + != storage->list[i].unlim_extent_virtual)) { + /* Check for "printf" style mapping */ + if(storage->list[i].unlim_dim_source >= 0) { + /* Non-printf mapping */ + /* Close previous clipped virtual selection, if any */ + if(storage->list[i].source_dset.clipped_virtual_select) { + HDassert(storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select); + if(H5S_close(storage->list[i].source_dset.clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + } /* end if */ - /* Check for unlimited dimension */ - if(storage->list[i].unlim_dim_virtual >= 0) { - /* Check if we are setting extent by the minimum of mappings */ - if(storage->view == H5D_VDS_FIRST_MISSING) { - /* Clip virtual selection to extent (only necessary if the - * extent changed, otherwise it will already be clipped to - * the extent) */ - if(changed) - if(H5S_hyper_clip_to_extent(storage->list[i].source_dset.virtual_select)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + /* Copy virtual selection */ + if(NULL == (storage->list[i].source_dset.clipped_virtual_select = H5S_copy(storage->list[i].source_dset.virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Clip space to virtual extent */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_virtual_select, new_dims[storage->list[i].unlim_dim_source])) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Get size that source selection will be clipped to to + * match size of source selection */ + if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].source_dset.clipped_virtual_select, &clip_size, FALSE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") + + /* Check if the clip size changed */ + if(clip_size != storage->list[i].clip_size_source) { + /* Close previous clipped source selection, if any */ + if(storage->list[i].source_dset.clipped_source_select) { + HDassert(storage->list[i].source_dset.clipped_source_select + != storage->list[i].source_select); + if(H5S_close(storage->list[i].source_dset.clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + } /* end if */ - /* Only clip source_select if this is not a "printf" style - * mapping */ - if(!(storage->list[i].parsed_source_file_name - || storage->list[i].parsed_source_dset_name)) { - /* Check if the virtual extent in the unlimited - * dimension changed since the last time the VDS - * extent/mapping was updated */ - if(new_dims[storage->list[i].unlim_dim_virtual] - == storage->list[i].unlim_extent_virtual) - /* Use cached result for clip size */ - clip_size = storage->list[i].clip_size_source; - else { - /* Get size that source selection will be clipped to - * to match size of virtual selection */ - if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].source_dset.virtual_select, &clip_size, FALSE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") - - /* Update cached values unlim_extent_virtual and - * clip_size_source */ - storage->list[i].unlim_extent_virtual = new_dims[storage->list[i].unlim_dim_virtual]; - storage->list[i].clip_size_source = clip_size; - } /* end else */ + /* Copy source selection */ + if(NULL == (storage->list[i].source_dset.clipped_source_select = H5S_copy(storage->list[i].source_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") - /* Clip source_select */ - if(H5S_hyper_clip_unlim(storage->list[i].source_select, clip_size)) + /* Clip source selection */ + if(H5S_hyper_clip_unlim(storage->list[i].source_dset.clipped_source_select, clip_size)) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + + /* Update cached value clip_size_source */ + storage->list[i].clip_size_source = clip_size; } /* end if */ } /* end if */ + else { + /* printf mapping */ + hsize_t first_inc_block; + hbool_t partial_block; + + /* Get index of first incomplete block in virtual + * selection */ + first_inc_block = H5S_hyper_get_first_inc_block(storage->list[i].source_dset.virtual_select, new_dims[storage->list[i].unlim_dim_virtual], &partial_block); + + /* Iterate over sub datasets */ + for(j = 0; j < storage->list[i].sub_dset_nalloc; j++) { + /* Close previous clipped source selection, if any */ + if(storage->list[i].sub_dset[j].clipped_source_select + != storage->list[i].source_select) { + if(storage->list[i].sub_dset[j].clipped_source_select) + if(H5S_close(storage->list[i].sub_dset[j].clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped source dataspace") + storage->list[i].sub_dset[j].clipped_source_select = storage->list[i].source_select; + } /* end if */ + + /* Close previous clipped virtual selection, if any */ + if(storage->list[i].sub_dset[j].clipped_virtual_select + != storage->list[i].sub_dset[j].virtual_select) { + if(storage->list[i].sub_dset[j].clipped_virtual_select) + if(H5S_close(storage->list[i].sub_dset[j].clipped_virtual_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release clipped virtual dataspace") + storage->list[i].sub_dset[j].clipped_virtual_select = storage->list[i].sub_dset[j].virtual_select; + } /* end if */ + + /* Check for partial block */ + else if(partial_block && (j == (size_t)first_inc_block)) { + /* Partial block, must clip source and virtual + * selections */ + hsize_t start[H5S_MAX_RANK]; + + /* Get bounds of virtual selection */ + if(H5S_SELECT_BOUNDS(storage->list[i].sub_dset[j].virtual_select, start, curr_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds") + + /* Convert bounds to extent (add 1) */ + for(k = 0; k < (size_t)rank; k++) + curr_dims[k]++; + + /* Temporarily set extent of virtual selection to bounds */ + if(H5S_set_extent(storage->list[i].sub_dset[j].virtual_select, curr_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + + /* Copy virtual selection */ + if(NULL == (storage->list[i].sub_dset[j].clipped_virtual_select = H5S_copy(storage->list[i].sub_dset[j].virtual_select, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + + /* Clip virtual selection to real virtual extent */ + (void)HDmemset(start, 0, sizeof(start)); + if(H5S_select_hyperslab(storage->list[i].sub_dset[j].clipped_virtual_select, H5S_SELECT_AND, start, NULL, new_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to clip hyperslab") + + /* Project intersection of virtual space and clipped + * virtual space onto source space */ + if(H5S_select_project_intersection(storage->list[i].sub_dset[j].virtual_select, storage->list[i].source_select, storage->list[i].sub_dset[j].clipped_virtual_select, &storage->list[i].sub_dset[j].clipped_source_select) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") + } /* end if */ + else if(j >= (size_t)first_inc_block) { + /* Unused block, clear clipped source and virtual + * selections */ + storage->list[i].sub_dset[j].clipped_source_select = NULL; + storage->list[i].sub_dset[j].clipped_virtual_select = NULL; + } /* end if */ + } /* end for */ + } /* end else */ + + /* Update cached value unlim_extent_virtual */ + storage->list[i].unlim_extent_virtual = new_dims[storage->list[i].unlim_dim_virtual]; } /* end if */ + + /* Update top level virtual_select and clipped_virtual_select + * extents */ + if(H5S_set_extent(storage->list[i].source_dset.virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + if((storage->list[i].source_dset.clipped_virtual_select + != storage->list[i].source_dset.virtual_select) + && storage->list[i].source_dset.clipped_virtual_select) + if(H5S_set_extent(storage->list[i].source_dset.clipped_virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + + /* Update sub dataset virtual_select and clipped_virtual_select + * extents */ + for(j = 0; j < storage->list[i].sub_dset_nalloc; j++) + if(storage->list[i].sub_dset[j].virtual_select) { + if(H5S_set_extent(storage->list[i].sub_dset[j].virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + if((storage->list[i].sub_dset[j].clipped_virtual_select + != storage->list[i].sub_dset[j].virtual_select) + && storage->list[i].sub_dset[j].clipped_virtual_select) + if(H5S_set_extent(storage->list[i].sub_dset[j].clipped_virtual_select, new_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + } /* end if */ + else + HDassert(!storage->list[i].sub_dset[j].clipped_virtual_select); } /* end for */ } /* end if */ /* Call H5D__mark so dataspace is updated on disk? VDSINC */ + /* Mark layout as fully initialized */ + storage->init = TRUE; + done: + /* Close temporary space */ + if(tmp_space) { + HDassert(ret_value < 0); + if(H5S_close(tmp_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_set_extent_unlim() */ @@ -1312,7 +1492,6 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, const H5S_t *file_space, const H5S_t *mem_space, hsize_t *tot_nelmts) { - H5S_t *tmp_space = NULL; /* Copied virtual_select VDSINC */ hssize_t select_nelmts; /* Number of elements in selection */ size_t i, j; /* Local index variables */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1325,6 +1504,10 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, HDassert(file_space); HDassert(tot_nelmts); + /* Initialize layout if necessary */ + if(!storage->init) + {} //VDSINC + /* Initialize tot_nelmts */ *tot_nelmts = 0; @@ -1338,57 +1521,16 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, || storage->list[i].parsed_source_dset_name) { /* Iterate over sub-source dsets */ for(j = 0; j < storage->list[i].sub_dset_nused; j++) { - H5S_t *virtual_select; /* Pointer to real virtual_select VDSINC */ - - /* Quick hack to make this work with printf VDSINC */ - if(storage->view == H5D_VDS_LAST_AVAILABLE) { - virtual_select = storage->list[i].sub_dset[j].virtual_select; - } /* end if */ - else { - hsize_t start[H5S_MAX_RANK]; - hsize_t count[H5S_MAX_RANK]; - - /* Quick hack to make this work with FIRST_MISSING */ - /* Copy virtual selection */ - if(NULL == (tmp_space = H5S_copy(storage->list[i].sub_dset[j].virtual_select, FALSE, TRUE))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual selection") - - /* Get virtual extent dimensions */ - if(H5S_get_simple_extent_dims(tmp_space, count, NULL) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get virtual dataspace dimensions") - - /* Set start to zeroes */ - (void)HDmemset(start, 0, sizeof(start)); - - /* Clip tmp_space selection to extent */ - if(H5S_select_hyperslab(tmp_space, H5S_SELECT_AND, start, NULL, count, NULL) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't clip selection to extent") - - /* Check for no elements selected */ - if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(tmp_space)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") - if(select_nelmts == 0) { - if(H5S_close(tmp_space) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") - tmp_space = NULL; - continue; - } /* end if */ - - virtual_select = tmp_space; - } /* end else */ - - /* Project intersection of file space and mapping virtual space onto - * memory space */ - if(H5S_select_project_intersection(file_space, mem_space, virtual_select, &storage->list[i].sub_dset[j].projected_mem_space) < 0) + /* Check for no clipped selection. This should be an assertion + * once we have I/O scoping for printf working VDSINC */ + if(!storage->list[i].sub_dset[j].clipped_virtual_select) + break; + + /* Project intersection of file space and mapping virtual space + * onto memory space */ + if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].sub_dset[j].clipped_virtual_select, &storage->list[i].sub_dset[j].projected_mem_space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") - /* Close temporary space VDSINC */ - if(tmp_space) { - if(H5S_close(tmp_space) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") - tmp_space = NULL; - } /* end if */ - /* Check number of elements selected */ if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(storage->list[i].sub_dset[j].projected_mem_space)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") @@ -1419,9 +1561,11 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, } /* end for */ } /* end if */ else { + HDassert(storage->list[i].source_dset.clipped_virtual_select); + /* Project intersection of file space and mapping virtual space onto * memory space */ - if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].source_dset.virtual_select, &storage->list[i].source_dset.projected_mem_space) < 0) + if(H5S_select_project_intersection(file_space, mem_space, storage->list[i].source_dset.clipped_virtual_select, &storage->list[i].source_dset.projected_mem_space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto memory space") /* Check number of elements selected, add to tot_nelmts */ @@ -1457,11 +1601,6 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, } /* end for */ done: - /* Release tmp_space VDSINC */ - if(tmp_space) - if(H5S_close(tmp_space) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_pre_io() */ @@ -1511,6 +1650,8 @@ H5D__virtual_post_io(H5O_storage_virtual_t *storage) storage->list[i].source_dset.projected_mem_space = NULL; } /* end if */ + /* Note the lack of a done: label. This is because there are no HGOTO_ERROR + * calls. If one is added, a done: label must also be added */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_post_io() */ @@ -1529,65 +1670,25 @@ H5D__virtual_post_io(H5O_storage_virtual_t *storage) */ static herr_t H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - const H5S_t *file_space, H5O_storage_virtual_ent_t *virtual_ent, - H5O_storage_virtual_srcdset_t *source_dset) + const H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset) { H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */ - H5S_t *tmp_space = NULL; /* Copied virtual_select VDSINC */ - H5S_t *virtual_select; /* Pointer to real virtual_select VDSINC */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC - HDassert(virtual_ent); HDassert(source_dset); - /* Quick hack to make this work with printf VDSINC */ - if((source_dset == &virtual_ent->source_dset) - || (io_info->dset->shared->layout.storage.u.virt.view == H5D_VDS_LAST_AVAILABLE)) { - virtual_select = source_dset->virtual_select; - } /* end if */ - else { - hsize_t start[H5S_MAX_RANK]; - hsize_t count[H5S_MAX_RANK]; - hssize_t select_nelmts; - - /* Copy virtual selection */ - if(NULL == (tmp_space = H5S_copy(source_dset->virtual_select, FALSE, TRUE))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual selection") - - /* Get virtual extent dimensions */ - if(H5S_get_simple_extent_dims(tmp_space, count, NULL) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get virtual dataspace dimensions") - - /* Set start to zeroes */ - (void)HDmemset(start, 0, sizeof(start)); - - /* Clip tmp_space selection to extent */ - if(H5S_select_hyperslab(tmp_space, H5S_SELECT_AND, start, NULL, count, NULL) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't clip selection to extent") - - /* Check for no elements selected */ - if((select_nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(tmp_space)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") - if(select_nelmts == 0) - HGOTO_DONE(SUCCEED) - - virtual_select = tmp_space; - } /* end else */ - /* Only perform I/O if there is a projected memory space, otherwise there * were no elements in the projection or the source dataset could not be * opened */ if(source_dset->projected_mem_space) { HDassert(source_dset->dset); - - /* Sanity check that the source space has been patched by now */ - HDassert(virtual_ent->source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + HDassert(source_dset->clipped_source_select); /* Project intersection of file space and mapping virtual space onto * mapping source space */ - if(H5S_select_project_intersection(virtual_select, virtual_ent->source_select, file_space, &projected_src_space) < 0) + if(H5S_select_project_intersection(source_dset->clipped_virtual_select, source_dset->clipped_source_select, file_space, &projected_src_space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto source space") /* Perform read on source dataset */ @@ -1608,11 +1709,6 @@ done: HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected source space") } /* end if */ - /* Release tmp_space VDSINC */ - if(tmp_space) - if(H5S_close(tmp_space) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close temporary space") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_read_one() */ @@ -1666,12 +1762,12 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, || storage->list[i].parsed_source_dset_name) { /* Iterate over sub-source dsets */ for(j = 0; j < storage->list[i].sub_dset_nused; j++) - if(H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i], &storage->list[i].sub_dset[j]) < 0) + if(H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i].sub_dset[j]) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read source dataset") } /* end if */ else /* Read from source dataset */ - if(H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i], &storage->list[i].source_dset) < 0) + if(H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i].source_dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read source dataset") } /* end for */ @@ -1748,30 +1844,26 @@ done: */ static herr_t H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - const H5S_t *file_space, H5O_storage_virtual_ent_t *virtual_ent, - H5O_storage_virtual_srcdset_t *source_dset) + const H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset) { H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC - HDassert(virtual_ent); HDassert(source_dset); /* Only perform I/O if there is a projected memory space, otherwise there * were no elements in the projection */ if(source_dset->projected_mem_space) { HDassert(source_dset->dset); - - /* Sanity check that the source space has been patched by now */ - HDassert(virtual_ent->source_space_status == H5O_VIRTUAL_STATUS_CORRECT); + HDassert(source_dset->clipped_source_select); /* 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(source_dset->virtual_select, virtual_ent->source_select, file_space, &projected_src_space) < 0) + if(H5S_select_project_intersection(source_dset->virtual_select, source_dset->clipped_source_select, file_space, &projected_src_space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project virtual intersection onto source space") /* Perform write on source dataset */ @@ -1852,13 +1944,13 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Iterate over sub-source dsets */ for(j = 0; j < storage->list[i].sub_dset_nused; j++) { HDassert(0 && "Checking code coverage..."); //VDSINC - if(H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i], &storage->list[i].sub_dset[j]) < 0) + if(H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i].sub_dset[j]) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to write to source dataset") } //VDSINC } /* end if */ else /* Write to source dataset */ - if(H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i], &storage->list[i].source_dset) < 0) + if(H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i].source_dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to write to source dataset") } /* end for */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 47f45a7..33c35ed 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -318,6 +318,12 @@ H5O_layout_decode(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED * mesg->storage.u.virt.list[i].clip_size_source = HSIZE_UNDEF; mesg->storage.u.virt.list[i].clip_size_virtual = HSIZE_UNDEF; + /* Clipped selections */ + if(mesg->storage.u.virt.list[i].unlim_dim_virtual < 0) { + mesg->storage.u.virt.list[i].source_dset.clipped_source_select = mesg->storage.u.virt.list[i].source_select; + mesg->storage.u.virt.list[i].source_dset.clipped_virtual_select = mesg->storage.u.virt.list[i].source_dset.virtual_select; + } /* end if */ + /* Update min_dims */ if(H5D_virtual_update_min_dims(mesg, i) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to update virtual dataset minimum dimensions") diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 817ad00..604dd73 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -420,6 +420,8 @@ typedef struct H5O_storage_virtual_srcdset_t { struct H5S_t *virtual_select; /* Selection in the virtual dataset that is mapped to source selection */ /* Not stored */ + struct H5S_t *clipped_source_select; /* Clipped version of source_select */ + struct H5S_t *clipped_virtual_select; /* Clipped version of virtual_select */ struct H5D_t *dset; /* Source dataset */ /* Temporary - only used during I/O operation, NULL at all other times */ @@ -476,6 +478,7 @@ typedef struct H5O_storage_virtual_t { hsize_t min_dims[H5S_MAX_RANK]; /* Minimum extent of VDS (maximum of all non-unlimited selection bounds) */ H5D_vds_view_t view; /* Method for calculating the extent of the virtual dataset with unlimited selections */ hsize_t printf_gap; /* Maximum number of sequential missing source datasets before terminating the search for more */ + hbool_t init; /* Whether all information has been completely initialized */ } H5O_storage_virtual_t; typedef struct H5O_storage_t { diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 37928a4..5f3e9ef 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -57,7 +57,7 @@ #define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0} #define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_IDX_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}} #define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} -#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, H5D_VDS_ERROR, HSIZE_UNDEF} +#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, H5D_VDS_ERROR, HSIZE_UNDEF, FALSE} #ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER #define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }} #define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }} @@ -1689,6 +1689,11 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name") ent->unlim_dim_source = H5S_get_select_unlim_dim(src_space); ent->unlim_dim_virtual = H5S_get_select_unlim_dim(vspace); + if(ent->unlim_dim_virtual < 0) { + ent->source_dset.clipped_source_select = ent->source_select; + ent->source_dset.clipped_virtual_select = ent->source_dset.virtual_select; + } /* end if */ + ent->unlim_extent_source = HSIZE_UNDEF; ent->unlim_extent_virtual = HSIZE_UNDEF; ent->clip_size_source = HSIZE_UNDEF; diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 6cc78a9..db81211 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -9317,7 +9317,15 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HDassert(proj_space); /* Assert that src_space and src_intersect_space have same extent and there - * are no point selections? */ + * are no point selections */ + HDassert(H5S_GET_EXTENT_NDIMS(src_space) + == H5S_GET_EXTENT_NDIMS(src_intersect_space)); + HDassert(!HDmemcmp(src_space->extent.size, src_intersect_space->extent.size, + (size_t)H5S_GET_EXTENT_NDIMS(src_space) + * sizeof(src_space->extent.size[0]))); + HDassert(H5S_GET_SELECT_TYPE(src_space) != H5S_SEL_POINTS); + HDassert(H5S_GET_SELECT_TYPE(dst_space) != H5S_SEL_POINTS); + HDassert(H5S_GET_SELECT_TYPE(src_intersect_space) != H5S_SEL_POINTS); /* Initialize prev_space, curr_span_tree, and curr_span_up_dim */ for(i = 0; i < H5S_MAX_RANK; i++) { @@ -9757,16 +9765,13 @@ done: Non-negative on success/Negative on failure. DESCRIPTION This function recalculates the internal description of the hyperslab - to make the unlimited dimension extend to the specified extent. if - superset is TRUE, then the hyperslab can be clipped to a size equal to - or greater than clip_size. + to make the unlimited dimension extend to the specified extent. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Note this function takes the offset into account. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static void +void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, hsize_t *block, hssize_t offset, hsize_t clip_size) { @@ -9796,7 +9801,7 @@ H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, } /* end else */ FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_get_clip_diminfo() */ +} /* end H5S_hyper_get_clip_diminfo() */ /*-------------------------------------------------------------------------- @@ -9811,10 +9816,7 @@ H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, Non-negative on success/Negative on failure. DESCRIPTION This function recalculates the internal description of the hyperslab - to make the unlimited dimension extend to the specified extent. if - superset is TRUE, then the hyperslab can be clipped to a size equal to - or greater than clip_size. If include_offset is TRUE, then the offset - is taken into account. + to make the unlimited dimension extend to the specified extent. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS Note this function takes the offset into account. @@ -9882,7 +9884,7 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Check if last block is partial. If superset is set, just keep the * last block complete to speed computation. */ if(((diminfo->stride * (diminfo->count - (hsize_t)1)) + diminfo->block) - > ((hsize_t)((hssize_t)clip_size - ((hssize_t)diminfo->start + > ((hsize_t)((hssize_t)clip_size - ((hssize_t)diminfo->start + space->select.offset[hslab->unlim_dim])))) { hsize_t start[H5S_MAX_RANK]; hsize_t block[H5S_MAX_RANK]; @@ -10147,6 +10149,64 @@ done: /*-------------------------------------------------------------------------- NAME + H5S_hyper_get_first_inc_block + PURPOSE + VDSINC + USAGE + VDSINC + RETURNS + Index of first incomplete block in clip_size (never fails). + DESCRIPTION + VDSINC + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this assumes the offset has been normalized. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hsize_t +H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, + hbool_t *partial) +{ + H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ + H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_diminfo in unlimited dimension */ + hsize_t ret_value; + + FUNC_ENTER_NOAPI_NOERR + + /* Check parameters */ + HDassert(space); + hslab = space->select.sel_info.hslab; + HDassert(hslab); + HDassert(hslab->unlim_dim >= 0); + HDassert(hslab->opt_unlim_diminfo[hslab->unlim_dim].count == H5S_UNLIMITED); + HDassert(partial); + + diminfo = &hslab->opt_unlim_diminfo[hslab->unlim_dim]; + + /* Check for selection outside of clip_size */ + if(diminfo->start >= clip_size) { + ret_value = 0; + partial = FALSE; + } /* end if */ + else { + /* Calculate index of first incomplete block */ + ret_value = (clip_size - diminfo->start + diminfo->stride + - diminfo->block) / diminfo->stride; + + /* Check for partial block */ + if((diminfo->stride * ret_value) < (clip_size - diminfo->start)) + *partial = TRUE; + else + *partial = FALSE; + } /* end else */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_get_first_inc_block */ + + +/*-------------------------------------------------------------------------- + NAME H5Sis_regular_hyperslab PURPOSE Determine if a hyperslab selection is regular diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 976c968..48fdf62 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -273,6 +273,8 @@ H5_DLL herr_t H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, hsize_t *clip_size, hbool_t incl_trail); H5_DLL H5S_t *H5S_hyper_get_unlim_block(const H5S_t *space, hsize_t block_index); +H5_DLL hsize_t H5S_hyper_get_first_inc_block(const H5S_t *space, + hsize_t clip_size, hbool_t *partial); /* Operations on selection iterators */ H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); diff --git a/test/vds.c b/test/vds.c index e6a57c2..b64e09b 100644 --- a/test/vds.c +++ b/test/vds.c @@ -948,8 +948,8 @@ test_api(test_api_config_t config, hid_t fapl) TEST_ERROR dcpl = -1; - PASSED(); - return 0; + PASSED(); + return 0; error: H5E_BEGIN_TRY { @@ -2747,8 +2747,8 @@ test_basic_io(unsigned config, hid_t fapl) TEST_ERROR dcpl = -1; - PASSED(); - return 0; + PASSED(); + return 0; error: H5E_BEGIN_TRY { @@ -5110,8 +5110,8 @@ test_unlim(unsigned config, hid_t fapl) TEST_ERROR memspace = -1; - PASSED(); - return 0; + PASSED(); + return 0; error: H5E_BEGIN_TRY { @@ -7504,19 +7504,702 @@ test_printf(unsigned config, hid_t fapl) vspace[1] = -1; - /* Close */ - if(H5Pclose(dcpl) < 0) + /* + * Test 6: 2 Source mappings, side-by-side, 5x5 and 5x10 blocks + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) TEST_ERROR - dcpl = -1; - if(H5Pclose(dapl) < 0) + + /* Create virtual dataspaces */ + dims[0] = 10; + dims[1] = 10; + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) TEST_ERROR - dapl = -1; - if(H5Sclose(memspace) < 0) + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace (1 dimensional) */ + dims[0] = 50; + if((srcspace = H5Screate_simple(1, dims, NULL)) < 0) + TEST_ERROR + + /* Select hyperslab in source space */ + count[0] = 25; + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + stride[0] = 1; + stride[1] = 5; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 5; + block[1] = 5; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 5; + stride[1] = 10; + block[1] = 10; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[0] = 0; + + /* Add virtual layout mappings (select ALL in source space for second + * mapping) */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "src_dset_a%b", srcspace) < 0) + TEST_ERROR + if(H5Sselect_all(srcspace) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "src_dset_b%b", srcspace) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Close srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 0) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Reopen srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create 2 source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset_a0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset_b0", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = fill; + + /* Write to srcdset[0] */ + block[0] = 5; + block[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + count[0] = 25; + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[1] */ + block[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Sselect_all(srcspace) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i + 5][j] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) TEST_ERROR - memspace = -1; - PASSED(); - return 0; + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Make sure that the 4th slice is no longer + * visible due to the change to H5D_VDS_FIRST_MISSING. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 5) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create 3rd source dataset */ + if((srcdset[2] = H5Dcreate2(srcfile[0], "src_dset_a1", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[2] */ + block[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(srcspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[2], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 5] = buf[i][j]; + + /* Close srcdset[2] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[2]) < 0) + TEST_ERROR + srcdset[2] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. There should be no change. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reopen srcfile if config option specified */ + if((config & TEST_IO_CLOSE_SRC) && (config & TEST_IO_DIFFERENT_FILE)) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create 4th source dataset */ + if((srcdset[3] = H5Dcreate2(srcfile[0], "src_dset_a2", H5T_NATIVE_INT, srcspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to srcdset[3] */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, block, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[3], H5T_NATIVE_INT, memspace, srcspace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 10] = buf[i][j]; + + /* Close srcdset[3] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[3]) < 0) + TEST_ERROR + srcdset[3] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Reopen virtual dataset and file if config option specified */ + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING, reopen file + * as well if config option specified */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if(config & TEST_IO_REOPEN_VIRT) { + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + HDmemset(rbuf[0], 0, sizeof(rbuf)); + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) { + if(j >= (int)dims[1]) { + if(rbuf[i][j] != 0) + TEST_ERROR + } /* end if */ + else + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + } /* end for */ + + /* Reset dapl */ + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + for(i = 0; i < 4; i++) { + if(H5Dclose(srcdset[i]) < 0) + TEST_ERROR + srcdset[i] = -1; + } /* end for */ + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace) < 0) + TEST_ERROR + srcspace = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(dapl) < 0) + TEST_ERROR + dapl = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + PASSED(); + return 0; error: H5E_BEGIN_TRY { -- cgit v0.12