diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5D.c | 77 | ||||
-rw-r--r-- | src/H5Distore.c | 2 | ||||
-rw-r--r-- | src/H5Fistore.c | 2 | ||||
-rw-r--r-- | src/H5Oefl.c | 4 | ||||
-rw-r--r-- | src/H5S.c | 3 | ||||
-rw-r--r-- | src/H5Sprivate.h | 20 | ||||
-rw-r--r-- | src/H5Ssimp.c | 215 | ||||
-rw-r--r-- | src/H5Tpkg.h | 2 | ||||
-rw-r--r-- | src/H5Tprivate.h | 7 | ||||
-rw-r--r-- | src/H5V.c | 29 |
10 files changed, 338 insertions, 23 deletions
@@ -31,6 +31,12 @@ static char RcsId[] = "@(#)$Revision$"; #define PABLO_MASK H5D_mask /* + * Define this to be zero or one depending on whether the I/O pipeline should + * be optimized. + */ +#define H5D_OPTIMIZE_PIPE 1 + +/* * A dataset is the following struct. */ struct H5D_t { @@ -807,7 +813,7 @@ H5D_create(H5F_t *f, const char *name, const H5T_t *type, const H5S_t *space, } /* Create (open for write access) an object header */ - if (H5O_create(f, 0, &(new_dset->ent)) < 0) { + if (H5O_create(f, 80, &(new_dset->ent)) < 0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset object header"); } @@ -1090,6 +1096,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, H5S_number_t numbering; /*element numbering info*/ H5T_cdata_t *cdata = NULL; /*type conversion data */ herr_t ret_value = FAIL; + herr_t status; FUNC_ENTER(H5D_read, FAIL); @@ -1140,10 +1147,36 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * Compute the size of the request and allocate scratch buffers. */ nelmts = H5S_get_npoints(mem_space); + + /* + * If there is no type conversion then try reading directly into the + * application's buffer. + */ + if (H5D_OPTIMIZE_PIPE && + H5T_conv_noop==tconv_func && + NULL!=sconv_func->read) { +#ifndef NDEBUG + fprintf (stderr, "HDF5-DIAG: Trying I/O pipe optimization...\n"); +#endif + status = (sconv_func->read)(dataset->ent.file, &(dataset->layout), + &(dataset->create_parms->efl), + H5T_get_size (dataset->type), file_space, + mem_space, buf/*out*/); + if (status>=0) goto succeed; +#ifndef NDEBUG + fprintf (stderr, "HDF5-DIAG: I/O pipe optimization failed\n"); +#endif + H5E_clear (); + } + + + /* + * This is the general case. + */ #ifndef LATER /* * Note: this prototype version allocates a buffer large enough to - * satisfy the entire request; strip mining is not implemented. + * satisfy the entire request; strip mining is not implemented. */ { size_t src_size = nelmts * H5T_get_size(dataset->type); @@ -1152,7 +1185,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (cdata->need_bkg) bkg_buf = H5MM_xmalloc (dst_size); } #endif - /* * Gather the data from disk into the data type conversion buffer. Also * gather data from application to background buffer (this step is not @@ -1192,9 +1224,12 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &numbering, 0, nelmts, buf/*out*/)<0) { HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "scatter failed"); } + + + succeed: ret_value = SUCCEED; - done: + done: if (src_id >= 0) H5A_dec_ref(src_id); if (dst_id >= 0) H5A_dec_ref(dst_id); tconv_buf = H5MM_xfree(tconv_buf); @@ -1233,7 +1268,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_conv_t *sconv_func = NULL; /*space conversion funcs*/ H5S_number_t numbering; /*element numbering info*/ H5T_cdata_t *cdata = NULL; /*type conversion data */ - herr_t ret_value = FAIL; + herr_t ret_value = FAIL, status; FUNC_ENTER(H5D_write, FAIL); @@ -1284,6 +1319,32 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * Compute the size of the request and allocate scratch buffers. */ nelmts = H5S_get_npoints(mem_space); + + /* + * If there is no type conversion then try writing directly from + * application buffer to file. + */ + if (H5D_OPTIMIZE_PIPE && + H5T_conv_noop==tconv_func && + NULL!=sconv_func->write) { +#ifndef NDEBUG + fprintf (stderr, "HDF5-DIAG: Trying I/O pipe optimization...\n"); +#endif + status = (sconv_func->write)(dataset->ent.file, &(dataset->layout), + &(dataset->create_parms->efl), + H5T_get_size (dataset->type), file_space, + mem_space, buf); + if (status>=0) goto succeed; +#ifndef NDEBUG + fprintf (stderr, "HDF5-DIAG: I/O pipe optimization failed\n"); +#endif + H5E_clear (); + } + + + /* + * This is the general case. + */ #ifndef LATER /* * Note: This prototype version allocates a buffer large enough to @@ -1296,8 +1357,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (cdata->need_bkg) bkg_buf = H5MM_xmalloc (dst_size); } #endif - - /* * Gather data from application buffer into the data type conversion * buffer. Also gather data from the file into the background buffer @@ -1338,9 +1397,11 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &numbering, 0, nelmts, tconv_buf)<0) { HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed"); } + + succeed: ret_value = SUCCEED; - done: + done: if (src_id >= 0) H5A_dec_ref(src_id); if (dst_id >= 0) H5A_dec_ref(dst_id); tconv_buf = H5MM_xfree(tconv_buf); diff --git a/src/H5Distore.c b/src/H5Distore.c index eeed99c..25b81b2 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -835,7 +835,9 @@ herr_t H5F_istore_create(H5F_t *f, H5O_layout_t *layout /*out */ ) { H5F_istore_ud1_t udata; +#ifndef NDEBUG int i; +#endif FUNC_ENTER(H5F_istore_create, FAIL); diff --git a/src/H5Fistore.c b/src/H5Fistore.c index eeed99c..25b81b2 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -835,7 +835,9 @@ herr_t H5F_istore_create(H5F_t *f, H5O_layout_t *layout /*out */ ) { H5F_istore_ud1_t udata; +#ifndef NDEBUG int i; +#endif FUNC_ENTER(H5F_istore_create, FAIL); diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 1b3fa6a..5f2db2a 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -373,7 +373,7 @@ H5O_efl_read (H5F_t *f, const H5O_efl_t *efl, haddr_t *addr, size_t size, uint8 *buf) { int i, fd=-1; - size_t to_read, cur, skip; + size_t to_read, cur, skip=0; ssize_t n; herr_t ret_value = FAIL; @@ -458,7 +458,7 @@ H5O_efl_write (H5F_t *f, const H5O_efl_t *efl, haddr_t *addr, size_t size, const uint8 *buf) { int i, fd=-1; - size_t to_write, cur, skip; + size_t to_write, cur, skip=0; herr_t ret_value = FAIL; FUNC_ENTER (H5O_efl_write, FAIL); @@ -538,6 +538,7 @@ H5S_get_npoints_max(const H5S_t *ds) FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5Sget_ndims @@ -1310,6 +1311,8 @@ H5S_find (const H5S_t *mem_space, const H5S_t *file_space) _conv.mscat = H5S_simp_mscat; _conv.mgath = H5S_simp_mgath; _conv.fscat = H5S_simp_fscat; + _conv.read = H5S_simp_read; + _conv.write = H5S_simp_write; conv = &_conv; } diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index c8a3aae..fbce725 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -88,6 +88,18 @@ typedef struct H5S_tconv_t { const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_number_t *numbering, size_t start, size_t nelmts, const void *tconv_buf); + + /* Read from file to application w/o intermediate scratch buffer */ + herr_t (*read)(H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + void *buf/*out*/); + + /* Write directly from app buffer to file */ + herr_t (*write)(H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + const void *buf); } H5S_conv_t; H5S_t *H5S_copy (const H5S_t *src); @@ -125,4 +137,12 @@ herr_t H5S_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_number_t *numbering, size_t start, size_t nelmts, const void *tconv_buf); +herr_t H5S_simp_read (H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + void *buf/*out*/); +herr_t H5S_simp_write (H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + const void *buf); #endif diff --git a/src/H5Ssimp.c b/src/H5Ssimp.c index ee2d680..6f1f498 100644 --- a/src/H5Ssimp.c +++ b/src/H5Ssimp.c @@ -471,3 +471,218 @@ H5S_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout, FUNC_LEAVE (SUCCEED); } + + +/*------------------------------------------------------------------------- + * Function: H5S_simp_read + * + * Purpose: Reads a dataset from file F directly into application memory + * BUF performing data space conversion in a single step from + * FILE_SPACE to MEM_SPACE. The dataset is stored in the file + * according to the LAYOUT and EFL (external file list) and data + * point in the file is ELMT_SIZE bytes. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, March 12, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_simp_read (H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + void *buf/*out*/) +{ + size_t hslab_size[H5O_LAYOUT_NDIMS]; + size_t file_offset[H5O_LAYOUT_NDIMS]; + size_t mem_size[H5O_LAYOUT_NDIMS]; + size_t mem_offset[H5O_LAYOUT_NDIMS]; + int i; + + FUNC_ENTER (H5S_simp_read, FAIL); + +#ifndef NDEBUG + assert (file_space->type==mem_space->type); + assert (file_space->u.simple.rank==mem_space->u.simple.rank); + for (i=0; i<file_space->u.simple.rank; i++) { + if (file_space->hslab_def && mem_space->hslab_def) { + assert (1==file_space->h.stride[i]); + assert (1==mem_space->h.stride[i]); + assert (file_space->h.count[i]==mem_space->h.count[i]); + } else if (file_space->hslab_def) { + assert (1==file_space->h.stride[i]); + assert (file_space->h.count[i]==mem_space->u.simple.size[i]); + } else if (mem_space->hslab_def) { + assert (1==mem_space->h.stride[i]); + assert (file_space->u.simple.size[i]==mem_space->h.count[i]); + } else { + assert (file_space->u.simple.size[i]== + mem_space->u.simple.size[i]); + } + } +#endif + + + /* + * Calculate size of hyperslab and offset of hyperslab into file and + * memory. + */ + if (file_space->hslab_def) { + for (i=0; i<file_space->u.simple.rank; i++) { + hslab_size[i] = file_space->h.count[i]; + } + } else { + for (i=0; i<file_space->u.simple.rank; i++) { + hslab_size[i] = file_space->u.simple.size[i]; + } + } + for (i=0; i<mem_space->u.simple.rank; i++) { + mem_size[i] = mem_space->u.simple.size[i]; + } + if (file_space->hslab_def) { + for (i=0; i<file_space->u.simple.rank; i++) { + file_offset[i] = file_space->h.start[i]; + } + } else { + for (i=0; i<file_space->u.simple.rank; i++) { + file_offset[i] = 0; + } + } + if (mem_space->hslab_def) { + for (i=0; i<mem_space->u.simple.rank; i++) { + mem_offset[i] = mem_space->h.start[i]; + } + } else { + for (i=0; i<mem_space->u.simple.rank; i++) { + mem_offset[i] = 0; + } + } + hslab_size[file_space->u.simple.rank] = elmt_size; + mem_size[file_space->u.simple.rank] = elmt_size; + file_offset[file_space->u.simple.rank] = 0; + mem_offset[file_space->u.simple.rank] = 0; + + /* Read the hyperslab */ + if (H5F_arr_read (f, layout, efl, hslab_size, + mem_size, mem_offset, file_offset, buf)<0) { + HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read dataset"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5S_simp_write + * + * Purpose: Write a dataset from application memory BUF directly into + * file F performing data space conversion in a single step from + * MEM_SPACE to FILE_SPACE. The dataset is stored in the file + * according to the LAYOUT and EFL (external file list) and data + * point in the file is ELMT_SIZE bytes. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, March 12, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_simp_write (H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + const void *buf) +{ + size_t hslab_size[H5O_LAYOUT_NDIMS]; + size_t file_offset[H5O_LAYOUT_NDIMS]; + size_t mem_size[H5O_LAYOUT_NDIMS]; + size_t mem_offset[H5O_LAYOUT_NDIMS]; + int i; + + FUNC_ENTER (H5S_simp_write, FAIL); + +#ifndef NDEBUG + assert (file_space->type==mem_space->type); + assert (file_space->u.simple.rank==mem_space->u.simple.rank); + for (i=0; i<file_space->u.simple.rank; i++) { + if (file_space->hslab_def && mem_space->hslab_def) { + assert (1==file_space->h.stride[i]); + assert (1==mem_space->h.stride[i]); + assert (file_space->h.count[i]==mem_space->h.count[i]); + } else if (file_space->hslab_def) { + assert (1==file_space->h.stride[i]); + assert (file_space->h.count[i]==mem_space->u.simple.size[i]); + } else if (mem_space->hslab_def) { + assert (1==mem_space->h.stride[i]); + assert (file_space->u.simple.size[i]==mem_space->h.count[i]); + } else { + assert (file_space->u.simple.size[i]== + mem_space->u.simple.size[i]); + } + } +#endif + + + /* + * Calculate size of hyperslab and offset of hyperslab into file and + * memory. + */ + if (file_space->hslab_def) { + for (i=0; i<file_space->u.simple.rank; i++) { + hslab_size[i] = file_space->h.count[i]; + } + } else { + for (i=0; i<file_space->u.simple.rank; i++) { + hslab_size[i] = file_space->u.simple.size[i]; + } + } + for (i=0; i<mem_space->u.simple.rank; i++) { + mem_size[i] = mem_space->u.simple.size[i]; + } + if (file_space->hslab_def) { + for (i=0; i<file_space->u.simple.rank; i++) { + file_offset[i] = file_space->h.start[i]; + } + } else { + for (i=0; i<file_space->u.simple.rank; i++) { + file_offset[i] = 0; + } + } + if (mem_space->hslab_def) { + for (i=0; i<mem_space->u.simple.rank; i++) { + mem_offset[i] = mem_space->h.start[i]; + } + } else { + for (i=0; i<mem_space->u.simple.rank; i++) { + mem_offset[i] = 0; + } + } + hslab_size[file_space->u.simple.rank] = elmt_size; + mem_size[file_space->u.simple.rank] = elmt_size; + file_offset[file_space->u.simple.rank] = 0; + mem_offset[file_space->u.simple.rank] = 0; + + /* Write the hyperslab */ + if (H5F_arr_write (f, layout, efl, hslab_size, + mem_size, mem_offset, file_offset, buf)<0) { + HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, + "unable to write dataset"); + } + + FUNC_LEAVE (SUCCEED); +} + + + + diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index a934b23..be52256 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -100,8 +100,6 @@ H5T_path_t *H5T_path_find (const H5T_t *src, const H5T_t *dst, hbool_t create, H5T_conv_t func); /* Conversion functions */ -herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, - size_t nelmts, void *buf, void *bkg); herr_t H5T_conv_order (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); herr_t H5T_conv_struct (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index d67c38d..6af43b8 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -41,4 +41,11 @@ herr_t H5T_sort_by_offset (H5T_t *dt); herr_t H5T_pack (H5T_t *dt); herr_t H5T_debug (H5T_t *dt, FILE * stream); H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata); + +/* + * This conversion function is here so we can determine whether a conversion + * is a no-op or not. The other conversion functions can go in H5Tpkg.h + */ +herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void *bkg); #endif @@ -502,23 +502,30 @@ H5V_stride_copy(intn n, size_t elmt_size, const size_t *size, FUNC_ENTER(H5V_stride_copy, FAIL); - H5V_vector_cpy(n, idx, size); - nelmts = H5V_vector_reduce_product(n, size); - for (i = 0; i < nelmts; i++) { - /* Copy an element */ - HDmemcpy(dst, src, elmt_size); + if (n) { + H5V_vector_cpy(n, idx, size); + nelmts = H5V_vector_reduce_product(n, size); + for (i = 0; i < nelmts; i++) { - /* Decrement indices and advance pointers */ - for (j = n - 1, carry = TRUE; j >= 0 && carry; --j) { - src += src_stride[j]; - dst += dst_stride[j]; + /* Copy an element */ + HDmemcpy(dst, src, elmt_size); - if (--idx[j]) carry = FALSE; - else idx[j] = size[j]; + /* Decrement indices and advance pointers */ + for (j = n - 1, carry = TRUE; j >= 0 && carry; --j) { + src += src_stride[j]; + dst += dst_stride[j]; + + if (--idx[j]) carry = FALSE; + else idx[j] = size[j]; + } } + } else { + HDmemcpy (dst, src, elmt_size); + HRETURN (SUCCEED); } + FUNC_LEAVE(SUCCEED); } |