From c4c6318e6ab92d8204226923e8e9302e2779aaf4 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 23 Jun 1999 21:16:13 -0500 Subject: [svn-r1374] Added in code to support the H5Diterate function, which I've got to add tests for now. Also, I revised some of the code for hyperslab I/O, which should provide a modest speedup in situations with lots of hyperslabs. --- src/H5D.c | 89 ++++++- src/H5Dpublic.h | 6 + src/H5S.c | 1 + src/H5Sall.c | 89 +++++++ src/H5Shyper.c | 775 +++++++++++++++++++++++++++++++++++-------------------- src/H5Snone.c | 42 +++ src/H5Spoint.c | 77 +++++- src/H5Sprivate.h | 10 + src/H5Sselect.c | 69 +++++ src/H5V.c | 46 ++++ src/H5Vprivate.h | 2 + 11 files changed, 917 insertions(+), 289 deletions(-) diff --git a/src/H5D.c b/src/H5D.c index 2b432d3..4a55b64 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -2579,6 +2579,93 @@ H5D_get_storage_size(H5D_t *dset) /*------------------------------------------------------------------------- + * Function: H5Diterate + * + * Purpose: This routine iterates over all the elements selected in a memory + * buffer. The callback function is called once for each element selected + * in the dataspace. The selection in the dataspace is modified so + * that any elements already iterated over are removed from the selection + * if the iteration is interrupted (by the H5D_operator_t function + * returning non-zero) in the "middle" of the iteration and may be + * re-started by the user where it left off. + * + * NOTE: Until "subtracting" elements from a selection is implemented, + * the selection is not modified. + * + * Parameters: + * void *buf; IN/OUT: Pointer to the buffer in memory containing + * the elements to iterate over. + * hid_t type_id; IN: Datatype ID for the elements stored in BUF. + * hid_t space_id; IN: Dataspace ID for BUF, also contains the + * selection to iterate over. + * H5D_operator_t operator; IN: Function pointer to the routine to be + * called for each element in BUF iterated over. + * void *operator_data; IN/OUT: Pointer to any user-defined data + * associated with the operation. + * + * Operation information: + * H5D_operator_t is defined as: + * typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, + * hsize_t ndim, hssize_t *point, void *operator_data); + * + * H5D_operator_t parameters: + * void *elem; IN/OUT: Pointer to the element in memory containing + * the current point. + * hid_t type_id; IN: Datatype ID for the elements stored in ELEM. + * hsize_t ndim; IN: Number of dimensions for POINT array + * hssize_t *point; IN: Array containing the location of the element + * within the original dataspace. + * void *operator_data; IN/OUT: Pointer to any user-defined data + * associated with the operation. + * + * The return values from an operator are: + * Zero causes the iterator to continue, returning zero when all + * elements have been processed. + * Positive causes the iterator to immediately return that positive + * value, indicating short-circuit success. The iterator can be + * restarted at the next element. + * Negative causes the iterator to immediately return that value, + * indicating failure. The iterator can be restarted at the next + * element. + * + * Return: Returns the return value of the last operator if it was non-zero, + * or zero if all elements were processed. Otherwise returns a + * negative value. + * + * Programmer: Quincey Koziol + * Friday, June 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t operator, + void *operator_data) +{ + H5S_t *space = NULL; + herr_t ret_value=FAIL; + + FUNC_ENTER(H5Diterate, FAIL); + + /* Check args */ + if (NULL==operator) + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator"); + if (buf==NULL) + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer"); + if (H5I_DATATYPE != H5I_get_type(type_id)) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype"); + if (H5I_DATASPACE != H5I_get_type(space_id) || + NULL == (space = H5I_object(space_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace"); + + ret_value=H5S_select_iterate(buf,type_id,space,operator,operator_data); + + FUNC_LEAVE(ret_value); +} /* end H5Diterate() */ + + +/*------------------------------------------------------------------------- * Function: H5Dvlen_reclaim * * Purpose: Frees the buffers allocated for storing variable-length data @@ -2614,7 +2701,7 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf) /* Call H5Diterate with args, etc. */ FUNC_LEAVE(ret_value); -} +} /* end H5Dvlen_reclaim() */ /*------------------------------------------------------------------------- diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 74c6549..ba0205c 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -39,6 +39,10 @@ typedef enum H5D_transfer_t { } H5D_transfer_t; +/* Define the operator function pointer for H5Diterate() */ +typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, hsize_t ndim, + hssize_t *point, void *operator_data); + #ifdef __cplusplus extern "C" { #endif @@ -56,6 +60,8 @@ __DLL__ herr_t H5Dread (hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, __DLL__ herr_t H5Dwrite (hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf); __DLL__ herr_t H5Dextend (hid_t dset_id, const hsize_t *size); +__DLL__ herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id, + H5D_operator_t operator, 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 H5Ddebug(hid_t dset_id, unsigned int flags); diff --git a/src/H5S.c b/src/H5S.c index 5446224..b311117 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -1818,6 +1818,7 @@ H5Soffset_simple(hid_t space_id, const hssize_t *offset) FUNC_LEAVE(SUCCEED); } /* end H5Soffset_simple() */ + /*------------------------------------------------------------------------- * Function: H5S_debug diff --git a/src/H5Sall.c b/src/H5Sall.c index 9ac1e5e..18d8f52 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -914,3 +914,92 @@ H5S_all_bounds(H5S_t *space, hsize_t *start, hsize_t *end) FUNC_LEAVE (ret_value); } /* H5Sget_all_bounds() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_all_select_iterate + PURPOSE + Iterate over a "all" selection, calling a user's function for each + element. + USAGE + herr_t H5S_all_select_iterate(buf, type_id, space, operator, operator_data) + void *buf; IN/OUT: Buffer containing elements to iterate over + hid_t type_id; IN: Datatype ID of BUF array. + H5S_t *space; IN: Dataspace object containing selection to iterate over + H5D_operator_t operator; IN: Function pointer to the routine to be + called for each element in BUF iterated over. + void *operator_data; IN/OUT: Pointer to any user-defined data + associated with the operation. + RETURNS + Returns the return value of the last operator if it was non-zero, or zero + if all elements were processed. Otherwise returns a negative value. + DESCRIPTION + Iterates over the selected elements in a memory buffer, calling the user's + callback function for each element. The selection in the dataspace is + modified so that any elements already iterated over are removed from the + selection if the iteration is interrupted (by the H5D_operator_t function + returning non-zero) in the "middle" of the iteration and may be re-started + by the user where it left off. + + NOTE: Until "subtracting" elements from a selection is implemented, + the selection is not modified. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator, + void *operator_data) +{ + hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */ + hsize_t mem_offset[H5O_LAYOUT_NDIMS]; /* current coordinates */ + hsize_t offset; /* offset of region in buffer */ + hsize_t nelemts; /* Number of elements to iterate through */ + void *tmp_buf; /* temporary location of the element in the buffer */ + intn rank; /* Dataspace rank */ + intn index; /* Index to increment */ + herr_t ret_value=0; /* return value */ + + FUNC_ENTER (H5S_all_select_iterate, 0); + + assert(buf); + assert(space); + assert(operator); + assert(H5I_DATATYPE != H5I_get_type(type_id)); + + /* Get the dataspace extent rank */ + rank=space->extent.u.simple.rank; + + /* Set up the size of the memory space */ + HDmemcpy(mem_size, space->extent.u.simple.size, rank*sizeof(hsize_t)); + mem_size[rank]=H5Tget_size(type_id); + + /* Set the coordinates to zero */ + HDmemset(mem_offset, 0, (rank+1)*sizeof(hsize_t)); + + /* Get the number of elements to iterate through */ + nelemts=H5S_get_simple_extent_npoints(space); + + /* Iterate through the entire dataset */ + while(nelemts>0 && ret_value==0) { + /* Get the offset in the memory buffer */ + offset=H5V_array_offset(rank+1,mem_size,mem_offset); + tmp_buf=((char *)buf+offset); + + ret_value=(*operator)(tmp_buf,type_id,rank,mem_offset,operator_data); + + /* Advance the coordinate (currently in C memory order) */ + index=rank-1; /* Leave the byte offset in the element alone */ + while(++mem_offset[index]==mem_size[index] && index>=0) { + mem_offset[index]=0; + index--; + } /* end while */ + + /* Decrement the number of elements to iterate through */ + nelemts--; + } /* end while */ + + FUNC_LEAVE (ret_value); +} /* H5S_all_select_iterate() */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 09c3b77..ecef87c 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -21,7 +22,7 @@ static intn interface_initialize_g = 0; /* Local datatypes */ -/* Parameter block for H5S_hyper_fread & H5S_hyper_fwrite */ +/* Parameter block for H5S_hyper_fread, H5S_hyper_fwrite, H5S_hyper_mread & H5S_hyper_mwrite */ typedef struct { H5F_t *f; const struct H5O_layout_t *layout; @@ -35,9 +36,27 @@ typedef struct { const H5F_xfer_t *xfer_parms; const void *src; void *dst; + hsize_t mem_size[H5O_LAYOUT_NDIMS]; + hssize_t offset[H5O_LAYOUT_NDIMS]; + hsize_t hsize[H5O_LAYOUT_NDIMS]; H5S_hyper_bound_t **lo_bounds; H5S_hyper_bound_t **hi_bounds; -} H5S_hyper_fhyper_info_t; +} H5S_hyper_io_info_t; + +/* Parameter block for H5S_hyper_select_iter_mem */ +typedef struct { + hid_t dt; + size_t elem_size; + const H5S_t *space; + H5S_sel_iter_t *iter; + void *src; + H5S_hyper_bound_t **lo_bounds; + H5S_hyper_bound_t **hi_bounds; + hsize_t mem_size[H5O_LAYOUT_NDIMS]; + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; + H5D_operator_t op; + void * op_data; +} H5S_hyper_iter_info_t; /* Static function prototypes */ static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr, @@ -47,9 +66,9 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos, hssize_t *offset); -static size_t H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info); +static size_t H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info); static size_t H5S_hyper_fwrite (intn dim, - H5S_hyper_fhyper_info_t *fhyper_info); + H5S_hyper_io_info_t *io_info); static herr_t H5S_hyper_init (const struct H5O_layout_t *layout, const H5S_t *space, H5S_sel_iter_t *iter, size_t *min_elem_out); static size_t H5S_hyper_favail (const H5S_t *space, const H5S_sel_iter_t *iter, @@ -120,7 +139,6 @@ H5S_hyper_init (const struct H5O_layout_t UNUSED *layout, FUNC_ENTER (H5S_hyper_init, FAIL); /* Check args */ - assert (layout); assert (space && H5S_SEL_HYPERSLABS==space->select.type); assert (sel_iter); @@ -275,7 +293,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, hi_bounds[0][i].bound!=reg[curr_reg].end) { /* Enlarge array */ - H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),®); + H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)®); /* Initialize with new region */ reg[num_reg].start=lo_bounds[0][i].bound+offset[0]; @@ -368,7 +386,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, (int)reg[curr_reg].end); #endif /* QAK */ /* Enlarge array */ - H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),®); + H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)®); /* Initialize with new region */ reg[num_reg].start=node->start[next_dim]+offset[next_dim]; @@ -429,7 +447,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, */ static herr_t H5S_hyper_block_cache (H5S_hyper_node_t *node, - H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read) + H5S_hyper_io_info_t *io_info, uintn block_read) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -438,27 +456,27 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, FUNC_ENTER (H5S_hyper_block_cache, SUCCEED); assert(node); - assert(fhyper_info); + assert(io_info); /* Allocate temporary buffer of proper size */ - if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*fhyper_info->elmt_size,1,(void **)&(node->cinfo.block)))<0) + if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*io_info->elmt_size,1,(void **)&(node->cinfo.block)))<0) HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab cache block"); /* Read in block, if we are read caching */ if(block_read) { /* Copy the location of the region in the file */ - HDmemcpy(file_offset,node->start,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t))); - file_offset[fhyper_info->space->extent.u.simple.rank]=0; + HDmemcpy(file_offset,node->start,(io_info->space->extent.u.simple.rank * sizeof(hssize_t))); + file_offset[io_info->space->extent.u.simple.rank]=0; /* Set the hyperslab size to read */ - for(i=0; ispace->extent.u.simple.rank; i++) + for(i=0; ispace->extent.u.simple.rank; i++) hsize[i]=(node->end[i]-node->start[i])+1; - hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; + hsize[io_info->space->extent.u.simple.rank]=io_info->elmt_size; - if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms, - fhyper_info->layout, fhyper_info->pline, - fhyper_info->fill, fhyper_info->efl, hsize, hsize, + if (H5F_arr_read (io_info->f, io_info->xfer_parms, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, hsize, hsize, zero, file_offset, node->cinfo.block/*out*/)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); } /* end if */ @@ -491,27 +509,25 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, *------------------------------------------------------------------------- */ static herr_t -H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, hsize_t region_size) +H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_io_info_t *io_info, hsize_t region_size) { FUNC_ENTER (H5S_hyper_block_read, SUCCEED); assert(node && node->cinfo.cached); - assert(fhyper_info); + assert(io_info); /* Copy the elements into the user's buffer */ /* !! NOTE !! This will need to be changed for different dimension permutations from the standard 'C' ordering! */ - HDmemcpy(fhyper_info->dst, - node->cinfo.rpos, - (size_t)(region_size*fhyper_info->elmt_size)); + HDmemcpy(io_info->dst, node->cinfo.rpos, (size_t)(region_size*io_info->elmt_size)); /* * Decrement the number of elements left in block to read & move the * offset */ - node->cinfo.rpos+=region_size*fhyper_info->elmt_size; + node->cinfo.rpos+=region_size*io_info->elmt_size; node->cinfo.rleft-=region_size; /* If we've read in all the elements from the block, throw it away */ @@ -542,7 +558,7 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in */ static herr_t H5S_hyper_block_write (H5S_hyper_node_t *node, - H5S_hyper_fhyper_info_t *fhyper_info, + H5S_hyper_io_info_t *io_info, hsize_t region_size) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ @@ -552,41 +568,36 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, FUNC_ENTER (H5S_hyper_block_write, SUCCEED); assert(node && node->cinfo.cached); - assert(fhyper_info); + assert(io_info); /* Copy the elements into the user's buffer */ /* !! NOTE !! This will need to be changed for different dimension permutations from the standard 'C' ordering! */ - HDmemcpy(node->cinfo.wpos, - fhyper_info->src, - (size_t)(region_size*fhyper_info->elmt_size)); + HDmemcpy(node->cinfo.wpos, io_info->src, (size_t)(region_size*io_info->elmt_size)); /* * Decrement the number of elements left in block to read & move the * offset */ - node->cinfo.wpos+=region_size*fhyper_info->elmt_size; + node->cinfo.wpos+=region_size*io_info->elmt_size; node->cinfo.wleft-=region_size; /* If we've read in all the elements from the block, throw it away */ if(node->cinfo.wleft==0 && (node->cinfo.rleft==0 || node->cinfo.rleft==node->cinfo.size)) { /* Copy the location of the region in the file */ - HDmemcpy(file_offset, - node->start, - (fhyper_info->space->extent.u.simple.rank * - sizeof(hssize_t))); - file_offset[fhyper_info->space->extent.u.simple.rank]=0; + HDmemcpy(file_offset, node->start, (io_info->space->extent.u.simple.rank * sizeof(hssize_t))); + file_offset[io_info->space->extent.u.simple.rank]=0; /* Set the hyperslab size to write */ - for(i=0; ispace->extent.u.simple.rank; i++) + for(i=0; ispace->extent.u.simple.rank; i++) hsize[i]=(node->end[i]-node->start[i])+1; - hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; + hsize[io_info->space->extent.u.simple.rank]=io_info->elmt_size; - if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms, - fhyper_info->layout, fhyper_info->pline, - fhyper_info->fill, fhyper_info->efl, hsize, hsize, + if (H5F_arr_write (io_info->f, io_info->xfer_parms, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, hsize, hsize, zero, file_offset, node->cinfo.block/*out*/)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); @@ -618,10 +629,8 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, *------------------------------------------------------------------------- */ static size_t -H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) +H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) { - hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ - hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hsize_t region_size; /* Size of lowest region */ uintn parm_init=0; /* Whether one-shot parameters set up */ hid_t reg_id; /* ID of temporary region buffer */ @@ -633,7 +642,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) FUNC_ENTER (H5S_hyper_fread, 0); - assert(fhyper_info); + assert(io_info); #ifdef QAK printf("%s: check 1.0, dim=%d\n",FUNC,dim); @@ -642,9 +651,9 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ if((reg_id=H5S_hyper_get_regions(&num_regions,dim, - fhyper_info->space->select.sel_info.hslab.hyper_lst->count, - fhyper_info->lo_bounds, fhyper_info->hi_bounds, - fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) { + io_info->space->select.sel_info.hslab.hyper_lst->count, + io_info->lo_bounds, io_info->hi_bounds, + io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { /* Get the pointer to the actual regions array */ regions=H5TB_buf_ptr(reg_id); @@ -656,45 +665,40 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) */ #ifdef QAK printf("%s: check 2.0, rank=%d, cache_hyper=%d\n", - FUNC,(int)fhyper_info->space->extent.u.simple.rank, - (int)fhyper_info->xfer_parms->cache_hyper); + FUNC,(int)io_info->space->extent.u.simple.rank, + (int)io_info->xfer_parms->cache_hyper); for(i=0; ispace->extent.u.simple.rank) { + if((dim+2)==io_info->space->extent.u.simple.rank) { /* perform I/O on data from regions */ - for(i=0; inelmts>0; i++) { + for(i=0; inelmts>0; i++) { /* Compute the size of the region to read */ - region_size=MIN(fhyper_info->nelmts, + region_size=MIN(io_info->nelmts, (regions[i].end-regions[i].start)+1); /* Check if this hyperslab block is cached or could be cached */ if(!regions[i].node->cinfo.cached && - (fhyper_info->xfer_parms->cache_hyper && - (fhyper_info->xfer_parms->block_limit==0 || - fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) { + (io_info->xfer_parms->cache_hyper && + (io_info->xfer_parms->block_limit==0 || + io_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) { /* if we aren't cached, attempt to cache the block */ - H5S_hyper_block_cache(regions[i].node,fhyper_info,1); + H5S_hyper_block_cache(regions[i].node,io_info,1); } /* end if */ /* Read information from the cached block */ if(regions[i].node->cinfo.cached) { - if(H5S_hyper_block_read(regions[i].node,fhyper_info,region_size)<0) + if(H5S_hyper_block_read(regions[i].node,io_info,region_size)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } else { /* Set up hyperslab I/O parameters which apply to all regions */ if(!parm_init) { /* Copy the location of the region in the file */ - HDmemcpy(file_offset,fhyper_info->iter->hyp.pos,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t))); - file_offset[fhyper_info->space->extent.u.simple.rank]=0; - - /* Set the hyperslab size to copy */ - hsize[0]=1; - H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank); - hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; - + HDmemcpy(io_info->offset,io_info->iter->hyp.pos,(io_info->space->extent.u.simple.rank * sizeof(hssize_t))); + io_info->offset[io_info->space->extent.u.simple.rank]=0; + /* Set flag */ parm_init=1; } /* end if */ @@ -703,45 +707,45 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) printf("%s: check 2.2, i=%d, region_size=%d\n",FUNC,(int)i,(int)region_size); #endif /* QAK */ /* Fill in the region specific parts of the I/O request */ - hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; - file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; + io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size; + io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start; /* * Gather from file. */ - if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms, - fhyper_info->layout, fhyper_info->pline, - fhyper_info->fill, fhyper_info->efl, - hsize, hsize, zero, file_offset, - fhyper_info->dst/*out*/)<0) { + if (H5F_arr_read (io_info->f, io_info->xfer_parms, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, + io_info->hsize, io_info->hsize, zero, io_info->offset, + io_info->dst/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } #ifdef QAK printf("%s: check 2.3, region #%d\n",FUNC,(int)i); - for(j=0; jspace->extent.u.simple.rank; j++) - printf("%s: %d - pos=%d\n", FUNC,j,(int)fhyper_info->iter->hyp.pos[j]); + for(j=0; jspace->extent.u.simple.rank; j++) + printf("%s: %d - pos=%d\n", FUNC,j,(int)io_info->iter->hyp.pos[j]); #endif /* QAK */ } /* end else */ /* Advance the pointer in the buffer */ - fhyper_info->dst = ((uint8_t *)fhyper_info->dst) + - region_size*fhyper_info->elmt_size; + io_info->dst = ((uint8_t *)io_info->dst) + + region_size*io_info->elmt_size; /* Increment the number of elements read */ num_read+=region_size; /* Decrement the buffer left */ - fhyper_info->nelmts-=region_size; + io_info->nelmts-=region_size; /* Set the next position to start at */ if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1)) - fhyper_info->iter->hyp.pos[dim+1]=(-1); + io_info->iter->hyp.pos[dim+1]=(-1); else - fhyper_info->iter->hyp.pos[dim+1] = regions[i].start + region_size; + io_info->iter->hyp.pos[dim+1] = regions[i].start + region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=region_size; + io_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ #ifdef QAK @@ -754,25 +758,25 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) dim++; /* Step through each region in this dimension */ - for(i=0; inelmts>0; i++) { + for(i=0; inelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) { + for(j=regions[i].start; j<=regions[i].end && io_info->nelmts>0; j++) { #ifdef QAK printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j); #endif /* QAK */ /* Set the correct position we are working on */ - fhyper_info->iter->hyp.pos[dim]=j; + io_info->iter->hyp.pos[dim]=j; /* Go get the regions in the next lower dimension */ - num_read+=H5S_hyper_fread(dim, fhyper_info); + num_read+=H5S_hyper_fread(dim, io_info); /* Advance to the next row if we got the whole region */ - if(fhyper_info->iter->hyp.pos[dim+1]==(-1)) - fhyper_info->iter->hyp.pos[dim]=j+1; + if(io_info->iter->hyp.pos[dim+1]==(-1)) + io_info->iter->hyp.pos[dim]=j+1; } /* end for */ - if(j>regions[i].end && fhyper_info->iter->hyp.pos[dim+1]==(-1)) - fhyper_info->iter->hyp.pos[dim]=(-1); + if(j>regions[i].end && io_info->iter->hyp.pos[dim+1]==(-1)) + io_info->iter->hyp.pos[dim]=(-1); } /* end for */ } /* end else */ @@ -817,7 +821,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, { H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ - H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */ + H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */ intn i; /*counters */ size_t num_read; /* number of elements read into buffer */ @@ -851,27 +855,33 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, } /* end for */ /* Initialize parameter block for recursive calls */ - fhyper_info.f=f; - fhyper_info.layout=layout; - fhyper_info.pline=pline; - fhyper_info.fill=fill; - fhyper_info.efl=efl; - fhyper_info.elmt_size=elmt_size; - fhyper_info.space=file_space; - fhyper_info.iter=file_iter; - fhyper_info.nelmts=nelmts; - fhyper_info.xfer_parms=xfer_parms; - fhyper_info.src=NULL; - fhyper_info.dst=_buf; - fhyper_info.lo_bounds=lo_bounds; - fhyper_info.hi_bounds=hi_bounds; + io_info.f=f; + io_info.layout=layout; + io_info.pline=pline; + io_info.fill=fill; + io_info.efl=efl; + io_info.elmt_size=elmt_size; + io_info.space=file_space; + io_info.iter=file_iter; + io_info.nelmts=nelmts; + io_info.xfer_parms=xfer_parms; + io_info.src=NULL; + io_info.dst=_buf; + + /* Set the hyperslab size to copy */ + io_info.hsize[0]=1; + H5V_array_fill(io_info.hsize,io_info.hsize,sizeof(io_info.hsize[0]),file_space->extent.u.simple.rank); + io_info.hsize[file_space->extent.u.simple.rank]=elmt_size; + + io_info.lo_bounds=lo_bounds; + io_info.hi_bounds=hi_bounds; /* Recursively input the hyperslabs currently defined */ /* starting with the slowest changing dimension */ #ifdef QAK printf("%s: check 4.0\n",FUNC); #endif /* QAK */ - num_read=H5S_hyper_fread(-1,&fhyper_info); + num_read=H5S_hyper_fread(-1,&io_info); #ifdef QAK printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read); #endif /* QAK */ @@ -901,10 +911,8 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, *------------------------------------------------------------------------- */ static size_t -H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) +H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) { - hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ - hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hsize_t region_size; /* Size of lowest region */ uintn parm_init=0; /* Whether one-shot parameters set up */ hid_t reg_id; /* ID of temporary region buffer */ @@ -916,7 +924,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) FUNC_ENTER (H5S_hyper_fwrite, 0); - assert(fhyper_info); + assert(io_info); #ifdef QAK printf("%s: check 1.0\n", FUNC); @@ -924,16 +932,16 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ if((reg_id=H5S_hyper_get_regions(&num_regions,dim, - fhyper_info->space->select.sel_info.hslab.hyper_lst->count, - fhyper_info->lo_bounds, fhyper_info->hi_bounds, - fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) { + io_info->space->select.sel_info.hslab.hyper_lst->count, + io_info->lo_bounds, io_info->hi_bounds, + io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { /* Get the pointer to the actual regions array */ regions=H5TB_buf_ptr(reg_id); #ifdef QAK printf("%s: check 1.1, regions=%p\n", FUNC,regions); printf("%s: check 1.2, rank=%d\n", - FUNC,(int)fhyper_info->space->extent.u.simple.rank); + FUNC,(int)io_info->space->extent.u.simple.rank); for(i=0; ispace->extent.u.simple.rank) { + if((dim+2)==io_info->space->extent.u.simple.rank) { /* perform I/O on data from regions */ - for(i=0; inelmts>0; i++) { + for(i=0; inelmts>0; i++) { /* Compute the size of the region to read */ - region_size=MIN(fhyper_info->nelmts, (regions[i].end-regions[i].start)+1); + region_size=MIN(io_info->nelmts, (regions[i].end-regions[i].start)+1); /* Check if this hyperslab block is cached or could be cached */ - if(!regions[i].node->cinfo.cached && (fhyper_info->xfer_parms->cache_hyper && (fhyper_info->xfer_parms->block_limit==0 || fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) { + if(!regions[i].node->cinfo.cached && (io_info->xfer_parms->cache_hyper && (io_info->xfer_parms->block_limit==0 || io_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) { /* if we aren't cached, attempt to cache the block */ - H5S_hyper_block_cache(regions[i].node,fhyper_info,0); + H5S_hyper_block_cache(regions[i].node,io_info,0); } /* end if */ - /* Read information from the cached block */ + /* Write information to the cached block */ if(regions[i].node->cinfo.cached) { - if(H5S_hyper_block_write(regions[i].node,fhyper_info,region_size)<0) + if(H5S_hyper_block_write(regions[i].node,io_info,region_size)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } else { /* Set up hyperslab I/O parameters which apply to all regions */ if(!parm_init) { - /* Copy the location of the region in the file */ - HDmemcpy(file_offset, fhyper_info->iter->hyp.pos, - (fhyper_info->space->extent.u.simple.rank * - sizeof(hssize_t))); - file_offset[fhyper_info->space->extent.u.simple.rank]=0; - - /* Set the hyperslab size to copy */ - hsize[0]=1; - H5V_array_fill(hsize, hsize, sizeof(hsize[0]), - fhyper_info->space->extent.u.simple.rank); - hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; + HDmemcpy(io_info->offset, io_info->iter->hyp.pos, (io_info->space->extent.u.simple.rank * sizeof(hssize_t))); + io_info->offset[io_info->space->extent.u.simple.rank]=0; /* Set flag */ parm_init=1; } /* end if */ - hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; - file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; + io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size; + io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start; /* * Scatter to file. */ - if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms, - fhyper_info->layout, fhyper_info->pline, - fhyper_info->fill, fhyper_info->efl, - hsize, hsize, zero, file_offset, - fhyper_info->src)<0) { - HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, - "write error"); + if (H5F_arr_write (io_info->f, io_info->xfer_parms, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, + io_info->hsize, io_info->hsize, zero, io_info->offset, + io_info->src)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } } /* end else */ /* Advance the pointer in the buffer */ - fhyper_info->src = ((const uint8_t *)fhyper_info->src) + - region_size*fhyper_info->elmt_size; + io_info->src = ((const uint8_t *)io_info->src) + + region_size*io_info->elmt_size; /* Increment the number of elements read */ num_written+=region_size; /* Decrement the buffer left */ - fhyper_info->nelmts-=region_size; + io_info->nelmts-=region_size; /* Set the next position to start at */ if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1)) - fhyper_info->iter->hyp.pos[dim+1]=(-1); + io_info->iter->hyp.pos[dim+1]=(-1); else - fhyper_info->iter->hyp.pos[dim+1] = regions[i].start + + io_info->iter->hyp.pos[dim+1] = regions[i].start + region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=region_size; + io_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ @@ -1022,21 +1020,21 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) dim++; /* Step through each region in this dimension */ - for(i=0; inelmts>0; i++) { + for(i=0; inelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) { + for(j=regions[i].start; j<=regions[i].end && io_info->nelmts>0; j++) { /* Set the correct position we are working on */ - fhyper_info->iter->hyp.pos[dim]=j; + io_info->iter->hyp.pos[dim]=j; /* Go get the regions in the next lower dimension */ - num_written+=H5S_hyper_fwrite(dim, fhyper_info); + num_written+=H5S_hyper_fwrite(dim, io_info); /* Advance to the next row if we got the whole region */ - if(fhyper_info->iter->hyp.pos[dim+1]==(-1)) - fhyper_info->iter->hyp.pos[dim]=j+1; + if(io_info->iter->hyp.pos[dim+1]==(-1)) + io_info->iter->hyp.pos[dim]=j+1; } /* end for */ - if(j>regions[i].end && fhyper_info->iter->hyp.pos[dim+1]==(-1)) - fhyper_info->iter->hyp.pos[dim]=(-1); + if(j>regions[i].end && io_info->iter->hyp.pos[dim+1]==(-1)) + io_info->iter->hyp.pos[dim]=(-1); } /* end for */ } /* end else */ @@ -1079,7 +1077,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, { H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ - H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */ + H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */ intn i; /*counters */ size_t num_written; /* number of elements read into buffer */ @@ -1114,24 +1112,30 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, } /* end for */ /* Initialize parameter block for recursive calls */ - fhyper_info.f=f; - fhyper_info.layout=layout; - fhyper_info.pline=pline; - fhyper_info.fill=fill; - fhyper_info.efl=efl; - fhyper_info.elmt_size=elmt_size; - fhyper_info.space=file_space; - fhyper_info.iter=file_iter; - fhyper_info.nelmts=nelmts; - fhyper_info.xfer_parms=xfer_parms; - fhyper_info.src=_buf; - fhyper_info.dst=NULL; - fhyper_info.lo_bounds=lo_bounds; - fhyper_info.hi_bounds=hi_bounds; + io_info.f=f; + io_info.layout=layout; + io_info.pline=pline; + io_info.fill=fill; + io_info.efl=efl; + io_info.elmt_size=elmt_size; + io_info.space=file_space; + io_info.iter=file_iter; + io_info.nelmts=nelmts; + io_info.xfer_parms=xfer_parms; + io_info.src=_buf; + io_info.dst=NULL; + + /* Set the hyperslab size to copy */ + io_info.hsize[0]=1; + H5V_array_fill(io_info.hsize,io_info.hsize,sizeof(io_info.hsize[0]),file_space->extent.u.simple.rank); + io_info.hsize[file_space->extent.u.simple.rank]=elmt_size; + + io_info.lo_bounds=lo_bounds; + io_info.hi_bounds=hi_bounds; /* Recursively input the hyperslabs currently defined */ /* starting with the slowest changing dimension */ - num_written=H5S_hyper_fwrite(-1,&fhyper_info); + num_written=H5S_hyper_fwrite(-1,&io_info); /* Release the memory we allocated */ H5MM_xfree(lo_bounds); @@ -1161,11 +1165,8 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, *------------------------------------------------------------------------- */ static size_t -H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) +H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info) { - hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*size of memory buffer*/ - hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in memory*/ - hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hsize_t region_size; /* Size of lowest region */ hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ @@ -1176,7 +1177,7 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) FUNC_ENTER (H5S_hyper_mread, 0); - assert(fhyper_info); + assert(io_info); #ifdef QAK printf("%s: check 1.0, dim=%d\n",FUNC,dim); @@ -1185,9 +1186,9 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ if((reg_id=H5S_hyper_get_regions(&num_regions,dim, - fhyper_info->space->select.sel_info.hslab.hyper_lst->count, - fhyper_info->lo_bounds, fhyper_info->hi_bounds, - fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) { + io_info->space->select.sel_info.hslab.hyper_lst->count, + io_info->lo_bounds, io_info->hi_bounds, + io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { /* Get the pointer to the actual regions array */ regions=H5TB_buf_ptr(reg_id); @@ -1197,40 +1198,26 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* changing dimension and should input those regions) */ #ifdef QAK printf("%s: check 2.0, rank=%d, num_regions=%d\n", - FUNC, (int)fhyper_info->space->extent.u.simple.rank, + FUNC, (int)io_info->space->extent.u.simple.rank, (int)num_regions); for(i=0; ispace->extent.u.simple.rank) { + if((dim+2)==io_info->space->extent.u.simple.rank) { /* Set up hyperslab I/O parameters which apply to all regions */ - /* Set up the size of the memory space */ - HDmemcpy(mem_size, fhyper_info->space->extent.u.simple.size, - fhyper_info->space->extent.u.simple.rank*sizeof(hsize_t)); - mem_size[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; - /* Copy the location of the region in the file */ - HDmemcpy(mem_offset, fhyper_info->iter->hyp.pos, - (fhyper_info->space->extent.u.simple.rank * - sizeof(hssize_t))); - mem_offset[fhyper_info->space->extent.u.simple.rank]=0; - - /* Set the hyperslab size to copy */ - hsize[0]=1; - H5V_array_fill(hsize, hsize, sizeof(hsize[0]), - fhyper_info->space->extent.u.simple.rank); - hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; + HDmemcpy(io_info->offset, io_info->iter->hyp.pos, (io_info->space->extent.u.simple.rank * sizeof(hssize_t))); + io_info->offset[io_info->space->extent.u.simple.rank]=0; /* perform I/O on data from regions */ - for(i=0; inelmts>0; i++) { - region_size=MIN(fhyper_info->nelmts, - (regions[i].end-regions[i].start)+1); - hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; - mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; + for(i=0; inelmts>0; i++) { + region_size=MIN(io_info->nelmts,(regions[i].end-regions[i].start)+1); + io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size; + io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start; #ifdef QAK printf("%s: check 2.1, i=%d, region_size=%d\n", FUNC,(int)i,(int)region_size); @@ -1239,32 +1226,31 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* * Gather from memory. */ - if (H5V_hyper_copy (fhyper_info->space->extent.u.simple.rank+1, - hsize, hsize, zero, fhyper_info->dst, - mem_size, mem_offset, fhyper_info->src)<0) { + if (H5V_hyper_copy (io_info->space->extent.u.simple.rank+1, + io_info->hsize, io_info->hsize, zero, io_info->dst, + io_info->mem_size, io_info->offset, io_info->src)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory"); } /* Advance the pointer in the buffer */ - fhyper_info->dst = ((uint8_t *)fhyper_info->dst) + - region_size*fhyper_info->elmt_size; + io_info->dst = ((uint8_t *)io_info->dst) + region_size*io_info->elmt_size; /* Increment the number of elements read */ num_read+=region_size; /* Decrement the buffer left */ - fhyper_info->nelmts-=region_size; + io_info->nelmts-=region_size; /* Set the next position to start at */ if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1)) - fhyper_info->iter->hyp.pos[dim+1]=(-1); + io_info->iter->hyp.pos[dim+1]=(-1); else - fhyper_info->iter->hyp.pos[dim+1] =regions[i].start + + io_info->iter->hyp.pos[dim+1] =regions[i].start + region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=region_size; + io_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ #ifdef QAK @@ -1275,27 +1261,25 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) dim++; /* Step through each region in this dimension */ - for(i=0; inelmts>0; i++) { + for(i=0; inelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; - j<=regions[i].end && fhyper_info->nelmts>0; - j++) { + for(j=regions[i].start; j<=regions[i].end && io_info->nelmts>0; j++) { #ifdef QAK printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j); #endif /* QAK */ /* - * If we are moving to a new position in this dim, reset - * the next lower dim. location. - */ - if(fhyper_info->iter->hyp.pos[dim]!=j) - fhyper_info->iter->hyp.pos[dim+1]=(-1); + * If we are moving to a new position in this dim, reset + * the next lower dim. location. + */ + if(io_info->iter->hyp.pos[dim]!=j) + io_info->iter->hyp.pos[dim+1]=(-1); /* Set the correct position we are working on */ - fhyper_info->iter->hyp.pos[dim]=j; + io_info->iter->hyp.pos[dim]=j; /* Go get the regions in the next lower dimension */ - num_read+=H5S_hyper_mread(dim, fhyper_info); + num_read+=H5S_hyper_mread(dim, io_info); } /* end for */ } /* end for */ } /* end else */ @@ -1334,7 +1318,7 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size, { H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ - H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */ + H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */ intn i; #ifdef QAK intn j; /* Counters */ @@ -1391,21 +1375,31 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size, } /* end for */ /* Initialize parameter block for recursive calls */ - fhyper_info.elmt_size=elmt_size; - fhyper_info.space=mem_space; - fhyper_info.iter=mem_iter; - fhyper_info.nelmts=nelmts; - fhyper_info.src=_buf; - fhyper_info.dst=_tconv_buf; - fhyper_info.lo_bounds=lo_bounds; - fhyper_info.hi_bounds=hi_bounds; + io_info.elmt_size=elmt_size; + io_info.space=mem_space; + io_info.iter=mem_iter; + io_info.nelmts=nelmts; + io_info.src=_buf; + io_info.dst=_tconv_buf; + + /* Set up the size of the memory space */ + HDmemcpy(io_info.mem_size, mem_space->extent.u.simple.size,mem_space->extent.u.simple.rank*sizeof(hsize_t)); + io_info.mem_size[mem_space->extent.u.simple.rank]=elmt_size; + + /* Set the hyperslab size to copy */ + io_info.hsize[0]=1; + H5V_array_fill(io_info.hsize, io_info.hsize, sizeof(io_info.hsize[0]),mem_space->extent.u.simple.rank); + io_info.hsize[mem_space->extent.u.simple.rank]=elmt_size; + + io_info.lo_bounds=lo_bounds; + io_info.hi_bounds=hi_bounds; /* Recursively input the hyperslabs currently defined */ /* starting with the slowest changing dimension */ #ifdef QAK printf("%s: check 4.0\n",FUNC); #endif /* QAK */ - num_read=H5S_hyper_mread(-1,&fhyper_info); + num_read=H5S_hyper_mread(-1,&io_info); #ifdef QAK printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read); #endif /* QAK */ @@ -1435,11 +1429,8 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size, *------------------------------------------------------------------------- */ static size_t -H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) +H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info) { - hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*size of memory buffer*/ - hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ - hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hsize_t region_size; /* Size of lowest region */ hid_t reg_id; /* ID of temporary region buffer */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ @@ -1450,7 +1441,7 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) FUNC_ENTER (H5S_hyper_mwrite, 0); - assert(fhyper_info); + assert(io_info); #ifdef QAK printf("%s: check 1.0\n",FUNC); #endif /* QAK */ @@ -1458,16 +1449,16 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* Get a sorted list (in the next dimension down) of the regions which */ /* overlap the current index in this dim */ if((reg_id=H5S_hyper_get_regions(&num_regions,dim, - fhyper_info->space->select.sel_info.hslab.hyper_lst->count, - fhyper_info->lo_bounds, fhyper_info->hi_bounds, - fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) { + io_info->space->select.sel_info.hslab.hyper_lst->count, + io_info->lo_bounds, io_info->hi_bounds, + io_info->iter->hyp.pos,io_info->space->select.offset))>=0) { /* Get the pointer to the actual regions array */ regions=H5TB_buf_ptr(reg_id); #ifdef QAK printf("%s: check 2.0, rank=%d\n", - FUNC,(int)fhyper_info->space->extent.u.simple.rank); + FUNC,(int)io_info->space->extent.u.simple.rank); for(i=0; ispace->extent.u.simple.rank) { + if((dim+2)==io_info->space->extent.u.simple.rank) { /* Set up hyperslab I/O parameters which apply to all regions */ - /* Set up the size of the memory space */ - HDmemcpy(mem_size, fhyper_info->space->extent.u.simple.size, - fhyper_info->space->extent.u.simple.rank*sizeof(hsize_t)); - mem_size[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; - /* Copy the location of the region in the file */ - HDmemcpy(mem_offset, fhyper_info->iter->hyp.pos, - (fhyper_info->space->extent.u.simple.rank* - sizeof(hssize_t))); - mem_offset[fhyper_info->space->extent.u.simple.rank]=0; - - /* Set the hyperslab size to copy */ - hsize[0]=1; - H5V_array_fill(hsize, hsize, sizeof(hsize[0]), - fhyper_info->space->extent.u.simple.rank); - hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size; + HDmemcpy(io_info->offset, io_info->iter->hyp.pos, (io_info->space->extent.u.simple.rank* sizeof(hssize_t))); + io_info->offset[io_info->space->extent.u.simple.rank]=0; #ifdef QAK printf("%s: check 3.0\n",FUNC); #endif /* QAK */ /* perform I/O on data from regions */ - for(i=0; inelmts>0; i++) { - region_size=MIN(fhyper_info->nelmts, - (regions[i].end-regions[i].start)+1); - hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; - mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; + for(i=0; inelmts>0; i++) { + region_size=MIN(io_info->nelmts, (regions[i].end-regions[i].start)+1); + io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size; + io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start; /* * Gather from memory. */ - if (H5V_hyper_copy (fhyper_info->space->extent.u.simple.rank+1, - hsize, mem_size, mem_offset, - fhyper_info->dst, hsize, zero, - fhyper_info->src)<0) { - HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, - "unable to gather data from memory"); + if (H5V_hyper_copy (io_info->space->extent.u.simple.rank+1, + io_info->hsize, io_info->mem_size, io_info->offset, + io_info->dst, io_info->hsize, zero, + io_info->src)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory"); } /* Advance the pointer in the buffer */ - fhyper_info->src = ((const uint8_t *)fhyper_info->src) + - region_size*fhyper_info->elmt_size; + io_info->src = ((const uint8_t *)io_info->src) + + region_size*io_info->elmt_size; /* Increment the number of elements read */ num_read+=region_size; /* Decrement the buffer left */ - fhyper_info->nelmts-=region_size; + io_info->nelmts-=region_size; /* Set the next position to start at */ if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1)) - fhyper_info->iter->hyp.pos[dim+1]=(-1); + io_info->iter->hyp.pos[dim+1]=(-1); else - fhyper_info->iter->hyp.pos[dim+1] = regions[i].start + + io_info->iter->hyp.pos[dim+1] = regions[i].start + region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=region_size; + io_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ @@ -1546,29 +1522,29 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) printf("%s: check 6.0, num_regions=%d\n",FUNC,(int)num_regions); #endif /* QAK */ /* Step through each region in this dimension */ - for(i=0; inelmts>0; i++) { + for(i=0; inelmts>0; i++) { /* Step through each location in each region */ #ifdef QAK printf("%s: check 7.0, start[%d]=%d, end[%d]=%d, nelmts=%d\n", FUNC, i, (int)regions[i].start, i, - (int)regions[i].end, (int)fhyper_info->nelmts); + (int)regions[i].end, (int)io_info->nelmts); #endif /* QAK */ for(j=regions[i].start; - j<=regions[i].end && fhyper_info->nelmts>0; + j<=regions[i].end && io_info->nelmts>0; j++) { /* * If we are moving to a new position in this dim, reset * the next lower dim. location. */ - if(fhyper_info->iter->hyp.pos[dim]!=j) - fhyper_info->iter->hyp.pos[dim+1]=(-1); + if(io_info->iter->hyp.pos[dim]!=j) + io_info->iter->hyp.pos[dim+1]=(-1); /* Set the correct position we are working on */ - fhyper_info->iter->hyp.pos[dim]=j; + io_info->iter->hyp.pos[dim]=j; /* Go get the regions in the next lower dimension */ - num_read+=H5S_hyper_mwrite(dim, fhyper_info); + num_read+=H5S_hyper_mwrite(dim, io_info); } /* end for */ } /* end for */ } /* end else */ @@ -1604,7 +1580,7 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size, { H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ - H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */ + H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */ intn i; /*counters */ size_t num_read; /* number of elements read into buffer */ @@ -1635,21 +1611,31 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size, } /* end for */ /* Initialize parameter block for recursive calls */ - fhyper_info.elmt_size=elmt_size; - fhyper_info.space=mem_space; - fhyper_info.iter=mem_iter; - fhyper_info.nelmts=nelmts; - fhyper_info.src=_tconv_buf; - fhyper_info.dst=_buf; - fhyper_info.lo_bounds=lo_bounds; - fhyper_info.hi_bounds=hi_bounds; + io_info.elmt_size=elmt_size; + io_info.space=mem_space; + io_info.iter=mem_iter; + io_info.nelmts=nelmts; + io_info.src=_tconv_buf; + io_info.dst=_buf; + + /* Set up the size of the memory space */ + HDmemcpy(io_info.mem_size, mem_space->extent.u.simple.size,mem_space->extent.u.simple.rank*sizeof(hsize_t)); + io_info.mem_size[mem_space->extent.u.simple.rank]=elmt_size; + + /* Set the hyperslab size to copy */ + io_info.hsize[0]=1; + H5V_array_fill(io_info.hsize, io_info.hsize, sizeof(io_info.hsize[0]), mem_space->extent.u.simple.rank); + io_info.hsize[mem_space->extent.u.simple.rank]=elmt_size; + + io_info.lo_bounds=lo_bounds; + io_info.hi_bounds=hi_bounds; /* Recursively input the hyperslabs currently defined */ /* starting with the slowest changing dimension */ #ifdef QAK printf("%s: check 1.0\n",FUNC); #endif /* QAK */ - num_read=H5S_hyper_mwrite(-1,&fhyper_info); + num_read=H5S_hyper_mwrite(-1,&io_info); #ifdef QAK printf("%s: check 2.0\n",FUNC); #endif /* QAK */ @@ -2919,6 +2905,7 @@ H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end) FUNC_LEAVE (ret_value); } /* H5Sget_hyper_bounds() */ + /*-------------------------------------------------------------------------- NAME @@ -2974,3 +2961,217 @@ H5S_hyper_select_contiguous(const H5S_t *space) } /* end else */ FUNC_LEAVE (ret_value); } /* H5S_hyper_select_contiguous() */ + + +/*------------------------------------------------------------------------- + * Function: H5S_hyper_select_iterate_mem + * + * Purpose: Recursively iterates over data points in memory using the parameters + * passed to H5S_hyper_select_iterate. + * + * Return: Success: Number of elements copied. + * + * Failure: 0 + * + * Programmer: Quincey Koziol + * Tuesday, June 22, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static size_t +H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info) +{ + hsize_t offset; /* offset of region in buffer */ + void *tmp_buf; /* temporary location of the element in the buffer */ + hid_t reg_id; /* ID of temporary region buffer */ + H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ + size_t num_regions; /* number of regions overlapped */ + herr_t user_ret=0; /* User's return value */ + size_t i; /* Counters */ + intn j; + + FUNC_ENTER (H5S_hyper_mwrite, 0); + + assert(iter_info); + + /* Get a sorted list (in the next dimension down) of the regions which */ + /* overlap the current index in this dim */ + if((reg_id=H5S_hyper_get_regions(&num_regions,dim, + iter_info->space->select.sel_info.hslab.hyper_lst->count, + iter_info->lo_bounds, iter_info->hi_bounds, + iter_info->iter->hyp.pos,iter_info->space->select.offset))>=0) { + + /* Get the pointer to the actual regions array */ + regions=H5TB_buf_ptr(reg_id); + + /* Check if this is the second to last dimension in dataset */ + /* (Which means that we've got a list of the regions in the fastest */ + /* changing dimension and should input those regions) */ + if((dim+2)==iter_info->space->extent.u.simple.rank) { + + /* Iterate over data from regions */ + for(i=0; imem_offset[iter_info->space->extent.u.simple.rank-1]=regions[i].start; + + /* Get the offset in the memory buffer */ + offset=H5V_array_offset(iter_info->space->extent.u.simple.rank+1, + iter_info->mem_size,iter_info->mem_offset); + tmp_buf=((char *)iter_info->src+offset); + + /* Iterate over each element in the current region */ + for(j=regions[i].start; j<=regions[i].end && user_ret==0; j++) { + /* Call the user's function */ + user_ret=(*(iter_info->op))(tmp_buf,iter_info->dt,iter_info->space->extent.u.simple.rank,iter_info->mem_offset,iter_info->op_data); + + /* Subtract the element from the selected region (not implemented yet) */ + + /* Advance the pointer in the buffer */ + tmp_buf=((char *)tmp_buf+iter_info->elem_size); + } /* end for */ + + /* Decrement the iterator count */ + iter_info->iter->hyp.elmt_left-=((regions[i].end-regions[i].start)+1); + } /* end for */ + + /* Set the next position to start at */ + iter_info->iter->hyp.pos[dim+1]=(-1); + } else { /* recurse on each region to next dimension down */ + + /* Increment the dimension we are working with */ + dim++; + + /* Step through each region in this dimension */ + for(i=0; iiter->hyp.pos[dim]!=j) + iter_info->iter->hyp.pos[dim+1]=(-1); + + /* Set the correct position we are working on */ + iter_info->iter->hyp.pos[dim]=j; + + /* Go get the regions in the next lower dimension */ + user_ret=H5S_hyper_select_iterate_mem(dim, iter_info); + } /* end for */ + } /* end for */ + } /* end else */ + + /* Release the temporary buffer */ + H5TB_release_buf(reg_id); + } /* end if */ + + FUNC_LEAVE (user_ret); +} /* H5S_hyper_select_iterate_mem() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_select_iterate + PURPOSE + Iterate over a hyperslab selection, calling a user's function for each + element. + USAGE + herr_t H5S_hyper_select_iterate(buf, type_id, space, operator, operator_data) + void *buf; IN/OUT: Buffer containing elements to iterate over + hid_t type_id; IN: Datatype ID of BUF array. + H5S_t *space; IN: Dataspace object containing selection to iterate over + H5D_operator_t operator; IN: Function pointer to the routine to be + called for each element in BUF iterated over. + void *operator_data; IN/OUT: Pointer to any user-defined data + associated with the operation. + RETURNS + Returns the return value of the last operator if it was non-zero, or zero + if all elements were processed. Otherwise returns a negative value. + DESCRIPTION + Iterates over the selected elements in a memory buffer, calling the user's + callback function for each element. The selection in the dataspace is + modified so that any elements already iterated over are removed from the + selection if the iteration is interrupted (by the H5D_operator_t function + returning non-zero) in the "middle" of the iteration and may be re-started + by the user where it left off. + + NOTE: Until "subtracting" elements from a selection is implemented, + the selection is not modified. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator, + void *operator_data) +{ + H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ + H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ + H5S_hyper_iter_info_t iter_info; /* Block of parameters to pass into recursive calls */ + H5S_sel_iter_t iter; /* selection iteration info*/ + size_t min_elem_out=1; /* Minimum # of elements to output*/ + intn i; /*counters */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_hyper_select_iterate, FAIL); + + assert(buf); + assert(space); + assert(operator); + assert(H5I_DATATYPE != H5I_get_type(type_id)); + + /* Initialize these before any errors can occur */ + HDmemset(&iter,0,sizeof(H5S_sel_iter_t)); + + /* Initialize the selection iterator */ + if (H5S_hyper_init(NULL, space, &iter, &min_elem_out)<0) { + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to initialize selection information"); + } + + /* Allocate space for the low & high bound arrays */ + lo_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *)); + hi_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *)); + + /* + * Initialize to correct order to walk through arrays. (When another + * iteration order besides the default 'C' order is chosen, this is the + * correct place to change the order of the array iterations) + */ + for(i=0; iextent.u.simple.rank; i++) { + lo_bounds[i]=space->select.sel_info.hslab.hyper_lst->lo_bounds[i]; + hi_bounds[i]=space->select.sel_info.hslab.hyper_lst->hi_bounds[i]; + } /* end for */ + + /* Initialize parameter block for recursive calls */ + iter_info.dt=type_id; + iter_info.elem_size=H5Tget_size(type_id); + iter_info.space=space; + iter_info.iter=&iter; + iter_info.src=buf; + iter_info.lo_bounds=lo_bounds; + iter_info.hi_bounds=hi_bounds; + /* Set up the size of the memory space */ + HDmemcpy(iter_info.mem_size, space->extent.u.simple.size, space->extent.u.simple.rank*sizeof(hsize_t)); + iter_info.mem_size[space->extent.u.simple.rank]=iter_info.elem_size; + /* Copy the location of the region in the file */ + HDmemcpy(iter_info.mem_offset, iter.hyp.pos,(space->extent.u.simple.rank*sizeof(hssize_t))); + iter_info.mem_offset[space->extent.u.simple.rank]=0; + iter_info.op=operator; + iter_info.op_data=operator_data; + + /* Recursively input the hyperslabs currently defined */ + /* starting with the slowest changing dimension */ + ret_value=H5S_hyper_select_iterate_mem(-1,&iter_info); + + /* Release the memory we allocated */ + H5MM_xfree(lo_bounds); + H5MM_xfree(hi_bounds); + +done: + FUNC_LEAVE (ret_value); +} /* H5S_hyper_select_iterate() */ diff --git a/src/H5Snone.c b/src/H5Snone.c index f0971cf..508be0e 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -95,3 +96,44 @@ H5S_none_select_deserialize (H5S_t *space, const uint8_t UNUSED *buf) done: FUNC_LEAVE (ret_value); } /* H5S_none_select_deserialize() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_none_select_iterate + PURPOSE + Iterate over a none selection, calling a user's function for each + element. (i.e. the user's function is not called because there are + zero elements selected) + USAGE + herr_t H5S_none_select_iterate(buf, type_id, space, operator, operator_data) + void *buf; IN/OUT: Buffer containing elements to iterate over + hid_t type_id; IN: Datatype ID of BUF array. + H5S_t *space; IN: Dataspace object containing selection to iterate over + H5D_operator_t operator; IN: Function pointer to the routine to be + called for each element in BUF iterated over. + void *operator_data; IN/OUT: Pointer to any user-defined data + associated with the operation. + RETURNS + Returns success (0). + DESCRIPTION + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_none_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator, + void UNUSED *operator_data) +{ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER (H5S_none_select_iterate, FAIL); + + assert(buf); + assert(space); + assert(operator); + assert(H5I_DATATYPE != H5I_get_type(type_id)); + + FUNC_LEAVE (ret_value); +} /* H5S_hyper_select_iterate() */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index ac3d3e1..583aab7 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -1107,4 +1108,78 @@ H5S_point_select_contiguous(const H5S_t *space) ret_value=FALSE; FUNC_LEAVE (ret_value); -} /* H5S_select_contiguous() */ +} /* H5S_point_select_contiguous() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_point_select_iterate + PURPOSE + Iterate over a point selection, calling a user's function for each + element. + USAGE + herr_t H5S_point_select_iterate(buf, type_id, space, operator, operator_data) + void *buf; IN/OUT: Buffer containing elements to iterate over + hid_t type_id; IN: Datatype ID of BUF array. + H5S_t *space; IN: Dataspace object containing selection to iterate over + H5D_operator_t operator; IN: Function pointer to the routine to be + called for each element in BUF iterated over. + void *operator_data; IN/OUT: Pointer to any user-defined data + associated with the operation. + RETURNS + Returns the return value of the last operator if it was non-zero, or zero + if all elements were processed. Otherwise returns a negative value. + DESCRIPTION + Iterates over the selected elements in a memory buffer, calling the user's + callback function for each element. The selection in the dataspace is + modified so that any elements already iterated over are removed from the + selection if the iteration is interrupted (by the H5D_operator_t function + returning non-zero) in the "middle" of the iteration and may be re-started + by the user where it left off. + + NOTE: Until "subtracting" elements from a selection is implemented, + the selection is not modified. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator, + void *operator_data) +{ + hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */ + hsize_t offset; /* offset of region in buffer */ + void *tmp_buf; /* temporary location of the element in the buffer */ + H5S_pnt_node_t *node; /* Point node */ + intn rank; /* Dataspace rank */ + herr_t ret_value=0; /* return value */ + + FUNC_ENTER (H5S_point_select_iterate, 0); + + assert(buf); + assert(space); + assert(operator); + assert(H5I_DATATYPE != H5I_get_type(type_id)); + + /* Get the dataspace extent rank */ + rank=space->extent.u.simple.rank; + + /* Set up the size of the memory space */ + HDmemcpy(mem_size, space->extent.u.simple.size, rank*sizeof(hsize_t)); + mem_size[rank]=H5Tget_size(type_id); + + /* Iterate through the node, checking the bounds on each element */ + node=space->select.sel_info.pnt_lst->head; + while(node!=NULL && ret_value==0) { + /* Get the offset in the memory buffer */ + offset=H5V_array_offset(rank+1,mem_size,node->pnt); + tmp_buf=((char *)buf+offset); + + ret_value=(*operator)(tmp_buf,type_id,rank,node->pnt,operator_data); + + node=node->next; + } /* end while */ + + FUNC_LEAVE (ret_value); +} /* H5S_point_select_iterate() */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 2dba002..4c1894f 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -342,6 +342,8 @@ __DLL__ hssize_t H5S_select_serial_size(const H5S_t *space); __DLL__ herr_t H5S_select_serialize(const H5S_t *space, uint8_t *buf); __DLL__ herr_t H5S_select_deserialize(H5S_t *space, const uint8_t *buf); __DLL__ htri_t H5S_select_contiguous(const H5S_t *space); +__DLL__ herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, + H5D_operator_t operator, void *operator_data); /* Point select functions */ __DLL__ herr_t H5S_point_add(H5S_t *space, size_t num_elemn, @@ -355,6 +357,8 @@ __DLL__ herr_t H5S_point_select_serialize(const H5S_t *space, uint8_t *buf); __DLL__ herr_t H5S_point_select_deserialize(H5S_t *space, const uint8_t *buf); __DLL__ herr_t H5S_point_bounds(H5S_t *space, hsize_t *start, hsize_t *end); __DLL__ htri_t H5S_point_select_contiguous(const H5S_t *space); +__DLL__ herr_t H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, + H5D_operator_t operator, void *operator_data); /* "All" select functions */ __DLL__ herr_t H5S_all_release(H5S_t *space); @@ -374,6 +378,8 @@ __DLL__ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, const H5S_t *file_space, const H5S_t *mem_space, const H5F_xfer_t *xfer_parms, const void *buf, hbool_t *must_convert/*out*/); +__DLL__ herr_t H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, + H5D_operator_t operator, void *operator_data); /* Hyperslab selection functions */ __DLL__ herr_t H5S_hyper_add(H5S_t *space, const hssize_t *start, @@ -396,10 +402,14 @@ __DLL__ herr_t H5S_hyper_select_serialize(const H5S_t *space, uint8_t *buf); __DLL__ herr_t H5S_hyper_select_deserialize(H5S_t *space, const uint8_t *buf); __DLL__ herr_t H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end); __DLL__ htri_t H5S_hyper_select_contiguous(const H5S_t *space); +__DLL__ herr_t H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, + H5D_operator_t operator, void *operator_data); /* "None" selection functions */ __DLL__ herr_t H5S_none_select_serialize(const H5S_t *space, uint8_t *buf); __DLL__ herr_t H5S_none_select_deserialize(H5S_t *space, const uint8_t *buf); +__DLL__ herr_t H5S_none_select_iterate(void *buf, hid_t type_id, H5S_t *space, + H5D_operator_t operator, void *operator_data); #ifdef HAVE_PARALLEL /* MPI-IO function to read directly from app buffer to file rky980813 */ diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 669cb94..1379617 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -1683,3 +1683,72 @@ H5S_select_contiguous(const H5S_t *space) FUNC_LEAVE (ret_value); } /* H5S_select_contiguous() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_iterate + PURPOSE + Iterate over the selected elements in a memory buffer. + USAGE + herr_t H5S_select_iterate(buf, type_id, space, operator, operator_data) + void *buf; IN/OUT: Buffer containing elements to iterate over + hid_t type_id; IN: Datatype ID of BUF array. + H5S_t *space; IN: Dataspace object containing selection to iterate over + H5D_operator_t operator; IN: Function pointer to the routine to be + called for each element in BUF iterated over. + void *operator_data; IN/OUT: Pointer to any user-defined data + associated with the operation. + RETURNS + Returns the return value of the last operator if it was non-zero, or zero + if all elements were processed. Otherwise returns a negative value. + DESCRIPTION + Iterates over the selected elements in a memory buffer, calling the user's + callback function for each element. The selection in the dataspace is + modified so that any elements already iterated over are removed from the + selection if the iteration is interrupted (by the H5D_operator_t function + returning non-zero) in the "middle" of the iteration and may be re-started + by the user where it left off. + + NOTE: Until "subtracting" elements from a selection is implemented, + the selection is not modified. +--------------------------------------------------------------------------*/ +herr_t +H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator, + void *operator_data) +{ + herr_t ret_value=FAIL; + + FUNC_ENTER(H5S_select_iterate, FAIL); + + /* Check args */ + assert(buf); + assert(space); + assert(operator); + assert(H5I_DATATYPE != H5I_get_type(type_id)); + + switch(space->select.type) { + case H5S_SEL_POINTS: /* Sequence of points selected */ + ret_value=H5S_point_select_iterate(buf,type_id,space,operator,operator_data); + break; + + case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ + ret_value=H5S_hyper_select_iterate(buf,type_id,space,operator,operator_data); + break; + + case H5S_SEL_ALL: /* Entire extent selected */ + ret_value=H5S_all_select_iterate(buf,type_id,space,operator,operator_data); + break; + + case H5S_SEL_NONE: /* Nothing selected */ + ret_value=H5S_none_select_iterate(buf,type_id,space,operator,operator_data); + break; + + case H5S_SEL_ERROR: + case H5S_SEL_N: + break; + } + + FUNC_LEAVE(SUCCEED); +} /* end H5S_select_iterate() */ + diff --git a/src/H5V.c b/src/H5V.c index 15cf867..dc61b22 100644 --- a/src/H5V.c +++ b/src/H5V.c @@ -679,3 +679,49 @@ H5V_array_fill(void *_dst, const void *src, size_t size, size_t count) FUNC_LEAVE(SUCCEED); } /* H5V_array_fill() */ + + +/*------------------------------------------------------------------------- + * Function: H5V_array_offset + * + * 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. + * + * Failure: abort() -- should never fail + * + * Programmer: Quincey Koziol + * Tuesday, June 22, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hsize_t +H5V_array_offset(intn n, const hsize_t *total_size, const hssize_t *offset) +{ + hsize_t skip; /*starting point byte offset */ + hsize_t acc; /*accumulator */ + int i; /*counter */ + + FUNC_ENTER(H5V_array_stride, (HDabort(), 0)); + + assert(n >= 0 && n <= H5V_HYPER_NDIMS); + assert(total_size); + assert(offset); + + /* others */ + for (i=n-1, acc=1, skip=0; i>=0; --i) { + skip += acc * offset[i]; + acc *= total_size[i]; + } + + FUNC_LEAVE(skip); +} + diff --git a/src/H5Vprivate.h b/src/H5Vprivate.h index fef02dc..c471b6a 100644 --- a/src/H5Vprivate.h +++ b/src/H5Vprivate.h @@ -72,6 +72,8 @@ __DLL__ herr_t H5V_stride_optimize2(intn *np, hsize_t *elmt_size, hssize_t *stride2); __DLL__ herr_t H5V_array_fill(void *_dst, const void *src, size_t size, size_t count); +__DLL__ hsize_t H5V_array_offset(intn n, const hsize_t *total_size, + const hssize_t *offset); /*------------------------------------------------------------------------- -- cgit v0.12