浏览代码

Add checks of return values + add checks in tests. Not really working yet...

Corentin Salingue 8 年之前
父节点
当前提交
23c31070d7
共有 2 个文件被更改,包括 254 次插入23 次删除
  1. 59 23
      src/core/disk_ops/disk_hdf5.c
  2. 195 0
      tests/disk/disk_compute.c

+ 59 - 23
src/core/disk_ops/disk_hdf5.c

@@ -29,8 +29,6 @@
 
 #define NITER	_starpu_calibration_minimum
 
-#define TEMP_HIERARCHY_DEPTH 2
-
 /* ------------------- use HDF5 to write on disk -------------------  */
 
 struct starpu_hdf5_base
@@ -51,8 +49,11 @@ struct starpu_hdf5_obj
 
 static hsize_t _starpu_get_size_obj(struct starpu_hdf5_obj * obj)
 {
+        herr_t status;
         hsize_t dims[1];
-        H5Sget_simple_extent_dims(obj->dataspace, dims, NULL);
+        status = H5Sget_simple_extent_dims(obj->dataspace, dims, NULL);
+        STARPU_ASSERT_MSG(status >= 0, "Can not get the size of this HDF5 dataset (%s)\n", obj->path);
+
         return dims[0];
 }
 
@@ -132,7 +133,7 @@ static void *starpu_hdf5_plug(void *parameter, starpu_ssize_t size STARPU_ATTRIB
         {
                 /* The file doesn't exist or the directory exists => create the datafile */
                 int id;
-                base->path = _starpu_mktemp_many(parameter, TEMP_HIERARCHY_DEPTH, O_RDWR | O_BINARY, &id);
+                base->path = _starpu_mktemp_many(parameter, 0, O_RDWR | O_BINARY, &id);
                 if (!base->path)
                 {
                         free(base);
@@ -178,9 +179,11 @@ static void *starpu_hdf5_plug(void *parameter, starpu_ssize_t size STARPU_ATTRIB
 static void starpu_hdf5_unplug(void *base)
 {
         struct starpu_hdf5_base * fileBase = (struct starpu_hdf5_base *) base;
+        herr_t status;
 
 	STARPU_PTHREAD_MUTEX_DESTROY(&fileBase->mutex);
-        H5Fclose(fileBase->fileID);
+        status = H5Fclose(fileBase->fileID);
+        STARPU_ASSERT_MSG(status >= 0, "Can not unplug this HDF5 disk (%s)\n", fileBase->path);
         if (fileBase->created)
         {
                 unlink(fileBase->path);        
@@ -228,14 +231,18 @@ static void starpu_hdf5_free(void *base, void *obj, size_t size STARPU_ATTRIBUTE
 {
         struct starpu_hdf5_base * fileBase = (struct starpu_hdf5_base *) base;
         struct starpu_hdf5_obj * dataObj = (struct starpu_hdf5_obj *) obj;
+        herr_t status;
 
         /* TODO delete dataset */
-        H5Dclose(dataObj->dataset);
-        H5Sclose(dataObj->dataspace);
+        status = H5Dclose(dataObj->dataset);
+        STARPU_ASSERT_MSG(status >= 0, "Can not free this HDF5 dataset (%s)\n", dataObj->path);
+        status = H5Sclose(dataObj->dataspace);
+        STARPU_ASSERT_MSG(status >= 0, "Can not free the HDF5 dataspace associed to this dataset (%s)\n", dataObj->path);
 
         /* remove the dataset link in the HDF5 
          * But it doesn't delete the space in the file */
-        H5Ldelete(fileBase->fileID, dataObj->path, H5P_DEFAULT);
+        status = H5Ldelete(fileBase->fileID, dataObj->path, H5P_DEFAULT);
+        STARPU_ASSERT_MSG(status >= 0, "Can not delete the link associed to this dataset (%s)\n", dataObj->path);
 
         free(dataObj->path);
         free(dataObj);
@@ -263,9 +270,12 @@ static void *starpu_hdf5_open(void *base, void *pos, size_t size)
 static void starpu_hdf5_close(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, size_t size STARPU_ATTRIBUTE_UNUSED)
 {
         struct starpu_hdf5_obj * dataObj = (struct starpu_hdf5_obj *) obj;
+        herr_t status;
 
-        H5Dclose(dataObj->dataset);
-        H5Sclose(dataObj->dataspace);
+        status = H5Dclose(dataObj->dataset);
+        STARPU_ASSERT_MSG(status >= 0, "Can not close this HDF5 dataset (%s)\n", dataObj->path);
+        status = H5Sclose(dataObj->dataspace);
+        STARPU_ASSERT_MSG(status >= 0, "Can not close the HDF5 dataspace associed to this dataset (%s)\n", dataObj->path);
 
         free(dataObj->path);
         free(dataObj);
@@ -274,13 +284,15 @@ static void starpu_hdf5_close(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, siz
 static int starpu_hdf5_full_read(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, void **ptr, size_t *size)
 {
         struct starpu_hdf5_obj * dataObj = (struct starpu_hdf5_obj *) obj;
+        herr_t status;
 
         /* Get the size of the dataspace (only 1 dimension) */
         *size = _starpu_get_size_obj(dataObj);
 
         starpu_malloc_flags(ptr, *size, 0); 
 
-        H5Dread(dataObj->dataset, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, *ptr);
+        status = H5Dread(dataObj->dataset, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, *ptr);
+        STARPU_ASSERT_MSG(status >= 0, "Can not read data associed to this dataset (%s)\n", dataObj->path);
 
         return 0;
 }
@@ -288,9 +300,11 @@ static int starpu_hdf5_full_read(void *base STARPU_ATTRIBUTE_UNUSED, void *obj,
 static int starpu_hdf5_full_write(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, void *ptr, size_t size)
 {
         struct starpu_hdf5_obj * dataObj = (struct starpu_hdf5_obj *) obj;
+        herr_t status;
 
         /* Write ALL the dataspace */
-        H5Dwrite(dataObj->dataset, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, ptr);
+        status = H5Dwrite(dataObj->dataset, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, ptr);
+        STARPU_ASSERT_MSG(status >= 0, "Can not write data to this dataset (%s)\n", dataObj->path);
 
         return 0;
 }
@@ -298,29 +312,42 @@ static int starpu_hdf5_full_write(void *base STARPU_ATTRIBUTE_UNUSED, void *obj,
 static int starpu_hdf5_read(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, void *buf, off_t offset, size_t size)
 {
         struct starpu_hdf5_obj * dataObj = (struct starpu_hdf5_obj *) obj;
+        herr_t status;
 
         /* duplicate the dataspace in the dataset */
         hsize_t sizeDataspace = _starpu_get_size_obj(dataObj);
         hsize_t dims_select[1];
         dims_select[0] = sizeDataspace;
         hid_t dataspace_select = H5Screate_simple(1, dims_select, NULL);
+        STARPU_ASSERT_MSG(dataspace_select >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
 
         /* Select what we want of the duplicated dataspace (it's called an hyperslab). This operation is done on place */
-        int offsets[1] = {offset};
-        int count[1] = {size};
+        hsize_t offsets[1] = {offset};
+        hsize_t count[1] = {size};
         /* stride and block size are NULL which is equivalent of a shift of 1 */
-        H5Sselect_hyperslab(dataspace_select, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        status = H5Sselect_hyperslab(dataspace_select, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        STARPU_ASSERT_MSG(status >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
 
         /* create the dataspace for the received data which describes ptr */
         hsize_t dims_receive[1];
         dims_receive[0] = size;
         hid_t dataspace_receive = H5Screate_simple(1, dims_receive, NULL);
+        STARPU_ASSERT_MSG(dataspace_receive >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
+
+        /* Receiver has to be an hyperslabs */
+        offsets[0] = 0;
+        count[0] = size;
+        status = H5Sselect_hyperslab(dataspace_receive, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        STARPU_ASSERT_MSG(dataspace_receive >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
 
-        H5Dread(dataObj->dataset, H5T_NATIVE_CHAR, dataspace_select, dataspace_receive, H5P_DEFAULT, buf);
+        status = H5Dread(dataObj->dataset, H5T_NATIVE_CHAR, dataspace_receive, dataspace_select, H5P_DEFAULT, buf);
+        STARPU_ASSERT_MSG(status >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
 
         /* don't need these dataspaces */
-        H5Sclose(dataspace_select);
-        H5Sclose(dataspace_receive);
+        status = H5Sclose(dataspace_select);
+        STARPU_ASSERT_MSG(status >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
+        status = H5Sclose(dataspace_receive);
+        STARPU_ASSERT_MSG(status >= 0, "Error when reading this HDF5 dataset (%s)\n", dataObj->path);
 
         return 0;
 }
@@ -328,33 +355,42 @@ static int starpu_hdf5_read(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, void
 static int starpu_hdf5_write(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, const void *buf, off_t offset, size_t size)
 {
         struct starpu_hdf5_obj * dataObj = (struct starpu_hdf5_obj *) obj;
+        herr_t status;
 
         /* duplicate the dataspace in the dataset */
         hsize_t sizeDataspace = _starpu_get_size_obj(dataObj);
         hsize_t dims_select[1];
         dims_select[0] = sizeDataspace;
         hid_t dataspace_select = H5Screate_simple(1, dims_select, NULL);
+        STARPU_ASSERT_MSG(dataspace_select >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
 
         /* Select what we want of the duplicated dataspace (it's called an hyperslab). This operation is done on place */
         hsize_t offsets[1] = {offset};
         hsize_t count[1] = {size};
         /* stride and block size are NULL which is equivalent of a shift of 1 */
-        H5Sselect_hyperslab(dataspace_select, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        status = H5Sselect_hyperslab(dataspace_select, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        STARPU_ASSERT_MSG(status >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
 
         /* create the dataspace for the received data which describes ptr */
         hsize_t dims_send[1];
         dims_send[0] = size;
         hid_t dataspace_send = H5Screate_simple(1, dims_send, NULL);
+        STARPU_ASSERT_MSG(dataspace_send >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
 
+        /* Receiver has to be an hyperslabs */
         offsets[0] = 0;
         count[0] = size;
-        H5Sselect_hyperslab(dataspace_send, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        status = H5Sselect_hyperslab(dataspace_send, H5S_SELECT_SET, offsets, NULL, count, NULL);
+        STARPU_ASSERT_MSG(dataspace_send >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
 
-        H5Dwrite(dataObj->dataset, H5T_NATIVE_CHAR, dataspace_send, dataspace_select, H5P_DEFAULT, buf);
+        status = H5Dwrite(dataObj->dataset, H5T_NATIVE_CHAR, dataspace_send, dataspace_select, H5P_DEFAULT, buf);
+        STARPU_ASSERT_MSG(status >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
 
         /* don't need these dataspaces */
-        H5Sclose(dataspace_select);
-        H5Sclose(dataspace_send);
+        status = H5Sclose(dataspace_select);
+        STARPU_ASSERT_MSG(status >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
+        status = H5Sclose(dataspace_send);
+        STARPU_ASSERT_MSG(status >= 0, "Error when writing this HDF5 dataset (%s)\n", dataObj->path);
 
         return 0;
 }

+ 195 - 0
tests/disk/disk_compute.c

@@ -27,6 +27,10 @@
 #include <common/config.h>
 #include "../helper.h"
 
+#ifdef STARPU_HAVE_HDF5
+#include <hdf5.h>
+#endif
+
 /*
  * Try to write into disk memory
  * Use mechanism to push datas from main ram to disk ram
@@ -197,6 +201,190 @@ enoent:
 	return STARPU_TEST_SKIPPED;
 }
 
+#ifdef STARPU_HAVE_HDF5
+int dotest_hdf5(struct starpu_disk_ops *ops, char *base)
+{
+	int *A, *C;
+        herr_t status;
+
+        /* Open and close file, just to create an empty file */
+        FILE * f = fopen(base, "wb+");
+        if (!f)
+                goto h5fail2;
+        fclose(f);
+
+	/* Initialize StarPU with default configuration */
+	int ret = starpu_init(NULL);
+
+	if (ret == -ENODEV) goto h5enodev;
+
+	/* Initialize path */
+	const char *path_obj_start = "STARPU_DISK_COMPUTE_DATA_";
+	const char *path_obj_end = "STARPU_DISK_COMPUTE_DATA_RESULT_";
+
+	/* register a disk */
+	int new_dd = starpu_disk_register(ops, (void *) base, STARPU_DISK_SIZE_MIN);
+	/* can't write on /tmp/ */
+	if (new_dd == -ENOENT) goto h5enoent;
+
+	unsigned dd = (unsigned) new_dd;
+
+	/* allocate two memory spaces */
+	starpu_malloc_flags((void **)&A, NX*sizeof(int), STARPU_MALLOC_COUNT);
+	starpu_malloc_flags((void **)&C, NX*sizeof(int), STARPU_MALLOC_COUNT);
+
+	FPRINTF(stderr, "TEST DISK MEMORY \n");
+
+	unsigned int j;
+	/* you register them in a vector */
+	for(j = 0; j < NX; ++j)
+	{
+		A[j] = j;
+		C[j] = 0;
+	}
+
+	/* Open HDF5 file to store data */
+        hid_t file = H5Fopen(base, H5F_ACC_RDWR, H5P_DEFAULT);
+        if (file < 0)
+                goto h5enoent2;
+
+	/* store initial data in the file */
+        hsize_t dims[1] = {NX};
+        hid_t dataspace = H5Screate_simple(1, dims, NULL);
+        if (dataspace < 0)
+        {
+                H5Fclose(file);
+                goto h5fail;
+        }
+
+        hid_t dataset = H5Dcreate2(file, path_obj_start, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+        if (dataset < 0)
+        {
+                H5Sclose(dataspace);
+                H5Fclose(file);
+                goto h5fail;
+        }
+
+        status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, A);
+
+	/* close the resources before checking the writing */
+        H5Dclose(dataset);
+
+        if (status < 0)
+        {
+                H5Fclose(file);
+                goto h5fail;
+        }
+
+        /* intialize results in file */
+        dataset = H5Dcreate2(file, path_obj_end, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+        if (dataset < 0)
+        {
+                H5Sclose(dataspace);
+                H5Fclose(file);
+                goto h5fail;
+        }
+
+        status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, A);
+
+	/* close the resources before checking the writing */
+        H5Dclose(dataset);
+        H5Sclose(dataspace);
+        H5Fclose(file);
+
+        if (status < 0)
+                goto h5fail;
+
+	/* And now, you want to use your datas in StarPU */
+	/* Open the file ON the disk */
+	void * data = starpu_disk_open(dd, (void *) path_obj_start, NX*sizeof(int));
+	void * data_result = starpu_disk_open(dd, (void *) path_obj_end, NX*sizeof(int));
+
+	starpu_data_handle_t vector_handleA, vector_handleC;
+
+	/* register vector in starpu */
+	starpu_vector_data_register(&vector_handleA, dd, (uintptr_t) data, NX, sizeof(int));
+
+	/* and do what you want with it, here we copy it into an other vector */
+	starpu_vector_data_register(&vector_handleC, dd, (uintptr_t) data_result, NX, sizeof(int));
+
+	starpu_data_cpy(vector_handleC, vector_handleA, 0, NULL, NULL);
+
+	/* free them */
+	starpu_data_unregister(vector_handleA);
+	starpu_data_unregister(vector_handleC);
+
+	/* close them in StarPU */
+	starpu_disk_close(dd, data, NX*sizeof(int));
+	starpu_disk_close(dd, data_result, NX*sizeof(int));
+
+	/* check results */
+        file = H5Fopen(base, H5F_ACC_RDWR, H5P_DEFAULT);
+        if (file < 0)
+                goto h5enoent2;
+
+        dataset = H5Dopen2(file, path_obj_end, H5P_DEFAULT);
+        if (dataset < 0)
+        {
+                H5Fclose(file);
+                goto h5fail;
+        }
+
+        status = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, C);
+
+	/* close the resources before checking the writing */
+        H5Dclose(dataset);
+        H5Fclose(file);
+
+        if (status < 0)
+                goto h5fail;
+
+	int try = 1;
+	for (j = 0; j < NX; ++j)
+		if (A[j] != C[j])
+		{
+			FPRINTF(stderr, "Fail A %d != C %d \n", A[j], C[j]);
+			try = 0;
+		}
+
+	starpu_free_flags(A, NX*sizeof(int), STARPU_MALLOC_COUNT);
+	starpu_free_flags(C, NX*sizeof(int), STARPU_MALLOC_COUNT);
+
+	/* terminate StarPU, no task can be submitted after */
+	starpu_shutdown();
+
+        unlink(base);
+
+	if(try)
+		FPRINTF(stderr, "TEST SUCCESS\n");
+	else
+		FPRINTF(stderr, "TEST FAIL\n");
+	return (try ? EXIT_SUCCESS : EXIT_FAILURE);
+
+h5enodev:
+        unlink(base);
+	return STARPU_TEST_SKIPPED;
+h5enoent2:
+	starpu_free_flags(A, NX*sizeof(int), STARPU_MALLOC_COUNT);
+	starpu_free_flags(C, NX*sizeof(int), STARPU_MALLOC_COUNT);
+h5enoent:
+	FPRINTF(stderr, "Couldn't write data: ENOENT\n");
+	starpu_shutdown();
+        unlink(base);
+	return STARPU_TEST_SKIPPED;
+h5fail:
+	starpu_free_flags(A, NX*sizeof(int), STARPU_MALLOC_COUNT);
+	starpu_free_flags(C, NX*sizeof(int), STARPU_MALLOC_COUNT);
+
+	starpu_shutdown();
+        unlink(base);
+h5fail2:
+	FPRINTF(stderr, "Something goes wrong with HDF5 dataset/dataspace/write \n");
+        return EXIT_FAILURE;
+
+}
+#endif
+
 static int merge_result(int old, int new)
 {
 	if (new == EXIT_FAILURE)
@@ -233,6 +421,13 @@ int main(void)
 		ret = merge_result(ret, STARPU_TEST_SKIPPED);
 	}
 #endif
+#ifdef STARPU_HAVE_HDF5
+        char hdf5_base[128];
+        strcpy(hdf5_base, s);
+        strcat(hdf5_base, "/STARPU_HDF5_file.h5");
+
+        ret = merge_result(ret, dotest_hdf5(&starpu_disk_hdf5_ops, hdf5_base));
+#endif
 
 	ret2 = rmdir(s);
 	if (ret2 < 0)