summaryrefslogtreecommitdiffstats
path: root/src/H5Shyper.c
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2008-01-09 21:32:25 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2008-01-09 21:32:25 (GMT)
commita594026a470785ae882d5a822b2ac50866038615 (patch)
tree2f71b08bb2b6f10fe0fdb14c6711141cffff1c0e /src/H5Shyper.c
parente3eeacdc731e349688612eb2c704586988706f52 (diff)
downloadhdf5-a594026a470785ae882d5a822b2ac50866038615.zip
hdf5-a594026a470785ae882d5a822b2ac50866038615.tar.gz
hdf5-a594026a470785ae882d5a822b2ac50866038615.tar.bz2
[svn-r14386] Bug fix for #956. The calculation of the coordinates for dataspace selection went wrong when
the selection of some dimensions are full and these dimensions are optimized through "flattenning". The calculation of the coordinates wasn't general enough in H5Shyper.c. Also added a test program for it. Tested on smirom only because the same code was tested on 3 platforms for v1.8.
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r--src/H5Shyper.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 81b9d1c..9aa1748 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -267,9 +267,13 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
if(iter->elmt_size>0) {
/* Check for any "contiguous" blocks that can be flattened */
for(u=rank-1; u>0; u--) {
- if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u])
+ if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u]) {
cont_dim++;
+ iter->u.hyp.flattened[u] = TRUE;
+ } else
+ iter->u.hyp.flattened[u] = FALSE;
} /* end for */
+ iter->u.hyp.flattened[0] = FALSE;
} /* end if */
/* Check if the regular selection can be "flattened" */
@@ -402,7 +406,9 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
* Tuesday, April 22, 2003
*
* Modifications:
- *
+ * Raymond Lu
+ * 9 January 2008
+ * Modified the algorithm to cover general cases.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -419,23 +425,59 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
/* Check for a single "regular" hyperslab */
if(iter->u.hyp.diminfo_valid) {
/* Check if this is a "flattened" regular hyperslab selection */
- if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) {
- unsigned flat_dim; /* The rank of the flattened dimension */
+ if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) {
+ int u, v; /* Dimension indices */
+
+ /* Set the starting rank of both the "natural" & "flattened" dimensions */
+ u = iter->rank - 1;
+ v = iter->u.hyp.iter_rank - 1;
+
+ /* Construct the "natural" dimensions from a set of flattened coordinates */
+ while(u >= 0) {
+ if(iter->u.hyp.flattened[u]) {
+ int begin = u; /* The rank of the first flattened dimension */
+
+ /* Walk up through as many flattened dimensions as possible */
+ do {
+ u--;
+ } while(u >= 0 && iter->u.hyp.flattened[u]);
- /* Get the rank of the flattened dimension */
- flat_dim=iter->u.hyp.iter_rank-1;
+ /* Compensate for possibly overshooting dim 0 */
+ if(u < 0)
+ u = 0;
- /* Copy the coordinates up to where things got flattened */
- HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*flat_dim);
+ /* Sanity check */
+ HDassert(v >= 0);
- /* Compute the coordinates for the flattened dimensions */
- H5V_array_calc(iter->u.hyp.off[flat_dim],iter->rank-flat_dim,&(iter->dims[flat_dim]),&(coords[flat_dim]));
+ /* Compute the coords for the flattened dimensions */
+ H5V_array_calc(iter->u.hyp.off[v], (unsigned)((begin - u) + 1), &(iter->dims[u]), &(coords[u]));
+
+ /* Continue to faster dimension in both indices */
+ u--;
+ v--;
+ } /* end if */
+ else {
+ /* Walk up through as many non-flattened dimensions as possible */
+ while(u >= 0 && !iter->u.hyp.flattened[u]) {
+ /* Sanity check */
+ HDassert(v >= 0);
+
+ /* Copy the coordinate */
+ coords[u] = iter->u.hyp.off[v];
+
+ /* Continue to faster dimension in both indices */
+ u--;
+ v--;
+ } /* end while */
+ } /* end else */
+ } /* end while */
+ HDassert(v < 0);
} /* end if */
else
- HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
+ HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank);
} /* end if */
else
- HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
+ HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank);
FUNC_LEAVE_NOAPI(SUCCEED);
} /* H5S_hyper_iter_coords() */