[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 :-)
This commit is contained in:
Albert Cheng 1999-05-25 16:29:31 -05:00
parent 9282a3e357
commit ac830927fb
7 changed files with 237 additions and 18 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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() */

View File

@ -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() */

View File

@ -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);

View File

@ -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() */