summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2011-04-12 20:25:27 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2011-04-12 20:25:27 (GMT)
commit6fc1d0535960edf24e66ca14afc27b31ec2320db (patch)
tree3b5cae467443e375c05433294137fe45c0d44717
parent1285f6734c5916ce54104e05163b4114655d7954 (diff)
downloadhdf5-6fc1d0535960edf24e66ca14afc27b31ec2320db.zip
hdf5-6fc1d0535960edf24e66ca14afc27b31ec2320db.tar.gz
hdf5-6fc1d0535960edf24e66ca14afc27b31ec2320db.tar.bz2
[svn-r20487] Bug 1386 - allow dimension size to be zero even though it isn't unlimited. This is a follow-up checkin for
r20440 and r20469: 1. The dataspace code has another bug - when the maximal dimension isn't passed in for H5Sset_extent_simple, it is supposed to be same as the dimension. The current library sets NULL to it. I corrected it and added a test case to it. 2. I corrected the tests of Fortran and C++ for this problem. Tested on heiwa, jam, and amani.
-rw-r--r--c++/test/th5s.cpp25
-rw-r--r--fortran/test/tH5S.f908
-rw-r--r--src/H5Aint.c5
-rw-r--r--src/H5S.c25
-rw-r--r--test/th5s.c82
5 files changed, 87 insertions, 58 deletions
diff --git a/c++/test/th5s.cpp b/c++/test/th5s.cpp
index e63c9af..221a61b 100644
--- a/c++/test/th5s.cpp
+++ b/c++/test/th5s.cpp
@@ -110,6 +110,9 @@ int space5_data = 7;
* passed to verify_val to 'long' as well. If problems
* arises later, this will have to be specificly handled
* with a special routine.
+ * April 12, 2011: Raymond Lu
+ * Starting from the 1.8.7 release, we allow dimension
+ * size to be zero. So I took out the test against it.
*-------------------------------------------------------------------------
*/
static void test_h5s_basic()
@@ -204,28 +207,6 @@ static void test_h5s_basic()
// CHECK_I(ret, "H5Fclose"); // leave this here, later, fake a failure
// in the p_close see how this will handle it. - BMR
- // Verify that incorrect dimensions don't work
- dims1[0] = 0;
- try {
- DataSpace wrongdim_ds (SPACE1_RANK, dims1);
-
- // Should FAIL but didn't, so throw an invalid action exception
- throw InvalidActionException("DataSpace constructor", "Attempted to use incorrect dimensions");
- }
- catch( DataSpaceIException E ) // catching use of incorrect dimensions
- {} // do nothing, exception expected
-
- // Another incorrect dimension case
- DataSpace sid3 (H5S_SIMPLE);
- try {
- sid3.setExtentSimple( SPACE1_RANK, dims1 );
-
- // Should FAIL but didn't, so throw an invalid action exception
- throw InvalidActionException("DataSpace::setExtentSimple", "Attempted to use incorrect dimensions");
- }
- catch (DataSpaceIException E) // catching use of incorrect dimensions
- {} // do nothing, exception expected
-
PASSED();
} // end of try block
diff --git a/fortran/test/tH5S.f90 b/fortran/test/tH5S.f90
index 29943bb..b56d3a7 100644
--- a/fortran/test/tH5S.f90
+++ b/fortran/test/tH5S.f90
@@ -163,7 +163,13 @@
IF (classtype .NE. 1) write(*,*)"class type not H5S_SIMPLE_f"
!
- !set the copied space to dim2 size.
+ !set the copied space to none before extend the dimensions.
+ !
+ CALL h5sset_extent_none_f(space2_id, error)
+ CALL check("h5sset_extent_none_f", error, total_error)
+
+ !
+ !set the copied space to dim2 size.
!
CALL h5sset_extent_simple_f(space2_id, rank2, dims2, maxdims2, error)
CALL check("h5sset_extent_simple_f", error, total_error)
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 3ffc6d3..a47ee14 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -888,8 +888,9 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
} /* end else */
- /* Copy the dataspace for the attribute */
- attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
+ /* Copy the dataspace for the attribute. Make sure the maximal dimension is also copied.
+ * Otherwise the comparison in the test may complain about it. SLU 2011/4/12 */
+ attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, TRUE);
HDassert(attr_dst->shared->ds);
/* Reset the dataspace's sharing in the source file before trying to share
diff --git a/src/H5S.c b/src/H5S.c
index 94fd72b..f002500 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1163,6 +1163,11 @@ H5Sis_simple(hid_t space_id)
Raymond Lu 03/30/2011
We allow 0-dimension for non-unlimited dimension starting from 1.8.7
release.
+
+ Raymond Lu 04/11/2011
+ I added a condition check to make sure the new size won't exceed the
+ current maximal size when this function is called to change the
+ dimension size of an existent dataspace.
--------------------------------------------------------------------------*/
herr_t
H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
@@ -1197,6 +1202,14 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
}
}
+ /* Check through all the dimensions to see if the new dimension size exceeds the current
+ * size or if the new maximal size exceeds the current maximal size */
+ for(u = 0; u < space->extent.rank; u++) {
+ if(space->extent.max && H5S_UNLIMITED!=space->extent.max[u] &&
+ (space->extent.max[u]<dims[u] || (max && space->extent.max[u]<max[u])))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new size exceeds current maximal size")
+ } /* end for */
+
/* Do it */
if (H5S_set_extent_simple(space, (unsigned)rank, dims, max)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set simple extent")
@@ -1259,13 +1272,15 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims,
} /* end for */
space->extent.nelem = nelem;
- /* Copy the maximum dimensions if specified */
+ /* Copy the maximum dimensions if specified. Otherwise, the maximal dimensions are the
+ * same as the dimension */
+ space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
if(max != NULL) {
- space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
HDmemcpy(space->extent.max, max, sizeof(hsize_t) * rank);
- } /* end if */
- else
- space->extent.max = NULL;
+ } else {
+ for(u = 0; u < space->extent.rank; u++)
+ space->extent.max[u] = dims[u];
+ }
} /* end else */
/* Selection related cleanup */
diff --git a/test/th5s.c b/test/th5s.c
index 2435fc9..916feb6 100644
--- a/test/th5s.c
+++ b/test/th5s.c
@@ -108,7 +108,7 @@ test_h5s_basic(void)
/* Output message about test being performed */
MESSAGE(5, ("Testing Dataspace Manipulation\n"));
- sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
+ sid1 = H5Screate_simple(SPACE1_RANK, dims1, max2);
CHECK(sid1, FAIL, "H5Screate_simple");
n = H5Sget_simple_extent_npoints(sid1);
@@ -144,9 +144,9 @@ test_h5s_basic(void)
VERIFY(HDmemcmp(tmax, max2, SPACE2_RANK * sizeof(hsize_t)), 0,
"H5Sget_simple_extent_dims");
- /* Change max dims from zero to non-zero and back again */
- ret = H5Sset_extent_simple(sid1, SPACE1_RANK, dims1, max2);
- CHECK(ret, FAIL, "H5Sset_extent_simple");
+ /* Change max dims to be equal to the dimensions */
+ /*ret = H5Sset_extent_simple(sid1, SPACE1_RANK, dims1, max2);
+ CHECK(ret, FAIL, "H5Sset_extent_simple");*/
ret = H5Sset_extent_simple(sid1, SPACE1_RANK, dims1, NULL);
CHECK(ret, FAIL, "H5Sset_extent_simple");
rank = H5Sget_simple_extent_dims(sid1, tdims, tmax);
@@ -523,11 +523,13 @@ test_h5s_zero_dim(void)
{
hid_t fid1; /* HDF5 File IDs */
hid_t sid1, attr_sid; /* Dataspace ID */
+ hid_t sid_chunk; /* Dataspace ID for chunked dataset */
hid_t dset1; /* Dataset ID */
hid_t plist_id; /* Dataset creation property list */
hid_t attr; /* Attribute ID */
int rank; /* Logical rank of dataspace */
- hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
+ hsize_t dims1[] = {0, SPACE1_DIM2, SPACE1_DIM3};
+ hsize_t max_dims[] = {SPACE1_DIM1+1, SPACE1_DIM2, SPACE1_DIM3};
hsize_t extend_dims[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
hsize_t chunk_dims[] = {SPACE1_DIM1, SPACE1_DIM2/3, SPACE1_DIM3};
hsize_t tdims[SPACE1_RANK]; /* Dimension array to test with */
@@ -552,7 +554,6 @@ test_h5s_zero_dim(void)
/* Make sure we can create the space with the dimension size 0 (starting from v1.8.7).
* The dimension doesn't need to be unlimited. */
- dims1[0]=0;
sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
CHECK(sid1, FAIL, "H5Screate_simple");
@@ -562,6 +563,8 @@ test_h5s_zero_dim(void)
sid1 = H5Screate(H5S_SIMPLE);
CHECK(sid1, FAIL, "H5Screate");
+ /* SID1 has the 1st dimension size as zero. The maximal dimension will be
+ * the same as the dimension because of the NULL passed in. */
ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
CHECK(ret, FAIL, "H5Sset_extent_simple");
@@ -593,6 +596,11 @@ test_h5s_zero_dim(void)
nelem = H5Sget_select_npoints(sid1);
VERIFY(nelem, 0, "H5Sget_select_npoints");
+ /* Create the dataspace for chunked dataset with the first dimension size as zero.
+ * The maximal dimensions are bigger than the dimensions for later expansion. */
+ sid_chunk = H5Screate_simple(SPACE1_RANK, dims1, max_dims);
+ CHECK(sid_chunk, FAIL, "H5Screate_simple");
+
/*============================================
* Make sure we can use 0-dimension to create
* contiguous, chunked, compact, and external
@@ -617,7 +625,7 @@ test_h5s_zero_dim(void)
wdata_real[i][j][k] = i + j + k;
- /* Contiguous dataset */
+ /*===================== Contiguous dataset =======================*/
dset1 = H5Dcreate2(fid1, BASICDATASET, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
CHECK(dset1, FAIL, "H5Dcreate2");
@@ -697,14 +705,14 @@ test_h5s_zero_dim(void)
ret = H5Dclose(dset1);
CHECK(ret, FAIL, "H5Dclose");
- /* Chunked dataset */
+ /*=================== Chunked dataset ====================*/
plist_id = H5Pcreate(H5P_DATASET_CREATE);
CHECK(plist_id, FAIL, "H5Pcreate");
ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims);
CHECK(ret, FAIL, "H5Pset_chunk");
- dset1 = H5Dcreate2(fid1, BASICDATASET1, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT);
+ dset1 = H5Dcreate2(fid1, BASICDATASET1, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT);
CHECK(dset1, FAIL, "H5Dcreate2");
/* Write "nothing" to the dataset */
@@ -728,7 +736,8 @@ test_h5s_zero_dim(void)
}
}
- /* Now extend the dataset and make sure we can write data to it */
+ /* Now extend the dataset to SPACE1_DIM1*SPACE1_DIM2*SPACE1_DIM3 and make sure
+ * we can write data to it */
ret = H5Dset_extent(dset1, extend_dims);
CHECK(ret, FAIL, "H5Dset_extent");
@@ -754,7 +763,7 @@ test_h5s_zero_dim(void)
}
}
- /* Now shrink the dataset to 0 dimension size and make sure no data is in it */
+ /* Now shrink the first dimension size of the dataset to 0 and make sure no data is in it */
extend_dims[0] = 0;
ret = H5Dset_extent(dset1, extend_dims);
CHECK(ret, FAIL, "H5Dset_extent");
@@ -782,7 +791,7 @@ test_h5s_zero_dim(void)
ret = H5Dclose(dset1);
CHECK(ret, FAIL, "H5Dclose");
- /* Compact dataset */
+ /*=================== Compact dataset =====================*/
plist_id = H5Pcreate(H5P_DATASET_CREATE);
CHECK(plist_id, FAIL, "H5Pcreate");
@@ -822,7 +831,7 @@ test_h5s_zero_dim(void)
ret = H5Dclose(dset1);
CHECK(ret, FAIL, "H5Dclose");
- /* Contiguous dataset with external storage */
+ /*=========== Contiguous dataset with external storage ============*/
plist_id = H5Pcreate(H5P_DATASET_CREATE);
CHECK(plist_id, FAIL, "H5Pcreate");
@@ -867,7 +876,7 @@ test_h5s_zero_dim(void)
ret = H5Dclose(dset1);
CHECK(ret, FAIL, "H5Dclose");
- /* Create an attribute for the file */
+ /*=============== Create an attribute for the file ================*/
attr = H5Acreate2(fid1, NULLATTR, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT);
CHECK(attr, FAIL, "H5Acreate2");
@@ -915,27 +924,38 @@ test_h5s_zero_dim(void)
}
}
- /* Extend the dimension to make it a normal dataspace (3x15x13). Verify that
- * data can be written to and read from the dataset now. */
- dims1[0]=3;
- ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
+ /*===============================================================
+ * Extend the dimension to make it a normal dataspace (3x15x13).
+ * Verify that data can be written to and read from the chunked
+ * dataset now.
+ *===============================================================
+ */
+ dims1[0]=SPACE1_DIM1;
+ ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,max_dims);
CHECK(ret, FAIL, "H5Sset_extent_simple");
- nelem = H5Sget_simple_extent_npoints(sid1);
+ nelem = H5Sget_simple_extent_npoints(sid_chunk);
CHECK(nelem, FAIL, "H5Sget_simple_extent_npoints");
VERIFY(nelem, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3,
"H5Sget_simple_extent_npoints");
- rank = H5Sget_simple_extent_ndims(sid1);
+ rank = H5Sget_simple_extent_ndims(sid_chunk);
CHECK(rank, FAIL, "H5Sget_simple_extent_ndims");
VERIFY(rank, SPACE1_RANK, "H5Sget_simple_extent_ndims");
- rank = H5Sget_simple_extent_dims(sid1, tdims, NULL);
+ rank = H5Sget_simple_extent_dims(sid_chunk, tdims, NULL);
CHECK(rank, FAIL, "H5Sget_simple_extent_dims");
VERIFY(HDmemcmp(tdims, dims1, SPACE1_RANK * sizeof(hsize_t)), 0,
"H5Sget_simple_extent_dims");
- dset1 = H5Dcreate2(fid1, BASICDATASET4, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ /* Set it to chunked dataset */
+ plist_id = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(plist_id, FAIL, "H5Pcreate");
+
+ ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims);
+ CHECK(ret, FAIL, "H5Pset_chunk");
+
+ dset1 = H5Dcreate2(fid1, BASICDATASET4, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT);
CHECK(dset1, FAIL, "H5Dcreate2");
ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_real);
@@ -960,35 +980,41 @@ test_h5s_zero_dim(void)
}
}
+ ret = H5Pclose(plist_id);
+ CHECK(ret, FAIL, "H5Pclose");
+
ret = H5Dclose(dset1);
CHECK(ret, FAIL, "H5Dclose");
/* Change the dimensions to make them zero size again (0x0x0). Verify that
* no element is in the dataspace. */
dims1[0]=dims1[1]=dims1[2]=0;
- ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
+ ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,NULL);
CHECK(ret, FAIL, "H5Sset_extent_simple");
/* Check that the dataspace actually has 0 elements */
- nelem = H5Sget_simple_extent_npoints(sid1);
+ nelem = H5Sget_simple_extent_npoints(sid_chunk);
VERIFY(nelem, 0, "H5Sget_simple_extent_npoints");
/* Check that the dataspace was created with an "all" selection */
- sel_type = H5Sget_select_type(sid1);
+ sel_type = H5Sget_select_type(sid_chunk);
VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type");
/* Check that the dataspace has 0 elements selected */
- nelem = H5Sget_select_npoints(sid1);
+ nelem = H5Sget_select_npoints(sid_chunk);
VERIFY(nelem, 0, "H5Sget_select_npoints");
/* Change to "none" selection */
- ret = H5Sselect_none(sid1);
+ ret = H5Sselect_none(sid_chunk);
CHECK(ret, FAIL, "H5Sselect_none");
/* Check that the dataspace has 0 elements selected */
- nelem = H5Sget_select_npoints(sid1);
+ nelem = H5Sget_select_npoints(sid_chunk);
VERIFY(nelem, 0, "H5Sget_select_npoints");
+ ret = H5Sclose(sid_chunk);
+ CHECK(ret, FAIL, "H5Sclose");
+
ret = H5Sclose(sid1);
CHECK(ret, FAIL, "H5Sclose");