summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1999-04-23 21:11:27 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1999-04-23 21:11:27 (GMT)
commitacbad9533eb3bba58a9c33c27a7435ae33c72e36 (patch)
tree221d4eabf44876a065c406f7355936452164656d /src
parentdaf4ab55869c71b69a4764bd5947ba230d5da0da (diff)
downloadhdf5-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.
Diffstat (limited to 'src')
-rw-r--r--src/H5Sall.c25
-rw-r--r--src/H5Shyper.c52
-rw-r--r--src/H5Spoint.c4
-rw-r--r--src/H5Sprivate.h12
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,