summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Shyper.c58
-rw-r--r--src/H5Sprivate.h7
-rw-r--r--src/H5Sselect.c8
3 files changed, 69 insertions, 4 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index dbc61c9..90bc320 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -3512,6 +3512,8 @@ H5S_hyper_release (H5S_t *space)
if(space->select.sel_info.hslab.diminfo!=NULL) {
H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo);
space->select.sel_info.hslab.diminfo = NULL;
+ H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.app_diminfo);
+ space->select.sel_info.hslab.app_diminfo = NULL;
} /* end if */
/* Release irregular hyperslab information */
@@ -3684,8 +3686,25 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
new_diminfo[i].count = src->select.sel_info.hslab.diminfo[i].count;
new_diminfo[i].block = src->select.sel_info.hslab.diminfo[i].block;
} /* end for */
+ dst->select.sel_info.hslab.diminfo = new_diminfo;
+
+ /* Create the per-dimension selection info */
+ if((new_diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array");
+
+ /* Copy the per-dimension selection info */
+ for(i=0; i<src->extent.u.simple.rank; i++) {
+ new_diminfo[i].start = src->select.sel_info.hslab.app_diminfo[i].start;
+ new_diminfo[i].stride = src->select.sel_info.hslab.app_diminfo[i].stride;
+ new_diminfo[i].count = src->select.sel_info.hslab.app_diminfo[i].count;
+ new_diminfo[i].block = src->select.sel_info.hslab.app_diminfo[i].block;
+ } /* end for */
+ dst->select.sel_info.hslab.app_diminfo = new_diminfo;
} /* end if */
- dst->select.sel_info.hslab.diminfo = new_diminfo;
+ else {
+ dst->select.sel_info.hslab.diminfo = new_diminfo;
+ dst->select.sel_info.hslab.app_diminfo = new_diminfo;
+ } /* end else */
/* Check if there is irregular hyperslab information to copy */
if(src->select.sel_info.hslab.hyper_lst!=NULL) {
@@ -4515,6 +4534,9 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
const hsize_t count[/*space_id*/],
const hsize_t block[/*space_id*/])
{
+ hssize_t real_stride[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */
+ hssize_t real_count[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */
+ hssize_t real_block[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */
hsize_t *_stride=NULL; /* Stride array */
hsize_t *_block=NULL; /* Block size array */
int i; /* Counters */
@@ -4578,7 +4600,7 @@ for(i=0; i<space->extent.u.simple.rank; i++)
"can't release hyperslab");
} /* end if */
- /* Copy all the per-dimension selection info into the space descriptor */
+ /* Copy all the application per-dimension selection info into the space descriptor */
if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
} /* end if */
@@ -4588,6 +4610,34 @@ for(i=0; i<space->extent.u.simple.rank; i++)
diminfo[i].count = count[i];
diminfo[i].block = block[i];
} /* end for */
+ space->select.sel_info.hslab.app_diminfo = diminfo;
+
+ /* Optimize the hyperslab selection to detect contiguously selected block/stride information */
+ /* Modify the stride, block & count for contiguous hyperslab selections */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ /* contiguous hyperslabs have the block size equal to the stride */
+ if(stride[i]==block[i]) {
+ real_count[i]=1;
+ real_stride[i]=1;
+ real_block[i]=count[i]*block[i];
+ } /* end if */
+ else {
+ real_stride[i]=stride[i];
+ real_count[i]=count[i];
+ real_block[i]=block[i];
+ } /* end else */
+ } /* end for */
+
+ /* Copy all the per-dimension selection info into the space descriptor */
+ if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
+ } /* end if */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ diminfo[i].start = start[i];
+ diminfo[i].stride = real_stride[i];
+ diminfo[i].count = real_count[i];
+ diminfo[i].block = real_block[i];
+ } /* end for */
space->select.sel_info.hslab.diminfo = diminfo;
/* Set the number of elements in the hyperslab selection */
@@ -4631,6 +4681,10 @@ for(i=0; i<space->extent.u.simple.rank; i++)
H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo);
space->select.sel_info.hslab.diminfo = NULL;
+ /* Remove the 'app_diminfo' information also, since we're adding to it */
+ H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.app_diminfo);
+ space->select.sel_info.hslab.app_diminfo = NULL;
+
/* Add in the new hyperslab information */
H5S_generate_hyperslab (space, op, start, stride, count, block);
} /* end if */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 4de6e34..2824af0 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -127,6 +127,13 @@ typedef struct {
* for one hyperslab selection. Perhaps this might need to be
* expanded into a list of arrays when the H5Sselect_hyperslab's
* restriction to H5S_SELECT_SET is removed. */
+ H5S_hyper_dim_t *app_diminfo;/* ->[rank] of per-dim selection info */
+ /* 'diminfo' points to a [potentially] optimized version of the user's
+ * hyperslab information. 'app_diminfo' points to the actual parameters
+ * that the application used for setting the hyperslab selection. These
+ * are only used for re-gurgitating the original values used to set the
+ * hyperslab to the application when it queries the hyperslab selection
+ * information. */
H5S_hyper_list_t *hyper_lst; /* List of selected hyperslabs (order is not important) */
} H5S_hyper_sel_t;
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index fc931e1..f31bba4 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -608,7 +608,7 @@ for(i=0; i<space->extent.u.simple.rank; i++)
#endif /*QAK */
/* Check each dimension */
for(ret_value=1,i=0; i<space->extent.u.simple.rank; i++)
- ret_value*=space->select.sel_info.hslab.diminfo[i].count;
+ ret_value*=space->select.sel_info.hslab.app_diminfo[i].count;
} /* end if */
else
ret_value = (hssize_t)space->select.sel_info.hslab.hyper_lst->count;
@@ -784,7 +784,11 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numbloc
/* Set some convienence values */
ndims=space->extent.u.simple.rank;
fast_dim=ndims-1;
- diminfo=space->select.sel_info.hslab.diminfo;
+ /*
+ * Use the "application dimension information" to pass back to the user
+ * the blocks they set, not the optimized, internal information.
+ */
+ diminfo=space->select.sel_info.hslab.app_diminfo;
/* Build the tables of count sizes as well as the initial offset */
for(i=0; i<ndims; i++) {