summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbert Cheng <acheng@hdfgroup.org>1999-05-25 21:29:31 (GMT)
committerAlbert Cheng <acheng@hdfgroup.org>1999-05-25 21:29:31 (GMT)
commitac830927fbda984086d7bd601282c5f3e5478176 (patch)
treed516c754a10ce7824f141e1bc82280977fab24f4
parent9282a3e3575d7e3af855bea6ddd4d1a0ba511671 (diff)
downloadhdf5-ac830927fbda984086d7bd601282c5f3e5478176.zip
hdf5-ac830927fbda984086d7bd601282c5f3e5478176.tar.gz
hdf5-ac830927fbda984086d7bd601282c5f3e5478176.tar.bz2
[svn-r1277] Added additional checks into the dataspace code to determine if the hyperslabs
being written out are contiguous in memory and on disk and write/read them as one I/O operation (if the datatypes don't require conversion). This should be a good performance boost for those situations. It's especially needed on the ASCI Red (TFlops) machine. - QAK (from Albert's account on modi4 :-)
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5S.c10
-rw-r--r--src/H5Sall.c94
-rw-r--r--src/H5Shyper.c55
-rw-r--r--src/H5Spoint.c39
-rw-r--r--src/H5Sprivate.h3
-rw-r--r--src/H5Sselect.c52
7 files changed, 237 insertions, 18 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 43c1fdb..8621018 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1905,7 +1905,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
}
}
#ifdef QAK
- printf("%s: after H5T_find, tconv_func=%p\n",FUNC,tconv_func);
+ printf("%s: after H5T_find, tpath=%p\n",FUNC,tpath);
#endif /* QAK */
if (NULL==(sconv=H5S_find(mem_space, file_space))) {
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL,
diff --git a/src/H5S.c b/src/H5S.c
index bf4e9cd..5446224 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1482,6 +1482,7 @@ H5S_conv_t *
H5S_find (const H5S_t *mem_space, const H5S_t *file_space)
{
size_t i;
+ htri_t c1,c2;
H5S_conv_t *path;
FUNC_ENTER (H5S_find, NULL);
@@ -1537,8 +1538,13 @@ H5S_find (const H5S_t *mem_space, const H5S_t *file_space)
/*
* Initialize direct read/write functions
*/
- if (H5S_SEL_ALL==file_space->select.type &&
- H5S_SEL_ALL==mem_space->select.type) {
+ c1=H5S_select_contiguous(file_space);
+ c2=H5S_select_contiguous(mem_space);
+ if(c1==FAIL || c2==FAIL)
+ HRETURN_ERROR(H5E_DATASPACE, H5E_INTERNAL, NULL,
+ "invalid check for contiguous dataspace ");
+
+ if (c1==TRUE && c2==TRUE) {
path->read = H5S_all_read;
path->write = H5S_all_write;
}
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 4deb877..87e7ac8 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -537,6 +537,7 @@ H5S_all_mscat (const void *_tconv_buf, size_t elmt_size,
* Thursday, April 22, 1999
*
* Modifications:
+ * Modified to allow contiguous hyperslabs to be written out - QAK - 5/25/99
*
*-------------------------------------------------------------------------
*/
@@ -546,8 +547,12 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline,
const H5S_t *mem_space, const H5F_xfer_t *xfer_parms,
void *buf/*out*/, hbool_t *must_convert/*out*/)
{
+ H5S_hyper_node_t *file_node,*mem_node; /* Hyperslab node */
+ hsize_t mem_size,file_size;
+ hssize_t file_off;
hsize_t size[H5S_MAX_RANK];
- hssize_t offset[H5S_MAX_RANK];
+ hssize_t file_offset[H5S_MAX_RANK];
+ hssize_t mem_offset[H5S_MAX_RANK];
int i;
FUNC_ENTER(H5S_all_read, FAIL);
@@ -558,6 +563,18 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline,
if (H5S_SIMPLE!=file_space->extent.type) goto fall_through;
if (mem_space->extent.u.simple.rank!=
file_space->extent.u.simple.rank) goto fall_through;
+ if (mem_space->select.type==H5S_SEL_HYPERSLABS) {
+ if(mem_space->select.sel_info.hslab.hyper_lst->count>1) goto fall_through;
+ mem_node=mem_space->select.sel_info.hslab.hyper_lst->head;
+ } /* end if */
+ else
+ if(mem_space->select.type!=H5S_SEL_ALL) goto fall_through;
+ if (file_space->select.type==H5S_SEL_HYPERSLABS) {
+ if(file_space->select.sel_info.hslab.hyper_lst->count>1) goto fall_through;
+ file_node=file_space->select.sel_info.hslab.hyper_lst->head;
+ } /* end if */
+ else
+ if(file_space->select.type!=H5S_SEL_ALL) goto fall_through;
/* Get information about memory and file */
for (i=0; i<mem_space->extent.u.simple.rank; i++) {
@@ -567,19 +584,34 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline,
if (file_space->extent.u.simple.max &&
file_space->extent.u.simple.size[i]!=
file_space->extent.u.simple.max[i]) goto fall_through;
- if (mem_space->extent.u.simple.size[i]!=
- file_space->extent.u.simple.size[i]) goto fall_through;
- size[i] = mem_space->extent.u.simple.size[i];
- offset[i] = 0;
+ if(mem_space->select.type==H5S_SEL_HYPERSLABS) {
+ mem_size=(mem_node->end[i]-mem_node->start[i])+1;
+ } /* end if */
+ else {
+ mem_size=mem_space->extent.u.simple.size[i];
+ } /* end else */
+ if(file_space->select.type==H5S_SEL_HYPERSLABS) {
+ file_size=(file_node->end[i]-file_node->start[i])+1;
+ file_off=file_node->start[i];
+ } /* end if */
+ else {
+ file_size=file_space->extent.u.simple.size[i];
+ file_off=0;
+ } /* end else */
+ if (mem_size!=file_size) goto fall_through;
+ size[i] = file_size;
+ file_offset[i] = file_off;
+ mem_offset[i] = 0;
}
size[i] = elmt_size;
- offset[i] = 0;
+ file_offset[i] = 0;
+ mem_offset[i] = 0;
/* Read data from the file */
if (H5F_arr_read(f, xfer_parms, layout, pline, NULL, efl, size,
- size, offset, offset, buf/*out*/)<0) {
+ size, mem_offset, file_offset, buf/*out*/)<0) {
HRETURN_ERROR(H5E_IO, H5E_INTERNAL, FAIL,
- "unable to write data to the file");
+ "unable to read data from the file");
}
*must_convert = FALSE;
@@ -604,6 +636,7 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline,
* Wednesday, April 21, 1999
*
* Modifications:
+ * Modified to allow contiguous hyperslabs to be written out - QAK - 5/25/99
*
*-------------------------------------------------------------------------
*/
@@ -614,8 +647,12 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout,
const H5S_t *mem_space, const H5F_xfer_t *xfer_parms,
const void *buf, hbool_t *must_convert/*out*/)
{
+ H5S_hyper_node_t *file_node,*mem_node; /* Hyperslab node */
+ hsize_t mem_size,file_size;
+ hssize_t file_off;
hsize_t size[H5S_MAX_RANK];
- hssize_t offset[H5S_MAX_RANK];
+ hssize_t file_offset[H5S_MAX_RANK];
+ hssize_t mem_offset[H5S_MAX_RANK];
int i;
FUNC_ENTER(H5S_all_write, FAIL);
@@ -626,6 +663,18 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout,
if (H5S_SIMPLE!=file_space->extent.type) goto fall_through;
if (mem_space->extent.u.simple.rank!=
file_space->extent.u.simple.rank) goto fall_through;
+ if (mem_space->select.type==H5S_SEL_HYPERSLABS) {
+ if(mem_space->select.sel_info.hslab.hyper_lst->count>1) goto fall_through;
+ mem_node=mem_space->select.sel_info.hslab.hyper_lst->head;
+ } /* end if */
+ else
+ if(mem_space->select.type!=H5S_SEL_ALL) goto fall_through;
+ if (file_space->select.type==H5S_SEL_HYPERSLABS) {
+ if(file_space->select.sel_info.hslab.hyper_lst->count>1) goto fall_through;
+ file_node=file_space->select.sel_info.hslab.hyper_lst->head;
+ } /* end if */
+ else
+ if(file_space->select.type!=H5S_SEL_ALL) goto fall_through;
/* Get information about memory and file */
for (i=0; i<mem_space->extent.u.simple.rank; i++) {
@@ -635,17 +684,32 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout,
if (file_space->extent.u.simple.max &&
file_space->extent.u.simple.size[i]!=
file_space->extent.u.simple.max[i]) goto fall_through;
- if (mem_space->extent.u.simple.size[i]!=
- file_space->extent.u.simple.size[i]) goto fall_through;
- size[i] = mem_space->extent.u.simple.size[i];
- offset[i] = 0;
+ if(mem_space->select.type==H5S_SEL_HYPERSLABS) {
+ mem_size=(mem_node->end[i]-mem_node->start[i])+1;
+ } /* end if */
+ else {
+ mem_size=mem_space->extent.u.simple.size[i];
+ } /* end else */
+ if(file_space->select.type==H5S_SEL_HYPERSLABS) {
+ file_size=(file_node->end[i]-file_node->start[i])+1;
+ file_off=file_node->start[i];
+ } /* end if */
+ else {
+ file_size=file_space->extent.u.simple.size[i];
+ file_off=0;
+ } /* end else */
+ if (mem_size!=file_size) goto fall_through;
+ size[i] = file_size;
+ file_offset[i] = file_off;
+ mem_offset[i] = 0;
}
size[i] = elmt_size;
- offset[i] = 0;
+ file_offset[i] = 0;
+ mem_offset[i] = 0;
/* Write data to the file */
if (H5F_arr_write(f, xfer_parms, layout, pline, NULL, efl, size,
- size, offset, offset, buf)<0) {
+ size, mem_offset, file_offset, buf)<0) {
HRETURN_ERROR(H5E_IO, H5E_INTERNAL, FAIL,
"unable to write data to the file");
}
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index fe8fe47..f686dfc 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -2921,3 +2921,58 @@ H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
FUNC_LEAVE (ret_value);
} /* H5Sget_hyper_bounds() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_select_contiguous
+ PURPOSE
+ Check if a hyperslab selection is contiguous within the dataspace extent.
+ USAGE
+ htri_t H5S_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 contiguous.
+ 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_contiguous(const H5S_t *space)
+{
+ htri_t ret_value=FAIL; /* return value */
+ H5S_hyper_node_t *node; /* Hyperslab node */
+ intn rank; /* Dataspace rank */
+ intn i; /* index variable */
+
+ FUNC_ENTER (H5S_hyper_select_contiguous, FAIL);
+
+ assert(space);
+
+ /* If there is more than one hyperslab in the selection, they are not contiguous */
+ if(space->select.sel_info.hslab.hyper_lst->count>1)
+ ret_value=FALSE;
+ else { /* If there is one hyperslab, then it might be contiguous */
+ /* Get the dataspace extent rank */
+ rank=space->extent.u.simple.rank;
+
+ /* Get the hyperslab node */
+ node=space->select.sel_info.hslab.hyper_lst->head;
+
+ /*
+ * For a hyperslab to be contiguous, it's size must be the same as the
+ * dataspace extent's in all but the slowest changing dimension
+ */
+ ret_value=TRUE; /* assume true and reset if the dimensions don't match */
+ for(i=1; i<rank; i++) {
+ if(((node->end[i]-node->start[i])+1)!=space->extent.u.simple.size[i]) {
+ ret_value=FALSE;
+ break;
+ } /* end if */
+ }
+ } /* end else */
+ FUNC_LEAVE (ret_value);
+} /* H5S_hyper_select_contiguous() */
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index dfdfa03..ac3d3e1 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -1069,3 +1069,42 @@ H5S_point_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
FUNC_LEAVE (ret_value);
} /* H5Sget_point_bounds() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_point_select_contiguous
+ PURPOSE
+ Check if a point selection is contiguous 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 contiguous.
+ This is primarily used for reading the entire selection in one swoop.
+ This code currently doesn't properly check for contiguousness when there is
+ more than one point, as that would take a lot of extra coding that we
+ don't need now.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5S_point_select_contiguous(const H5S_t *space)
+{
+ htri_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5S_point_select_contiguous, FAIL);
+
+ assert(space);
+
+ /* One point is definitely contiguous */
+ if(space->select.num_elem==1)
+ ret_value=TRUE;
+ else /* More than one point might be contiguous, but it's complex to check and we don't need it right now */
+ ret_value=FALSE;
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_select_contiguous() */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 0a652e2..2dba002 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -341,6 +341,7 @@ __DLL__ herr_t H5S_register(H5S_sel_type cls, const H5S_fconv_t *fconv,
__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);
/* Point select functions */
__DLL__ herr_t H5S_point_add(H5S_t *space, size_t num_elemn,
@@ -353,6 +354,7 @@ __DLL__ hssize_t H5S_point_select_serial_size(const H5S_t *space);
__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);
/* "All" select functions */
__DLL__ herr_t H5S_all_release(H5S_t *space);
@@ -393,6 +395,7 @@ __DLL__ hssize_t H5S_hyper_select_serial_size(const H5S_t *space);
__DLL__ herr_t H5S_hyper_select_serialize(const H5S_t *space, uint8_t *buf);
__DLL__ herr_t H5S_hyper_select_deserialize(H5S_t *space, const uint8_t *buf);
__DLL__ herr_t H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end);
+__DLL__ htri_t H5S_hyper_select_contiguous(const H5S_t *space);
/* "None" selection functions */
__DLL__ herr_t H5S_none_select_serialize(const H5S_t *space, uint8_t *buf);
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index e9c03c2..669cb94 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -1631,3 +1631,55 @@ H5Sget_select_bounds(hid_t spaceid, hsize_t *start, hsize_t *end)
FUNC_LEAVE (ret_value);
} /* H5Sget_select_bounds() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_contiguous
+ PURPOSE
+ Check if the selection is contiguous within the dataspace extent.
+ USAGE
+ htri_t H5S_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 contiguous.
+ This is primarily used for reading the entire selection in one swoop.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5S_select_contiguous(const H5S_t *space)
+{
+ htri_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5S_select_contiguous, FAIL);
+
+ assert(space);
+
+ switch(space->select.type) {
+ case H5S_SEL_POINTS: /* Sequence of points selected */
+ ret_value=H5S_point_select_contiguous(space);
+ break;
+
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
+ ret_value=H5S_hyper_select_contiguous(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_contiguous() */