Browse Source

Fix and test disk support with pack/unpack-only interfaces

Samuel Thibault 10 years ago
parent
commit
51e895087b

+ 14 - 7
doc/doxygen/chapters/api/data_out_of_core.doxy

@@ -30,6 +30,13 @@ into \p buf. Returns the actual number of read bytes.
 \var int (*starpu_disk_ops::write)(void *base, void *obj, const void *buf, off_t offset, size_t size)
 Write \p size bytes of data to \p obj in \p base, at offset \p offset, from \p buf. Returns 0 on success.
 
+\var int (*starpu_disk_ops::full_read)(void * base, void * obj, void ** ptr, size_t * size)
+Read all data from \p obj of \p base, from offset 0. Returns it in an allocated buffer \p ptr, of size \p size
+
+\var int (*starpu_disk_ops::full_write)(void * base, void * obj, void * ptr, size_t size)
+Write data in \p ptr to \p obj of \p base, from offset 0, and truncate \p obj to
+\p size, so that a \c full_read will get it.
+
 \var void* (*starpu_disk_ops::plug) (void *parameters, size_t size)
 Connect a disk memory at location \p parameter with size \p size, and return a
 base as void*, which will be passed by StarPU to all other methods.
@@ -47,6 +54,13 @@ Asynchronously write \p size bytes of data to \p obj in \p base, at offset \p
 offset, from \p buf. Returns a void* pointer that StarPU will pass to \c
 *_request methods for testing for the completion.
 
+\var void * (*starpu_disk_ops::async_full_read)(void * base, void * obj, void ** ptr, size_t * size)
+Read all data from \p obj of \p base, from offset 0. Returns it in an allocated buffer \p ptr, of size \p size
+
+\var void * (*starpu_disk_ops::async_full_write)(void * base, void * obj, void * ptr, size_t size)
+Write data in \p ptr to \p obj of \p base, from offset 0, and truncate \p obj to
+\p size, so that a \c full_read will get it.
+
 \var void* (*starpu_disk_ops::copy)(void *base_src, void* obj_src, off_t offset_src,  void *base_dst, void* obj_dst, off_t offset_dst, size_t size)
 Copy from offset \p offset_src of disk object \p obj_src in \p base_src to
 offset \p offset_dst of disk object \p obj_dst in \p base_dst. Returns a void*
@@ -68,13 +82,6 @@ asynchronous read, write or copy. Returns 1 on completion, 0 otherwise.
 \var void (*starpu_disk_ops::free_request)(void *async_channel)
 Free the request allocated by a previous asynchronous read, write or copy.
 
-\var int (*starpu_disk_ops::full_read)(void * base, void * obj, void ** ptr, size_t * size)
-Read all data from \p obj of \p base, from offset 0. Returns it in an allocated buffer \p ptr, of size \p size
-
-\var int (*starpu_disk_ops::full_write)(void * base, void * obj, void * ptr, size_t size)
-Write data in \p ptr to \p obj of \p base, from offset 0, and truncate \p obj to
-\p size, so that a \c full_read will get it.
-
 \fn int starpu_disk_register(struct starpu_disk_ops *func, void *parameter, size_t size)
 \ingroup API_Out_Of_Core
 Register a disk memory node with a set of functions to manipulate datas. The \c

+ 0 - 5
include/starpu_data_interfaces.h

@@ -426,11 +426,6 @@ size_t starpu_data_get_size(starpu_data_handle_t handle);
 
 starpu_data_handle_t starpu_data_lookup(const void *ptr);
 
-struct starpu_disk_interface
-{
-	uintptr_t dev_handle;
-};
-
 #ifdef __cplusplus
 }
 #endif

+ 6 - 2
include/starpu_disk.h

