summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-04-02 20:51:41 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-04-02 20:51:41 (GMT)
commitd2232a345f36988f4a60034d63ddca25c476fc08 (patch)
tree2ba460735cb162b5ee94ae98f0d46873488fa454 /src
parentc1e44699f0460cd5a675a71dc85296740f07063a (diff)
downloadhdf5-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.c36
-rw-r--r--src/H5Dseq.c46
-rw-r--r--src/H5Farray.c53
-rw-r--r--src/H5Fistore.c36
-rw-r--r--src/H5Fpkg.h4
-rw-r--r--src/H5Fseq.c46
-rw-r--r--src/H5S.c8
-rw-r--r--src/H5Sall.c537
-rw-r--r--src/H5Shyper.c78
-rw-r--r--src/H5Spkg.h2
-rw-r--r--src/H5Spoint.c38
-rw-r--r--src/H5Sprivate.h1
-rw-r--r--src/H5Sselect.c53
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");
}
diff --git a/src/H5S.c b/src/H5S.c
index 0b6632c..43547db 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -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() */
+