mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-04-18 17:40:55 +08:00
[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:
parent
9282a3e357
commit
ac830927fb
@ -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,
|
||||
|
10
src/H5S.c
10
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;
|
||||
}
|
||||
|
94
src/H5Sall.c
94
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");
|
||||
}
|
||||
|
@ -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() */
|
||||
|
@ -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() */
|
||||
|
@ -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);
|
||||
|
@ -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() */
|
||||
|
Loading…
x
Reference in New Issue
Block a user