summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2003-05-13 16:49:38 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2003-05-13 16:49:38 (GMT)
commit27c63279734a2e508f15f1d51162ac31c865be47 (patch)
tree904cf6f1446543a49189e0d772f6e7bb9d2f5862
parent8751379484a7ea6747e32ab795d820ed93884f2e (diff)
downloadhdf5-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.c20
-rw-r--r--test/dsets.c155
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;