diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-10-01 18:56:51 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-10-01 18:56:51 (GMT) |
commit | 849d36019d929c409c50cce08842354139dca2f8 (patch) | |
tree | 360639325199a5d2a59ea02d3a9e4ee2662016f9 | |
parent | d809c9309b7fa204ed9f94409228d01087f8b00a (diff) | |
download | hdf5-849d36019d929c409c50cce08842354139dca2f8.zip hdf5-849d36019d929c409c50cce08842354139dca2f8.tar.gz hdf5-849d36019d929c409c50cce08842354139dca2f8.tar.bz2 |
[svn-r733]
Changes since 19980930
----------------------
./MANIFEST
./doc/html/H5.format.html
./src/H5D.c
./src/H5Dprivate.h
./src/H5Farray.c
./src/H5Fistore.c
./src/H5Fprivate.h
./src/H5O.c
./src/H5Ofill.c [NEW]
./src/H5Oprivate.h
./src/H5P.c
./src/H5Ppublic.h
./src/H5Sall.c
./src/H5Shyper.c
./src/H5Spoint.c
./src/H5Sprivate.h
./src/Makefile.in
Added fill values as documented in previous e-mails. They only
work for chunked datasets so far.
./src/H5E.c
./src/H5Epublic.h
./src/H5P.c
Changed H5E_TEMPLATE to H5E_PLIST.
./src/H5Omtime.c
./src/H5V.c
Fixed a typo in a comment.
./src/H5Tconv.c
Fixed a bug in compound type conversions that caused an
assertion to fail.
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | doc/html/H5.format.html | 69 | ||||
-rw-r--r-- | src/H5D.c | 33 | ||||
-rw-r--r-- | src/H5Distore.c | 30 | ||||
-rw-r--r-- | src/H5Dprivate.h | 1 | ||||
-rw-r--r-- | src/H5E.c | 2 | ||||
-rw-r--r-- | src/H5Epublic.h | 2 | ||||
-rw-r--r-- | src/H5Farray.c | 23 | ||||
-rw-r--r-- | src/H5Fistore.c | 30 | ||||
-rw-r--r-- | src/H5Fprivate.h | 14 | ||||
-rw-r--r-- | src/H5O.c | 2 | ||||
-rw-r--r-- | src/H5Ofill.c | 328 | ||||
-rw-r--r-- | src/H5Omtime.c | 4 | ||||
-rw-r--r-- | src/H5Oprivate.h | 16 | ||||
-rw-r--r-- | src/H5P.c | 212 | ||||
-rw-r--r-- | src/H5Ppublic.h | 2 | ||||
-rw-r--r-- | src/H5Sall.c | 25 | ||||
-rw-r--r-- | src/H5Shyper.c | 70 | ||||
-rw-r--r-- | src/H5Spoint.c | 26 | ||||
-rw-r--r-- | src/H5Sprivate.h | 2 | ||||
-rw-r--r-- | src/H5Tconv.c | 4 | ||||
-rw-r--r-- | src/H5V.c | 6 | ||||
-rw-r--r-- | src/Makefile.in | 2 | ||||
-rw-r--r-- | test/istore.c | 14 | ||||
-rw-r--r-- | test/overhead.c | 356 |
25 files changed, 1158 insertions, 116 deletions
@@ -235,6 +235,7 @@ ./src/H5Ocont.c ./src/H5Odtype.c ./src/H5Oefl.c +./src/H5Ofill.c ./src/H5Olayout.c ./src/H5Omtime.c ./src/H5Oname.c diff --git a/doc/html/H5.format.html b/doc/html/H5.format.html index 86d591c..9902bca 100644 --- a/doc/html/H5.format.html +++ b/doc/html/H5.format.html @@ -1,7 +1,7 @@ <html> <head> <title> - HDF5 Draft Disk-Format Specification + HDF5 Disk-Format Specification </title> </head> <body> @@ -40,8 +40,8 @@ Name: Data-Space</a> <li><a href="#DataTypeMessage"> <!-- 0x0003 --> Name: Data-Type</a> - <li><a href="#ReservedMessage_0004"> <!-- 0x0004 --> - Name: Reserved - not assigned yet</a> + <li><a href="#FillValueMessage"> <!-- 0x0004 --> + Name: Data Storage - Fill Value</a> <li><a href="#ReservedMessage_0005"> <!-- 0x0005 --> Name: Reserved - not assigned yet</a> <li><a href="#CompactDataStorageMessage"> <!-- 0x0006 --> @@ -2268,15 +2268,64 @@ </center> <p>Data type examples are <a href="Datatypes.html">here</a>. - + <hr> - <h3><a name="ReservedMessage_0004">Name: Reserved - Not Assigned - Yet</a></h3> - <b>Type:</b> 0x0004<BR> - <b>Length:</b> N/A<BR> - <b>Status:</b> N/A<BR> + <h3><a name="FillValueMessage">Name: Data Storage - Fill Value</a></h3> + <b>Type:</b> 0x0004<br> + <b>Length:</b> varies<br> + <b>Status:</b> Optional, may not be repeated.<br> + + <p>The fill value message stores a single data point value which + is returned to the application when an uninitialized data point + is read from the dataset. The fill value is interpretted with + the same data type as the dataset. If no fill value message is + present then a fill value of all zero is assumed. + + <p> + <center> + <table border cellpadding=4 width="80%"> + <caption align=top> + <b>Fill Value Message</b> + </caption> + + <tr align=center> + <th width="25%">byte</th> + <th width="25%">byte</th> + <th width="25%">byte</th> + <th width="25%">byte</th> + </tr> + + <tr align=center> + <td colspan=4>Size (4 bytes)</td> + </tr> + + <tr align=center> + <td colspan=4><br>Fill Value<br><br></td> + </tr> + </table> + </center> + + <p> + <center> + <table align=center width="80%"> + <tr> + <th width="30%">Field Name</th> + <th width="70%">Description</th> + </tr> + <tr valign=top> + <td>Size (4 bytes)</td> + <td>This is the size of the Fill Value field in bytes.</td> + </tr> + + <tr valign=top> + <td>Fill Value</td> + <td>The fill value. The bytes of the fill value are + interpreted using the same data type as for the dataset.</td> + </tr> + </table> + </center> <hr> <h3><a name="ReservedMessage_0005">Name: Reserved - Not Assigned @@ -3353,7 +3402,7 @@ data-type. <address><a href="mailto:koziol@ncsa.uiuc.edu">Quincey Koziol</a></address> <address><a href="mailto:matzke@llnl.gov">Robb Matzke</a></address> <!-- hhmts start --> -Last modified: Fri Aug 7 11:04:44 EDT 1998 +Last modified: Thu Oct 1 10:09:54 EDT 1998 <!-- hhmts end --> </body> </html> @@ -56,6 +56,9 @@ const H5D_create_t H5D_create_dflt = { 1, 1, 1, 1, 1, 1, 1, 1, /*...produce fewer, but larger I/O......*/ 1, 1, 1, 1, 1, 1, 1, 1}, /*...requests. */ + /* Fill value */ + {NULL, 0, NULL}, /* No fill value */ + /* External file list */ {H5F_ADDR_UNDEF, /* External file list heap address */ 0, /*...slots allocated */ @@ -531,6 +534,14 @@ H5Dget_create_plist(hid_t dset_id) "unable to copy the creation property list"); } + /* Copy the dataset type into the fill value message */ + if (!copied_parms->fill.type && + NULL==(copied_parms->fill.type=H5T_copy(dset->type, + H5T_COPY_TRANSIENT))) { + HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, + "unable to copy dataset data type for fill value"); + } + /* Create an atom */ if ((ret_value=H5I_register ((H5I_group_t)(H5_TEMPLATE_0+ H5P_DATASET_CREATE), @@ -944,6 +955,17 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, "unable to create dataset object header"); } + /* Convert the fill value to the dataset type and write the message */ + if (H5O_fill_convert(&(new_dset->create_parms->fill), new_dset->type)<0) { + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, + "unable to convert fill value to dataset type"); + } + if (H5O_modify(&(new_dset->ent), H5O_FILL, 0, H5O_FLAG_CONSTANT, + &(new_dset->create_parms->fill))<0) { + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, + "unable to update fill value header message"); + } + /* Update the type and space header messages */ if (H5O_modify(&(new_dset->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT|H5O_FLAG_SHARED, new_dset->type)<0 || @@ -1105,6 +1127,14 @@ H5D_open(H5G_entry_t *loc, const char *name) "unable to read data space info from dataset header"); } + /* Get the optional fill value message */ + if (NULL==H5O_read(&(dataset->ent), H5O_FILL, 0, + &(dataset->create_parms->fill))) { + H5E_clear(); + HDmemset(&(dataset->create_parms->fill), 0, + sizeof(dataset->create_parms->fill)); + } + /* Get the optional filters message */ if (NULL==H5O_read (&(dataset->ent), H5O_PLINE, 0, &(dataset->create_parms->pline))) { @@ -1513,6 +1543,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, #endif n = (sconv->f->gath)(dataset->ent.file, &(dataset->layout), &(dataset->create_parms->pline), + &(dataset->create_parms->fill), &(dataset->create_parms->efl), src_type_size, file_space, &file_iter, smine_nelmts, xfer_parms, tconv_buf/*out*/); @@ -1913,6 +1944,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, #endif n = (sconv->f->gath)(dataset->ent.file, &(dataset->layout), &(dataset->create_parms->pline), + &(dataset->create_parms->fill), &(dataset->create_parms->efl), dst_type_size, file_space, &bkg_iter, smine_nelmts, xfer_parms, bkg_buf/*out*/); @@ -1955,6 +1987,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, #endif status = (sconv->f->scat)(dataset->ent.file, &(dataset->layout), &(dataset->create_parms->pline), + &(dataset->create_parms->fill), &(dataset->create_parms->efl), dst_type_size, file_space, &file_iter, smine_nelmts, xfer_parms, tconv_buf); diff --git a/src/H5Distore.c b/src/H5Distore.c index 88399fd..ebfb004 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1170,8 +1170,8 @@ H5F_istore_prune (H5F_t *f, size_t size) static void * H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, const double split_ratios[], const H5O_pline_t *pline, - const hssize_t offset[], hbool_t relax, - intn *idx_hint/*in,out*/) + const H5O_fill_t *fill, const hssize_t offset[], + hbool_t relax, intn *idx_hint/*in,out*/) { uintn idx; /*hash index number */ hbool_t found = FALSE; /*already in cache? */ @@ -1268,9 +1268,20 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, "data pipeline read failed"); } rdcc->nmisses++; + } else if (fill && fill->buf) { + /* + * The chunk doesn't exist in the file. Replicate the fill + * value throughout the chunk. + */ + assert(0==chunk_size % fill->size); + H5V_array_fill(chunk, fill->buf, fill->size, + chunk_size/fill->size); + rdcc->ninits++; + } else { /* - * The chunk doesn't exist in the file. Assume all zeros. + * The chunk doesn't exist in the file and no fill value was + * specified. Assume all zeros. */ HDmemset (chunk, 0, chunk_size); rdcc->ninits++; @@ -1510,8 +1521,8 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, */ herr_t H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, - const H5O_pline_t *pline, const hssize_t offset_f[], - const hsize_t size[], void *buf) + const H5O_pline_t *pline, const H5O_fill_t *fill, + const hssize_t offset_f[], const hsize_t size[], void *buf) { hssize_t offset_m[H5O_LAYOUT_NDIMS]; hsize_t size_m[H5O_LAYOUT_NDIMS]; @@ -1635,7 +1646,7 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, * the chunk. */ if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, chunk_offset, + pline, fill, chunk_offset, FALSE, &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk"); @@ -1682,8 +1693,9 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, */ herr_t H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, - const H5O_pline_t *pline, const hssize_t offset_f[], - const hsize_t size[], const void *buf) + const H5O_pline_t *pline, const H5O_fill_t *fill, + const hssize_t offset_f[], const hsize_t size[], + const void *buf) { hssize_t offset_m[H5O_LAYOUT_NDIMS]; hsize_t size_m[H5O_LAYOUT_NDIMS]; @@ -1811,7 +1823,7 @@ H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, * chunk. */ if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, chunk_offset, + pline, fill, chunk_offset, naccessed==chunk_size, &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index c647cf0..2f65c7a 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -45,6 +45,7 @@ typedef struct H5D_create_t { H5D_layout_t layout; /*storage layout */ intn chunk_ndims; /*chunk dimensionality */ hsize_t chunk_size[32]; /*chunk size if chunked storage */ + H5O_fill_t fill; /*fill value */ H5O_efl_t efl; /*external file list */ H5O_pline_t pline; /*data filter pipeline */ } H5D_create_t; @@ -53,7 +53,7 @@ static const H5E_major_mesg_t H5E_major_mesg_g[] = { {H5E_DATASPACE, "Dataspace interface"}, {H5E_DATASET, "Dataset interface"}, {H5E_STORAGE, "Data storage layer"}, - {H5E_TEMPLATE, "Property list interface"}, + {H5E_PLIST, "Property list interface"}, {H5E_ATTR, "Attribute layer"}, {H5E_PLINE, "Data filters layer"}, {H5E_EFL, "External file list"}, diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 6415b60..a31317f 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -70,7 +70,7 @@ typedef enum H5E_major_t { H5E_DATASPACE, /*Dataspace */ H5E_DATASET, /*Dataset */ H5E_STORAGE, /*data storage */ - H5E_TEMPLATE, /*Property lists */ + H5E_PLIST, /*Property lists */ H5E_ATTR, /*Attribute */ H5E_PLINE, /*Data filters */ H5E_EFL, /*External file list */ diff --git a/src/H5Farray.c b/src/H5Farray.c index b3ebcff..2a2cd1c 100644 --- a/src/H5Farray.c +++ b/src/H5Farray.c @@ -119,10 +119,10 @@ H5F_arr_create (H5F_t *f, struct H5O_layout_t *layout/*in,out*/) herr_t H5F_arr_read (H5F_t *f, const H5D_xfer_t *xfer, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, - const hsize_t _hslab_size[], const hsize_t mem_size[], - const hssize_t mem_offset[], const hssize_t file_offset[], - void *_buf/*out*/) + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const hsize_t _hslab_size[], + const hsize_t mem_size[], const hssize_t mem_offset[], + const hssize_t file_offset[], void *_buf/*out*/) { uint8 *buf = (uint8 *)_buf; /*cast for arithmetic */ hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */ @@ -292,8 +292,8 @@ H5F_arr_read (H5F_t *f, const H5D_xfer_t *xfer, "unable to copy into a proper hyperslab"); } } - if (H5F_istore_read (f, xfer, layout, pline, file_offset, hslab_size, - buf)<0) { + if (H5F_istore_read (f, xfer, layout, pline, fill, file_offset, + hslab_size, buf)<0) { HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } break; @@ -344,9 +344,10 @@ herr_t H5F_arr_write (H5F_t *f, const H5D_xfer_t *xfer, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, - const struct H5O_efl_t *efl, const hsize_t _hslab_size[], - const hsize_t mem_size[], const hssize_t mem_offset[], - const hssize_t file_offset[], const void *_buf) + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + const hsize_t _hslab_size[], const hsize_t mem_size[], + const hssize_t mem_offset[], const hssize_t file_offset[], + const void *_buf) { const uint8 *buf = (const uint8 *)_buf; /*cast for arithmetic */ hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */ @@ -522,8 +523,8 @@ H5F_arr_write (H5F_t *f, const H5D_xfer_t *xfer, "unable to copy from a proper hyperslab"); } } - if (H5F_istore_write (f, xfer, layout, pline, file_offset, hslab_size, - buf)<0) { + if (H5F_istore_write (f, xfer, layout, pline, fill, file_offset, + hslab_size, buf)<0) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 88399fd..ebfb004 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1170,8 +1170,8 @@ H5F_istore_prune (H5F_t *f, size_t size) static void * H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, const double split_ratios[], const H5O_pline_t *pline, - const hssize_t offset[], hbool_t relax, - intn *idx_hint/*in,out*/) + const H5O_fill_t *fill, const hssize_t offset[], + hbool_t relax, intn *idx_hint/*in,out*/) { uintn idx; /*hash index number */ hbool_t found = FALSE; /*already in cache? */ @@ -1268,9 +1268,20 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, "data pipeline read failed"); } rdcc->nmisses++; + } else if (fill && fill->buf) { + /* + * The chunk doesn't exist in the file. Replicate the fill + * value throughout the chunk. + */ + assert(0==chunk_size % fill->size); + H5V_array_fill(chunk, fill->buf, fill->size, + chunk_size/fill->size); + rdcc->ninits++; + } else { /* - * The chunk doesn't exist in the file. Assume all zeros. + * The chunk doesn't exist in the file and no fill value was + * specified. Assume all zeros. */ HDmemset (chunk, 0, chunk_size); rdcc->ninits++; @@ -1510,8 +1521,8 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, */ herr_t H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, - const H5O_pline_t *pline, const hssize_t offset_f[], - const hsize_t size[], void *buf) + const H5O_pline_t *pline, const H5O_fill_t *fill, + const hssize_t offset_f[], const hsize_t size[], void *buf) { hssize_t offset_m[H5O_LAYOUT_NDIMS]; hsize_t size_m[H5O_LAYOUT_NDIMS]; @@ -1635,7 +1646,7 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, * the chunk. */ if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, chunk_offset, + pline, fill, chunk_offset, FALSE, &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk"); @@ -1682,8 +1693,9 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, */ herr_t H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, - const H5O_pline_t *pline, const hssize_t offset_f[], - const hsize_t size[], const void *buf) + const H5O_pline_t *pline, const H5O_fill_t *fill, + const hssize_t offset_f[], const hsize_t size[], + const void *buf) { hssize_t offset_m[H5O_LAYOUT_NDIMS]; hsize_t size_m[H5O_LAYOUT_NDIMS]; @@ -1811,7 +1823,7 @@ H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout, * chunk. */ if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, chunk_offset, + pline, fill, chunk_offset, naccessed==chunk_size, &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 9513689..ca787f7 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -503,10 +503,12 @@ typedef struct H5F_t { case 2: UINT16DECODE(p,l); break; \ } -struct H5O_layout_t; /*forward decl for prototype arguments */ -struct H5O_efl_t; /*forward decl for prototype arguments */ -struct H5O_pline_t; /*forward decl for prototype arguments */ -struct H5D_xfer_t; /*forward decl for prototype arguments */ +/* Forward declarations for prototypes arguments */ +struct H5O_layout_t; +struct H5O_efl_t; +struct H5O_pline_t; +struct H5D_xfer_t; +struct H5O_fill_t; /* library variables */ extern const H5F_create_t H5F_create_dflt; @@ -533,12 +535,14 @@ herr_t H5F_arr_create(H5F_t *f, struct H5O_layout_t *layout /*in,out*/); herr_t H5F_arr_read (H5F_t *f, const struct H5D_xfer_t *xfer, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, const hsize_t _hslab_size[], const hsize_t mem_size[], const hssize_t mem_offset[], const hssize_t file_offset[], void *_buf/*out*/); herr_t H5F_arr_write (H5F_t *f, const struct H5D_xfer_t *xfer, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, const hsize_t _hslab_size[], const hsize_t mem_size[], const hssize_t mem_offset[], const hssize_t file_offset[], const void *_buf); @@ -552,11 +556,13 @@ herr_t H5F_istore_create(H5F_t *f, struct H5O_layout_t *layout /*in,out*/); herr_t H5F_istore_read(H5F_t *f, const struct H5D_xfer_t *xfer, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const hssize_t offset[], const hsize_t size[], void *buf /*out */ ); herr_t H5F_istore_write(H5F_t *f, const struct H5D_xfer_t *xfer, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const hssize_t offset[], const hsize_t size[], const void *buf); herr_t H5F_istore_allocate (H5F_t *f, @@ -55,7 +55,7 @@ static const H5O_class_t *const message_type_g[] = { H5O_SDSPACE, /*0x0001 Simple Dimensionality */ NULL, /*0x0002 Data space (fiber bundle?) */ H5O_DTYPE, /*0x0003 Data Type */ - NULL, /*0x0004 Not assigned */ + H5O_FILL, /*0x0004 Data storage -- fill value */ NULL, /*0x0005 Not assigned */ NULL, /*0x0006 Data storage -- compact object */ H5O_EFL, /*0x0007 Data storage -- external data files */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c new file mode 100644 index 0000000..1328307 --- /dev/null +++ b/src/H5Ofill.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 1998 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Wednesday, September 30, 1998 + * + * Purpose: The fill message indicates a bit pattern to use for + * uninitialized data points of a dataset. + */ +#include <H5private.h> +#include <H5Eprivate.h> +#include <H5MMprivate.h> +#include <H5Oprivate.h> + +#define PABLO_MASK H5O_fill_mask + +static void *H5O_fill_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh); +static herr_t H5O_fill_encode(H5F_t *f, uint8 *p, const void *_mesg); +static void *H5O_fill_copy(const void *_mesg, void *_dest); +static size_t H5O_fill_size(H5F_t *f, const void *_mesg); +static herr_t H5O_fill_reset(void *_mesg); +static herr_t H5O_fill_debug(H5F_t *f, const void *_mesg, FILE *stream, + intn indent, intn fwidth); + +/* This message derives from H5O */ +const H5O_class_t H5O_FILL[1] = {{ + H5O_FILL_ID, /*message id number */ + "fill", /*message name for debugging */ + sizeof(H5O_fill_t), /*native message size */ + H5O_fill_decode, /*decode message */ + H5O_fill_encode, /*encode message */ + H5O_fill_copy, /*copy the native value */ + H5O_fill_size, /*raw message size */ + H5O_fill_reset, /*free internal memory */ + NULL, /*get share method */ + NULL, /*set share method */ + H5O_fill_debug, /*debug the message */ +}}; + +/* Interface initialization */ +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_decode + * + * Purpose: Decode a fill value message. + * + * Return: Success: Ptr to new message in native struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, September 30, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5O_fill_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh) +{ + H5O_fill_t *mesg=NULL; + void *ret_value = NULL; + + FUNC_ENTER(H5O_fill_decode, NULL); + assert(f); + assert(p); + assert(!sh); + + if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill value message"); + } + UINT32DECODE(p, mesg->size); + if (NULL==(mesg->buf=H5MM_malloc(mesg->size))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill value"); + } + HDmemcpy(mesg->buf, p, mesg->size); + ret_value = (void*)mesg; + + done: + if (!ret_value && mesg) { + H5MM_xfree(mesg->buf); + H5MM_xfree(mesg); + } + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_encode + * + * Purpose: Encode a fill value message. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fill_encode(H5F_t *f, uint8 *p, const void *_mesg) +{ + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + + FUNC_ENTER(H5O_fill_encode, FAIL); + assert(f); + assert(p); + assert(mesg && NULL==mesg->type); + + UINT32ENCODE(p, mesg->size); + HDmemcpy(p, mesg->buf, mesg->size); + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_copy + * + * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if + * necessary. + * + * Return: Success: Ptr to _DEST + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5O_fill_copy(const void *_mesg, void *_dest) +{ + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + H5O_fill_t *dest = (H5O_fill_t *)_dest; + void *ret_value = NULL; + + FUNC_ENTER(H5O_fill_copy, NULL); + assert(mesg); + + if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill message"); + } + if (mesg->type && + NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "unable to copy fill value data type"); + } + if (mesg->buf) { + if (NULL==(dest->buf=H5MM_malloc(mesg->size))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill value"); + } + dest->size = mesg->size; + HDmemcpy(dest->buf, mesg->buf, mesg->size); + } + ret_value = dest; + + done: + if (!ret_value && dest) { + H5MM_xfree(dest->buf); + if (dest->type) H5T_close(dest->type); + if (!_dest) H5MM_xfree(dest); + } + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_size + * + * Purpose: Returns the size of the raw message in bytes not counting the + * message type or size fields, but only the data fields. This + * function doesn't take into account alignment. + * + * Return: Success: Message data size in bytes w/o alignment. + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static size_t +H5O_fill_size(H5F_t *f, const void *_mesg) +{ + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + + FUNC_ENTER(H5O_fill_size, 0); + assert(f); + assert(mesg); + + FUNC_LEAVE(4+mesg->size); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_reset + * + * Purpose: Resets a message to an initial state + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fill_reset(void *_mesg) +{ + H5O_fill_t *mesg = (H5O_fill_t *)_mesg; + + FUNC_ENTER(H5O_fill_reset, FAIL); + assert(mesg); + + mesg->buf = H5MM_xfree(mesg->buf); + mesg->size = 0; + if (mesg->type) { + H5T_close(mesg->type); + mesg->type = NULL; + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_debug + * + * Purpose: Prints debugging info for the message. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fill_debug(H5F_t *f, const void *_mesg, FILE *stream, intn indent, + intn fwidth) +{ + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + + FUNC_ENTER(H5O_fill_debug, FAIL); + assert(f); + assert(mesg); + assert(stream); + assert(indent>=0); + assert(fwidth>=0); + + HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, + "Bytes:", mesg->size); + fprintf(stream, "%*s%-*s ", indent, "", fwidth, "Data type:"); + if (mesg->type) { + H5T_debug(mesg->type, stream); + fprintf(stream, "\n"); + } else { + fprintf(stream, "<dataset type>\n"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_convert + * + * Purpose: Convert a fill value from whatever data type it currently has + * to the specified data type. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type) +{ + FUNC_ENTER(H5O_fill_convert, FAIL); + assert(fill); + assert(dset_type); + + /* No-op cases */ + if (!fill->buf || !fill->type || 0==H5T_cmp(fill->type, dset_type)) { + if (fill->type) H5T_close(fill->type); + fill->type = NULL; + HRETURN(SUCCEED); + } + + + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "fill value conversion not supported yet"); + + FUNC_LEAVE(SUCCEED); +} diff --git a/src/H5Omtime.c b/src/H5Omtime.c index f144364..8693032 100644 --- a/src/H5Omtime.c +++ b/src/H5Omtime.c @@ -18,7 +18,7 @@ static void *H5O_mtime_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh); static herr_t H5O_mtime_encode(H5F_t *f, uint8 *p, const void *_mesg); static void *H5O_mtime_copy(const void *_mesg, void *_dest); static size_t H5O_mtime_size(H5F_t *f, const void *_mesg); -static herr_t H5O_mtime_debug(H5F_t *f, const void *_mesg, FILE * stream, +static herr_t H5O_mtime_debug(H5F_t *f, const void *_mesg, FILE *stream, intn indent, intn fwidth); /* This message derives from H5O */ @@ -246,7 +246,7 @@ H5O_mtime_copy(const void *_mesg, void *_dest) * * Return: Success: Message data size in bytes w/o alignment. * - * Failure: FAIL + * Failure: 0 * * Programmer: Robb Matzke * matzke@llnl.gov diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 748e619..adc9396 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -133,6 +133,19 @@ extern const H5O_class_t H5O_DTYPE[1]; /* operates on an H5T_t struct */ /* + * Fill Value Message. + */ +#define H5O_FILL_ID 0x0004 +extern const H5O_class_t H5O_FILL[1]; + +typedef struct H5O_fill_t { + H5T_t *type; /*type. Null implies same as dataset */ + size_t size; /*number of bytes in the fill value */ + void *buf; /*the fill value */ +} H5O_fill_t; + + +/* * External File List Message */ #define H5O_EFL_ID 0x0007 /*external file list id */ @@ -281,4 +294,7 @@ herr_t H5O_efl_read (H5F_t *f, const H5O_efl_t *efl, haddr_t *addr, herr_t H5O_efl_write (H5F_t *f, const H5O_efl_t *efl, haddr_t *addr, hsize_t size, const uint8 *buf); +/* Fill value operators */ +herr_t H5O_fill_convert(H5O_fill_t *fill, H5T_t *type); + #endif @@ -346,6 +346,7 @@ H5P_close (H5P_class_t type, void *plist) break; case H5P_DATASET_CREATE: + H5O_reset(H5O_FILL, &(dc_list->fill)); H5O_reset(H5O_EFL, &(dc_list->efl)); H5O_reset(H5O_PLINE, &(dc_list->pline)); break; @@ -2086,15 +2087,16 @@ H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/) /*------------------------------------------------------------------------- * Function: H5Pset_hyper_cache * - * Purpose: Given a dataset transfer property list, indicate whether to cache - * the hyperslab blocks during the I/O (which speeds things up) and the - * maximum size of the hyperslab block to cache. If a block is smaller - * than to limit, it may still not be cached if no memory is available. - * Setting the limit to 0 indicates no limitation on the size of block - * to attempt to cache. + * Purpose: Given a dataset transfer property list, indicate whether to + * cache the hyperslab blocks during the I/O (which speeds + * things up) and the maximum size of the hyperslab block to + * cache. If a block is smaller than to limit, it may still not + * be cached if no memory is available. Setting the limit to 0 + * indicates no limitation on the size of block to attempt to + * cache. * - * The default is to cache blocks with no limit on block size for serial - * I/O and to not cache blocks for parallel I/O + * The default is to cache blocks with no limit on block size + * for serial I/O and to not cache blocks for parallel I/O * * Return: Success: SUCCEED * @@ -2147,7 +2149,8 @@ H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit) *------------------------------------------------------------------------- */ herr_t -H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, unsigned *limit/*out*/) +H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, + unsigned *limit/*out*/) { H5D_xfer_t *plist = NULL; @@ -2594,7 +2597,6 @@ herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right) { - H5D_xfer_t *plist = NULL; FUNC_ENTER(H5Pget_btree_ratios, FAIL); @@ -2621,6 +2623,186 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle, } +/*------------------------------------------------------------------------- + * Function: H5Pset_fill_value + * + * Purpose: Set the fill value for a dataset creation property list. The + * VALUE is interpretted as being of type TYPE, which need not + * be the same type as the dataset but the library must be able + * to convert VALUE to the dataset type when the dataset is + * created. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value) +{ + H5D_create_t *plist = NULL; + H5T_t *type = NULL; + + FUNC_ENTER(H5Pset_fill_value, FAIL); + H5TRACE3("e","iix",plist_id,type_id,value); + + /* Check arguments */ + if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) || + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation property list"); + } + if (H5_DATATYPE!=H5I_group(type_id) || + NULL==(type=H5I_object(type_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (!value) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value specified"); + } + + /* Set the fill value */ + H5O_reset(H5O_FILL, &(plist->fill)); + if (NULL==(plist->fill.type=H5T_copy(type, H5T_COPY_TRANSIENT))) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to copy data type"); + } + plist->fill.size = H5T_get_size(type); + if (NULL==(plist->fill.buf=H5MM_malloc(plist->fill.size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, + "memory allocation failed for fill value"); + } + HDmemcpy(plist->fill.buf, value, plist->fill.size); + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_fill_value + * + * Purpose: Queries the fill value property of a dataset creation + * property list. The fill value is returned through the VALUE + * pointer and the memory is allocated by the caller. The fill + * value will be converted from its current data type to the + * specified TYPE. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) +{ + H5D_create_t *plist = NULL; + H5T_t *type = NULL; + H5T_cdata_t *cdata = NULL; /*conversion data */ + H5T_conv_t cfunc = NULL; /*conversion function */ + void *buf = NULL; /*conversion buffer */ + void *bkg = NULL; /*conversion buffer */ + H5_timer_t timer; /*conversion timer */ + hid_t src_id = -1; /*source data type id */ + herr_t status; + herr_t ret_value = FAIL; + + FUNC_ENTER(H5Pget_fill_value, FAIL); + H5TRACE3("e","iix",plist_id,type_id,value); + + /* Check arguments */ + if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) || + NULL==(plist=H5I_object(plist_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation proprety list"); + } + if (H5_DATATYPE!=H5I_group(type_id) || + NULL==(type=H5I_object(type_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (!value) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "no fill value output buffer"); + } + + /* + * If no fill value is defined then return an error. We can't even + * return zero because we don't know the data type of the dataset and + * data type conversion might not have resulted in zero. + */ + if (NULL==plist->fill.buf) { + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no fill value defined"); + } + + /* + * Can we convert between the source and destination data types? + */ + if (NULL==(cfunc=H5T_find(plist->fill.type, type, H5T_BKG_NO, &cdata))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to convert between src and dst data types"); + } + src_id = H5I_register(H5_DATATYPE, + H5T_copy (plist->fill.type, H5T_COPY_TRANSIENT)); + if (src_id<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to copy/register data type"); + } + + /* + * Data type conversions are always done in place, so we need a buffer + * other than the fill value buffer that is large enough for both source + * and destination. The app-supplied buffer might do okay. + */ + if (H5T_get_size(type)>=H5T_get_size(plist->fill.type)) { + buf = value; + if (cdata->need_bkg>=H5T_BKG_TEMP && + NULL==(bkg=H5MM_malloc(H5T_get_size(type)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } + } else { + if (NULL==(buf=H5MM_malloc(H5T_get_size(plist->fill.type)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } + if (cdata->need_bkg>=H5T_BKG_TEMP) bkg = value; + } + HDmemcpy(buf, plist->fill.buf, H5T_get_size(plist->fill.type)); + + /* Do the conversion */ +#ifdef H5T_DEBUG + H5T_timer_begin(&timer, cdata); +#endif + cdata->command = H5T_CONV_CONV; + status = (cfunc)(src_id, type_id, cdata, 1, buf, bkg); +#ifdef H5T_DEBUG + H5T_timer_end(&timer, cdata, 1); +#endif + if (status<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "data type conversion failed"); + } + if (buf!=value) HDmemcpy(value, buf, H5T_get_size(type)); + ret_value = SUCCEED; + + done: + if (buf!=value) H5MM_xfree(buf); + if (bkg!=value) H5MM_xfree(bkg); + if (src_id>=0) H5I_dec_ref(src_id); + FUNC_LEAVE(ret_value); +} + + #ifdef HAVE_PARALLEL /*------------------------------------------------------------------------- * Function: H5Pset_mpi @@ -3015,16 +3197,22 @@ H5P_copy (H5P_class_t type, const void *src) dc_src = (const H5D_create_t*)src; dc_dst = (H5D_create_t*)dst; + /* Copy the fill value */ + if (NULL==H5O_copy(H5O_FILL, &(dc_src->fill), &(dc_dst->fill))) { + HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL, + "unabe to copy fill value message"); + } + /* Copy the external file list */ HDmemset(&(dc_dst->efl), 0, sizeof(dc_dst->efl)); if (NULL==H5O_copy(H5O_EFL, &(dc_src->efl), &(dc_dst->efl))) { - HRETURN_ERROR(H5E_TEMPLATE, H5E_CANTINIT, NULL, + HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL, "unable to copy external file list message"); } /* Copy the filter pipeline */ if (NULL==H5O_copy(H5O_PLINE, &(dc_src->pline), &(dc_dst->pline))) { - HRETURN_ERROR(H5E_TEMPLATE, H5E_CANTINIT, NULL, + HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL, "unable to copy filter pipeline message"); } diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index cc6c4e3..cccd4fd 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -112,6 +112,8 @@ herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right); herr_t H5Pget_btree_ratios(hid_t plist_id, double *left/*out*/, double *middle/*out*/, double *right/*out*/); +herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); +herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/); #ifdef HAVE_PARALLEL herr_t H5Pset_mpi (hid_t plist_id, MPI_Comm comm, MPI_Info info); diff --git a/src/H5Sall.c b/src/H5Sall.c index e3ea157..c798a61 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -24,12 +24,14 @@ static size_t H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *iter, size_t max); static size_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, const H5D_xfer_t *xfer_parms, void *buf/*out*/); static herr_t H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, @@ -167,9 +169,10 @@ H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *sel_iter, size_t max) static size_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, - const struct H5O_efl_t *efl, size_t elmt_size, - const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const H5D_xfer_t *xfer_parms, void *_buf/*out*/) + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + size_t elmt_size, const H5S_t *file_space, + H5S_sel_iter_t *file_iter, size_t nelmts, + const H5D_xfer_t *xfer_parms, void *_buf/*out*/) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -222,8 +225,8 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, /* * Gather from file. */ - if (H5F_arr_read (f, xfer_parms, layout, pline, efl, hsize, hsize, zero, - file_offset, buf/*out*/)<0) { + if (H5F_arr_read (f, xfer_parms, layout, pline, fill, efl, hsize, hsize, + zero, file_offset, buf/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } @@ -256,10 +259,10 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, */ static herr_t H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, - size_t elmt_size, const H5S_t *file_space, - H5S_sel_iter_t *file_iter, size_t nelmts, - const H5D_xfer_t *xfer_parms, const void *_buf) + const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, H5S_sel_iter_t *file_iter, + size_t nelmts, const H5D_xfer_t *xfer_parms, const void *_buf) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -308,8 +311,8 @@ H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, /* * Scatter to file. */ - if (H5F_arr_write (f, xfer_parms, layout, pline, efl, hsize, hsize, zero, - file_offset, buf)<0) { + if (H5F_arr_write (f, xfer_parms, layout, pline, fill, efl, hsize, hsize, + zero, file_offset, buf)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); } diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 54ee1bd..c27d068 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -26,6 +26,7 @@ typedef struct { H5F_t *f; const struct H5O_layout_t *layout; const struct H5O_pline_t *pline; + const struct H5O_fill_t *fill; const struct H5O_efl_t *efl; size_t elmt_size; const H5S_t *space; @@ -55,12 +56,14 @@ static size_t H5S_hyper_favail (const H5S_t *space, const H5S_sel_iter_t *iter, size_t max); static size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, const H5D_xfer_t *xfer_parms, void *buf/*out*/); static herr_t H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, @@ -425,7 +428,8 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, *------------------------------------------------------------------------- */ static herr_t -H5S_hyper_block_cache (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read) +H5S_hyper_block_cache (H5S_hyper_node_t *node, + H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -454,8 +458,8 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_i if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms, fhyper_info->layout, fhyper_info->pline, - fhyper_info->efl, hsize, hsize, zero, file_offset, - node->cinfo.block/*out*/)<0) + fhyper_info->fill, fhyper_info->efl, hsize, hsize, + zero, file_offset, node->cinfo.block/*out*/)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); } /* end if */ else { @@ -501,9 +505,14 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in !! NOTE !! This will need to be changed for different dimension permutations from the standard 'C' ordering! */ - HDmemcpy(fhyper_info->dst,node->cinfo.pos,region_size*fhyper_info->elmt_size); + HDmemcpy(fhyper_info->dst, + node->cinfo.pos, + region_size*fhyper_info->elmt_size); - /* Decrement the number of elements left in block to read & move the offset */ + /* + * Decrement the number of elements left in block to read & move the + * offset + */ node->cinfo.pos+=region_size*fhyper_info->elmt_size; node->cinfo.left-=region_size; @@ -536,7 +545,9 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in *------------------------------------------------------------------------- */ static herr_t -H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, hsize_t region_size) +H5S_hyper_block_write (H5S_hyper_node_t *node, + H5S_hyper_fhyper_info_t *fhyper_info, + hsize_t region_size) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -552,16 +563,24 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_i !! NOTE !! This will need to be changed for different dimension permutations from the standard 'C' ordering! */ - HDmemcpy(node->cinfo.pos,fhyper_info->src,region_size*fhyper_info->elmt_size); + HDmemcpy(node->cinfo.pos, + fhyper_info->src, + region_size*fhyper_info->elmt_size); - /* Decrement the number of elements left in block to read & move the offset */ + /* + * Decrement the number of elements left in block to read & move the + * offset + */ node->cinfo.pos+=region_size*fhyper_info->elmt_size; node->cinfo.left-=region_size; /* If we've read in all the elements from the block, throw it away */ if(node->cinfo.left==0) { /* Copy the location of the region in the file */ - HDmemcpy(file_offset,node->start,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t))); + HDmemcpy(file_offset, + node->start, + (fhyper_info->space->extent.u.simple.rank * + sizeof(hssize_t))); file_offset[fhyper_info->space->extent.u.simple.rank]=0; /* Set the hyperslab size to write */ @@ -571,8 +590,8 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_i if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms, fhyper_info->layout, fhyper_info->pline, - fhyper_info->efl, hsize, hsize, zero, file_offset, - node->cinfo.block/*out*/)<0) + fhyper_info->fill, fhyper_info->efl, hsize, hsize, + zero, file_offset, node->cinfo.block/*out*/)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); /* Release the temporary buffer */ @@ -650,10 +669,14 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) /* perform I/O on data from regions */ for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { /* Compute the size of the region to read */ - region_size=MIN(fhyper_info->nelmts, (regions[i].end-regions[i].start)+1); + region_size=MIN(fhyper_info->nelmts, + (regions[i].end-regions[i].start)+1); /* Check if this hyperslab block is cached or could be cached */ - if(!regions[i].node->cinfo.cached && (fhyper_info->xfer_parms->cache_hyper && (fhyper_info->xfer_parms->block_limit==0 || fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) { + if(!regions[i].node->cinfo.cached && + (fhyper_info->xfer_parms->cache_hyper && + (fhyper_info->xfer_parms->block_limit==0 || + fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) { /* if we aren't cached, attempt to cache the block */ H5S_hyper_block_cache(regions[i].node,fhyper_info,1); } /* end if */ @@ -691,17 +714,17 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) */ if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms, fhyper_info->layout, fhyper_info->pline, - fhyper_info->efl, hsize, hsize, zero, - file_offset, + fhyper_info->fill, fhyper_info->efl, + hsize, hsize, zero, file_offset, fhyper_info->dst/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } #ifdef QAK - printf("%s: check 2.3, region #%d\n",FUNC,(int)i); - for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++) - printf("%s: %d - pos=%d\n", - FUNC,j,(int)fhyper_info->iter->hyp.pos[j]); + printf("%s: check 2.3, region #%d\n",FUNC,(int)i); + for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++) + printf("%s: %d - pos=%d\n", + FUNC,j,(int)fhyper_info->iter->hyp.pos[j]); #endif /* QAK */ } /* end else */ @@ -789,6 +812,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) static size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, const H5D_xfer_t *xfer_parms, @@ -833,6 +857,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, fhyper_info.f=f; fhyper_info.layout=layout; fhyper_info.pline=pline; + fhyper_info.fill=fill; fhyper_info.efl=efl; fhyper_info.elmt_size=elmt_size; fhyper_info.space=file_space; @@ -961,8 +986,9 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) */ if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms, fhyper_info->layout, fhyper_info->pline, - fhyper_info->efl, hsize, hsize, zero, - file_offset, fhyper_info->src)<0) { + fhyper_info->fill, fhyper_info->efl, + hsize, hsize, zero, file_offset, + fhyper_info->src)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } @@ -1049,6 +1075,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) static herr_t H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, const H5D_xfer_t *xfer_parms, @@ -1094,6 +1121,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, fhyper_info.f=f; fhyper_info.layout=layout; fhyper_info.pline=pline; + fhyper_info.fill=fill; fhyper_info.efl=efl; fhyper_info.elmt_size=elmt_size; fhyper_info.space=file_space; diff --git a/src/H5Spoint.c b/src/H5Spoint.c index d532fcf..11aa324 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -25,6 +25,7 @@ static size_t H5S_point_favail (const H5S_t *space, const H5S_sel_iter_t *iter, size_t max); static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, @@ -32,6 +33,7 @@ static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, void *buf/*out*/); static herr_t H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, @@ -265,10 +267,10 @@ H5S_point_favail (const H5S_t __unused__ *space, static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, - const struct H5O_efl_t *efl, size_t elmt_size, - const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const H5D_xfer_t *xfer_parms, - void *_buf/*out*/) + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + size_t elmt_size, const H5S_t *file_space, + H5S_sel_iter_t *file_iter, size_t nelmts, + const H5D_xfer_t *xfer_parms, void *_buf/*out*/) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -317,8 +319,8 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, file_offset[i] += file_space->select.offset[i]; /* Go read the point */ - if (H5F_arr_read (f, xfer_parms, layout, pline, efl, hsize, hsize, - zero, file_offset, buf/*out*/)<0) { + if (H5F_arr_read (f, xfer_parms, layout, pline, fill, efl, hsize, + hsize, zero, file_offset, buf/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } @@ -374,10 +376,10 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, static herr_t H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, - const struct H5O_efl_t *efl, size_t elmt_size, - const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const H5D_xfer_t *xfer_parms, - const void *_buf) + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + size_t elmt_size, const H5S_t *file_space, + H5S_sel_iter_t *file_iter, size_t nelmts, + const H5D_xfer_t *xfer_parms, const void *_buf) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -445,8 +447,8 @@ H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, } #endif /* QAK */ /* Go write the point */ - if (H5F_arr_write (f, xfer_parms, layout, pline, efl, hsize, hsize, - zero, file_offset, buf)<0) { + if (H5F_arr_write (f, xfer_parms, layout, pline, fill, efl, hsize, + hsize, zero, file_offset, buf)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index c870a29..c434690 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -191,6 +191,7 @@ typedef struct H5S_fconv_t { /* Gather elements from disk to type conversion buffer */ size_t (*gath)(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, const struct H5D_xfer_t *xfer_parms, @@ -199,6 +200,7 @@ typedef struct H5S_fconv_t { /* Scatter elements from type conversion buffer to disk */ herr_t (*scat)(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, const struct H5D_xfer_t *xfer_parms, diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 0f1d120..76d92c9 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -517,16 +517,18 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (src2dst[i]<0) continue; src_memb = src->u.compnd.memb + i; dst_memb = dst->u.compnd.memb + src2dst[i]; - offset -= dst_memb->size; if (dst_memb->size > src_memb->size) { H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]]; H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]]; + offset -= src_memb->size; memb_cdata->command = H5T_CONV_CONV; (tconv_func)(priv->src_memb_id[src2dst[i]], priv->dst_memb_id[src2dst[i]], memb_cdata, priv->memb_nelmts[i], buf+offset, bkg+dst_memb->offset); + } else { + offset -= dst_memb->size; } HDmemmove (bkg+dst_memb->offset, buf+offset, dst_memb->size); } @@ -643,9 +643,9 @@ H5V_stride_copy2(hsize_t nelmts, hsize_t elmt_size, /*------------------------------------------------------------------------- * Function: H5V_array_fill * - * Purpose: Fills all bytes of an array with the same value using memset(). - * Increases amount copied by power of two until the halfway point is - * crossed, then copies the rest in one swoop. + * Purpose: Fills all bytes of an array with the same value using + * memset(). Increases amount copied by power of two until the + * halfway point is crossed, then copies the rest in one swoop. * * Return: Success: SUCCEED * diff --git a/src/Makefile.in b/src/Makefile.in index 158b452..750a200 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -17,7 +17,7 @@ LIB=libhdf5.a LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c \ H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c \ H5Fstdio.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c \ - H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c \ + H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c \ H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c \ H5Ostab.c H5P.c H5R.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Spoint.c \ H5Sselect.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5TB.c H5V.c H5Z.c diff --git a/test/istore.c b/test/istore.c index 7e3ef1d..468ee01 100644 --- a/test/istore.c +++ b/test/istore.c @@ -319,8 +319,8 @@ test_extend(H5F_t *f, const char *prefix, memset(buf, (signed)(128+ctr), (size_t)nelmts); /* Write to disk */ - if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, size, size, - zero, offset, buf)<0) { + if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, size, + size, zero, offset, buf)<0) { puts("*FAILED*"); if (!isatty(1)) { AT(); @@ -330,8 +330,8 @@ test_extend(H5F_t *f, const char *prefix, } /* Read from disk */ memset(check, 0xff, (size_t)nelmts); - if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, size, size, - zero, offset, check)<0) { + if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, size, + size, zero, offset, check)<0) { puts("*FAILED*"); if (!isatty(1)) { AT(); @@ -366,7 +366,7 @@ test_extend(H5F_t *f, const char *prefix, /* Now read the entire array back out and check it */ memset(buf, 0xff, nx * ny * nz); - if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, whole_size, + if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, whole_size, whole_size, zero, zero, buf)<0) { puts("*FAILED*"); if (!isatty(1)) { @@ -490,8 +490,8 @@ test_sparse(H5F_t *f, const char *prefix, size_t nblocks, memset(buf, (signed)(128+ctr), nx * ny * nz); /* write to disk */ - if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, size, size, - zero, offset, buf)<0) { + if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, size, + size, zero, offset, buf)<0) { puts("*FAILED*"); if (!isatty(1)) { AT(); diff --git a/test/overhead.c b/test/overhead.c new file mode 100644 index 0000000..785bfd7 --- /dev/null +++ b/test/overhead.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 1998 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, September 28, 1998 + * + * Purpose: Creates a chunked dataset and measures the storage overhead. + */ +#include <ctype.h> +#include <fcntl.h> +#include <hdf5.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <H5config.h> +#ifndef HAVE_ATTRIBUTE +# undef __attribute__ +# define __attribute__(X) /*void*/ +# define __unused__ /*void*/ +#else +# define __unused__ __attribute__((unused)) +#endif + +#define FILE_NAME_1 "overhead.h5" +#define FALSE 0 +#define TRUE 1 + +typedef enum fill_t { + FILL_ALL, + FILL_FORWARD, + FILL_REVERSE, + FILL_INWARD, + FILL_OUTWARD, + FILL_RANDOM +} fill_t; + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: Prints a usage message and exits. + * + * Return: never returns + * + * Programmer: Robb Matzke + * Wednesday, September 30, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +usage(const char *prog) +{ + fprintf(stderr, "usage: %s [STYLE|cache] [LEFT [MIDDLE [RIGHT]]]\n", + prog); + fprintf(stderr, "\ + STYLE is the order that the dataset is filled and should be one of:\n\ + forward -- Fill the dataset from lowest address to highest\n\ + address. This style tests the right split ratio.\n\ + reverse -- Fill the dataset from highest address to lowest\n\ + address. This is the reverse order of `forward' and\n\ + tests the left split ratio.\n\ + inward -- Fill beginning at both the lowest and highest\n\ + addresses and work in toward the center of the\n\ + dataset. This tests the middle split ratio.\n\ + outward -- Start at the center of the dataset and work outward\n\ + toward the lowest and highest addresses. This tests\n\ + both left and right split ratios.\n\ + random -- Write the chunks of the dataset in random order. This\n\ + tests all split ratios.\n\ + If no fill style is specified then all fill styles are tried and a\n\ + single value is printed for each one.\n\ +\n\ + If the word `cache' is used instead of a fill style then the raw data\n\ + cache is enabled. It is not possible to enable the raw data cache when\n\ + a specific fill style is used because H5Fflush() is called after each\n\ + chunk is written in order to calculate overhead during the test. If\n\ + the cache is enabled then chunks are written to disk in different orders\n\ + than the actual H5Dwrite() calls in the test due to collisions and the\n\ + resulting B-tree will be split differently.\n\ +\n\ + LEFT, MIDDLE, and RIGHT are the ratios to use for splitting and should\n\ + be values between zero and one, inclusive.\n"); + exit(1); +} + + +/*------------------------------------------------------------------------- + * Function: cleanup + * + * Purpose: Removes test files + * + * Return: void + * + * Programmer: Robb Matzke + * Thursday, June 4, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +cleanup (void) +{ + if (!getenv ("HDF5_NOCLEANUP")) { + remove (FILE_NAME_1); + } +} + + +/*------------------------------------------------------------------------- + * Function: display_error_cb + * + * Purpose: Displays the error stack after printing "*FAILED*". + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, March 4, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +display_error_cb (void __unused__ *client_data) +{ + puts ("*FAILED*"); + H5Eprint (stdout); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: test + * + * Purpose: The guts of the test + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Robb Matzke + * Wednesday, September 30, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test(fill_t fill_style, const double splits[], + hbool_t verbose, hbool_t use_rdcc) +{ + hid_t file, fapl, dcpl, xfer, mspace, fspace, dset; + hsize_t ch_size[1] = {1}; /*chunk size */ + hsize_t cur_size[1] = {1000}; /*current dataset size */ + hsize_t max_size[1] = {H5S_UNLIMITED}; /*maximum dataset size */ + hssize_t hs_start[1]; /*hyperslab start offset*/ + hsize_t hs_count[1] = {1}; /*hyperslab nelmts */ + int fd; /*h5 file direct */ + static int *had = NULL; /*for random filling */ + const char *sname; /*fill style nam */ + int mdc_nelmts; /*num meta objs to cache*/ + hsize_t i; + int j; + struct stat sb; + + if (!had) had = calloc(cur_size[0], sizeof(int)); + if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) goto error; + if (!use_rdcc) { + if (H5Pget_cache(fapl, &mdc_nelmts, NULL, NULL, NULL)<0) goto error; + if (H5Pset_cache(fapl, mdc_nelmts, 0, 0, 0.0)<0) goto error; + } + if ((file=H5Fcreate(FILE_NAME_1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } + if ((dcpl=H5Pcreate(H5P_DATASET_CREATE))<0) goto error; + if (H5Pset_chunk(dcpl, 1, ch_size)<0) goto error; + if ((xfer=H5Pcreate(H5P_DATASET_XFER))<0) goto error; + if (H5Pset_btree_ratios(xfer, splits[0], splits[1], splits[2])<0) { + goto error; + } + if ((fspace=H5Screate_simple(1, cur_size, max_size))<0) goto error; + if ((mspace=H5Screate_simple(1, ch_size, ch_size))<0) goto error; + if ((dset=H5Dcreate(file, "chunked", H5T_NATIVE_INT, + fspace, dcpl))<0) goto error; + if ((fd=open(FILE_NAME_1, O_RDONLY))<0) goto error; + + for (i=1; i<=cur_size[0]; i++) { + + /* Decide which chunk to write to */ + switch (fill_style) { + case FILL_FORWARD: + hs_start[0] = i-1; + break; + case FILL_REVERSE: + hs_start[0] = cur_size[0]-i; + break; + case FILL_INWARD: + hs_start[0] = i%2 ? i/2 : cur_size[0]-i/2; + break; + case FILL_OUTWARD: + j = (cur_size[0]-i)+1; + hs_start[0] = j%2 ? j/2 : cur_size[0]-j/2; + break; + case FILL_RANDOM: + for (j=rand()%cur_size[0]; had[j]; j=(j+1)%cur_size[0]) /*void*/; + hs_start[0] = j; + had[j] = 1; + break; + case FILL_ALL: + abort(); + } + + /* Write the chunk */ + if (H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_start, NULL, + hs_count, NULL)<0) goto error; + if (H5Dwrite(dset, H5T_NATIVE_INT, mspace, fspace, xfer, &i)<0) { + goto error; + } + + /* Determine overhead */ + if (verbose) { + if (H5Fflush(file)<0) goto error; + if (fstat(fd, &sb)<0) goto error; + printf("%4lu %8.3f\n", + (unsigned long)i, + (double)(sb.st_size-i*sizeof(int))/(double)i); + } + } + + H5Dclose(dset); + H5Sclose(mspace); + H5Sclose(fspace); + H5Pclose(dcpl); + H5Fclose(file); + + if (!verbose) { + switch (fill_style) { + case FILL_FORWARD: + sname = "forward"; + break; + case FILL_REVERSE: + sname = "reverse"; + break; + case FILL_INWARD: + sname = "inward"; + break; + case FILL_OUTWARD: + sname = "outward"; + break; + case FILL_RANDOM: + sname = "random"; + break; + case FILL_ALL: + abort(); + } + if (fstat(fd, &sb)<0) goto error; + printf("%-7s %8.3f\n", sname, + (sb.st_size-cur_size[0]*sizeof(int))/(double)cur_size[0]); + + } + close(fd); + return 0; + + error: + H5Dclose(dset); + H5Sclose(mspace); + H5Sclose(fspace); + H5Pclose(dcpl); + H5Fclose(file); + free(had); + close(fd); + return 1; +} + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: + * + * Return: Success: zero + * + * Failure: non-zero + * + * Programmer: Robb Matzke + * Monday, September 28, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + hid_t xfer; + fill_t fill_style = FILL_ALL; + hbool_t use_cache = FALSE; + double splits[3]; + int i, j, nerrors=0; + + /* Default split ratios */ + H5Eset_auto(display_error_cb, NULL); + if ((xfer=H5Pcreate(H5P_DATASET_XFER))<0) goto error; + if (H5Pget_btree_ratios(xfer, splits+0, splits+1, splits+2)<0) { + goto error; + } + if (H5Pclose(xfer)<0) goto error; + + /* Parse command-line options */ + for (i=1, j=0; i<argc; i++) { + if (!strcmp(argv[i], "forward")) { + fill_style = FILL_FORWARD; + } else if (!strcmp(argv[i], "reverse")) { + fill_style = FILL_REVERSE; + } else if (!strcmp(argv[i], "inward")) { + fill_style = FILL_INWARD; + } else if (!strcmp(argv[i], "outward")) { + fill_style = FILL_OUTWARD; + } else if (!strcmp(argv[i], "random")) { + fill_style = FILL_RANDOM; + } else if (!strcmp(argv[i], "cache")) { + use_cache = TRUE; + } else if (j<3 && (isdigit(argv[i][0]) || '.'==argv[i][0])) { + splits[j++] = strtod(argv[i], NULL); + } else { + usage(argv[0]); + } + } + + if (FILL_ALL==fill_style) { + printf("%-7s %8s\n", "Style", "Bytes/Chunk"); + printf("%-7s %8s\n", "-----", "-----------"); + nerrors += test(FILL_FORWARD, splits, FALSE, use_cache); + nerrors += test(FILL_REVERSE, splits, FALSE, use_cache); + nerrors += test(FILL_INWARD, splits, FALSE, use_cache); + nerrors += test(FILL_OUTWARD, splits, FALSE, use_cache); + nerrors += test(FILL_RANDOM, splits, FALSE, use_cache); + } else { + if (use_cache) usage(argv[0]); + nerrors += test(fill_style, splits, TRUE, FALSE); + } + if (nerrors>0) goto error; + cleanup(); + return 0; + + error: + fprintf(stderr, "*** ERRORS DETECTED ***\n"); + return 1; +} |