diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 1999-04-23 21:11:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 1999-04-23 21:11:27 (GMT) |
commit | acbad9533eb3bba58a9c33c27a7435ae33c72e36 (patch) | |
tree | 221d4eabf44876a065c406f7355936452164656d | |
parent | daf4ab55869c71b69a4764bd5947ba230d5da0da (diff) | |
download | hdf5-acbad9533eb3bba58a9c33c27a7435ae33c72e36.zip hdf5-acbad9533eb3bba58a9c33c27a7435ae33c72e36.tar.gz hdf5-acbad9533eb3bba58a9c33c27a7435ae33c72e36.tar.bz2 |
[svn-r1210] Changed parameters for function calls which figure out the buffer size for
H5Dread/H5Dwrite to use to allow the I/O calls to break up a user's buffer into
pieces that are at least as large as the sequence of bytes being written in the
fastest changing dimension.
Also fixed a hard-to-find bug in the hyperslab I/O routines which could cause
data to be corrupted when writing out fields to compound datatype data with
background preservation turned on and hyperslabs which were large enough to
require two I/O passes on a hyperslab block. A pretty obscure situation, but
it would be worthwhile for users to upgrade to this code in order to be certain
that correct data is being written.
-rw-r--r-- | src/H5Sall.c | 25 | ||||
-rw-r--r-- | src/H5Shyper.c | 52 | ||||
-rw-r--r-- | src/H5Spoint.c | 4 | ||||
-rw-r--r-- | src/H5Sprivate.h | 12 |
4 files changed, 56 insertions, 37 deletions
diff --git a/src/H5Sall.c b/src/H5Sall.c index 6ebd241..4deb877 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -19,7 +19,7 @@ static intn interface_initialize_g = 0; static herr_t H5S_all_init (const struct H5O_layout_t *layout, - const H5S_t *space, H5S_sel_iter_t *iter); + const H5S_t *space, H5S_sel_iter_t *iter, size_t *min_elem_out); static size_t H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *iter, size_t max); static size_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, @@ -76,8 +76,13 @@ const H5S_mconv_t H5S_ALL_MCONV[1] = {{ */ static herr_t H5S_all_init (const struct H5O_layout_t UNUSED *layout, - const H5S_t *space, H5S_sel_iter_t *sel_iter) + const H5S_t *space, H5S_sel_iter_t *sel_iter, size_t *min_elem_out) { + hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + intn space_ndims; /*dimensionality of space*/ + hsize_t acc; /*accumulator */ + intn i; /*counters */ + FUNC_ENTER (H5S_all_init, FAIL); /* Check args */ @@ -90,6 +95,19 @@ H5S_all_init (const struct H5O_layout_t UNUSED *layout, /* Start at the upper left location */ sel_iter->all.offset=0; + + /* Get the dimensions of the space, to set the min. # of elements */ + if ((space_ndims=H5S_get_simple_extent_dims (space, hsize, NULL))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to retrieve hyperslab parameters"); + } + + /* Adjust the slowest varying dimension to account for strip mining */ + for (i=1, acc=1; i<space_ndims; i++) + acc *= hsize[i]; + + /* Set the minimum # of elements to output */ + *min_elem_out=acc; FUNC_LEAVE (SUCCEED); } @@ -471,8 +489,9 @@ H5S_all_mscat (const void *_tconv_buf, size_t elmt_size, } /* Adjust the slowest varying dimension to take care of strip mining */ - for (i=1, acc=1; i<space_ndims; i++) + for (i=1, acc=1; i<space_ndims; i++) { acc *= hsize[i]; + } assert (0==mem_iter->all.offset % acc); assert (0==nelmts % acc); mem_offset[0] += mem_iter->all.offset / acc; diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 2fba497..3e4df79 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -51,7 +51,7 @@ static size_t H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info); static size_t H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info); static herr_t H5S_hyper_init (const struct H5O_layout_t *layout, - const H5S_t *space, H5S_sel_iter_t *iter); + 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, size_t max); static size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, @@ -114,7 +114,7 @@ static const hssize_t zero[H5O_LAYOUT_NDIMS]={0}; /* Array of zeros */ */ static herr_t H5S_hyper_init (const struct H5O_layout_t UNUSED *layout, - const H5S_t *space, H5S_sel_iter_t *sel_iter) + const H5S_t *space, H5S_sel_iter_t *sel_iter, size_t *min_elem_out) { FUNC_ENTER (H5S_hyper_init, FAIL); @@ -160,7 +160,7 @@ H5S_hyper_favail (const H5S_t UNUSED *space, assert (sel_iter); #ifdef QAK - printf("%s: max=%d\n",FUNC,(int)max); + printf("%s: max=%u\n",FUNC,(unsigned)max); #endif /* QAK */ FUNC_LEAVE (MIN(sel_iter->hyp.elmt_left,max)); } /* H5S_hyper_favail() */ @@ -464,9 +464,9 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, /* keep information for writing block later? */ } /* end else */ - /* Set up parameters for accessing block */ - node->cinfo.left=node->cinfo.size; - node->cinfo.pos=node->cinfo.block; + /* Set up parameters for accessing block (starting the read and write information at the same point) */ + node->cinfo.wleft=node->cinfo.rleft=node->cinfo.size; + node->cinfo.wpos=node->cinfo.rpos=node->cinfo.block; /* Set cached flag */ node->cinfo.cached=1; @@ -502,18 +502,18 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in permutations from the standard 'C' ordering! */ HDmemcpy(fhyper_info->dst, - node->cinfo.pos, + node->cinfo.rpos, (size_t)(region_size*fhyper_info->elmt_size)); /* * Decrement the number of elements left in block to read & move the * offset */ - node->cinfo.pos+=region_size*fhyper_info->elmt_size; - node->cinfo.left-=region_size; + node->cinfo.rpos+=region_size*fhyper_info->elmt_size; + node->cinfo.rleft-=region_size; /* If we've read in all the elements from the block, throw it away */ - if(node->cinfo.left==0) { + if(node->cinfo.rleft==0 && (node->cinfo.wleft==0 || node->cinfo.wleft==node->cinfo.size)) { /* Release the temporary buffer */ H5TB_release_buf(node->cinfo.block_id); @@ -557,7 +557,7 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, !! NOTE !! This will need to be changed for different dimension permutations from the standard 'C' ordering! */ - HDmemcpy(node->cinfo.pos, + HDmemcpy(node->cinfo.wpos, fhyper_info->src, (size_t)(region_size*fhyper_info->elmt_size)); @@ -565,11 +565,11 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, * Decrement the number of elements left in block to read & move the * offset */ - node->cinfo.pos+=region_size*fhyper_info->elmt_size; - node->cinfo.left-=region_size; + node->cinfo.wpos+=region_size*fhyper_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.left==0) { + 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, @@ -697,7 +697,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) } /* end if */ #ifdef QAK - printf("%s: check 2.2, i=%d\n",FUNC,(int)i); + printf("%s: check 2.2, i=%d\n",FUNC,(int)i); #endif /* QAK */ /* Fill in the region specific parts of the I/O request */ hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; @@ -715,10 +715,9 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) "read error"); } #ifdef QAK - printf("%s: check 2.3, region #%d\n",FUNC,(int)i); - for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++) - printf("%s: %d - pos=%d\n", - FUNC,j,(int)fhyper_info->iter->hyp.pos[j]); + printf("%s: check 2.3, region #%d\n",FUNC,(int)i); + for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++) + printf("%s: %d - pos=%d\n", FUNC,j,(int)fhyper_info->iter->hyp.pos[j]); #endif /* QAK */ } /* end else */ @@ -929,6 +928,11 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) 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); + for(i=0; i<num_regions; i++) + printf("%s: check 2.1, region #%d: start=%d, end=%d\n", + FUNC,i,(int)regions[i].start,(int)regions[i].end); #endif /* QAK */ /* Check if this is the second to last dimension in dataset */ @@ -1875,9 +1879,6 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) size_t elem_count; /* Number of elements in hyperslab selection */ intn i; /* Counters */ herr_t ret_value=SUCCEED; -#ifdef QAK - extern int qak_debug; -#endif /* QAK */ FUNC_ENTER (H5S_hyper_add, FAIL); @@ -1886,9 +1887,6 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) assert (start); assert (end); -#ifdef QAK - qak_debug=1; -#endif /* QAK */ #ifdef QAK printf("%s: check 1.0\n",FUNC); @@ -1918,9 +1916,9 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end) /* Initialize caching parameters */ slab->cinfo.cached=0; slab->cinfo.size=elem_count; - slab->cinfo.left=0; + slab->cinfo.wleft=slab->cinfo.rleft=0; slab->cinfo.block_id=(-1); - slab->cinfo.block=slab->cinfo.pos=NULL; + slab->cinfo.block=slab->cinfo.wpos=slab->cinfo.rpos=NULL; #ifdef QAK printf("%s: check 3.0, lo_bounds=%p, hi_bounds=%p\n", diff --git a/src/H5Spoint.c b/src/H5Spoint.c index a58461b..7d8672a 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -20,7 +20,7 @@ static intn interface_initialize_g = 0; static herr_t H5S_point_init (const struct H5O_layout_t *layout, - const H5S_t *space, H5S_sel_iter_t *iter); + const H5S_t *space, H5S_sel_iter_t *iter, size_t *min_elem_out); static size_t H5S_point_favail (const H5S_t *space, const H5S_sel_iter_t *iter, size_t max); static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, @@ -83,7 +83,7 @@ const H5S_mconv_t H5S_POINT_MCONV[1] = {{ */ static herr_t H5S_point_init (const struct H5O_layout_t UNUSED *layout, - const H5S_t *space, H5S_sel_iter_t *sel_iter) + const H5S_t *space, H5S_sel_iter_t *sel_iter, size_t *min_elem_out) { FUNC_ENTER (H5S_point_init, FAIL); diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index ff0a021..b01d9dc 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -78,11 +78,13 @@ typedef struct H5S_hyper_node_tag { hssize_t *end; /* Pointer to a corner of a hyperslab furthest from the origin */ struct { uintn cached; /* Flag to indicate that the block is cached (during I/O only) */ - size_t size; /* Size of cached block (in elements) */ - uintn left; /* Elements left to access in block */ + size_t size; /* Size of cached block (in elements) */ + uintn rleft; /* Read elements left to access in block */ + uintn wleft; /* Write elements left to access in block */ hid_t block_id; /* Temporary buffer ID */ uint8_t *block; /* Pointer into temporary buffer for cache */ - uint8_t *pos; /* Pointer to current location within block */ + uint8_t *rpos; /* Pointer to current read location within block */ + uint8_t *wpos; /* Pointer to current write location within block */ } cinfo; struct H5S_hyper_node_tag *next; /* pointer to next hyperslab in list */ } H5S_hyper_node_t; @@ -182,7 +184,7 @@ typedef struct H5S_fconv_t { /* Initialize file element numbering information */ herr_t (*init)(const struct H5O_layout_t *layout, const H5S_t *space, - H5S_sel_iter_t *iter); + H5S_sel_iter_t *iter, size_t *min_elem_out); /* Determine optimal number of elements to transfer */ size_t (*avail)(const H5S_t *file_space, const H5S_sel_iter_t *file_iter, @@ -214,7 +216,7 @@ typedef struct H5S_mconv_t { /* Initialize memory element numbering information */ herr_t (*init)(const struct H5O_layout_t *layout, const H5S_t *space, - H5S_sel_iter_t *iter); + H5S_sel_iter_t *iter, size_t *min_elem_out); /* Gather elements from app buffer to type conversion buffer */ size_t (*gath)(const void *buf, size_t elmt_size, |