@@ -36,11 +36,15 @@ struct starpu_disk_ops {
 	 int     (*read)   (void *base, void *obj, void *buf, off_t offset, size_t size);
 	 int     (*write)  (void *base, void *obj, const void *buf, off_t offset, size_t size);
 
-	 int	(*full_read)    (unsigned node, void * base, void * obj, void ** ptr, size_t * size);
-	 int 	(*full_write)   (unsigned node, void * base, void * obj, void * ptr, size_t size);
+	 int	(*full_read)    (void * base, void * obj, void ** ptr, size_t * size);
+	 int 	(*full_write)   (void * base, void * obj, void * ptr, size_t size);
 
 	 void *  (*async_write)  (void *base, void *obj, void *buf, off_t offset, size_t size); 
 	 void *  (*async_read)   (void *base, void *obj, void *buf, off_t offset, size_t size); 
+
+	 void *	(*async_full_read)    (void * base, void * obj, void ** ptr, size_t * size);
+	 void *	(*async_full_write)   (void * base, void * obj, void * ptr, size_t size);
+
 	 void *  (*copy)   (void *base_src, void* obj_src, off_t offset_src,  void *base_dst, void* obj_dst, off_t offset_dst, size_t size);
 	 void   (*wait_request) (void * async_channel);
 	 int    (*test_request) (void * async_channel);

+ 46 - 5
src/core/disk.c

@@ -177,7 +177,6 @@ _starpu_disk_write(unsigned src_node STARPU_ATTRIBUTE_UNUSED, unsigned dst_node,
         	return 0;
         }
         return -EAGAIN;
-
 }
 
 int
@@ -194,16 +193,58 @@ _starpu_disk_copy(unsigned node_src, void* obj_src, off_t offset_src, unsigned n
 	return -EAGAIN;
 }
 
-int _starpu_disk_full_read(unsigned src_node, unsigned dst_node STARPU_ATTRIBUTE_UNUSED, void * obj, void ** ptr, size_t * size)
+int _starpu_disk_full_read(unsigned src_node, unsigned dst_node STARPU_ATTRIBUTE_UNUSED, void * obj, void ** ptr, size_t * size, struct _starpu_async_channel *channel)
 {
 	int pos = get_location_with_node(src_node);
-        return disk_register_list[pos]->functions->full_read(src_node, disk_register_list[pos]->base, obj, ptr, size);
+
+	if (channel != NULL)
+	{
+		if (disk_register_list[pos]->functions->async_full_read == NULL)
+			channel = NULL;
+		else
+		{
+			channel->type = STARPU_DISK_RAM;
+			channel->event.disk_event.memory_node = src_node;
+
+			_STARPU_TRACE_START_DRIVER_COPY_ASYNC(src_node, dst_node);
+			channel->event.disk_event.backend_event = disk_register_list[pos]->functions->async_full_read(disk_register_list[pos]->base, obj, ptr, size);
+			_STARPU_TRACE_END_DRIVER_COPY_ASYNC(src_node, dst_node);
+		}
+	}
+	/* asynchronous request failed or synchronous request is asked */
+	if (channel == NULL || !channel->event.disk_event.backend_event)
+	{
+		disk_register_list[pos]->functions->full_read(disk_register_list[pos]->base, obj, ptr, size);
+		return 0;
+	}
+	return -EAGAIN;
 }
 
-int _starpu_disk_full_write(unsigned src_node STARPU_ATTRIBUTE_UNUSED, unsigned dst_node, void * obj, void * ptr, size_t size)
+int _starpu_disk_full_write(unsigned src_node STARPU_ATTRIBUTE_UNUSED, unsigned dst_node, void * obj, void * ptr, size_t size, struct _starpu_async_channel *channel)
 {
 	int pos = get_location_with_node(dst_node);
-        return disk_register_list[pos]->functions->full_write(dst_node, disk_register_list[pos]->base, obj, ptr, size);
+
+	if (channel != NULL)
+	{
+		if (disk_register_list[pos]->functions->async_full_write == NULL)
+			channel = NULL;
+		else
+		{
+			channel->type = STARPU_DISK_RAM;
+			channel->event.disk_event.memory_node = dst_node;
+
+			_STARPU_TRACE_START_DRIVER_COPY_ASYNC(src_node, dst_node);
+			channel->event.disk_event.backend_event = disk_register_list[pos]->functions->async_full_write(disk_register_list[pos]->base, obj, ptr, size);
+			_STARPU_TRACE_END_DRIVER_COPY_ASYNC(src_node, dst_node);
+		}
+	}
+	/* asynchronous request failed or synchronous request is asked */
+	if (channel == NULL || !channel->event.disk_event.backend_event)
+	{
+		disk_register_list[pos]->functions->full_write(disk_register_list[pos]->base, obj, ptr, size);
+		return 0;
+	}
+	return -EAGAIN;
 }
 
 void * 

+ 2 - 2
src/core/disk.h

