diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2003-05-13 16:49:38 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2003-05-13 16:49:38 (GMT) |
commit | 27c63279734a2e508f15f1d51162ac31c865be47 (patch) | |
tree | 904cf6f1446543a49189e0d772f6e7bb9d2f5862 | |
parent | 8751379484a7ea6747e32ab795d820ed93884f2e (diff) | |
download | hdf5-27c63279734a2e508f15f1d51162ac31c865be47.zip hdf5-27c63279734a2e508f15f1d51162ac31c865be47.tar.gz hdf5-27c63279734a2e508f15f1d51162ac31c865be47.tar.bz2 |
[svn-r6857] Purpose: bug fix
Description: when a datatype element size is bigger than I/O datatype
conversion buffer(1MB), library reports failure.
Solution: adjust conversion buffer to be at least equal to one element size
Platforms tested: h5committest
-rw-r--r-- | src/H5Dio.c | 20 | ||||
-rw-r--r-- | test/dsets.c | 155 |
2 files changed, 173 insertions, 2 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 2053139..e447c4f 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -994,7 +994,14 @@ H5D_contig_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S src_type_size = H5T_get_size(dataset->type); dst_type_size = H5T_get_size(mem_type); target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME); + if(target_size==H5D_XFER_MAX_TEMP_BUF_DEF && + target_size<MAX(src_type_size, dst_type_size)) + target_size = MAX(src_type_size, dst_type_size); request_nelmts = target_size / MAX(src_type_size, dst_type_size); + + /* Sanity check elements in temporary buffer */ + if (request_nelmts<=0) + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small"); /* Figure out the strip mine size. */ if (H5S_select_iter_init(&file_iter, file_space, src_type_size)<0) @@ -1230,6 +1237,9 @@ H5D_contig_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5 src_type_size = H5T_get_size(mem_type); dst_type_size = H5T_get_size(dataset->type); target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME); + if(target_size==H5D_XFER_MAX_TEMP_BUF_DEF && + target_size<MAX(src_type_size, dst_type_size)) + target_size = MAX(src_type_size, dst_type_size); request_nelmts = target_size / MAX (src_type_size, dst_type_size); /* Sanity check elements in temporary buffer */ @@ -1491,8 +1501,11 @@ H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_ src_type_size = H5T_get_size(dataset->type); dst_type_size = H5T_get_size(mem_type); target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME); - request_nelmts = target_size / MAX(src_type_size, dst_type_size); - + if(target_size==H5D_XFER_MAX_TEMP_BUF_DEF && + target_size<MAX(src_type_size, dst_type_size)) + target_size = MAX(src_type_size, dst_type_size); + request_nelmts = target_size / MAX (src_type_size, dst_type_size); + /* Sanity check elements in temporary buffer */ if (request_nelmts<=0) HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small"); @@ -1787,6 +1800,9 @@ H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S src_type_size = H5T_get_size(mem_type); dst_type_size = H5T_get_size(dataset->type); target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME); + if(target_size==H5D_XFER_MAX_TEMP_BUF_DEF && + target_size<MAX(src_type_size, dst_type_size)) + target_size = MAX(src_type_size, dst_type_size); request_nelmts = target_size / MAX (src_type_size, dst_type_size); /* Sanity check elements in temporary buffer */ diff --git a/test/dsets.c b/test/dsets.c index df0feb3..823fd4a 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -51,6 +51,7 @@ const char *FILENAME[] = { #define DSET_COMPACT_IO_NAME "compact_io" #define DSET_COMPACT_MAX_NAME "max_compact" #define DSET_COMPACT_MAX2_NAME "max_compact_2" +#define DSET_CONV_BUF_NAME "conv_buf" #define DSET_TCONV_NAME "tconv" #define DSET_DEFLATE_NAME "deflate" #define DSET_SZIP_NAME "szip" @@ -91,6 +92,11 @@ const char *FILENAME[] = { #define BOGUS2_PARAM_2 35 /* (No particular meaning, just for checking value) */ #define BOGUS2_ALL_NPARMS 4 /* Total number of parameter = permanent + "local" parameters */ +/* Dimensionality for conversion buffer test */ +#define DIM1 100 /* Dim. Size of data member # 1 */ +#define DIM2 5000 /* Dim. Size of data member # 2 */ +#define DIM3 10 /* Dim. Size of data member # 3 */ + #ifdef TESTING /* Parameters for internal filter test */ #define FILTER_CHUNK_DIM1 2 @@ -731,6 +737,154 @@ error: /*------------------------------------------------------------------------- + * Function: test_conv_buffer + * + * Purpose: Test size of data type conversion buffer. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Raymond Lu + * Monday, May 12, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +test_conv_buffer(hid_t fid) +{ + typedef struct + { + int a[DIM1][DIM2][DIM3]; + float b[DIM2]; + double c[DIM3]; + } CmpField; + + typedef struct + { + float b[DIM2]; + double c[DIM3]; + } CmpFieldR; + + herr_t status = -1; + int j, k, l; + + CmpField *cf; + CmpFieldR *cfrR; + + hid_t dataset = -1; /* dataset ID */ + hid_t space = -1; /* data space ID */ + hid_t ctype1, ctype2; /* data type ID */ + hid_t arr_type1, arr_type2, arr_type3, arr_type4, arr_type5; + hsize_t dimsa[3]; + hsize_t dimsb[1]; + hsize_t dimsc[1]; + hid_t xfer_list; + hsize_t size; + + TESTING("data type conversion buffer size"); + + cf = (CmpField *)calloc(1, sizeof(CmpField)); + + /* Populate the data members */ + for (j = 0; j < DIM1; j++) + for (k = 0; k < DIM2; k++) + for (l = 0; l < DIM3; l++) + cf->a[j][k][l] = 10*(j+1) + l + k; + + for (j = 0; j < DIM2; j++) + cf->b[j] = 100.*(j+1) + 0.01*j; + + for (j = 0; j < DIM3; j++) + cf->c[j] = 100.*(j+1) + 0.02*j; + + + /* Create data space */ + if((space=H5Screate(H5S_SCALAR))<0) goto error; + + /* Add members to the compound data type */ + dimsa[0] = DIM1; + dimsa[1] = DIM2; + dimsa[2] = DIM3; + dimsb[0] = DIM2; + dimsc[0] = DIM3; + + /* Create the memory data type */ + if((ctype1 = H5Tcreate(H5T_COMPOUND, sizeof (CmpField)))<0) goto error; + + if((arr_type1 = H5Tarray_create(H5T_NATIVE_INT, 3, dimsa, NULL))<0) goto error; + if((arr_type2 = H5Tarray_create(H5T_NATIVE_FLOAT, 1, dimsb, NULL))<0) goto error; + if((arr_type3 = H5Tarray_create(H5T_NATIVE_DOUBLE, 1, dimsc, NULL))<0) goto error; + + if(H5Tinsert(ctype1, "A", HOFFSET(CmpField, a), arr_type1)<0) goto error; + if(H5Tinsert (ctype1, "B", HOFFSET(CmpField, b), arr_type2)<0) goto error; + if(H5Tinsert (ctype1, "C", HOFFSET(CmpField, c), arr_type3)<0) goto error; + + /* Create the dataset */ + if((dataset = H5Dcreate(fid, DSET_CONV_BUF_NAME, ctype1, space, H5P_DEFAULT))<0) goto error; + if(H5Dwrite(dataset, ctype1, H5S_ALL, H5S_ALL, H5P_DEFAULT, cf)<0) goto error; + + if((ctype2 = H5Tcreate(H5T_COMPOUND, sizeof (CmpFieldR)))<0) goto error; + + if((arr_type4 = H5Tarray_create(H5T_NATIVE_FLOAT, 1, dimsb, NULL))<0) goto error; + if((arr_type5 = H5Tarray_create(H5T_NATIVE_DOUBLE, 1, dimsc, NULL))<0) goto error; + + if(H5Tinsert (ctype2, "B", HOFFSET(CmpFieldR, b), arr_type4)<0) goto error; + if(H5Tinsert (ctype2, "C", HOFFSET(CmpFieldR, c), arr_type5)<0) goto error; + + /* Read should succeed since library will set conversion buffer big enough */ + cfrR = (CmpFieldR *)calloc(1, sizeof(CmpFieldR)); + if(H5Dread(dataset, ctype2, H5S_ALL, H5S_ALL, H5P_DEFAULT, cfrR)<0) goto error; + + /* Read should fail since conversion buffer isn't big enough */ + xfer_list = H5Pcreate (H5P_DATASET_XFER); + size = (DIM2*DIM3*(sizeof(int))+ DIM2*(sizeof(float))+ + DIM3*(sizeof(double))); + if(H5Pset_buffer (xfer_list, size, NULL, NULL)<0) goto error; + + H5E_BEGIN_TRY { + status = H5Dread(dataset, ctype2, H5S_ALL, H5S_ALL, xfer_list, cfrR); + } H5E_END_TRY; + if (status >= 0) { + H5_FAILED(); + puts(" Library shouldn't allow conversion buffer too small"); + goto error; + } + + /* Read will succeed since conversion buffer is big enough */ + size = (DIM1*DIM2*DIM3*(sizeof(int))+ DIM2*(sizeof(float))+ + DIM3*(sizeof(double))); + if(H5Pset_buffer (xfer_list, size, NULL, NULL)<0) goto error; + + if(H5Dread(dataset, ctype2, H5S_ALL, H5S_ALL, xfer_list, cfrR)<0) goto error; + + + if(H5Pclose(xfer_list)<0) goto error; + if(H5Sclose(space)<0) goto error; + if(H5Tclose(arr_type1)<0) goto error; + if(H5Tclose(arr_type2)<0) goto error; + if(H5Tclose(arr_type3)<0) goto error; + if(H5Tclose(ctype1)<0) goto error; + if(H5Tclose(ctype2)<0) goto error; + if(H5Tclose(arr_type4)<0) goto error; + if(H5Tclose(arr_type5)<0) goto error; + if(H5Dclose(dataset)<0) goto error; + + if(cf) + HDfree(cf); + if(cfrR) + HDfree(cfrR); + puts(" PASSED"); + return(0); + +error: + return -1; +} + + +/*------------------------------------------------------------------------- * Function: test_tconv * * Purpose: Test some simple data type conversion stuff. @@ -2858,6 +3012,7 @@ main(void) nerrors += test_simple_io(fapl)<0 ?1:0; nerrors += test_compact_io(fapl)<0 ?1:0; nerrors += test_max_compact(fapl)<0 ?1:0; + nerrors += test_conv_buffer(file)<0 ?1:0; nerrors += test_tconv(file)<0 ?1:0; nerrors += test_filters(file)<0 ?1:0; nerrors += test_onebyte_shuffle(file)<0 ?1:0; |