[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]
This commit is contained in:
Quincey Koziol 2002-04-09 07:47:34 -05:00
parent e403006cc2
commit 1ffe083f61
12 changed files with 1164 additions and 46 deletions

View File

@ -156,6 +156,8 @@ Documentation
New Features
============
* Added new routine "H5Dfill" to fill a selection with a particular value
in memory. QAK - 2002/04/09
* A new query function H5Tget_member_index has been added for compound
and enumeration data types, to retrieve member's index by name.
SLU - 2002/04/05

View File

@ -3596,6 +3596,90 @@ done:
FUNC_LEAVE(ret_value);
} /* 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

View File

@ -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

View File

@ -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);

View File

@ -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() */

View File

@ -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 */
@ -6568,6 +6567,402 @@ done:
FUNC_LEAVE (ret_value);
} /* H5S_hyper_release() */
/*--------------------------------------------------------------------------
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
@ -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 */

View File

@ -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);

View File

@ -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() */

View File

@ -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

View File

@ -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() */

View File

@ -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() */

View File

@ -4075,6 +4075,9 @@ test_select_combine(void)
hsize_t blocks[128][2][SPACE7_RANK]; /* List of blocks */
herr_t error;
/* Output message about test being performed */
MESSAGE(5, ("Testing Selection Combinations\n"));
/* Create dataspace for dataset on disk */
base_id = H5Screate_simple(SPACE7_RANK, dims, NULL);
CHECK(base_id, FAIL, "H5Screate_simple");
@ -4407,6 +4410,423 @@ test_select_combine(void)
CHECK(error, FAIL, "H5Sclose");
} /* test_select_combine() */
/****************************************************************
**
** test_select_fill_all(): Test basic H5S (dataspace) selection code.
** Tests filling "all" selections
**
****************************************************************/
static void
test_select_fill_all(void)
{
hid_t sid1; /* Dataspace ID */
hsize_t dims1[] = {SPACE7_DIM1, SPACE7_DIM2};
int fill_value; /* Fill value */
unsigned short *wbuf, /* buffer to write to disk */
*tbuf; /* temporary buffer pointer */
int i,j; /* Counters */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Filling 'all' Selections\n"));
/* Allocate memory buffer */
wbuf=malloc(sizeof(unsigned short)*SPACE7_DIM1*SPACE7_DIM2);
/* Initialize memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++)
*tbuf++=(unsigned short)(i*SPACE7_DIM2)+j;
/* Create dataspace for dataset on disk */
sid1 = H5Screate_simple(SPACE7_RANK, dims1, NULL);
CHECK(sid1, FAIL, "H5Screate_simple");
/* Space defaults to "all" selection */
/* Set fill value */
fill_value=254;
/* Fill selection in memory */
ret=H5Dfill(&fill_value,H5T_NATIVE_INT,wbuf,H5T_NATIVE_USHORT,sid1);
CHECK(ret, FAIL, "H5Dfill");
/* Close dataspace */
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");
/* Verify memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++)
if(*tbuf!=(unsigned short)fill_value) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%x, fill_value=%x\n",j,i,(unsigned)*tbuf,(unsigned)fill_value);
} /* end if */
/* Free memory buffers */
free(wbuf);
} /* test_select_fill_all() */
/****************************************************************
**
** test_select_fill_point(): Test basic H5S (dataspace) selection code.
** Tests filling "point" selections
**
****************************************************************/
static void
test_select_fill_point(hssize_t *offset)
{
hid_t sid1; /* Dataspace ID */
hsize_t dims1[] = {SPACE7_DIM1, SPACE7_DIM2};
hssize_t real_offset[SPACE7_RANK]; /* Actual offset to use */
hssize_t points[5][SPACE7_RANK] = {{2,4}, {3,8}, {8,4}, {7,5}, {7,7}};
size_t num_points=5; /* Number of points selected */
int fill_value; /* Fill value */
unsigned short *wbuf, /* buffer to write to disk */
*tbuf; /* temporary buffer pointer */
int i,j,k; /* Counters */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Filling 'point' Selections\n"));
/* Allocate memory buffer */
wbuf=malloc(sizeof(unsigned short)*SPACE7_DIM1*SPACE7_DIM2);
/* Initialize memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++)
*tbuf++=(unsigned short)(i*SPACE7_DIM2)+j;
/* Create dataspace for dataset on disk */
sid1 = H5Screate_simple(SPACE7_RANK, dims1, NULL);
CHECK(sid1, FAIL, "H5Screate_simple");
/* Select "point" selection */
ret = H5Sselect_elements(sid1, H5S_SELECT_SET,num_points,(const hssize_t **)points);
CHECK(ret, FAIL, "H5Sselect_elements");
if(offset!=NULL)
HDmemcpy(real_offset,offset,2*sizeof(hssize_t));
else
HDmemset(real_offset,0,2*sizeof(hssize_t));
/* Set offset */
ret = H5Soffset_simple(sid1,real_offset);
CHECK(ret, FAIL, "H5Soffset_simple");
/* Set fill value */
fill_value=254;
/* Fill selection in memory */
ret=H5Dfill(&fill_value,H5T_NATIVE_INT,wbuf,H5T_NATIVE_USHORT,sid1);
CHECK(ret, FAIL, "H5Dfill");
/* Close dataspace */
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");
/* Verify memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++, tbuf++) {
for(k=0; k<(int)num_points; k++) {
if(i==(points[k][0]+real_offset[0]) && j==(points[k][1]+real_offset[1])) {
if(*tbuf!=(unsigned short)fill_value) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, fill_value=%u\n",j,i,(unsigned)*tbuf,(unsigned)fill_value);
} /* end if */
break;
} /* end if */
} /* end for */
if(k==(int)num_points && *tbuf!=((unsigned short)(i*SPACE7_DIM2)+j)) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, should be: %u\n",j,i,(unsigned)*tbuf,(unsigned)((i*SPACE7_DIM2)+j));
} /* end if */
} /* end for */
/* Free memory buffers */
free(wbuf);
} /* test_select_fill_point() */
/****************************************************************
**
** test_select_fill_hyper_simple(): Test basic H5S (dataspace) selection code.
** Tests filling "simple" (i.e. one block) hyperslab selections
**
****************************************************************/
static void
test_select_fill_hyper_simple(hssize_t *offset)
{
hid_t sid1; /* Dataspace ID */
hsize_t dims1[] = {SPACE7_DIM1, SPACE7_DIM2};
hssize_t real_offset[SPACE7_RANK]; /* Actual offset to use */
hssize_t start[SPACE7_RANK]; /* Hyperslab start */
hsize_t count[SPACE7_RANK]; /* Hyperslab block size */
int fill_value; /* Fill value */
unsigned short *wbuf, /* buffer to write to disk */
*tbuf; /* temporary buffer pointer */
int i,j; /* Counters */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Filling Simple 'hyperslab' Selections\n"));
/* Allocate memory buffer */
wbuf=malloc(sizeof(unsigned short)*SPACE7_DIM1*SPACE7_DIM2);
/* Initialize memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++)
*tbuf++=(unsigned short)(i*SPACE7_DIM2)+j;
/* Create dataspace for dataset on disk */
sid1 = H5Screate_simple(SPACE7_RANK, dims1, NULL);
CHECK(sid1, FAIL, "H5Screate_simple");
/* Select "hyperslab" selection */
start[0]=3; start[1]=3;
count[0]=4; count[1]=4;
ret = H5Sselect_hyperslab(sid1, H5S_SELECT_SET,start,NULL,count,NULL);
CHECK(ret, FAIL, "H5Sselect_hyperslab");
if(offset!=NULL)
HDmemcpy(real_offset,offset,2*sizeof(hssize_t));
else
HDmemset(real_offset,0,2*sizeof(hssize_t));
/* Set offset */
ret = H5Soffset_simple(sid1,real_offset);
CHECK(ret, FAIL, "H5Soffset_simple");
/* Set fill value */
fill_value=254;
/* Fill selection in memory */
ret=H5Dfill(&fill_value,H5T_NATIVE_INT,wbuf,H5T_NATIVE_USHORT,sid1);
CHECK(ret, FAIL, "H5Dfill");
/* Close dataspace */
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");
/* Verify memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++, tbuf++) {
if((i>=(int)(start[0]+real_offset[0]) && i<(int)(start[0]+count[0]+real_offset[0]))
&& (j>=(int)(start[1]+real_offset[1]) && j<(int)(start[1]+count[1]+real_offset[1]))) {
if(*tbuf!=(unsigned short)fill_value) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, fill_value=%u\n",j,i,(unsigned)*tbuf,(unsigned)fill_value);
} /* end if */
} /* end if */
else {
if(*tbuf!=((unsigned short)(i*SPACE7_DIM2)+j)) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, should be: %u\n",j,i,(unsigned)*tbuf,(unsigned)((i*SPACE7_DIM2)+j));
} /* end if */
} /* end else */
} /* end for */
/* Free memory buffers */
free(wbuf);
} /* test_select_fill_hyper_simple() */
/****************************************************************
**
** test_select_fill_hyper_regular(): Test basic H5S (dataspace) selection code.
** Tests filling "regular" (i.e. strided block) hyperslab selections
**
****************************************************************/
static void
test_select_fill_hyper_regular(hssize_t *offset)
{
hid_t sid1; /* Dataspace ID */
hsize_t dims1[] = {SPACE7_DIM1, SPACE7_DIM2};
hssize_t real_offset[SPACE7_RANK]; /* Actual offset to use */
hssize_t start[SPACE7_RANK]; /* Hyperslab start */
hsize_t stride[SPACE7_RANK]; /* Hyperslab stride size */
hsize_t count[SPACE7_RANK]; /* Hyperslab block count */
hsize_t block[SPACE7_RANK]; /* Hyperslab block size */
hssize_t points[16][SPACE7_RANK] = {
{2,2}, {2,3}, {3,2}, {3,3},
{2,6}, {2,7}, {3,6}, {3,7},
{6,2}, {6,3}, {7,2}, {7,3},
{6,6}, {6,7}, {7,6}, {7,7},
};
size_t num_points=16; /* Number of points selected */
int fill_value; /* Fill value */
unsigned short *wbuf, /* buffer to write to disk */
*tbuf; /* temporary buffer pointer */
int i,j,k; /* Counters */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Filling Regular 'hyperslab' Selections\n"));
/* Allocate memory buffer */
wbuf=malloc(sizeof(unsigned short)*SPACE7_DIM1*SPACE7_DIM2);
/* Initialize memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++)
*tbuf++=(unsigned short)(i*SPACE7_DIM2)+j;
/* Create dataspace for dataset on disk */
sid1 = H5Screate_simple(SPACE7_RANK, dims1, NULL);
CHECK(sid1, FAIL, "H5Screate_simple");
/* Select "hyperslab" selection */
start[0]=2; start[1]=2;
stride[0]=4; stride[1]=4;
count[0]=2; count[1]=2;
block[0]=2; block[1]=2;
ret = H5Sselect_hyperslab(sid1,H5S_SELECT_SET,start,stride,count,block);
CHECK(ret, FAIL, "H5Sselect_hyperslab");
if(offset!=NULL)
HDmemcpy(real_offset,offset,2*sizeof(hssize_t));
else
HDmemset(real_offset,0,2*sizeof(hssize_t));
/* Set offset */
ret = H5Soffset_simple(sid1,real_offset);
CHECK(ret, FAIL, "H5Soffset_simple");
/* Set fill value */
fill_value=254;
/* Fill selection in memory */
ret=H5Dfill(&fill_value,H5T_NATIVE_INT,wbuf,H5T_NATIVE_USHORT,sid1);
CHECK(ret, FAIL, "H5Dfill");
/* Close dataspace */
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");
/* Verify memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++, tbuf++) {
for(k=0; k<(int)num_points; k++) {
if(i==(points[k][0]+real_offset[0]) && j==(points[k][1]+real_offset[1])) {
if(*tbuf!=(unsigned short)fill_value) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, fill_value=%u\n",j,i,(unsigned)*tbuf,(unsigned)fill_value);
} /* end if */
break;
} /* end if */
} /* end for */
if(k==(int)num_points && *tbuf!=((unsigned short)(i*SPACE7_DIM2)+j)) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, should be: %u\n",j,i,(unsigned)*tbuf,(unsigned)((i*SPACE7_DIM2)+j));
} /* end if */
} /* end for */
/* Free memory buffers */
free(wbuf);
} /* test_select_fill_hyper_regular() */
/****************************************************************
**
** test_select_fill_hyper_irregular(): Test basic H5S (dataspace) selection code.
** Tests filling "irregular" (i.e. combined blocks) hyperslab selections
**
****************************************************************/
static void
test_select_fill_hyper_irregular(hssize_t *offset)
{
hid_t sid1; /* Dataspace ID */
hsize_t dims1[] = {SPACE7_DIM1, SPACE7_DIM2};
hssize_t real_offset[SPACE7_RANK]; /* Actual offset to use */
hssize_t start[SPACE7_RANK]; /* Hyperslab start */
hsize_t count[SPACE7_RANK]; /* Hyperslab block count */
hssize_t points[32][SPACE7_RANK] = { /* Yes, some of the are duplicated.. */
{2,2}, {2,3}, {2,4}, {2,5},
{3,2}, {3,3}, {3,4}, {3,5},
{4,2}, {4,3}, {4,4}, {4,5},
{5,2}, {5,3}, {5,4}, {5,5},
{4,4}, {4,5}, {4,6}, {4,7},
{5,4}, {5,5}, {5,6}, {5,7},
{6,4}, {6,5}, {6,6}, {6,7},
{7,4}, {7,5}, {7,6}, {7,7},
};
size_t num_points=32; /* Number of points selected */
int fill_value; /* Fill value */
unsigned short *wbuf, /* buffer to write to disk */
*tbuf; /* temporary buffer pointer */
int i,j,k; /* Counters */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
MESSAGE(5, ("Testing Filling Irregular 'hyperslab' Selections\n"));
/* Allocate memory buffer */
wbuf=malloc(sizeof(unsigned short)*SPACE7_DIM1*SPACE7_DIM2);
/* Initialize memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++)
*tbuf++=(unsigned short)(i*SPACE7_DIM2)+j;
/* Create dataspace for dataset on disk */
sid1 = H5Screate_simple(SPACE7_RANK, dims1, NULL);
CHECK(sid1, FAIL, "H5Screate_simple");
/* Select first "hyperslab" selection */
start[0]=2; start[1]=2;
count[0]=4; count[1]=4;
ret = H5Sselect_hyperslab(sid1,H5S_SELECT_SET,start,NULL,count,NULL);
CHECK(ret, FAIL, "H5Sselect_hyperslab");
/* Combine with second "hyperslab" selection */
start[0]=4; start[1]=4;
count[0]=4; count[1]=4;
ret = H5Sselect_hyperslab(sid1,H5S_SELECT_OR,start,NULL,count,NULL);
CHECK(ret, FAIL, "H5Sselect_hyperslab");
if(offset!=NULL)
HDmemcpy(real_offset,offset,2*sizeof(hssize_t));
else
HDmemset(real_offset,0,2*sizeof(hssize_t));
/* Set offset */
ret = H5Soffset_simple(sid1,real_offset);
CHECK(ret, FAIL, "H5Soffset_simple");
/* Set fill value */
fill_value=254;
/* Fill selection in memory */
ret=H5Dfill(&fill_value,H5T_NATIVE_INT,wbuf,H5T_NATIVE_USHORT,sid1);
CHECK(ret, FAIL, "H5Dfill");
/* Close dataspace */
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");
/* Verify memory buffer */
for(i=0, tbuf=wbuf; i<SPACE7_DIM1; i++)
for(j=0; j<SPACE7_DIM2; j++, tbuf++) {
for(k=0; k<(int)num_points; k++) {
if(i==(points[k][0]+real_offset[0]) && j==(points[k][1]+real_offset[1])) {
if(*tbuf!=(unsigned short)fill_value) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, fill_value=%u\n",j,i,(unsigned)*tbuf,(unsigned)fill_value);
} /* end if */
break;
} /* end if */
} /* end for */
if(k==(int)num_points && *tbuf!=((unsigned short)(i*SPACE7_DIM2)+j)) {
num_errs++;
printf("Error! j=%d, i=%d, *tbuf=%u, should be: %u\n",j,i,(unsigned)*tbuf,(unsigned)((i*SPACE7_DIM2)+j));
} /* end if */
} /* end for */
/* Free memory buffers */
free(wbuf);
} /* test_select_fill_hyper_irregular() */
/****************************************************************
**
** test_select(): Main H5S selection testing routine.
@ -4425,6 +4845,7 @@ test_select(void)
#endif /* H5_WANT_H5_V1_4_COMPAT */
size_t rdcc_nbytes; /* Raw data number of bytes */
double rdcc_w0; /* Raw data write percentage */
hssize_t offset[SPACE7_RANK]={1,1}; /* Offset for testing selection offsets */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
@ -4514,6 +4935,17 @@ test_select(void)
/* Tests for combining "all" and "none" selections with hyperslabs */
test_select_combine();
/* Test filling selections */
test_select_fill_all();
test_select_fill_point(NULL);
test_select_fill_point(offset);
test_select_fill_hyper_simple(NULL);
test_select_fill_hyper_simple(offset);
test_select_fill_hyper_regular(NULL);
test_select_fill_hyper_regular(offset);
test_select_fill_hyper_irregular(NULL);
test_select_fill_hyper_irregular(offset);
} /* test_select() */