@@ -39,8 +39,8 @@ int _starpu_disk_read(unsigned src_node, unsigned dst_node, void *obj, void *buf
 /* src_node is for the moment the STARU_MAIN_RAM, dst_node is a disk node */ 
 int _starpu_disk_write(unsigned src_node, unsigned dst_node, void *obj, void *buf, off_t offset, size_t size, struct _starpu_async_channel * async_channel);
 
-int _starpu_disk_full_read(unsigned src_node, unsigned dst_node, void * obj, void ** ptr, size_t * size);
-int _starpu_disk_full_write(unsigned src_node, unsigned dst_node, void * obj, void * ptr, size_t size);
+int _starpu_disk_full_read(unsigned src_node, unsigned dst_node, void * obj, void ** ptr, size_t * size, struct _starpu_async_channel * async_channel);
+int _starpu_disk_full_write(unsigned src_node, unsigned dst_node, void * obj, void * ptr, size_t size, struct _starpu_async_channel * async_channel);
 
 int _starpu_disk_copy(unsigned node_src, void* obj_src, off_t offset_src, unsigned node_dst, void* obj_dst, off_t offset_dst, size_t size, struct _starpu_async_channel * async_channel);
 

+ 28 - 16
src/core/disk_ops/disk_leveldb.cpp

@@ -33,7 +33,7 @@
 
 struct starpu_leveldb_obj {
 	char * key;
-	double size;
+	size_t size;
 	starpu_pthread_mutex_t mutex;
 };
 
@@ -143,14 +143,28 @@ starpu_leveldb_read (void *base, void *obj, void *buf, off_t offset, size_t size
 }
 
 static int
-starpu_leveldb_full_read(unsigned node, void *base, void * obj, void ** ptr, size_t * size)
+starpu_leveldb_full_read(void *base, void * obj, void ** ptr, size_t * size)
 {
         struct starpu_leveldb_obj * tmp = (struct starpu_leveldb_obj *) obj;
         struct starpu_leveldb_base * base_tmp = (struct starpu_leveldb_base *) base;
 
-	*size = tmp->size;
-	*ptr = (size_t *)malloc(*size);
-	return _starpu_disk_read(node, STARPU_MAIN_RAM, obj, *ptr, 0, *size, NULL);
+	STARPU_PTHREAD_MUTEX_LOCK(&tmp->mutex);
+
+	/* leveldb need a string to store datas */
+	std::string value;
+	leveldb::Status s = base_tmp->db->Get(leveldb::ReadOptions(), tmp->key, &value);
+
+	STARPU_ASSERT(s.ok());
+
+	*size = value.length();
+	*ptr = malloc(*size);
+
+	/* use buffer */
+	memcpy(*ptr, value.c_str(), *size);
+
+	STARPU_PTHREAD_MUTEX_UNLOCK(&tmp->mutex);
+
+	return 0;
 }
 
 /* write on the memory disk */
@@ -201,20 +215,14 @@ starpu_leveldb_write (void *base, void *obj, const void *buf, off_t offset, size
 }
 
 static int
-starpu_leveldb_full_write (unsigned node, void * base, void * obj, void * ptr, size_t size)
+starpu_leveldb_full_write (void * base, void * obj, void * ptr, size_t size)
 {
 	struct starpu_leveldb_obj * tmp = (struct starpu_leveldb_obj *) obj;
 	struct starpu_leveldb_base * base_tmp = (struct starpu_leveldb_base *) base;
-	
-	/* update file size to realise the next good full_read */
-	if(size != tmp->size)
-	{
-		_starpu_memory_manager_deallocate_size(tmp->size, node);
-		if (_starpu_memory_manager_can_allocate_size(size, node))
-			tmp->size = size;
-		else
-			STARPU_ASSERT_MSG(0, "Can't allocate size %u on the disk !", (int) size); 
-	}	
+
+	/* update file size to achieve correct writes */
+	tmp->size = size;
+
 	leveldb::WriteOptions write_options;
 	write_options.sync = true;
 
@@ -335,6 +343,8 @@ struct starpu_disk_ops starpu_disk_leveldb_ops = {
 	.full_write = starpu_leveldb_full_write,
 	.async_write = NULL,
 	.async_read = NULL,
+	.async_full_read = NULL,
+	.async_full_write = NULL,
 	.copy = NULL,
 	.wait_request = NULL,
 	.test_request = NULL,
@@ -358,6 +368,8 @@ struct starpu_disk_ops starpu_disk_leveldb_ops = {
 	NULL,
 	NULL,
 	NULL,
+	NULL,
+	NULL,
 	NULL
 };
 #endif

+ 20 - 18
src/core/disk_ops/disk_stdio.c

@@ -40,7 +40,7 @@ struct starpu_stdio_obj
 	int descriptor;
 	FILE * file;
 	char * path;
-	double size;
+	size_t size;
 	starpu_pthread_mutex_t mutex;
 };
 
@@ -196,13 +196,20 @@ static int starpu_stdio_read(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, void
 	return 0;
 }
 
-static int starpu_stdio_full_read(unsigned node, void *base STARPU_ATTRIBUTE_UNUSED, void * obj, void ** ptr, size_t * size)
+static int starpu_stdio_full_read(void *base STARPU_ATTRIBUTE_UNUSED, void * obj, void ** ptr, size_t * size)
 {
 	struct starpu_stdio_obj * tmp = (struct starpu_stdio_obj *) obj;
 
-	*size = tmp->size;
+	STARPU_PTHREAD_MUTEX_LOCK(&tmp->mutex);
+
+	int res = fseek(tmp->file, 0, SEEK_END);
+	STARPU_ASSERT_MSG(res == 0, "Stdio write failed");
+	*size = ftell(tmp->file);
+
+	STARPU_PTHREAD_MUTEX_UNLOCK(&tmp->mutex);
+
 	*ptr = malloc(*size);
-	return _starpu_disk_read(node, STARPU_MAIN_RAM, obj, *ptr, 0, *size, NULL);
+	return starpu_stdio_read(base, obj, *ptr, 0, *size);
 }
 
 /* write on the memory disk */
@@ -222,31 +229,26 @@ static int starpu_stdio_write(void *base STARPU_ATTRIBUTE_UNUSED, void *obj, con
 	return 0;
 }
 
-static int starpu_stdio_full_write(unsigned node, void * base STARPU_ATTRIBUTE_UNUSED, void * obj, void * ptr, size_t size)
+static int starpu_stdio_full_write(void * base STARPU_ATTRIBUTE_UNUSED, void * obj, void * ptr, size_t size)
 {
 	struct starpu_stdio_obj * tmp = (struct starpu_stdio_obj *) obj;
 
 	/* update file size to realise the next good full_read */
 	if(size != tmp->size)
 	{
-		_starpu_memory_manager_deallocate_size(tmp->size, node);
-		if (_starpu_memory_manager_can_allocate_size(size, node))
-		{
 #ifdef STARPU_HAVE_WINDOWS
-			int val = _chsize(tmp->descriptor, size);
+		int val = _chsize(tmp->descriptor, size);
 #else
-			int val = ftruncate(tmp->descriptor,size);
+		int val = ftruncate(tmp->descriptor,size);
 #endif
+		STARPU_ASSERT(val == 0);
 
-			STARPU_ASSERT_MSG(val >= 0,"StarPU Error to truncate file in STDIO full_write function");
-			tmp->size = size;
-		}
-		else
-		{
-			STARPU_ASSERT_MSG(0, "Can't allocate size %u on the disk !", (int) size);
-		}
+		tmp->size = size;
 	}
-	return _starpu_disk_write(STARPU_MAIN_RAM, node, obj, ptr, 0, tmp->size, NULL);
+
+	starpu_stdio_write(base, obj, ptr, 0, size);
+
+	return 0;
 }
 
 /* create a new copy of parameter == base */

+ 18 - 19
src/core/disk_ops/unistd/disk_unistd_global.c

@@ -213,13 +213,21 @@ starpu_unistd_global_async_read (void *base STARPU_ATTRIBUTE_UNUSED, void *obj,
 #endif
 
 int
-starpu_unistd_global_full_read(unsigned node, void *base STARPU_ATTRIBUTE_UNUSED, void * obj, void ** ptr, size_t * size)
+starpu_unistd_global_full_read(void *base STARPU_ATTRIBUTE_UNUSED, void * obj, void ** ptr, size_t * size)
 {
         struct starpu_unistd_global_obj * tmp = (struct starpu_unistd_global_obj *) obj;
 
-        *size = tmp->size;
+#ifdef STARPU_HAVE_WINDOWS
+	*size = _filelength(tmp->descriptor);
+#else
+	struct stat st;
+	fstat(tmp->descriptor, &st);
+
+	*size = st.st_size;
+#endif
+
         *ptr = malloc(*size);
-	return _starpu_disk_read(node, STARPU_MAIN_RAM, obj, *ptr, 0, *size, NULL);
+	return starpu_unistd_global_read(base, obj, *ptr, 0, *size);
 }
 
 
@@ -268,32 +276,23 @@ starpu_unistd_global_async_write (void *base STARPU_ATTRIBUTE_UNUSED, void *obj,
 #endif
 
 int
-starpu_unistd_global_full_write (unsigned node, void * base STARPU_ATTRIBUTE_UNUSED, void * obj, void * ptr, size_t size)
+starpu_unistd_global_full_write (void * base STARPU_ATTRIBUTE_UNUSED, void * obj, void * ptr, size_t size)
 {
         struct starpu_unistd_global_obj * tmp = (struct starpu_unistd_global_obj *) obj;
 
         /* update file size to realise the next good full_read */
         if(size != tmp->size)
         {
-                _starpu_memory_manager_deallocate_size(tmp->size, node);
-                if (_starpu_memory_manager_can_allocate_size(size, node))
-                {
 #ifdef STARPU_HAVE_WINDOWS
-                        int val = _chsize(tmp->descriptor, size);
+		int val = _chsize(tmp->descriptor, size);
 #else
-                        int val = ftruncate(tmp->descriptor,size);
+		int val = ftruncate(tmp->descriptor,size);
 #endif
-
-                        STARPU_ASSERT_MSG(val >= 0,"StarPU Error to truncate file in UNISTD full_write function");
-			tmp->size = size;
-                }
-                else
-                {
-                        STARPU_ASSERT_MSG(0, "Can't allocate size %u on the disk !", (int) size);
-                }
-
+		STARPU_ASSERT(val == 0);
+		tmp->size = size;
         }
-	return _starpu_disk_write(STARPU_MAIN_RAM, node, obj, ptr, 0, tmp->size, NULL);
+
+	return starpu_unistd_global_write(base, obj, ptr, 0, size);
 }
 
 

+ 3 - 3
src/core/disk_ops/unistd/disk_unistd_global.h

@@ -26,7 +26,7 @@
 struct starpu_unistd_global_obj {
         int descriptor;
         char * path;
-        double size;
+        size_t size;
 	int flags;
 	starpu_pthread_mutex_t mutex;
 };
@@ -45,6 +45,6 @@ void* starpu_unistd_global_async_write (void *base, void *obj, void *buf, off_t
 void starpu_unistd_global_wait_request(void * async_channel);
 int starpu_unistd_global_test_request(void * async_channel);
 void starpu_unistd_global_free_request(void * async_channel);
-int starpu_unistd_global_full_read(unsigned node, void *base, void * obj, void ** ptr, size_t * size);
-int starpu_unistd_global_full_write (unsigned node, void * base, void * obj, void * ptr, size_t size);
+int starpu_unistd_global_full_read(void *base, void * obj, void ** ptr, size_t * size);
+int starpu_unistd_global_full_write (void * base, void * obj, void * ptr, size_t size);
 #endif

+ 20 - 11
src/datawizard/copy_driver.c

@@ -417,14 +417,17 @@ static int copy_data_1_to_1_generic(starpu_data_handle_t handle,
 
 		else
 		{
-			struct starpu_disk_interface * disk_interface = (struct starpu_disk_interface *) dst_interface; 
-			void * obj = (void *) disk_interface->dev_handle;
+			void *obj = starpu_data_handle_to_pointer(handle, dst_node);
 			void * ptr = NULL;
 			starpu_ssize_t size = 0;
 			handle->ops->pack_data(handle, src_node, &ptr, &size);
-			ret = _starpu_disk_full_write(src_node, dst_node, obj, ptr, size);
-			/* ptr is allocated in pack_data */
-			free(ptr);
+			ret = _starpu_disk_full_write(src_node, dst_node, obj, ptr, size, &req->async_channel);
+			if (ret == 0)
+				/* write is already finished, ptr was allocated in pack_data */
+				free(ptr);
+
+			/* For now, asynchronous is not supported */
+			STARPU_ASSERT(ret == 0);
 		}
 		break;
 		
@@ -433,14 +436,20 @@ static int copy_data_1_to_1_generic(starpu_data_handle_t handle,
 			ret = copy_methods->any_to_any(src_interface, src_node, dst_interface, dst_node, req && !starpu_asynchronous_copy_disabled()  ? &req->async_channel : NULL);
 		else
 		{
-			struct starpu_disk_interface * disk_interface = (struct starpu_disk_interface *) src_interface; 
-			void * obj = (void *) disk_interface->dev_handle;
+			void *obj = starpu_data_handle_to_pointer(handle, src_node);
 			void * ptr = NULL;
 			size_t size = 0;
-			ret = _starpu_disk_full_read(src_node, dst_node, obj, &ptr, &size);
-			handle->ops->unpack_data(handle, dst_node, ptr, size); 
-			/* ptr is allocated in full_read */
-			free(ptr);
+			ret = _starpu_disk_full_read(src_node, dst_node, obj, &ptr, &size, &req->async_channel);
+			if (ret == 0)
+			{
+				/* read is already finished, we can already unpack */
+				handle->ops->unpack_data(handle, dst_node, ptr, size); 
+				/* ptr is allocated in full_read */
+				free(ptr);
+			}
+
+			/* For now, asynchronous is not supported */
+			STARPU_ASSERT(ret == 0);
 		}
 		break;
 

+ 0 - 1
src/datawizard/interfaces/data_interface.h

@@ -39,7 +39,6 @@ union _starpu_interface
 	struct starpu_bcsr_interface bcsr;
 	struct starpu_variable_interface variable;
 	struct starpu_multiformat_interface multiformat;
-	struct starpu_disk_interface disk;
 };
 
 /* Some data interfaces or filters use this interface internally */

+ 1 - 0
tests/Makefile.am

@@ -207,6 +207,7 @@ noinst_PROGRAMS =				\
 	datawizard/specific_node		\
 	disk/disk_copy				\
 	disk/disk_compute			\
+	disk/disk_pack				\
 	errorcheck/starpu_init_noworker		\
 	errorcheck/invalid_blocking_calls	\
 	errorcheck/invalid_tasks		\

+ 243 - 0
tests/disk/disk_pack.c

@@ -0,0 +1,243 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013 Corentin Salingue
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+/* Try to write into disk memory
+ * Use mechanism to push datas from main ram to disk ram
+ */
+
+#include <fcntl.h>
+#include <starpu.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <math.h>
+#include <common/config.h>
+#include "../helper.h"
+
+#ifdef STARPU_HAVE_WINDOWS
+        #include <io.h>
+#endif 
+
+#define NX (1024)
+
+const struct starpu_data_copy_methods my_vector_copy_data_methods_s;
+struct starpu_data_interface_ops starpu_interface_my_vector_ops;
+
+void starpu_my_vector_data_register(starpu_data_handle_t *handleptr, unsigned home_node,
+                        uintptr_t ptr, uint32_t nx, size_t elemsize)
+{
+	struct starpu_vector_interface vector =
+	{
+		.id = STARPU_VECTOR_INTERFACE_ID,
+		.ptr = ptr,
+		.nx = nx,
+		.elemsize = elemsize,
+                .dev_handle = ptr,
+		.slice_base = 0,
+                .offset = 0
+	};
+
+	starpu_data_register(handleptr, home_node, &vector, &starpu_interface_my_vector_ops);
+}
+
+int dotest(struct starpu_disk_ops *ops)
+{
+	int *A, *C;
+
+	/* Initialize StarPU without GPU devices to make sure the memory of the GPU devices will not be used */
+	struct starpu_conf conf;
+	int ret = starpu_conf_init(&conf);
+	if (ret == -EINVAL)
+		return EXIT_FAILURE;
+	conf.ncuda = 0;
+	conf.nopencl = 0;
+	ret = starpu_init(&conf);
+	if (ret == -ENODEV) goto enodev;
+
+	/* Initialize path and name */
+	char pid_str[16];
+	int pid = getpid();
+	snprintf(pid_str, 16, "%d", pid);
+
+	char * base = "/tmp";
+
+	const char *name_file_start = "STARPU_DISK_COMPUTE_DATA_";
+	const char *name_file_end = "STARPU_DISK_COMPUTE_DATA_RESULT_";
+
+	char * path_file_start = malloc(strlen(base) + 1 + strlen(name_file_start) + 1);
+	strcpy(path_file_start, base);
+	strcat(path_file_start, "/");
+	strcat(path_file_start, name_file_start);
+
+	char * path_file_end = malloc(strlen(base) + 1 + strlen(name_file_end) + 1);
+	strcpy(path_file_end, base);
+	strcat(path_file_end, "/");
+	strcat(path_file_end, name_file_end);
+
+
+	/* register a disk */
+	int new_dd = starpu_disk_register(ops, (void *) base, 1024*1024*1);
+	/* can't write on /tmp/ */
+	if (new_dd == -ENOENT) goto enoent;
+	
+	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;
+	}
+
+
+
+
+	/* you create a file to store the vector ON the disk */
+	FILE * f = fopen(path_file_start, "wb+");
+	if (f == NULL)
+		goto enoent;
+
+	/* store it in the file */
+	fwrite(A, sizeof(int), NX, f);
+
+	/* close the file */
+	fclose(f);
+
+	int descriptor = open(path_file_start, O_RDWR);
+#ifdef STARPU_HAVE_WINDOWS
+	_commit(descriptor);
+#else
+	fsync(descriptor);
+#endif
+	close(descriptor);
+
+	/* create a file to store result */
+	f = fopen(path_file_end, "wb+");
+	if (f == NULL)
+		goto enoent;
+
+	/* replace all datas by 0 */
+	fwrite(C, sizeof(int), NX, f);
+
+	/* close the file */
+	fclose(f);
+
+        descriptor = open(path_file_end, O_RDWR);
+#ifdef STARPU_HAVE_WINDOWS
+        _commit(descriptor);
+#else
+        fsync(descriptor);
+#endif
+	close(descriptor);
+
+	/* And now, you want to use your datas in StarPU */
+	/* Open the file ON the disk */
+	void * data = starpu_disk_open(dd, (void *) name_file_start, NX*sizeof(int));
+	void * data_result = starpu_disk_open(dd, (void *) name_file_end, NX*sizeof(int));
+
+	starpu_data_handle_t vector_handleA, vector_handleC;
+
+	/* Build an vector-like interface which doesn't have the any_to_any helper, to force making use of pack/unpack */
+	memcpy(&starpu_interface_my_vector_ops, &starpu_interface_vector_ops, sizeof(starpu_interface_my_vector_ops));
+	starpu_interface_my_vector_ops.copy_methods = &my_vector_copy_data_methods_s;
+
+	/* register vector in starpu */
+	starpu_my_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_my_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 */	
+	f = fopen(path_file_end, "rb+");
+	if (f == NULL)
+		goto enoent;
+	/* take datas */
+	int size = fread(C, sizeof(int), NX, f);
+
+	/* close the file */
+	fclose(f);
+
+	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(double), STARPU_MALLOC_COUNT);
+	starpu_free_flags(C, NX*sizeof(double), STARPU_MALLOC_COUNT);
+
+	unlink(path_file_start);
+	unlink(path_file_end);
+
+	free(path_file_start);
+	free(path_file_end);
+
+	/* terminate StarPU, no task can be submitted after */
+	starpu_shutdown();
+
+	if(try)
+		FPRINTF(stderr, "TEST SUCCESS\n");
+	else
+		FPRINTF(stderr, "TEST FAIL\n");
+	return (try ? EXIT_SUCCESS : EXIT_FAILURE);
+
+enodev:
+	return STARPU_TEST_SKIPPED;
+enoent:
+	FPRINTF(stderr, "Couldn't write data: ENOENT\n");
+	starpu_shutdown();
+	return STARPU_TEST_SKIPPED;
+}
+
+static int merge_result(int old, int new)
+{
+	if (new == EXIT_FAILURE)
+		return EXIT_FAILURE;
+	if (old == 0)
+		return 0;
+	return new;
+}
+
+int main(void) {
+	int ret = 0;
+	ret = merge_result(ret, dotest(&starpu_disk_stdio_ops));
+	ret = merge_result(ret, dotest(&starpu_disk_unistd_ops));
+#ifdef STARPU_LINUX_SYS
+	ret = merge_result(ret, dotest(&starpu_disk_unistd_o_direct_ops));
+#endif
+	return ret;
+}