From ac830927fbda984086d7bd601282c5f3e5478176 Mon Sep 17 00:00:00 2001 From: Albert Cheng Date: Tue, 25 May 1999 16:29:31 -0500 Subject: [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 :-) --- src/H5D.c | 2 +- src/H5S.c | 10 ++++-- src/H5Sall.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++--------- src/H5Shyper.c | 55 +++++++++++++++++++++++++++++++++ src/H5Spoint.c | 39 +++++++++++++++++++++++ src/H5Sprivate.h | 3 ++ src/H5Sselect.c | 52 +++++++++++++++++++++++++++++++ 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; iextent.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; iextent.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; iend[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() */ -- cgit v0.12