diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2002-04-02 20:51:41 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2002-04-02 20:51:41 (GMT) |
commit | d2232a345f36988f4a60034d63ddca25c476fc08 (patch) | |
tree | 2ba460735cb162b5ee94ae98f0d46873488fa454 /src | |
parent | c1e44699f0460cd5a675a71dc85296740f07063a (diff) | |
download | hdf5-d2232a345f36988f4a60034d63ddca25c476fc08.zip hdf5-d2232a345f36988f4a60034d63ddca25c476fc08.tar.gz hdf5-d2232a345f36988f4a60034d63ddca25c476fc08.tar.bz2 |
[svn-r5130] Purpose:
Bug Fix & Feature
Description:
The selection offset was being ignored for optimized hyperslab selection
I/O operations.
Additionally, I've found that the restrictions on optimized selection
I/O operations were too strict and found a way to allow more hyperslabs
to use the optimized I/O routines.
Solution:
Incorporate the selection offset into the selection location when performing
optimized I/O operations.
Allow optimized I/O on any single hyperslab selection and also allow
hyperslab operations on chunked datasets.
Platforms tested:
FreeBSD 4.5 (sleipnir)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Distore.c | 36 | ||||
-rw-r--r-- | src/H5Dseq.c | 46 | ||||
-rw-r--r-- | src/H5Farray.c | 53 | ||||
-rw-r--r-- | src/H5Fistore.c | 36 | ||||
-rw-r--r-- | src/H5Fpkg.h | 4 | ||||
-rw-r--r-- | src/H5Fseq.c | 46 | ||||
-rw-r--r-- | src/H5S.c | 8 | ||||
-rw-r--r-- | src/H5Sall.c | 537 | ||||
-rw-r--r-- | src/H5Shyper.c | 78 | ||||
-rw-r--r-- | src/H5Spkg.h | 2 | ||||
-rw-r--r-- | src/H5Spoint.c | 38 | ||||
-rw-r--r-- | src/H5Sprivate.h | 1 | ||||
-rw-r--r-- | src/H5Sselect.c | 53 |
13 files changed, 448 insertions, 490 deletions
diff --git a/src/H5Distore.c b/src/H5Distore.c index 1a9a3d6..c12a98e 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1695,15 +1695,17 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, * Robb Matzke, 1999-08-02 * The data transfer property list is passed as an object ID * since that's how the virtual file layer wants it. + * + * Quincey Koziol, 2002-04-02 + * Enable hyperslab I/O into memory buffer *------------------------------------------------------------------------- */ herr_t H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, + const hsize_t size_m[], const hssize_t offset_m[], const hssize_t offset_f[], const hsize_t size[], void *buf) { - hssize_t offset_m[H5O_LAYOUT_NDIMS]; - hsize_t size_m[H5O_LAYOUT_NDIMS]; hsize_t idx_cur[H5O_LAYOUT_NDIMS]; hsize_t idx_min[H5O_LAYOUT_NDIMS]; hsize_t idx_max[H5O_LAYOUT_NDIMS]; @@ -1726,19 +1728,15 @@ H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, assert(layout && H5D_CHUNKED==layout->type); assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); assert(H5F_addr_defined(layout->addr)); + assert(size_m); + assert(offset_m); assert(offset_f); assert(size); assert(buf); - /* - * For now, a hyperslab of the file must be read into an array in - * memory.We do not yet support reading into a hyperslab of memory. - */ - for (u=0, chunk_size=1; u<layout->ndims; u++) { - offset_m[u] = 0; - size_m[u] = size[u]; + /* Compute chunk size */ + for (u=0, chunk_size=1; u<layout->ndims; u++) chunk_size *= layout->dim[u]; - } /* end for */ #ifndef NDEBUG for (u=0; u<layout->ndims; u++) { @@ -1874,16 +1872,18 @@ H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, * Robb Matzke, 1999-08-02 * The data transfer property list is passed as an object ID * since that's how the virtual file layer wants it. + * + * Quincey Koziol, 2002-04-02 + * Enable hyperslab I/O into memory buffer *------------------------------------------------------------------------- */ herr_t H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, + const hsize_t size_m[], const hssize_t offset_m[], const hssize_t offset_f[], const hsize_t size[], const void *buf) { - hssize_t offset_m[H5O_LAYOUT_NDIMS]; - hsize_t size_m[H5O_LAYOUT_NDIMS]; int i, carry; unsigned u; hsize_t idx_cur[H5O_LAYOUT_NDIMS]; @@ -1905,19 +1905,15 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, assert(layout && H5D_CHUNKED==layout->type); assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); assert(H5F_addr_defined(layout->addr)); + assert(size_m); + assert(offset_m); assert(offset_f); assert(size); assert(buf); - /* - * For now the source must not be a hyperslab. It must be an entire - * memory buffer. - */ - for (u=0, chunk_size=1; u<layout->ndims; u++) { - offset_m[u] = 0; - size_m[u] = size[u]; + /* Compute chunk size */ + for (u=0, chunk_size=1; u<layout->ndims; u++) chunk_size *= layout->dim[u]; - } /* end for */ #ifndef NDEBUG for (u=0; u<layout->ndims; u++) { diff --git a/src/H5Dseq.c b/src/H5Dseq.c index 0fec03d..20c71a7 100644 --- a/src/H5Dseq.c +++ b/src/H5Dseq.c @@ -152,6 +152,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t file_offset; /* Offset in dataset */ hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */ @@ -283,10 +284,13 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); /* Build the array of cumulative hyperslab sizes */ + /* (And set the memory offset to zero) */ for(acc=1, i=(ndims-1); i>=0; i--) { + mem_offset[i]=0; down_size[i]=acc; acc*=dset_dims[i]; } /* end for */ + mem_offset[ndims]=0; /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ for(v=0; v<nseq; v++) { @@ -336,8 +340,9 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -396,8 +401,8 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read the full hyperslab in */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -443,8 +448,9 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, + fill, hslab_size, mem_offset, coords, + hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -478,8 +484,9 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -538,6 +545,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t file_offset; /* Offset in dataset */ hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */ @@ -671,10 +679,13 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); /* Build the array of cumulative hyperslab sizes */ + /* (And set the memory offset to zero) */ for(acc=1, i=(ndims-1); i>=0; i--) { + mem_offset[i]=0; down_size[i]=acc; acc*=dset_dims[i]; } /* end for */ + mem_offset[ndims]=0; /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ for(v=0; v<nseq; v++) { @@ -724,8 +735,9 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write out the partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset,coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -784,8 +796,8 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write the full hyperslab in */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -831,8 +843,9 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write out the partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, + fill, hslab_size, mem_offset, coords, + hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -866,8 +879,9 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write out the final partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } diff --git a/src/H5Farray.c b/src/H5Farray.c index 6b4155c..58d8558 100644 --- a/src/H5Farray.c +++ b/src/H5Farray.c @@ -352,29 +352,20 @@ H5F_arr_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, case H5D_CHUNKED: /* - * This method is unable to access external raw data files or to copy - * into a proper hyperslab. + * This method is unable to access external raw data files */ - if (efl && efl->nused>0) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually exclusive"); - } - for (u=0; u<layout->ndims; u++) { - if (0!=mem_offset[u] || hslab_size[u]!=mem_size[u]) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "unable to copy into a proper hyperslab"); - } - } - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, file_offset, - hslab_size, buf)<0) { + if (efl && efl->nused>0) + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive"); + + /* Go get the data from the chunks */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, mem_size, + mem_offset, file_offset, hslab_size, buf)<0) HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } break; default: assert("not implemented yet" && 0); - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "unsupported storage layout"); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout"); } FUNC_LEAVE(SUCCEED); @@ -628,30 +619,20 @@ H5F_arr_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, case H5D_CHUNKED: /* - * This method is unable to access external raw data files or to copy - * from a proper hyperslab. + * This method is unable to access external raw data files */ - if (efl && efl->nused>0) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually exclusive"); - } - for (u=0; u<layout->ndims; u++) { - if (0!=mem_offset[u] || hslab_size[u]!=mem_size[u]) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "unable to copy from a proper hyperslab"); - } - } - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, file_offset, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "chunked write failed"); - } + if (efl && efl->nused>0) + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive"); + + /* Write the read to the chunks */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, mem_size, + mem_offset, file_offset, hslab_size, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); break; default: assert("not implemented yet" && 0); - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "unsupported storage layout"); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout"); } FUNC_LEAVE (SUCCEED); diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 1a9a3d6..c12a98e 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1695,15 +1695,17 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, * Robb Matzke, 1999-08-02 * The data transfer property list is passed as an object ID * since that's how the virtual file layer wants it. + * + * Quincey Koziol, 2002-04-02 + * Enable hyperslab I/O into memory buffer *------------------------------------------------------------------------- */ herr_t H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, + const hsize_t size_m[], const hssize_t offset_m[], const hssize_t offset_f[], const hsize_t size[], void *buf) { - hssize_t offset_m[H5O_LAYOUT_NDIMS]; - hsize_t size_m[H5O_LAYOUT_NDIMS]; hsize_t idx_cur[H5O_LAYOUT_NDIMS]; hsize_t idx_min[H5O_LAYOUT_NDIMS]; hsize_t idx_max[H5O_LAYOUT_NDIMS]; @@ -1726,19 +1728,15 @@ H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, assert(layout && H5D_CHUNKED==layout->type); assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); assert(H5F_addr_defined(layout->addr)); + assert(size_m); + assert(offset_m); assert(offset_f); assert(size); assert(buf); - /* - * For now, a hyperslab of the file must be read into an array in - * memory.We do not yet support reading into a hyperslab of memory. - */ - for (u=0, chunk_size=1; u<layout->ndims; u++) { - offset_m[u] = 0; - size_m[u] = size[u]; + /* Compute chunk size */ + for (u=0, chunk_size=1; u<layout->ndims; u++) chunk_size *= layout->dim[u]; - } /* end for */ #ifndef NDEBUG for (u=0; u<layout->ndims; u++) { @@ -1874,16 +1872,18 @@ H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, * Robb Matzke, 1999-08-02 * The data transfer property list is passed as an object ID * since that's how the virtual file layer wants it. + * + * Quincey Koziol, 2002-04-02 + * Enable hyperslab I/O into memory buffer *------------------------------------------------------------------------- */ herr_t H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, + const hsize_t size_m[], const hssize_t offset_m[], const hssize_t offset_f[], const hsize_t size[], const void *buf) { - hssize_t offset_m[H5O_LAYOUT_NDIMS]; - hsize_t size_m[H5O_LAYOUT_NDIMS]; int i, carry; unsigned u; hsize_t idx_cur[H5O_LAYOUT_NDIMS]; @@ -1905,19 +1905,15 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, assert(layout && H5D_CHUNKED==layout->type); assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); assert(H5F_addr_defined(layout->addr)); + assert(size_m); + assert(offset_m); assert(offset_f); assert(size); assert(buf); - /* - * For now the source must not be a hyperslab. It must be an entire - * memory buffer. - */ - for (u=0, chunk_size=1; u<layout->ndims; u++) { - offset_m[u] = 0; - size_m[u] = size[u]; + /* Compute chunk size */ + for (u=0, chunk_size=1; u<layout->ndims; u++) chunk_size *= layout->dim[u]; - } /* end for */ #ifndef NDEBUG for (u=0; u<layout->ndims; u++) { diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 822896d..5c81dfc 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -186,12 +186,14 @@ __DLL__ herr_t H5F_istore_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, - const hssize_t offset[], const hsize_t size[], + const hsize_t size_m[], const hssize_t offset_m[], + const hssize_t offset_f[], const hsize_t size[], void *buf/*out*/); __DLL__ herr_t H5F_istore_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, + const hsize_t size_m[], const hssize_t offset_m[], const hssize_t offset[], const hsize_t size[], const void *buf); __DLL__ herr_t H5F_istore_allocate (H5F_t *f, hid_t dxpl_id, diff --git a/src/H5Fseq.c b/src/H5Fseq.c index 0fec03d..20c71a7 100644 --- a/src/H5Fseq.c +++ b/src/H5Fseq.c @@ -152,6 +152,7 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t file_offset; /* Offset in dataset */ hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */ @@ -283,10 +284,13 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); /* Build the array of cumulative hyperslab sizes */ + /* (And set the memory offset to zero) */ for(acc=1, i=(ndims-1); i>=0; i--) { + mem_offset[i]=0; down_size[i]=acc; acc*=dset_dims[i]; } /* end for */ + mem_offset[ndims]=0; /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ for(v=0; v<nseq; v++) { @@ -336,8 +340,9 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -396,8 +401,8 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read the full hyperslab in */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -443,8 +448,9 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, + fill, hslab_size, mem_offset, coords, + hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -478,8 +484,9 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } @@ -538,6 +545,7 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t file_offset; /* Offset in dataset */ hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */ @@ -671,10 +679,13 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); /* Build the array of cumulative hyperslab sizes */ + /* (And set the memory offset to zero) */ for(acc=1, i=(ndims-1); i>=0; i--) { + mem_offset[i]=0; down_size[i]=acc; acc*=dset_dims[i]; } /* end for */ + mem_offset[ndims]=0; /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ for(v=0; v<nseq; v++) { @@ -724,8 +735,9 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write out the partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset,coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -784,8 +796,8 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write the full hyperslab in */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -831,8 +843,9 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write out the partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, + fill, hslab_size, mem_offset, coords, + hslab_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -866,8 +879,9 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ /* Write out the final partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, + hslab_size, mem_offset, coords, hslab_size, + buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } @@ -1525,8 +1525,8 @@ H5S_find (const H5S_t *mem_space, const H5S_t *file_space) /* * Initialize direct read/write functions */ - c1=H5S_select_contiguous(file_space); - c2=H5S_select_contiguous(mem_space); + c1=H5S_select_single(file_space); + c2=H5S_select_single(mem_space); if(c1==FAIL || c2==FAIL) HRETURN_ERROR(H5E_DATASPACE, H5E_BADRANGE, NULL, "invalid check for contiguous dataspace "); @@ -1563,8 +1563,8 @@ H5S_find (const H5S_t *mem_space, const H5S_t *file_space) /* * Initialize direct read/write functions */ - c1=H5S_select_contiguous(file_space); - c2=H5S_select_contiguous(mem_space); + c1=H5S_select_single(file_space); + c2=H5S_select_single(mem_space); if(c1==FAIL || c2==FAIL) HRETURN_ERROR(H5E_DATASPACE, H5E_BADRANGE, NULL, "invalid check for contiguous dataspace "); diff --git a/src/H5Sall.c b/src/H5Sall.c index 3c111f7..1692ff7 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -400,18 +400,13 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline, { H5S_hyper_span_t *file_span=NULL,*mem_span=NULL; /* Hyperslab span node */ char *buf=(char*)_buf; /* Get pointer to buffer */ - hsize_t mem_size,file_size; - hssize_t file_off,mem_off; - hssize_t count; /* Regular hyperslab count */ - hsize_t size[H5O_LAYOUT_NDIMS]; - hssize_t file_offset[H5O_LAYOUT_NDIMS]; - hssize_t mem_offset[H5O_LAYOUT_NDIMS]; - unsigned u; - unsigned small_contiguous=0, /* Flags for indicating contiguous hyperslabs */ - large_contiguous=0; - int i; - size_t down_size[H5O_LAYOUT_NDIMS]; - hsize_t acc; + hsize_t mem_elmts,file_elmts; /* Number of elements in each dimension of selection */ + hssize_t file_off,mem_off; /* Offset (in elements) of selection */ + hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Size of memory buffer */ + hsize_t size[H5O_LAYOUT_NDIMS]; /* Size of selection */ + hssize_t file_offset[H5O_LAYOUT_NDIMS]; /* Offset of selection in file */ + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* Offset of selection in memory */ + unsigned u; /* Index variable */ herr_t ret_value=SUCCEED; FUNC_ENTER(H5S_all_read, FAIL); @@ -428,204 +423,95 @@ printf("%s: check 1.0\n",FUNC); if (mem_space->extent.u.simple.rank!=file_space->extent.u.simple.rank) HGOTO_DONE(SUCCEED); - /* Check for a single hyperslab block defined in memory dataspace */ - if (mem_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(mem_space->select.sel_info.hslab.diminfo != NULL) { - /* Check each dimension */ - for(count=1,u=0; u<mem_space->extent.u.simple.rank; u++) - count*=mem_space->select.sel_info.hslab.diminfo[u].count; - /* If the regular hyperslab definition creates more than one hyperslab, fall through */ - if(count>1) - HGOTO_DONE(SUCCEED); - } /* end if */ - else { - /* Get the pointer to the hyperslab spans to check */ - mem_span=mem_space->select.sel_info.hslab.span_lst->head; - - /* Spin through the spans, checking for more than one span in each dimension */ - while(mem_span!=NULL) { - /* If there are more than one span in the dimension, we can't use this routine */ - if(mem_span->next!=NULL) - HGOTO_DONE(SUCCEED); - - /* Advance to the next span, if it's available */ - if(mem_span->down==NULL) - break; - else - mem_span=mem_span->down->head; - } /* end while */ - - /* Get the pointer to the hyperslab spans to use */ - mem_span=mem_space->select.sel_info.hslab.span_lst->head; - } /* end else */ - } /* end if */ - else - if(mem_space->select.type!=H5S_SEL_ALL) - HGOTO_DONE(SUCCEED); - - /* Check for a single hyperslab block defined in file dataspace */ - if (file_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(file_space->select.sel_info.hslab.diminfo != NULL) { - /* Check each dimension */ - for(count=1,u=0; u<file_space->extent.u.simple.rank; u++) - count*=file_space->select.sel_info.hslab.diminfo[u].count; - /* If the regular hyperslab definition creates more than one hyperslab, fall through */ - if(count>1) - HGOTO_DONE(SUCCEED); - } /* end if */ - else { - /* Get the pointer to the hyperslab spans to check */ - file_span=file_space->select.sel_info.hslab.span_lst->head; - - /* Spin through the spans, checking for more than one span in each dimension */ - while(file_span!=NULL) { - /* If there are more than one span in the dimension, we can't use this routine */ - if(file_span->next!=NULL) - HGOTO_DONE(SUCCEED); - - /* Advance to the next span, if it's available */ - if(file_span->down==NULL) - break; - else - file_span=file_span->down->head; - } /* end while */ - - /* Get the pointer to the hyperslab spans to use */ - file_span=file_space->select.sel_info.hslab.span_lst->head; - } /* end else */ - } /* end if */ - else - if(file_space->select.type!=H5S_SEL_ALL) - HGOTO_DONE(SUCCEED); - /* Get information about memory and file */ for (u=0; u<mem_space->extent.u.simple.rank; u++) { - if(mem_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(mem_space->select.sel_info.hslab.diminfo != NULL) { - mem_size=mem_space->select.sel_info.hslab.diminfo[u].block; - mem_off=mem_space->select.sel_info.hslab.diminfo[u].start; - } /* end if */ - else { - mem_size=(mem_span->high-mem_span->low)+1; - mem_off=mem_span->low; - mem_span=mem_span->down->head; - } /* end else */ - } /* end if */ - else { - mem_size=mem_space->extent.u.simple.size[u]; - mem_off=0; - } /* end else */ - - if(file_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(file_space->select.sel_info.hslab.diminfo != NULL) { - file_size=file_space->select.sel_info.hslab.diminfo[u].block; - file_off=file_space->select.sel_info.hslab.diminfo[u].start; - } /* end if */ - else { - file_size=(file_span->high-file_span->low)+1; - file_off=file_span->low; - file_span=file_span->down->head; - } /* end else */ - } /* end if */ - else { - file_size=file_space->extent.u.simple.size[u]; - file_off=0; - } /* end else */ - - if (mem_size!=file_size) + switch(mem_space->select.type) { + case H5S_SEL_HYPERSLABS: + /* Check for a "regular" hyperslab selection */ + if(mem_space->select.sel_info.hslab.diminfo != NULL) { + mem_elmts=mem_space->select.sel_info.hslab.diminfo[u].block; + mem_off=mem_space->select.sel_info.hslab.diminfo[u].start; + } /* end if */ + else { + mem_elmts=(mem_span->high-mem_span->low)+1; + mem_off=mem_span->low; + mem_span=mem_span->down->head; + } /* end else */ + mem_off+=mem_space->select.offset[u]; + break; + + case H5S_SEL_ALL: + mem_elmts=mem_space->extent.u.simple.size[u]; + mem_off=0; + break; + + case H5S_SEL_POINTS: + mem_elmts=1; + mem_off=mem_space->select.sel_info.pnt_lst->head->pnt[u] + +mem_space->select.offset[u]; + break; + + default: + assert(0 && "Invalid selection type!"); + } /* end switch */ + + switch(file_space->select.type) { + case H5S_SEL_HYPERSLABS: + /* Check for a "regular" hyperslab selection */ + if(file_space->select.sel_info.hslab.diminfo != NULL) { + file_elmts=file_space->select.sel_info.hslab.diminfo[u].block; + file_off=file_space->select.sel_info.hslab.diminfo[u].start; + } /* end if */ + else { + file_elmts=(file_span->high-file_span->low)+1; + file_off=file_span->low; + file_span=file_span->down->head; + } /* end else */ + file_off+=file_space->select.offset[u]; + break; + + case H5S_SEL_ALL: + file_elmts=file_space->extent.u.simple.size[u]; + file_off=0; + break; + + case H5S_SEL_POINTS: + file_elmts=1; + file_off=file_space->select.sel_info.pnt_lst->head->pnt[u] + +file_space->select.offset[u]; + break; + + default: + assert(0 && "Invalid selection type!"); + } /* end switch */ + + if (mem_elmts!=file_elmts) HGOTO_DONE(SUCCEED); - size[u] = file_size; + mem_size[u]=mem_space->extent.u.simple.size[u]; + size[u] = file_elmts; file_offset[u] = file_off; mem_offset[u] = mem_off; } + mem_size[u]=elmt_size; size[u] = elmt_size; file_offset[u] = 0; mem_offset[u] = 0; - /* Disallow reading a memory hyperslab in the "middle" of a dataset which */ - /* spans multiple rows in "interior" dimensions, but allow reading a */ - /* hyperslab which is in the "middle" of the fastest or slowest changing */ - /* dimension because a hyperslab which "fills" the interior dimensions is */ - /* contiguous in memory. i.e. these are allowed: */ - /* --------------------- --------------------- */ - /* | | | | */ - /* |*******************| | ********* | */ - /* |*******************| | | */ - /* | | | | */ - /* | | | | */ - /* --------------------- --------------------- */ - /* ("large" contiguous block) ("small" contiguous block) */ - /* But this is not: */ - /* --------------------- */ - /* | | */ - /* | ********* | */ - /* | ********* | */ - /* | | */ - /* | | */ - /* --------------------- */ - /* (not contiguous in memory) */ - if(mem_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "small" contiguous block */ - if(size[0]==1) { - small_contiguous=1; - /* size of block in all dimensions except the fastest must be '1' */ - for (u=0; u<(mem_space->extent.u.simple.rank-1); u++) { - if(size[u]>1) { - small_contiguous=0; - break; - } /* end if */ - } /* end for */ - } /* end if */ - /* Check for a "large" contiguous block */ - else { - large_contiguous=1; - /* size of block in all dimensions except the slowest must be the */ - /* full size of the dimension */ - for (u=1; u<mem_space->extent.u.simple.rank; u++) { - if(size[u]!=mem_space->extent.u.simple.size[u]) { - large_contiguous=0; - break; - } /* end if */ - } /* end for */ - } /* end else */ - - /* Check for contiguous block */ - if(small_contiguous || large_contiguous) { - /* Compute the "down sizes" for each dimension */ - for (acc=elmt_size, i=(mem_space->extent.u.simple.rank-1); i>=0; i--) { - H5_ASSIGN_OVERFLOW(down_size[i],acc,hsize_t,size_t); - acc*=mem_space->extent.u.simple.size[i]; - } /* end for */ - - /* Adjust the buffer offset and memory offsets by the proper amount */ - for (u=0; u<mem_space->extent.u.simple.rank; u++) { - buf+=mem_offset[u]*down_size[u]; - mem_offset[u]=0; - } /* end for */ - } /* end if */ - else { - /* Non-contiguous hyperslab block */ - HGOTO_DONE(SUCCEED); - } /* end else */ - } /* end if */ - #ifdef QAK printf("%s: check 2.0\n",FUNC); for (u=0; u<mem_space->extent.u.simple.rank; u++) printf("size[%u]=%lu\n",u,(unsigned long)size[u]); for (u=0; u<=mem_space->extent.u.simple.rank; u++) + printf("mem_size[%u]=%lu\n",u,(unsigned long)mem_size[u]); +for (u=0; u<=mem_space->extent.u.simple.rank; u++) printf("mem_offset[%u]=%lu\n",u,(unsigned long)mem_offset[u]); for (u=0; u<=mem_space->extent.u.simple.rank; u++) printf("file_offset[%u]=%lu\n",u,(unsigned long)file_offset[u]); #endif /* QAK */ /* Read data from the file */ if (H5F_arr_read(f, dxpl_id, layout, pline, fill, efl, size, - size, mem_offset, file_offset, buf/*out*/)<0) { + mem_size, mem_offset, file_offset, buf/*out*/)<0) { HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read data from the file"); } @@ -671,23 +557,21 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, { H5S_hyper_span_t *file_span=NULL,*mem_span=NULL; /* Hyperslab span node */ const char *buf=(const char*)_buf; /* Get pointer to buffer */ - hsize_t mem_size,file_size; - hssize_t file_off,mem_off; - hssize_t count; /* Regular hyperslab count */ - hsize_t size[H5O_LAYOUT_NDIMS]; - hssize_t file_offset[H5O_LAYOUT_NDIMS]; - hssize_t mem_offset[H5O_LAYOUT_NDIMS]; - unsigned u; - unsigned small_contiguous=0, /* Flags for indicating contiguous hyperslabs */ - large_contiguous=0; - int i; - size_t down_size[H5O_LAYOUT_NDIMS]; - hsize_t acc; + hsize_t mem_elmts,file_elmts; /* Number of elements in each dimension of selection */ + hssize_t file_off,mem_off; /* Offset (in elements) of selection */ + hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Size of memory buffer */ + hsize_t size[H5O_LAYOUT_NDIMS]; /* Size of selection */ + hssize_t file_offset[H5O_LAYOUT_NDIMS]; /* Offset of selection in file */ + hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* Offset of selection in memory */ + unsigned u; /* Index variable */ herr_t ret_value=SUCCEED; FUNC_ENTER(H5S_all_write, FAIL); *must_convert = TRUE; +#ifdef QAK +printf("%s: check 1.0\n",FUNC); +#endif /* QAK */ /* Check whether we can handle this */ if (H5S_SIMPLE!=mem_space->extent.type) HGOTO_DONE(SUCCEED); @@ -696,201 +580,100 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, if (mem_space->extent.u.simple.rank!=file_space->extent.u.simple.rank) HGOTO_DONE(SUCCEED); - /* Check for a single hyperslab block defined in memory dataspace */ - if (mem_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(mem_space->select.sel_info.hslab.diminfo != NULL) { - /* Check each dimension */ - for(count=1,u=0; u<mem_space->extent.u.simple.rank; u++) - count*=mem_space->select.sel_info.hslab.diminfo[u].count; - /* If the regular hyperslab definition creates more than one hyperslab, fall through */ - if(count>1) - HGOTO_DONE(SUCCEED); - } /* end if */ - else { - /* Get the pointer to the hyperslab spans to check */ - mem_span=mem_space->select.sel_info.hslab.span_lst->head; - - /* Spin through the spans, checking for more than one span in each dimension */ - while(mem_span!=NULL) { - /* If there are more than one span in the dimension, we can't use this routine */ - if(mem_span->next!=NULL) - HGOTO_DONE(SUCCEED); - - /* Advance to the next span, if it's available */ - if(mem_span->down==NULL) - break; - else - mem_span=mem_span->down->head; - } /* end while */ - - /* Get the pointer to the hyperslab spans to use */ - mem_span=mem_space->select.sel_info.hslab.span_lst->head; - } /* end else */ - } /* end if */ - else - if(mem_space->select.type!=H5S_SEL_ALL) - HGOTO_DONE(SUCCEED); - - /* Check for a single hyperslab block defined in file dataspace */ - if (file_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(file_space->select.sel_info.hslab.diminfo != NULL) { - /* Check each dimension */ - for(count=1,u=0; u<file_space->extent.u.simple.rank; u++) - count*=file_space->select.sel_info.hslab.diminfo[u].count; - /* If the regular hyperslab definition creates more than one hyperslab, fall through */ - if(count>1) - HGOTO_DONE(SUCCEED); - } /* end if */ - else { - /* Get the pointer to the hyperslab spans to check */ - file_span=file_space->select.sel_info.hslab.span_lst->head; - - /* Spin through the spans, checking for more than one span in each dimension */ - while(file_span!=NULL) { - /* If there are more than one span in the dimension, we can't use this routine */ - if(file_span->next!=NULL) - HGOTO_DONE(SUCCEED); - - /* Advance to the next span, if it's available */ - if(file_span->down==NULL) - break; - else - file_span=file_span->down->head; - } /* end while */ - - /* Get the pointer to the hyperslab spans to use */ - file_span=file_space->select.sel_info.hslab.span_lst->head; - } /* end else */ - } /* end if */ - else - if(file_space->select.type!=H5S_SEL_ALL) - HGOTO_DONE(SUCCEED); - /* Get information about memory and file */ for (u=0; u<mem_space->extent.u.simple.rank; u++) { - if(mem_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(mem_space->select.sel_info.hslab.diminfo != NULL) { - mem_size=mem_space->select.sel_info.hslab.diminfo[u].block; - mem_off=mem_space->select.sel_info.hslab.diminfo[u].start; - } /* end if */ - else { - mem_size=(mem_span->high-mem_span->low)+1; - mem_off=mem_span->low; - mem_span=mem_span->down->head; - } /* end else */ - } /* end if */ - else { - mem_size=mem_space->extent.u.simple.size[u]; - mem_off=0; - } /* end else */ - - if(file_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "regular" hyperslab selection */ - if(file_space->select.sel_info.hslab.diminfo != NULL) { - file_size=file_space->select.sel_info.hslab.diminfo[u].block; - file_off=file_space->select.sel_info.hslab.diminfo[u].start; - } /* end if */ - else { - file_size=(file_span->high-file_span->low)+1; - file_off=file_span->low; - file_span=file_span->down->head; - } /* end else */ - } /* end if */ - else { - file_size=file_space->extent.u.simple.size[u]; - file_off=0; - } /* end else */ - - if (mem_size!=file_size) + switch(mem_space->select.type) { + case H5S_SEL_HYPERSLABS: + /* Check for a "regular" hyperslab selection */ + if(mem_space->select.sel_info.hslab.diminfo != NULL) { + mem_elmts=mem_space->select.sel_info.hslab.diminfo[u].block; + mem_off=mem_space->select.sel_info.hslab.diminfo[u].start; + } /* end if */ + else { + mem_elmts=(mem_span->high-mem_span->low)+1; + mem_off=mem_span->low; + mem_span=mem_span->down->head; + } /* end else */ + mem_off+=mem_space->select.offset[u]; + break; + + case H5S_SEL_ALL: + mem_elmts=mem_space->extent.u.simple.size[u]; + mem_off=0; + break; + + case H5S_SEL_POINTS: + mem_elmts=1; + mem_off=mem_space->select.sel_info.pnt_lst->head->pnt[u] + +mem_space->select.offset[u]; + break; + + default: + assert(0 && "Invalid selection type!"); + } /* end switch */ + + switch(file_space->select.type) { + case H5S_SEL_HYPERSLABS: + /* Check for a "regular" hyperslab selection */ + if(file_space->select.sel_info.hslab.diminfo != NULL) { + file_elmts=file_space->select.sel_info.hslab.diminfo[u].block; + file_off=file_space->select.sel_info.hslab.diminfo[u].start; + } /* end if */ + else { + file_elmts=(file_span->high-file_span->low)+1; + file_off=file_span->low; + file_span=file_span->down->head; + } /* end else */ + file_off+=file_space->select.offset[u]; + break; + + case H5S_SEL_ALL: + file_elmts=file_space->extent.u.simple.size[u]; + file_off=0; + break; + + case H5S_SEL_POINTS: + file_elmts=1; + file_off=file_space->select.sel_info.pnt_lst->head->pnt[u] + +file_space->select.offset[u]; + break; + + default: + assert(0 && "Invalid selection type!"); + } /* end switch */ + + if (mem_elmts!=file_elmts) HGOTO_DONE(SUCCEED); - size[u] = file_size; + mem_size[u]=mem_space->extent.u.simple.size[u]; + size[u] = file_elmts; file_offset[u] = file_off; mem_offset[u] = mem_off; } + mem_size[u]=elmt_size; size[u] = elmt_size; file_offset[u] = 0; mem_offset[u] = 0; - /* Disallow reading a memory hyperslab in the "middle" of a dataset which */ - /* spans multiple rows in "interior" dimensions, but allow reading a */ - /* hyperslab which is in the "middle" of the fastest or slowest changing */ - /* dimension because a hyperslab which "fills" the interior dimensions is */ - /* contiguous in memory. i.e. these are allowed: */ - /* --------------------- --------------------- */ - /* | | | | */ - /* |*******************| | ********* | */ - /* |*******************| | | */ - /* | | | | */ - /* | | | | */ - /* --------------------- --------------------- */ - /* ("large" contiguous block) ("small" contiguous block) */ - /* But this is not: */ - /* --------------------- */ - /* | | */ - /* | ********* | */ - /* | ********* | */ - /* | | */ - /* | | */ - /* --------------------- */ - /* (not contiguous in memory) */ - if(mem_space->select.type==H5S_SEL_HYPERSLABS) { - /* Check for a "small" contiguous block */ - if(size[0]==1) { - small_contiguous=1; - /* size of block in all dimensions except the fastest must be '1' */ - for (u=0; u<(mem_space->extent.u.simple.rank-1); u++) { - if(size[u]>1) { - small_contiguous=0; - break; - } /* end if */ - } /* end for */ - } /* end if */ - /* Check for a "large" contiguous block */ - else { - large_contiguous=1; - /* size of block in all dimensions except the slowest must be the */ - /* full size of the dimension */ - for (u=1; u<mem_space->extent.u.simple.rank; u++) { - if(size[u]!=mem_space->extent.u.simple.size[u]) { - large_contiguous=0; - break; - } /* end if */ - } /* end for */ - } /* end else */ - - /* Check for contiguous block */ - if(small_contiguous || large_contiguous) { - /* Compute the "down sizes" for each dimension */ - for (acc=elmt_size, i=(mem_space->extent.u.simple.rank-1); i>=0; i--) { - H5_ASSIGN_OVERFLOW(down_size[i],acc,hsize_t,size_t); - acc*=mem_space->extent.u.simple.size[i]; - } /* end for */ - - /* Adjust the buffer offset and memory offsets by the proper amount */ - for (u=0; u<mem_space->extent.u.simple.rank; u++) { - buf+=mem_offset[u]*down_size[u]; - mem_offset[u]=0; - } /* end for */ - } /* end if */ - else { - /* Non-contiguous hyperslab block */ - HGOTO_DONE(SUCCEED); - } /* end else */ - } /* end if */ - +#ifdef QAK +printf("%s: check 2.0\n",FUNC); +for (u=0; u<mem_space->extent.u.simple.rank; u++) + printf("size[%u]=%lu\n",u,(unsigned long)size[u]); +for (u=0; u<=mem_space->extent.u.simple.rank; u++) + printf("mem_size[%u]=%lu\n",u,(unsigned long)mem_size[u]); +for (u=0; u<=mem_space->extent.u.simple.rank; u++) + printf("mem_offset[%u]=%lu\n",u,(unsigned long)mem_offset[u]); +for (u=0; u<=mem_space->extent.u.simple.rank; u++) + printf("file_offset[%u]=%lu\n",u,(unsigned long)file_offset[u]); +#endif /* QAK */ /* Write data to the file */ if (H5F_arr_write(f, dxpl_id, layout, pline, fill, efl, size, - size, mem_offset, file_offset, buf)<0) { + mem_size, mem_offset, file_offset, buf)<0) { HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write data to the file"); } *must_convert = FALSE; - done: FUNC_LEAVE(ret_value); } diff --git a/src/H5Shyper.c b/src/H5Shyper.c index c6639d7..487de1b 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -5935,6 +5935,84 @@ H5S_hyper_select_contiguous(const H5S_t *space) /*-------------------------------------------------------------------------- NAME + H5S_hyper_select_single + PURPOSE + Check if a hyperslab selection is a single block within the dataspace extent. + USAGE + htri_t H5S_select_single(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + TRUE/FALSE/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspace is a single block. + This is primarily used for reading the entire selection in one swoop. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S_hyper_select_single(const H5S_t *space) +{ + H5S_hyper_span_info_t *spans; /* Hyperslab span info node */ + H5S_hyper_span_t *span; /* Hyperslab span node */ + unsigned u; /* index variable */ + htri_t ret_value=FALSE; /* return value */ + + FUNC_ENTER (H5S_hyper_select_single, FAIL); + + assert(space); + + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab.diminfo != NULL) { + /* + * For a regular hyperslab to be single, it must have only one + * block (i.e. count==1 in all dimensions) + */ + + /* Initialize flags */ + ret_value=TRUE; /* assume true and reset if the dimensions don't match */ + + /* Check for a single block */ + for(u=0; u<space->extent.u.simple.rank; u++) { + if(space->select.sel_info.hslab.diminfo[u].count>1) { + ret_value=FALSE; + break; + } /* end if */ + } /* end for */ + } /* end if */ + else { + /* + * For a region to be single, it must have only one block + */ + /* Initialize flags */ + ret_value=TRUE; /* assume true and reset if the dimensions don't match */ + + /* Get information for slowest changing information */ + spans=space->select.sel_info.hslab.span_lst; + + /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ + while(spans!=NULL) { + span=spans->head; + + /* Check that this is the only span and it spans the entire dimension */ + if(span->next!=NULL) { + ret_value=FALSE; + break; + } /* end if */ + else { + /* Walk down to the next span */ + spans=span->down; + } /* end else */ + } /* end while */ + } /* end else */ + + FUNC_LEAVE (ret_value); +} /* H5S_hyper_select_single() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_hyper_select_iterate_helper PURPOSE Internal routine to iterate over the elements of a span tree hyperslab selection diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 7e3da29..0e6a0c5 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -132,6 +132,7 @@ __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__ htri_t H5S_point_select_single(const H5S_t *space); __DLL__ herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem, const hssize_t **coord); __DLL__ herr_t H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, @@ -174,6 +175,7 @@ __DLL__ hssize_t H5S_hyper_span_nblocks(H5S_hyper_span_info_t *spans); __DLL__ herr_t H5S_hyper_span_blocklist(H5S_hyper_span_info_t *spans, hssize_t start[], hssize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, hsize_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__ htri_t H5S_hyper_select_single(const H5S_t *space); __DLL__ herr_t H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op, void *operator_data); diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 06f198d..5cb9079 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -1086,6 +1086,7 @@ H5S_point_bounds(H5S_t *space, hsize_t *start, hsize_t *end) FUNC_LEAVE (ret_value); } /* H5Sget_point_bounds() */ + /*-------------------------------------------------------------------------- NAME @@ -1129,6 +1130,43 @@ H5S_point_select_contiguous(const H5S_t *space) /*-------------------------------------------------------------------------- NAME + H5S_point_select_single + PURPOSE + Check if a point selection is single within the dataspace extent. + USAGE + htri_t H5S_point_select_contiguous(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + TRUE/FALSE/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspace is a single block. + This is primarily used for reading the entire selection in one swoop. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S_point_select_single(const H5S_t *space) +{ + htri_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_point_select_single, FAIL); + + assert(space); + + /* One point is definitely contiguous */ + if(space->select.num_elem==1) + ret_value=TRUE; + else + ret_value=FALSE; + + FUNC_LEAVE (ret_value); +} /* H5S_point_select_single() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_select_elements PURPOSE Specify a series of elements in the dataspace to select diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index e024502..86a46bc 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -219,6 +219,7 @@ __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__ htri_t H5S_select_single(const H5S_t *space); __DLL__ herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op, void *operator_data); __DLL__ herr_t H5S_sel_iter_release(const H5S_t *space, diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 9fc4149..b592e9f 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -1316,3 +1316,56 @@ H5Sget_select_type(hid_t space_id) FUNC_LEAVE(space->select.type); } /* end H5Sget_select_type() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_single + PURPOSE + Check if the selection is a single block within the dataspace extent. + USAGE + htri_t H5S_select_single(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + TRUE/FALSE/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspace is a single block. + This is primarily used for reading the entire selection in one swoop. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S_select_single(const H5S_t *space) +{ + htri_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_select_single, FAIL); + + assert(space); + + switch(space->select.type) { + case H5S_SEL_POINTS: /* Sequence of points selected */ + ret_value=H5S_point_select_single(space); + break; + + case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ + ret_value=H5S_hyper_select_single(space); + break; + + case H5S_SEL_ALL: /* Entire extent selected */ + ret_value=TRUE; + break; + + case H5S_SEL_NONE: /* Nothing selected */ + ret_value=FALSE; + break; + + case H5S_SEL_ERROR: + case H5S_SEL_N: + break; + } + + FUNC_LEAVE (ret_value); +} /* H5S_select_single() */ + |