summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-04-09 12:47:34 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-04-09 12:47:34 (GMT)
commit1ffe083f61eacb68e0a91e46d6a6377813849d5a (patch)
treea6fb3175bd830445fdd56b285012032b187aa681 /src
parente403006cc276b29a4b5f3f8fc6c7b11796d1b8d0 (diff)
downloadhdf5-1ffe083f61eacb68e0a91e46d6a6377813849d5a.zip
hdf5-1ffe083f61eacb68e0a91e46d6a6377813849d5a.tar.gz
hdf5-1ffe083f61eacb68e0a91e46d6a6377813849d5a.tar.bz2
[svn-r5152] Purpose:
New Feature Description: Added new H5Dfill() routine to fill the elements in a selection for a memory buffer with a fill value. This is a user API wrapper around some internal routines which were needed for the fill-value modifications from Raymond as well as Pedro's code for reducing the size of a chunked dataset. Platforms tested: FreeBSD 4.5 (sleipnir) [and IRIX64 6.5 (modi4) in parallel, in a few minutes]
Diffstat (limited to 'src')
-rw-r--r--src/H5D.c84
-rw-r--r--src/H5Dpublic.h2
-rw-r--r--src/H5F.c2
-rw-r--r--src/H5Sall.c54
-rw-r--r--src/H5Shyper.c411
-rw-r--r--src/H5Spkg.h6
-rw-r--r--src/H5Spoint.c121
-rw-r--r--src/H5Sprivate.h2
-rw-r--r--src/H5Sselect.c69
-rw-r--r--src/H5V.c25
10 files changed, 730 insertions, 46 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 2b0b717..6345862 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -3597,6 +3597,90 @@ done:
} /* end H5Dvlen_get_buf_size() */
+/*--------------------------------------------------------------------------
+ NAME
+ H5Dfill
+ PURPOSE
+ Fill a selection in memory with a value
+ USAGE
+ herr_t H5Dfill(fill, fill_type, space, buf, buf_type)
+ const void *fill; IN: Pointer to fill value to use
+ hid_t fill_type_id; IN: Datatype of the fill value
+ void *buf; IN/OUT: Memory buffer to fill selection within
+ hid_t buf_type_id; IN: Datatype of the elements in buffer
+ hid_t space_id; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id)
+{
+ H5S_t *space; /* Dataspace */
+ H5T_t *fill_type; /* Fill-value datatype */
+ H5T_t *buf_type; /* Buffer datatype */
+ H5T_path_t *tpath = NULL; /* Conversion information*/
+ uint8_t *tconv_buf = NULL; /* Data type conv buffer */
+ uint8_t *bkg_buf = NULL; /* Temp conversion buffer */
+ size_t src_type_size; /* Size of source type */
+ size_t dst_type_size; /* Size of destination type*/
+ size_t buf_size; /* Desired buffer size */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER (H5Dfill, FAIL);
+
+ /* Check args */
+ if (fill==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fill value");
+ if (buf==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer");
+ if (H5I_DATASPACE != H5I_get_type(space_id) || NULL == (space=H5I_object(space_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataspace");
+ if (H5I_DATATYPE != H5I_get_type(fill_type_id) || NULL == (fill_type=H5I_object(fill_type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
+ if (H5I_DATATYPE != H5I_get_type(buf_type_id) || NULL == (buf_type=H5I_object(buf_type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
+
+ /* Get the memory and file datatype sizes */
+ src_type_size = H5T_get_size(fill_type);
+ dst_type_size = H5T_get_size(buf_type);
+
+ /* Get the maximum buffer size needed and allocate it */
+ buf_size=MAX(src_type_size,dst_type_size);
+ if (NULL==(tconv_buf = H5MM_malloc (buf_size)) || NULL==(bkg_buf = H5MM_calloc(buf_size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Copy the user's data into the buffer for conversion */
+ HDmemcpy(tconv_buf,fill,src_type_size);
+
+ /* Convert memory buffer into disk buffer */
+ /* Set up type conversion function */
+ if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL)))
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
+
+ /* Perform data type conversion */
+ if (H5T_convert(tpath, fill_type_id, buf_type_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, H5P_DEFAULT)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
+
+ /* Fill the selection in the memory buffer */
+ if(H5S_select_fill(tconv_buf, dst_type_size, space, buf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed");
+
+done:
+ if (tconv_buf)
+ H5MM_xfree(tconv_buf);
+ if (bkg_buf)
+ H5MM_xfree(bkg_buf);
+ FUNC_LEAVE (ret_value);
+} /* H5Dfill() */
+
+
/*-------------------------------------------------------------------------
* Function: H5Ddebug
*
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index b889c35..41e479d 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -57,6 +57,8 @@ __DLL__ herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
H5D_operator_t op, void *operator_data);
__DLL__ herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
__DLL__ herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
+__DLL__ herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
+ hid_t buf_type, hid_t space);
__DLL__ herr_t H5Ddebug(hid_t dset_id, unsigned int flags);
#ifdef __cplusplus
diff --git a/src/H5F.c b/src/H5F.c
index 71b009a..9c1fd21 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -3280,7 +3280,7 @@ H5F_get_fileno(const H5F_t *f, unsigned long *filenum)
/* Retrieve the file's serial number */
if(H5FD_get_fileno(f->shared->lf,filenum)<0)
- HRETURN_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno");
+ HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno");
done:
FUNC_LEAVE(ret_value);
diff --git a/src/H5Sall.c b/src/H5Sall.c
index ea5eac5..d988de2 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -1057,3 +1057,57 @@ H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op
FUNC_LEAVE (ret_value);
} /* H5S_all_select_iterate() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_all_select_fill
+ PURPOSE
+ Fill an "all" selection in memory with a value
+ USAGE
+ herr_t H5S_all_select_fill(fill,fill_size,space,buf)
+ const void *fill; IN: Pointer to fill value to use
+ size_t fill_size; IN: Size of elements in memory buffer & size of
+ fill value
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ void *buf; IN/OUT: Memory buffer to fill selection in
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The memory buffer elements are assumed to have the same datatype as the
+ fill value being placed into them.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_all_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf)
+{
+ hssize_t nelemts; /* Number of elements in dataspace */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_all_select_fill, FAIL);
+
+ /* Check args */
+ assert(fill);
+ assert(fill_size>0);
+ assert(space);
+ assert(buf);
+
+ /* Fill the selection in the memory buffer */
+
+ /* Get the number of elements to iterate through */
+ if((nelemts=H5S_get_simple_extent_npoints(space))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements");
+
+ /* Fill the elements in the buffer */
+ H5_CHECK_OVERFLOW(nelemts,hssize_t,size_t);
+ H5V_array_fill(buf, fill, fill_size, (size_t)nelemts);
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_all_select_fill() */
+
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 4c1f3f5..029b7d7 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -6047,18 +6047,17 @@ H5S_hyper_select_regular(const H5S_t *space)
else
ret_value=FALSE;
-done:
FUNC_LEAVE (ret_value);
} /* H5S_hyper_select_regular() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_iterate_helper
+ H5S_hyper_select_iterate_mem_gen
PURPOSE
Internal routine to iterate over the elements of a span tree hyperslab selection
USAGE
- herr_t H5S_iterate_hyperslab_io(iter_info)
+ herr_t H5S_hyper_select_iterate_mem_gen(iter_info)
H5S_hyper_iter_info_t *iter_info; IN/OUT: Block of iteration parameters to pass into recursive calls
RETURNS
Non-negative on success, negative on failure
@@ -6071,7 +6070,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_select_iterate_helper(H5S_hyper_iter_info_t *iter_info)
+H5S_hyper_select_iterate_mem_gen(H5S_hyper_iter_info_t *iter_info)
{
const H5S_t *space; /* Dataspace operating with */
H5S_sel_iter_t *iter; /* Selection iterator */
@@ -6090,7 +6089,7 @@ H5S_hyper_select_iterate_helper(H5S_hyper_iter_info_t *iter_info)
unsigned u; /* Index variable */
herr_t ret_value=FAIL;
- FUNC_ENTER (H5S_hyper_select_iterate_helper, FAIL);
+ FUNC_ENTER (H5S_hyper_select_iterate_mem_gen, FAIL);
/* Check args */
assert(iter_info);
@@ -6244,7 +6243,7 @@ H5S_hyper_select_iterate_helper(H5S_hyper_iter_info_t *iter_info)
done:
#endif /* LATER */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_iterate_helper() */
+} /* end H5S_hyper_select_iterate_mem_gen() */
/*--------------------------------------------------------------------------
@@ -6503,7 +6502,7 @@ H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t
iter_info.op_data=operator_data;
/* Call the recursive iterator routine */
- ret_value=H5S_hyper_select_iterate_helper(&iter_info);
+ ret_value=H5S_hyper_select_iterate_mem_gen(&iter_info);
} /* end else */
/* Release selection iterator */
@@ -6571,6 +6570,402 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_hyper_select_fill_gen
+ PURPOSE
+ Fill a hyperslab selection in memory with a value
+ USAGE
+ herr_t H5S_hyper_select_fill_gen(fill,fill_size,space,buf)
+ const void *fill; IN: Pointer to fill value to use
+ size_t fill_size; IN: Size of elements in memory buffer & size of
+ fill value
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ void *buf; IN/OUT: Memory buffer to fill selection in
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The memory buffer elements are assumed to have the same datatype as the
+ fill value being placed into them.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_select_fill_gen(const void *fill, size_t fill_size, H5S_t *space, void *buf)
+{
+ H5S_hyper_span_info_t *spans=NULL; /* Pointer to copy of the span tree */
+ H5S_hyper_span_info_t *tmp_spans; /* Temporary pointer to a span tree */
+ H5S_hyper_span_t *span[H5O_LAYOUT_NDIMS]; /* Array of pointers to span nodes */
+ H5S_hyper_span_t *curr_span; /* Current hyperslab span node */
+ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Cumulative size of each dimension in bytes */
+ hssize_t abs_arr[H5O_LAYOUT_NDIMS]; /* Absolute hyperslab span position */
+ hssize_t *off_arr; /* Offset within the dataspace extent */
+ hsize_t acc; /* Accumulator for computing cumulative sizes */
+ int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ int curr_dim; /* Current dimension being operated on */
+ int ndims; /* Number of dimensions of dataset */
+ hsize_t span_io; /* Number of elements in current span to actually process */
+ hsize_t num_elem; /* Number of elements in the selection */
+ uint8_t *loc; /* Current element location pointer */
+ int i; /* Index variable */
+ unsigned u; /* Index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER (H5S_hyper_select_fill_gen, FAIL);
+
+ /* Set the rank of the fastest changing dimension */
+ ndims=space->extent.u.simple.rank;
+ fast_dim=(ndims-1);
+
+ /* Set the pointer to the selection offset in the dataspace */
+ off_arr=space->select.offset;
+
+ /* Make a copy of the span tree to iterate over */
+ spans=H5S_hyper_copy_span(space->select.sel_info.hslab.span_lst);
+
+ /* Set the nelem & pstride values according to the element size */
+ H5S_hyper_span_precompute(spans,fill_size);
+
+ /* Build arrays of span heads & offsets in each dimension */
+ for(u=0, tmp_spans=spans; u<space->extent.u.simple.rank; u++) {
+ /* Set the pointers to the initial span in each dimension */
+ assert(tmp_spans);
+ assert(tmp_spans->head);
+
+ /* Set the pointer to the first span in the list for this node */
+ span[u] = tmp_spans->head;
+
+ /* Set the initial offset to low bound of span */
+ abs_arr[u]=span[u]->low;
+
+ /* Get the pointer to the next level down */
+ tmp_spans=tmp_spans->head->down;
+ } /* end for */
+
+ /* Compute sizes of "slab" in each dimension */
+ for(i=fast_dim, acc=fill_size; i>=0; i--) {
+ slab[i]=acc;
+ acc*=space->extent.u.simple.size[i];
+ } /* end for */
+
+ /* Set the offset of the first element iterated on */
+ for(i=0, loc=buf; i<ndims; i++)
+ /* Compute the sequential element offset */
+ loc+=(abs_arr[i]+off_arr[i])*slab[i];
+
+ /* Get the number of elements in selection */
+ num_elem=space->select.num_elem;
+
+ /* Get the pointer to the current span nodes */
+ curr_span=span[fast_dim];
+
+ /* Go iterate over the hyperslabs */
+ while(num_elem>0) {
+ /* Loop through the fastest dim's spans */
+ while(curr_span!=NULL) {
+ /* Compute the number of elements to attempt in this span */
+ span_io=(curr_span->high-curr_span->low)+1;
+
+ /* Double check that things haven't gotten out of sync */
+ assert(num_elem>0);
+
+ /* Fill the elements in the current block */
+ H5_CHECK_OVERFLOW(span_io,hsize_t,size_t);
+ H5V_array_fill(loc, fill, fill_size, (size_t)span_io);
+
+ /* Increment the buffer offset */
+ loc+=curr_span->pstride;
+
+ /* Decrement the number of elements left */
+ num_elem-=span_io;
+
+ /* Advance span in fastest dimension */
+ curr_span=curr_span->next;
+ } /* end while */
+
+ /* Check if there are more elements left */
+ if(num_elem>0) {
+ /* Recursively advance to next offset (not necessarily span) in next dimension up */
+
+ /* Start at the fastest dim */
+ curr_dim=fast_dim-1;
+
+ /* Get the pointer to the correct dimension */
+ curr_span=span[curr_dim];
+
+ /* Work back up through the dimensions */
+ while(curr_dim>=0) {
+ /* Increment position in span */
+ abs_arr[curr_dim]++;
+
+ /* Check if we are still within the span */
+ if(abs_arr[curr_dim]<=curr_span->high) {
+ break;
+ } /* end if */
+ /* If we walked off that span, advance to the next span */
+ else {
+ /* Advance span in this dimension */
+ curr_span=curr_span->next;
+
+ /* Check if we have a valid span in this dimension still */
+ if(curr_span!=NULL) {
+ /* Reset the offset for the dim */
+ abs_arr[curr_dim]=curr_span->low;
+
+ break;
+ } /* end if */
+ else {
+ /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */
+ curr_dim--;
+
+ /* Reset the curr_span to the next dim */
+ if(curr_dim>=0)
+ curr_span=span[curr_dim];
+ } /* end else */
+ } /* end else */
+ } /* end while */
+
+ /* Reset the span in the current dimension */
+ span[curr_dim]=curr_span;
+
+ /* Walk back down the iterator positions, reseting them */
+ while(curr_dim<fast_dim) {
+ assert(curr_span);
+ assert(curr_span->down);
+ assert(curr_span->down->head);
+
+ /* Set the new span for this dimension */
+ span[curr_dim+1]=curr_span->down->head;
+
+ /* Advance span down the tree */
+ curr_span=curr_span->down->head;
+
+ /* Reset the offset for the dim */
+ abs_arr[curr_dim+1]=curr_span->low;
+
+ /* Increment current dimension */
+ curr_dim++;
+ } /* end while */
+
+ /* Verify that the curr_span points to the fastest dim */
+ assert(curr_span==span[fast_dim]);
+
+ /* Verify that the offset is correct for the fastest dim */
+ assert(abs_arr[fast_dim]==curr_span->low);
+
+ /* Recompute offset in buffer */
+ for(i=0, loc=buf; i<ndims; i++)
+ loc+=(abs_arr[i]+off_arr[i])*slab[i];
+ } /* end if */
+ } /* end while */
+
+#ifdef LATER
+done:
+#endif /* LATER */
+ /* Free the copy of the selections span tree */
+ if(spans!=NULL)
+ H5S_hyper_free_span_info(spans);
+
+ FUNC_LEAVE (ret_value);
+} /* end H5S_hyper_select_fill_gen() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_select_fill_opt
+ PURPOSE
+ Fill a hyperslab selection in memory with a value
+ USAGE
+ herr_t H5S_hyper_select_fill_opt(fill,fill_size,space,buf)
+ const void *fill; IN: Pointer to fill value to use
+ size_t fill_size; IN: Size of elements in memory buffer & size of
+ fill value
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ void *buf; IN/OUT: Memory buffer to fill selection in
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The memory buffer elements are assumed to have the same datatype as the
+ fill value being placed into them.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_select_fill_opt(const void *fill, size_t fill_size, H5S_t *space, void *buf)
+{
+ H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
+ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab blocks */
+ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Size of objects in buffer */
+ hsize_t acc; /* Size accumulator */
+ hsize_t num_elem; /* Number of elements in the selection */
+ hsize_t fast_elem; /* Block size in the fastest dimension */
+ hsize_t fast_stride; /* Stride in the fastest dimension */
+ hssize_t temp_off; /* Offset in a given dimension */
+ uint8_t *loc; /* Current element location */
+ int i; /* Counter */
+ unsigned u; /* Counter */
+ int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ int temp_dim; /* Temporary rank holder */
+ unsigned ndims; /* Rank of the dataspace */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER (H5S_hyper_select_fill_opt, FAIL);
+
+ /* Set some convienence values */
+ ndims=space->extent.u.simple.rank;
+ fast_dim=ndims-1;
+ diminfo=space->select.sel_info.hslab.diminfo;
+
+ /* Build the table of next-dimension down 'element' sizes */
+ for(i=fast_dim, acc=fill_size; i>=0; i--) {
+ slab[i]=acc;
+ acc*=space->extent.u.simple.size[i];
+ } /* end for */
+
+ /* Build the tables of count & block sizes as well as the initial starting location */
+ for(u=0, loc=buf; u<ndims; u++) {
+ tmp_count[u]=diminfo[u].count;
+ tmp_block[u]=diminfo[u].block;
+ loc+=(diminfo[u].start+space->select.offset[u])*slab[u];
+ } /* end for */
+
+ /* Get the number of elements in selection */
+ num_elem=space->select.num_elem;
+
+ /* Get the number of elements in the fastest dimension of the selection */
+ fast_elem=tmp_block[fast_dim];
+ fast_stride=diminfo[fast_dim].stride;
+
+ /* Go iterate over the hyperslabs */
+ while(num_elem>0) {
+ /* Iterate over the blocks in the fastest dimension */
+ while(tmp_count[fast_dim]>0) {
+ /* Double check that things haven't gotten out of sync */
+ assert(num_elem>0);
+
+ /* Fill the elements in the current block */
+ H5_CHECK_OVERFLOW(fast_elem,hsize_t,size_t);
+ H5V_array_fill(loc, fill, fill_size, (size_t)fast_elem);
+
+ /* Advance the pointer in the memory buffer */
+ loc+=(fast_stride*fill_size);
+
+ /* Decrement the block count */
+ tmp_count[fast_dim]--;
+
+ /* Decrement the number of elements to process */
+ num_elem-=fast_elem;
+ } /* end while */
+
+ /* Work on other dimensions if necessary */
+ if(num_elem>0) {
+ /* Reset the sequence and block counts */
+ tmp_count[fast_dim]=diminfo[fast_dim].count;
+
+ /* Bubble up the decrement to the slower changing dimensions */
+ temp_dim=fast_dim-1;
+ while(temp_dim>=0) {
+ /* Decrement the sequence count in this dimension */
+ tmp_block[temp_dim]--;
+
+ /* Check if we are still in the sequence */
+ if(tmp_block[temp_dim]>0)
+ break;
+
+ /* Reset the sequence count in this dimension */
+ tmp_block[temp_dim]=diminfo[temp_dim].block;
+
+ /* Decrement the block count */
+ tmp_count[temp_dim]--;
+
+ /* Check if we have more blocks left */
+ if(tmp_count[temp_dim]>0)
+ break;
+
+ /* Reset the block count in this dimension */
+ tmp_count[temp_dim]=diminfo[temp_dim].count;
+
+ /* Wrapped a dimension, go up to next dimension */
+ temp_dim--;
+ } /* end while */
+
+ /* Re-compute buffer location */
+ for(loc=buf,u=0; u<ndims; u++) {
+ temp_off=(diminfo[u].start+space->select.offset[u])
+ +diminfo[u].stride*(diminfo[u].count-tmp_count[u])
+ +(diminfo[u].block-tmp_block[u]);
+ loc+=temp_off*slab[u];
+ } /* end for */
+ } /* end if */
+ } /* end while */
+
+#ifdef LATER
+done:
+#endif /* LATER */
+ FUNC_LEAVE (ret_value);
+} /* end H5S_hyper_select_fill_opt() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_select_fill
+ PURPOSE
+ Fill a hyperslab selection in memory with a value
+ USAGE
+ herr_t H5S_hyper_select_fill(fill,fill_size,space,buf)
+ const void *fill; IN: Pointer to fill value to use
+ size_t fill_size; IN: Size of elements in memory buffer & size of
+ fill value
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ void *buf; IN/OUT: Memory buffer to fill selection in
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The memory buffer elements are assumed to have the same datatype as the
+ fill value being placed into them.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf)
+{
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_hyper_select_fill, FAIL);
+
+ /* Check args */
+ assert(fill);
+ assert(fill_size>0);
+ assert(space);
+ assert(buf);
+
+ /* Fill the selection in the memory buffer */
+
+ /* Check for the special case of just one H5Sselect_hyperslab call made */
+ if(space->select.sel_info.hslab.diminfo!=NULL)
+ /* Use optimized call to fill regular hyperslab */
+ ret_value=H5S_hyper_select_fill_opt(fill, fill_size, space, buf);
+ else
+ /* Call the general fill routine */
+ ret_value=H5S_hyper_select_fill_gen(fill, fill_size, space, buf);
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_hyper_select_fill() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_hyper_recover_span
PURPOSE
Recover a generated span, if appropriate
@@ -6703,7 +7098,7 @@ H5S_hyper_append_span (H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t ** sp
} /* end if */
} /* end if */
- /* Indicate elements to previous span */
+ /* Indicate elements from previous span */
new_span->pstride=low-(*prev_span)->low;
/* Append to end of merged spans list */
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 0fc4513..668e9a6 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -138,6 +138,8 @@ __DLL__ herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op,
size_t num_elem, const hssize_t **coord);
__DLL__ herr_t H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space,
H5D_operator_t op, void *operator_data);
+__DLL__ herr_t H5S_point_select_fill(const void *fill, size_t fill_size,
+ H5S_t *space, void *buf);
/* "All" select functions */
__DLL__ herr_t H5S_all_release(H5S_t *space);
@@ -159,6 +161,8 @@ __DLL__ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout,
hid_t dxpl_id, const void *buf);
__DLL__ herr_t H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space,
H5D_operator_t op, void *operator_data);
+__DLL__ herr_t H5S_all_select_fill(const void *fill, size_t fill_size,
+ H5S_t *space, void *buf);
__DLL__ htri_t H5S_all_opt_possible(const H5S_t *mem_space,
const H5S_t *file_space, const unsigned flags);
@@ -179,6 +183,8 @@ __DLL__ htri_t H5S_hyper_select_single(const H5S_t *space);
__DLL__ htri_t H5S_hyper_select_regular(const H5S_t *space);
__DLL__ herr_t H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space,
H5D_operator_t op, void *operator_data);
+__DLL__ herr_t H5S_hyper_select_fill(const void *fill, size_t fill_size,
+ H5S_t *space, void *buf);
/* "None" selection functions */
__DLL__ herr_t H5S_select_none(H5S_t *space);
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 7ca1bed..883dfae 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -520,11 +520,11 @@ H5S_point_mgath (const void *_buf, size_t elmt_size,
#ifdef QAK
printf("%s: check 1.0\n",FUNC);
#endif /* QAK */
- if ((space_ndims=H5S_get_simple_extent_dims (mem_space, mem_size, NULL))<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0,
- "unable to retrieve data space dimensions");
- }
+ /* Get the dataspace dimensions */
+ if ((space_ndims=H5S_get_simple_extent_dims (mem_space, mem_size, NULL))<0)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, "unable to retrieve data space dimensions");
+ /* Loop through all the points selected */
for(num_gath=0; num_gath<nelmts; num_gath++) {
if(mem_iter->pnt.elmt_left>0) {
/* Compute the location of the point to get */
@@ -596,17 +596,11 @@ H5S_point_mscat (const void *_tconv_buf, size_t elmt_size,
#ifdef QAK
printf("%s: check 1.0\n",FUNC);
#endif /* QAK */
- /*
- * Retrieve hyperslab information to determine what elements are being
- * selected (there might be other selection methods in the future). We
- * only handle hyperslabs with unit sample because there's currently no
- * way to pass sample information to H5V_hyper_copy().
- */
- if ((space_ndims=H5S_get_simple_extent_dims (mem_space, mem_size, NULL))<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
- "unable to retrieve data space dimensions");
- }
+ /* Get the dataspace dimensions */
+ if ((space_ndims=H5S_get_simple_extent_dims (mem_space, mem_size, NULL))<0)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve data space dimensions");
+ /* Loop through all the points selected */
for(num_scat=0; num_scat<nelmts; num_scat++) {
if(mem_iter->pnt.elmt_left>0) {
/* Compute the location of the point to get */
@@ -1202,7 +1196,6 @@ H5S_point_select_regular(const H5S_t *space)
else
ret_value=FALSE;
-done:
FUNC_LEAVE (ret_value);
} /* H5S_point_select_regular() */
@@ -1384,18 +1377,21 @@ done:
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
+ QAK - 2002/4/5 - Wasn't using selection offset in calculation, corrected.
--------------------------------------------------------------------------*/
herr_t
H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
void *operator_data)
{
- hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* Point offset */
- hsize_t offset; /* offset of region in buffer */
- void *tmp_buf; /* temporary location of the element in the buffer */
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
+ hsize_t acc; /* Size accumulator */
+ hsize_t offset; /* Offset of region in buffer */
+ hsize_t elmt_size; /* Size of datatype */
+ void *tmp_buf; /* Temporary location of the element in the buffer */
H5S_pnt_node_t *node; /* Point node */
- unsigned rank; /* Dataspace rank */
- H5T_t *dt; /* Datatype structure */
+ unsigned rank; /* Dataspace rank */
+ H5T_t *dt; /* Datatype structure */
+ int i; /* Index variable */
herr_t ret_value=0; /* return value */
FUNC_ENTER (H5S_point_select_iterate, 0);
@@ -1414,17 +1410,18 @@ H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t
/* Set the size of the datatype */
if (NULL==(dt=H5I_object(type_id)))
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype");
- mem_size[rank]=H5T_get_size(dt);
+ mem_size[rank]=elmt_size=H5T_get_size(dt);
/* Iterate through the node, checking the bounds on each element */
node=space->select.sel_info.pnt_lst->head;
while(node!=NULL && ret_value==0) {
- /* Set up the location of the point */
- HDmemcpy(mem_offset, node->pnt, rank*sizeof(hssize_t));
- mem_offset[rank]=0;
+ /* Compute the offset of each selected point in the buffer */
+ for(i=rank-1,acc=elmt_size,offset=0; i>=0; i--) {
+ offset+=(node->pnt[i]+space->select.offset[i])*acc;
+ acc*=mem_size[i];
+ } /* end for */
/* Get the offset in the memory buffer */
- offset=H5V_array_offset(rank+1,mem_size,(const hssize_t *)mem_offset);
tmp_buf=((char *)buf+offset);
ret_value=(*op)(tmp_buf,type_id,(hsize_t)rank,node->pnt,operator_data);
@@ -1434,3 +1431,75 @@ H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t
FUNC_LEAVE (ret_value);
} /* H5S_point_select_iterate() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_point_select_fill
+ PURPOSE
+ Fill a point selection in memory with a value
+ USAGE
+ herr_t H5S_point_select_fill(fill,fill_size,space,buf)
+ const void *fill; IN: Pointer to fill value to use
+ size_t fill_size; IN: Size of elements in memory buffer & size of
+ fill value
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ void *buf; IN/OUT: Memory buffer to fill selection in
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The memory buffer elements are assumed to have the same datatype as the
+ fill value being placed into them.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_point_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *_buf)
+{
+ hsize_t size[H5O_LAYOUT_NDIMS]; /* Total size of memory buf */
+ uint8_t *buf=(uint8_t *)_buf; /* Alias for memory buffer */
+ hsize_t acc; /* Coordinate accumulator */
+ hsize_t off; /* Coordinate offset */
+ H5S_pnt_node_t *node; /* Point node */
+ int ndims; /* Dimensionality of space*/
+ int i; /* Index variable */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_point_select_fill, FAIL);
+
+ /* Check args */
+ assert(fill);
+ assert(fill_size>0);
+ assert(space);
+ assert(buf);
+
+ /* Fill the selection in the memory buffer */
+
+ /* Get the dataspace dimensions */
+ if ((ndims=H5S_get_simple_extent_dims (space, size, NULL))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve data space dimensions");
+
+ /* Loop through all the points selected */
+ node=space->select.sel_info.pnt_lst->head;
+ while(node!=NULL) {
+ /* Compute the offset of each selected point in the buffer */
+ for(i=ndims-1,acc=fill_size,off=0; i>=0; i--) {
+ off+=(node->pnt[i]+space->select.offset[i])*acc;
+ acc*=size[i];
+ } /* end for */
+
+ /* Set the selected point to the fill value */
+ HDmemcpy(buf+off,fill,fill_size);
+
+ /* Advance to the next point */
+ node=node->next;
+ } /* end while */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_point_select_fill() */
+
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 5af635d..0380d36 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -223,6 +223,8 @@ __DLL__ herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space,
H5D_operator_t op, void *operator_data);
__DLL__ herr_t H5S_sel_iter_release(const H5S_t *space,
H5S_sel_iter_t *sel_iter);
+__DLL__ herr_t H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space,
+ void *buf);
#ifdef H5_HAVE_PARALLEL
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 92f9832..8d18e5c 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -1220,7 +1220,7 @@ H5S_select_contiguous(const H5S_t *space)
/*--------------------------------------------------------------------------
NAME
- H5S_iterate
+ H5S_select_iterate
PURPOSE
Iterate over the selected elements in a memory buffer.
USAGE
@@ -1536,7 +1536,72 @@ H5S_select_regular(const H5S_t *space)
break;
} /* end switch */
-done:
FUNC_LEAVE (ret_value);
} /* H5S_select_regular() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_fill
+ PURPOSE
+ Fill a selection in memory with a value
+ USAGE
+ herr_t H5S_select_fill(fill,fill_size,space,buf)
+ const void *fill; IN: Pointer to fill value to use
+ size_t fill_size; IN: Size of elements in memory buffer & size of
+ fill value
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ void *buf; IN/OUT: Memory buffer to fill selection in
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The memory buffer elements are assumed to have the same datatype as the
+ fill value being placed into them.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf)
+{
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5S_select_fill, FAIL);
+
+ /* Check args */
+ assert(fill);
+ assert(fill_size>0);
+ assert(space);
+ assert(buf);
+
+ /* Fill the selection in the memory buffer */
+ /* [Defer (mostly) to the selection routines] */
+ switch(space->select.type) {
+ case H5S_SEL_POINTS: /* Sequence of points selected */
+ ret_value=H5S_point_select_fill(fill,fill_size,space,buf);
+ break;
+
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
+ ret_value=H5S_hyper_select_fill(fill,fill_size,space,buf);
+ break;
+
+ case H5S_SEL_ALL: /* Entire extent selected */
+ ret_value=H5S_all_select_fill(fill,fill_size,space,buf);
+ break;
+
+ case H5S_SEL_NONE: /* Nothing selected */
+ ret_value=SUCCEED;
+ break;
+
+ case H5S_SEL_ERROR:
+ case H5S_SEL_N:
+ assert(0 && "Invalid selection type!");
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_select_fill() */
+
diff --git a/src/H5V.c b/src/H5V.c
index d4ac850..50b937f 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -80,6 +80,9 @@ H5V_stride_optimize1(unsigned *np/*in,out*/, hsize_t *elmt_size/*in,out*/,
* Saturday, October 11, 1997
*
* Modifications:
+ * Unrolled loops for common cases
+ * Quincey Koziol
+ * ?, ? ?, 2001?
*
*-------------------------------------------------------------------------
*/
@@ -224,6 +227,9 @@ H5V_stride_optimize2(unsigned *np/*in,out*/, hsize_t *elmt_size/*in,out*/,
* Saturday, October 11, 1997
*
* Modifications:
+ * Unrolled loops for common cases
+ * Quincey Koziol
+ * ?, ? ?, 2001?
*
*-------------------------------------------------------------------------
*/
@@ -491,6 +497,9 @@ H5V_hyper_fill(unsigned n, const hsize_t *_size,
* Friday, October 10, 1997
*
* Modifications:
+ * Unrolled loops for common cases
+ * Quincey Koziol
+ * ?, ? ?, 2001?
*
*-------------------------------------------------------------------------
*/
@@ -901,13 +910,11 @@ H5V_array_fill(void *_dst, const void *src, size_t size, size_t count)
* Purpose: Given a coordinate description of a location in an array, this
* function returns the byte offset of the coordinate.
*
- * The dimensionality of the whole array, the hyperslab, and the
- * returned stride array is N. The whole array dimensions are
- * TOTAL_SIZE and the coordinate is at offset OFFSET.
- *
- * Return: Success: Byte offset from beginning of array to start
- * of striding.
+ * The dimensionality of the whole array, and the offset is N.
+ * The whole array dimensions are TOTAL_SIZE and the coordinate
+ * is at offset OFFSET.
*
+ * Return: Success: Byte offset from beginning of array to element offset
* Failure: abort() -- should never fail
*
* Programmer: Quincey Koziol
@@ -924,7 +931,7 @@ H5V_array_offset(unsigned n, const hsize_t *total_size, const hssize_t *offset)
hsize_t acc; /*accumulator */
int i; /*counter */
- FUNC_ENTER(H5V_array_stride, (HDabort(), 0));
+ FUNC_ENTER(H5V_array_offset, (HDabort(), 0));
assert(n <= H5V_HYPER_NDIMS);
assert(total_size);
@@ -934,8 +941,8 @@ H5V_array_offset(unsigned n, const hsize_t *total_size, const hssize_t *offset)
for (i=(int)(n-1), acc=1, skip=0; i>=0; --i) {
skip += acc * offset[i];
acc *= total_size[i];
- }
+ } /* end for */
FUNC_LEAVE(skip);
-}
+} /* end H5V_array_offset() */