Nathalie Furmento %!s(int64=7) %!d(string=hai) anos
pai
achega
321094291c

+ 4 - 4
doc/doxygen/chapters/510_configure_options.doxy

@@ -513,7 +513,7 @@ Enable linking with LevelDB if available
 Disable building HDF5 support.
 </dd>
 
-<dt>--with-hdf5-include-dir=<c>path</></dt>
+<dt>--with-hdf5-include-dir=<c>path</c></dt>
 <dd>
 \anchor with-hdf5-include-dir
 \addindex __configure__--with-hdf5-include-dir
@@ -698,9 +698,9 @@ exploring various execution paths.
 <dd>
 \anchor enable-calibration-heuristic
 \addindex __configure__--enable-calibration-heuristic
-Allows to set the maximum authorized percentage of deviation 
-for the history-based calibrator of StarPU. A correct value 
-of this parameter must be in [0..100]. The default value of 
+Allows to set the maximum authorized percentage of deviation
+for the history-based calibrator of StarPU. A correct value
+of this parameter must be in [0..100]. The default value of
 this parameter is 10. Experimental.
 </dd>
 

+ 6 - 3
examples/profiling/profiling.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2010-2013, 2015  Université de Bordeaux
+ * Copyright (C) 2010-2013, 2015, 2017  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013  CNRS
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -118,8 +118,11 @@ int main(int argc, char **argv)
 
 	free(tasks);
 
-	FPRINTF(stderr, "Avg. delay : %2.2lf us\n", (delay_sum)/niter);
-	FPRINTF(stderr, "Avg. length : %2.2lf us\n", (length_sum)/niter);
+	if (niter)
+	{
+		FPRINTF(stderr, "Avg. delay : %2.2lf us\n", (delay_sum)/niter);
+		FPRINTF(stderr, "Avg. length : %2.2lf us\n", (length_sum)/niter);
+	}
 
 	/* Display the occupancy of all workers during the test */
 	unsigned worker;

+ 17 - 6
mpi/src/starpu_mpi.c

@@ -97,9 +97,11 @@ int _starpu_mpi_fake_world_rank = -1;
 
 /* Count requests posted by the application and not yet submitted to MPI */
 static starpu_pthread_mutex_t mutex_posted_requests;
-static int posted_requests = 0, newer_requests, barrier_running = 0;
+static starpu_pthread_mutex_t mutex_ready_requests;
+static int posted_requests = 0, ready_requests = 0, newer_requests, barrier_running = 0;
 
 #define _STARPU_MPI_INC_POSTED_REQUESTS(value) { STARPU_PTHREAD_MUTEX_LOCK(&mutex_posted_requests); posted_requests += value; STARPU_PTHREAD_MUTEX_UNLOCK(&mutex_posted_requests); }
+#define _STARPU_MPI_INC_READY_REQUESTS(value) { STARPU_PTHREAD_MUTEX_LOCK(&mutex_ready_requests); ready_requests += value; STARPU_PTHREAD_MUTEX_UNLOCK(&mutex_ready_requests); }
 
 #pragma weak smpi_simulated_main_
 extern int smpi_simulated_main_(int argc, char *argv[]);
@@ -235,6 +237,7 @@ static void _starpu_mpi_submit_ready_request(void *arg)
 					  req, _starpu_mpi_request_type(req->request_type), req->node_tag.data_tag, req->node_tag.rank, req->data_handle, req->ptr,
 					  req->datatype_name, (int)req->count, req->registered_datatype);
 			_starpu_mpi_req_list_push_front(&ready_recv_requests, req);
+			_STARPU_MPI_INC_READY_REQUESTS(+1);
 
 			/* inform the starpu mpi thread that the request has been pushed in the ready_requests list */
 			STARPU_PTHREAD_MUTEX_UNLOCK(&progress_mutex);
@@ -301,6 +304,7 @@ static void _starpu_mpi_submit_ready_request(void *arg)
 						_STARPU_MPI_MALLOC(req->ptr, req->count);
 					}
 					_starpu_mpi_req_list_push_front(&ready_recv_requests, req);
+					_STARPU_MPI_INC_READY_REQUESTS(+1);
 					_starpu_mpi_request_destroy(sync_req);
 				}
 				else
@@ -317,6 +321,7 @@ static void _starpu_mpi_submit_ready_request(void *arg)
 			_starpu_mpi_req_prio_list_push_front(&ready_send_requests, req);
 		else
 			_starpu_mpi_req_list_push_front(&ready_recv_requests, req);
+		_STARPU_MPI_INC_READY_REQUESTS(+1);
 		_STARPU_MPI_DEBUG(3, "Pushing new request %p type %s tag %d src %d data %p ptr %p datatype '%s' count %d registered_datatype %d \n",
 				  req, _starpu_mpi_request_type(req->request_type), req->node_tag.data_tag, req->node_tag.rank, req->data_handle, req->ptr,
 				  req->datatype_name, (int)req->count, req->registered_datatype);
@@ -991,10 +996,10 @@ static void _starpu_mpi_barrier_func(struct _starpu_mpi_req *barrier_req)
 
 int _starpu_mpi_barrier(MPI_Comm comm)
 {
-	_STARPU_MPI_LOG_IN();
-
-	int ret = posted_requests;
 	struct _starpu_mpi_req *barrier_req;
+	int ret = posted_requests+ready_requests;
+
+	_STARPU_MPI_LOG_IN();
 
 	/* First wait for *both* all tasks and MPI requests to finish, in case
 	 * some tasks generate MPI requests, MPI requests generate tasks, etc.
@@ -1004,7 +1009,7 @@ int _starpu_mpi_barrier(MPI_Comm comm)
 	barrier_running = 1;
 	do
 	{
-		while (posted_requests)
+		while (posted_requests || ready_requests)
 			/* Wait for all current MPI requests to finish */
 			STARPU_PTHREAD_COND_WAIT(&barrier_cond, &progress_mutex);
 		/* No current request, clear flag */
@@ -1016,7 +1021,7 @@ int _starpu_mpi_barrier(MPI_Comm comm)
 		/* Check newer_requests again, in case some MPI requests
 		 * triggered by tasks completed and triggered tasks between
 		 * wait_for_all finished and we take the lock */
-	} while (posted_requests || newer_requests);
+	} while (posted_requests || ready_requests || newer_requests);
 	barrier_running = 0;
 	STARPU_PTHREAD_MUTEX_UNLOCK(&progress_mutex);
 
@@ -1391,6 +1396,7 @@ static void _starpu_mpi_receive_early_data(struct _starpu_mpi_envelope *envelope
 	// Handle the request immediatly to make sure the mpi_irecv is
 	// posted before receiving an other envelope
 	_starpu_mpi_req_list_erase(&ready_recv_requests, early_data_handle->req);
+	_STARPU_MPI_INC_READY_REQUESTS(-1);
 	STARPU_PTHREAD_MUTEX_UNLOCK(&progress_mutex);
 	_starpu_mpi_handle_ready_request(early_data_handle->req);
 	STARPU_PTHREAD_MUTEX_LOCK(&progress_mutex);
@@ -1503,6 +1509,7 @@ static void *_starpu_mpi_progress_thread_func(void *arg)
 				break;
 
 			req = _starpu_mpi_req_list_pop_back(&ready_recv_requests);
+			_STARPU_MPI_INC_READY_REQUESTS(-1);
 
 			/* handling a request is likely to block for a while
 			 * (on a sync_data_with_mem call), we want to let the
@@ -1524,6 +1531,7 @@ static void *_starpu_mpi_progress_thread_func(void *arg)
 				break;
 
 			req = _starpu_mpi_req_prio_list_pop_back_highest(&ready_send_requests);
+			_STARPU_MPI_INC_READY_REQUESTS(-1);
 
 			/* handling a request is likely to block for a while
 			 * (on a sync_data_with_mem call), we want to let the
@@ -1756,6 +1764,8 @@ int _starpu_mpi_progress_init(struct _starpu_mpi_argc_argv *argc_argv)
 	_starpu_mpi_req_list_init(&detached_requests);
 
         STARPU_PTHREAD_MUTEX_INIT(&mutex_posted_requests, NULL);
+        STARPU_PTHREAD_MUTEX_INIT(&mutex_ready_requests, NULL);
+
         _starpu_mpi_comm_debug = starpu_getenv("STARPU_MPI_COMM") != NULL;
 	nready_process = starpu_get_env_number_default("STARPU_MPI_NREADY_PROCESS", 10);
 	ndetached_send = starpu_get_env_number_default("STARPU_MPI_NDETACHED_SEND", 10);
@@ -1812,6 +1822,7 @@ void _starpu_mpi_progress_shutdown(int *value)
 #endif
 
         STARPU_PTHREAD_MUTEX_DESTROY(&mutex_posted_requests);
+        STARPU_PTHREAD_MUTEX_DESTROY(&mutex_ready_requests);
         STARPU_PTHREAD_MUTEX_DESTROY(&progress_mutex);
         STARPU_PTHREAD_COND_DESTROY(&barrier_cond);
 }

+ 1 - 1
mpi/src/starpu_mpi_cache.c

@@ -105,10 +105,10 @@ void _starpu_mpi_cache_shutdown()
 void _starpu_mpi_cache_data_clear(starpu_data_handle_t data_handle)
 {
 	struct _starpu_mpi_data *mpi_data = data_handle->mpi_data;
-	struct _starpu_data_entry *entry;
 
 	if (_starpu_cache_enabled == 1)
 	{
+		struct _starpu_data_entry *entry;
 		STARPU_PTHREAD_MUTEX_LOCK(&_cache_mutex);
 		_starpu_mpi_cache_flush_nolock(data_handle);
 		HASH_FIND_PTR(_cache_data, &data_handle, entry);

+ 37 - 25
src/core/disk.c

@@ -53,7 +53,7 @@ static inline unsigned get_location_with_node(unsigned node);
 
 static struct disk_register **disk_register_list = NULL;
 static unsigned memnode_to_disknode[STARPU_MAXNODES];
-static int disk_number = -1;
+static int disk_number = 0;
 static int size_register_list = 2;
 
 int starpu_disk_swap_node = -1;
@@ -61,7 +61,7 @@ int starpu_disk_swap_node = -1;
 static void add_async_event(struct _starpu_async_channel * channel, void * event)
 {
         if (!event)
-                return; 
+                return;
 
         if (channel->event.disk_event.requests == NULL)
         {
@@ -99,16 +99,16 @@ int starpu_disk_register(struct starpu_disk_ops *func, void *parameter, starpu_s
 		_starpu_memory_node_add_nworkers(disk_memnode);
 		_starpu_worker_drives_memory_node(workerarg, disk_memnode);
 	}
-	
+
 	//Add bus for disk <-> disk copy
-	if (func->copy != NULL)
+	if (func->copy != NULL && disk_register_list != NULL)
 	{
 		int disk;
-		for (disk = 0; disk < disk_number; disk++)
-			if (disk_register_list[disk]->functions->copy != NULL)
+		for (disk = 0; disk < size_register_list; disk++)
+			if (disk_register_list[disk] != NULL && disk_register_list[disk]->functions->copy != NULL && disk_register_list[disk]->functions->copy == func->copy)
 			{
-				_starpu_register_bus(disk_memnode, disk);
-				_starpu_register_bus(disk, disk_memnode);
+				_starpu_register_bus(disk_memnode, disk_register_list[disk]->node);
+				_starpu_register_bus(disk_register_list[disk]->node, disk_memnode);
 			}
 	}
 
@@ -137,27 +137,33 @@ int starpu_disk_register(struct starpu_disk_ops *func, void *parameter, starpu_s
 
 void _starpu_disk_unregister(void)
 {
-	int i;
-
-	/* search disk and delete it */
-	for (i = 0; i <= disk_number; ++i)
+	if (disk_register_list)
 	{
-		_starpu_set_disk_flag(disk_register_list[i]->node, STARPU_DISK_NO_RECLAIM);
-		_starpu_free_all_automatically_allocated_buffers(disk_register_list[i]->node);
+		int i;
 
-		/* don't forget to unplug */
-		disk_register_list[i]->functions->unplug(disk_register_list[i]->base);
-		free(disk_register_list[i]);
-	}
+		/* search disk and delete it */
+		for (i = 0; i < size_register_list; ++i)
+		{
+			if (disk_register_list[i] == NULL)
+				continue;
 
-	/* no disk in the list -> delete the list */
-	disk_number--;
+			_starpu_set_disk_flag(disk_register_list[i]->node, STARPU_DISK_NO_RECLAIM);
+			_starpu_free_all_automatically_allocated_buffers(disk_register_list[i]->node);
 
-	if (disk_register_list != NULL && disk_number == -1)
-	{
+			/* don't forget to unplug */
+			disk_register_list[i]->functions->unplug(disk_register_list[i]->base);
+			free(disk_register_list[i]);
+			disk_register_list[i] = NULL;
+
+			disk_number--;
+		}
+
+		/* no disk in the list -> delete the list */
 		free(disk_register_list);
 		disk_register_list = NULL;
 	}
+
+	STARPU_ASSERT_MSG(disk_number == 0, "Some disks are not unregistered !");
 }
 
 /* interface between user and disk memory */
@@ -408,13 +414,19 @@ static int add_disk_in_list(unsigned node,  struct starpu_disk_ops *func, void *
 	/* initialization */
 	if (disk_register_list == NULL)
 	{
-		_STARPU_MALLOC(disk_register_list, size_register_list*sizeof(struct disk_register *));
+		_STARPU_CALLOC(disk_register_list, size_register_list, sizeof(struct disk_register *));
 	}
 	/* small size -> new size  */
-	if ((disk_number+1) > size_register_list)
+	if (disk_number >= size_register_list)
 	{
+		int old_size = size_register_list;
 		size_register_list *= 2;
 		_STARPU_REALLOC(disk_register_list, size_register_list*sizeof(struct disk_register *));
+
+		/* Initialize the new part */
+		int i;
+		for (i = old_size; i < size_register_list; i++)
+			disk_register_list[i] = NULL;
 	}
 
 	struct disk_register *dr;
@@ -423,7 +435,7 @@ static int add_disk_in_list(unsigned node,  struct starpu_disk_ops *func, void *
 	dr->base = base;
 	dr->flag = STARPU_DISK_ALL;
 	dr->functions = func;
-	n = ++disk_number;
+	n = disk_number++;
 	disk_register_list[n] = dr;
 	memnode_to_disknode[node] = n;
 	return n;

+ 7 - 16
src/core/disk_ops/disk_hdf5.c

@@ -259,20 +259,11 @@ static void starpu_hdf5_copy_internal(struct _starpu_hdf5_work * work)
 	/* HDF5 H50copy supports only same size in both areas and copies the entire object */
 	if (work->offset_src == 0 && work->offset_dst == 0 && work->size == work->obj_src->size && work->size == work->obj_dst->size)
 	{
-		/* Add creation of intermediate group. It's not really used in our case but HDF5 doc is very weird */
-		hid_t grp_prop = H5Pcreate(H5P_LINK_CREATE);
-		status = H5Pset_create_intermediate_group(grp_prop, 1);
-		STARPU_ASSERT_MSG(status >= 0, "Can not copy data (%s) associed to this disk (%s) to the data (%s) on this disk (%s)\n", work->obj_src->path, work->base_src->path, work->obj_dst->path, work->base_dst->path);
-
-		hid_t copy_prop = H5Pcreate(H5P_OBJECT_COPY);
-		status = H5Pset_copy_object(copy_prop, H5O_COPY_SHALLOW_HIERARCHY_FLAG);
-		STARPU_ASSERT_MSG(status >= 0, "Can not copy data (%s) associed to this disk (%s) to the data (%s) on this disk (%s)\n", work->obj_src->path, work->base_src->path, work->obj_dst->path, work->base_dst->path);
+		/* Dirty : Delete dataspace because H5Ocopy only works if destination does not exist */
+		H5Ldelete(work->base_dst->fileID, work->obj_dst->path, H5P_DEFAULT);
 
-		status = H5Ocopy(work->obj_src->dataset, work->obj_src->path, work->obj_dst->dataset, work->obj_dst->path, copy_prop, grp_prop); 
+		status = H5Ocopy(work->base_src->fileID, work->obj_src->path, work->base_dst->fileID, work->obj_dst->path, H5P_DEFAULT, H5P_DEFAULT); 
 		STARPU_ASSERT_MSG(status >= 0, "Can not copy data (%s) associed to this disk (%s) to the data (%s) on this disk (%s)\n", work->obj_src->path, work->base_src->path, work->obj_dst->path, work->base_dst->path);
-
-		H5Pclose(grp_prop);
-		H5Pclose(copy_prop);
 	}
 	else
 	{
@@ -282,17 +273,17 @@ static void starpu_hdf5_copy_internal(struct _starpu_hdf5_work * work)
 			warned = 1;
 		}
 
-		void ** ptr = NULL;
-		int ret = _starpu_malloc_flags_on_node(STARPU_MAIN_RAM, ptr, work->size, 0);
+		void * ptr;
+		int ret = _starpu_malloc_flags_on_node(STARPU_MAIN_RAM, &ptr, work->size, 0);
 		STARPU_ASSERT_MSG(ret == 0, "Cannot allocate %lu bytes to perform disk to disk operation", work->size);
 
 		/* buffer is only used internally to store intermediate data */
-		work->ptr = *ptr;
+		work->ptr = ptr;
 		
 		starpu_hdf5_read_internal(work);
 		starpu_hdf5_write_internal(work);
 
-		_starpu_free_flags_on_node(STARPU_MAIN_RAM, *ptr, work->size, 0);
+		_starpu_free_flags_on_node(STARPU_MAIN_RAM, ptr, work->size, 0);
 	}
 }
 

+ 1 - 1
src/core/disk_ops/disk_leveldb.cpp

@@ -192,7 +192,7 @@ static int starpu_leveldb_write(void *base, void *obj, const void *buf, off_t of
 		memcpy(buffer, (void *) value_read, tmp->size);
 
 		/* put the new data on their new place */
-		memcpy(buffer + offset, (void *) buf_tmp, size);
+		memcpy((void *) ((uintptr_t) buffer + offset), (void *) buf_tmp, size);
 	}
 
 	/* and write them */

+ 3 - 2
src/core/perfmodel/perfmodel_history.c

@@ -1658,6 +1658,9 @@ void _starpu_update_perfmodel_history(struct _starpu_job *j, struct starpu_perfm
 				break;
 			}
 		}
+
+		STARPU_PTHREAD_RWLOCK_WRLOCK(&model->state->model_rwlock);
+
 		if(!found)
 		{
 			if (model->state->ncombs + 1 >= model->state->ncombs_set)
@@ -1669,8 +1672,6 @@ void _starpu_update_perfmodel_history(struct _starpu_job *j, struct starpu_perfm
 			model->state->combs[model->state->ncombs++] = comb;
 		}
 
-		STARPU_PTHREAD_RWLOCK_WRLOCK(&model->state->model_rwlock);
-
 		if(!model->state->per_arch[comb])
 		{
 			_starpu_perfmodel_malloc_per_arch(model, comb, STARPU_MAXIMPLEMENTATIONS);

+ 2 - 2
src/core/workers.c

@@ -2068,7 +2068,6 @@ int starpu_worker_get_by_devid(enum starpu_worker_archtype type, int devid)
 
 int starpu_worker_get_devids(enum starpu_worker_archtype type, int *devids, int num)
 {
-	int cnt = 0;
 	unsigned nworkers = starpu_worker_get_count();
 	int workerids[nworkers];
 
@@ -2079,10 +2078,11 @@ int starpu_worker_get_devids(enum starpu_worker_archtype type, int *devids, int
 	if(ndevice_workers > 0)
 	{
 		unsigned id, devid;
-		int curr_devid = -1;
+		int cnt = 0;
 		unsigned found = 0;
 		for(id = 0; id < ndevice_workers; id++)
 		{
+			int curr_devid;
 			curr_devid = _starpu_config.workers[workerids[id]].devid;
 			for(devid = 0; devid < ndevids; devid++)
 			{

+ 2 - 2
src/debug/traces/starpu_fxt.c

@@ -120,11 +120,11 @@ struct task_info *tasks_info;
 static struct task_info *get_task(unsigned long job_id, int mpi_rank)
 {
 	struct task_info *task;
-	unsigned i;
 
 	HASH_FIND(hh, tasks_info, &job_id, sizeof(job_id), task);
 	if (!task)
 	{
+		unsigned i;
 		_STARPU_MALLOC(task, sizeof(*task));
 		task->model_name = NULL;
 		task->name = NULL;
@@ -3032,10 +3032,10 @@ void _starpu_fxt_process_bandwidth(struct starpu_fxt_options *options)
 	char *prefix = options->file_prefix;
 
 	/* Loop through completed communications */
-	struct _starpu_communication*itor;
 	while (!_starpu_communication_list_empty(&communication_list)
 			&& _starpu_communication_list_begin(&communication_list)->peer)
 	{
+		struct _starpu_communication*itor;
 		/* This communication is complete */
 		itor = _starpu_communication_list_pop_front(&communication_list);
 

+ 1 - 2
src/drivers/cpu/driver_cpu.c

@@ -156,8 +156,6 @@ static size_t _starpu_cpu_get_global_mem_size(int nodeid STARPU_ATTRIBUTE_UNUSED
 	starpu_ssize_t limit = -1;
 
 #if defined(STARPU_HAVE_HWLOC)
-	char name[32];
-
 	struct _starpu_machine_topology *topology = &config->topology;
 
 	int nnumas = starpu_memory_nodes_get_numa_count();
@@ -171,6 +169,7 @@ static size_t _starpu_cpu_get_global_mem_size(int nodeid STARPU_ATTRIBUTE_UNUSED
 		}
 		else
 		{
+			char name[32];
 			hwloc_obj_t obj = hwloc_get_obj_by_depth(topology->hwtopology, depth_node, nodeid);
 			global_mem = obj->memory.local_memory;
 			snprintf(name, sizeof(name), "STARPU_LIMIT_CPU_NUMA_%d_MEM", obj->os_index);

+ 3 - 1
starpufft/src/starpufftx.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2009-2012, 2014  Université de Bordeaux
+ * Copyright (C) 2009-2012, 2014, 2017  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013, 2014  CNRS
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -451,6 +451,8 @@ STARPUFFT(showstats)(FILE *out)
 	for (worker = 0, total = 0; worker < starpu_worker_get_count(); worker++)
 		total += task_per_worker[worker];
 
+	if (!total)
+		return;
 	for (worker = 0; worker < starpu_worker_get_count(); worker++)
 	{
 		if (task_per_worker[worker])

+ 1 - 0
tests/Makefile.am

@@ -278,6 +278,7 @@ myPROGRAMS +=				\
 	datawizard/invalidate_pending_requests	\
 	datawizard/temporary_partition		\
 	disk/disk_copy				\
+	disk/disk_copy_to_disk			\
 	disk/disk_compute			\
 	disk/disk_pack				\
 	disk/mem_reclaim			\

+ 411 - 0
tests/disk/disk_copy_to_disk.c

@@ -0,0 +1,411 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2017  Inria
+ *
+ * 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.
+ */
+
+#include <fcntl.h>
+#include <starpu.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.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_HDF5
+#include <hdf5.h>
+#endif
+
+/*
+ * Try to write into disk memory
+ * Use mechanism to push data from disk to disk.
+ */
+
+#define NX (16*1024)
+
+int dotest(struct starpu_disk_ops *ops, char *base)
+{
+	int *A, *C;
+
+	/* Initialize StarPU with default configuration */
+	int ret = starpu_init(NULL);
+	if (ret == -ENODEV) goto enodev;
+
+	/* Initialize path and name */
+	const char *name_file_start = "STARPU_DISK_COMPUTE_DATA";
+	const char *name_dir_src = "src";
+	const char *name_dir_dst = "dst";
+
+	char * path_file_start = malloc(strlen(base) + 1 + strlen(name_dir_src) + 1 + strlen(name_file_start) + 1);
+	strcpy(path_file_start, base);
+	strcat(path_file_start, "/");
+	strcat(path_file_start, name_dir_src);
+	strcat(path_file_start, "/");
+	strcat(path_file_start, name_file_start);
+
+        char * base_src = malloc(strlen(base) + 1 + strlen(name_dir_src) + 1);
+        strcpy(base_src, base);
+        strcat(base_src, "/");
+        strcat(base_src, name_dir_src);
+
+        char * base_dst = malloc(strlen(base) + 1 + strlen(name_dir_dst) + 1);
+        strcpy(base_dst, base);
+        strcat(base_dst, "/");
+        strcat(base_dst, name_dir_dst);
+
+	/* register a disks */
+	int disk_src = starpu_disk_register(ops, (void *) base_src, STARPU_DISK_SIZE_MIN);
+	if (disk_src == -ENOENT) goto enoent;
+
+	int disk_dst = starpu_disk_register(ops, (void *) base_dst, STARPU_DISK_SIZE_MIN);
+	if (disk_dst == -ENOENT) goto enoent;
+
+	/* 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 enoent2;
+
+	/* store it in the file */
+	fwrite(A, sizeof(int), NX, f);
+
+	/* close the file */
+	fclose(f);
+
+	int descriptor = open(path_file_start, O_RDWR);
+	if (descriptor < 0)
+		goto enoent2;
+#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(disk_src, (void *) name_file_start, NX*sizeof(int));
+
+	starpu_data_handle_t vector_handleA;
+	starpu_vector_data_register(&vector_handleA, disk_src, (uintptr_t) data, NX, sizeof(int));
+
+	/* Move and invalidate copy to an other disk */
+	starpu_data_acquire_on_node(vector_handleA, disk_dst, STARPU_W);
+	starpu_data_release_on_node(vector_handleA, disk_dst);
+
+	starpu_data_acquire_on_node(vector_handleA, disk_src, STARPU_W);
+	starpu_data_release_on_node(vector_handleA, disk_src);
+
+	/* free them */
+	starpu_data_unregister(vector_handleA);
+
+	/* close them in StarPU */
+	starpu_disk_close(disk_src, data, NX*sizeof(int));
+
+	/* check results */
+	f = fopen(path_file_start, "rb+");
+	if (f == NULL)
+		goto enoent2;
+	/* take datas */
+	size_t read = fread(C, sizeof(int), NX, f);
+        STARPU_ASSERT(read == NX);
+
+	/* 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(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(path_file_start);
+	rmdir(base_src);
+
+	free(base_src);
+	free(base_dst);
+	free(path_file_start);
+
+	if(try)
+		FPRINTF(stderr, "TEST SUCCESS\n");
+	else
+		FPRINTF(stderr, "TEST FAIL\n");
+	return try ? EXIT_SUCCESS : EXIT_FAILURE;
+
+enodev:
+	return STARPU_TEST_SKIPPED;
+enoent2:
+	starpu_free_flags(A, NX*sizeof(int), STARPU_MALLOC_COUNT);
+	starpu_free_flags(C, NX*sizeof(int), STARPU_MALLOC_COUNT);
+enoent:
+	free(base_src);
+	free(base_dst);
+	free(path_file_start);
+
+	FPRINTF(stderr, "Couldn't write data: ENOENT\n");
+	starpu_shutdown();
+	return STARPU_TEST_SKIPPED;
+}
+
+#ifdef STARPU_HAVE_HDF5
+int dotest_hdf5(struct starpu_disk_ops *ops, char *base)
+{
+	int *A, *C;
+        herr_t status;
+
+
+	/* Initialize path */
+	const char *path_obj_start = "STARPU_DISK_COMPUTE_DATA";
+	const char *name_hdf5_start = "STARPU_HDF5_src_file.h5";
+	const char *name_hdf5_end = "STARPU_HDF5_dst_file.h5";
+
+        char * hdf5_base_src = malloc(strlen(base) + 1 + strlen(name_hdf5_start) + 1);
+        strcpy(hdf5_base_src, base);
+        strcat(hdf5_base_src, "/");
+        strcat(hdf5_base_src, name_hdf5_start);
+
+        char * hdf5_base_dst = malloc(strlen(base) + 1 + strlen(name_hdf5_end) + 1);
+        strcpy(hdf5_base_dst, base);
+        strcat(hdf5_base_dst, "/");
+        strcat(hdf5_base_dst, name_hdf5_end);
+
+        /* Open and close files, just to create empty files */
+        FILE * file_src = fopen(hdf5_base_src, "wb+");
+        if (!file_src)
+                goto h5fail2;
+        fclose(file_src);
+
+        FILE * file_dst = fopen(hdf5_base_dst, "wb+");
+        if (!file_dst)
+	{
+                goto h5fail2;
+	}
+        fclose(file_dst);
+
+	/* Initialize StarPU with default configuration */
+	int ret = starpu_init(NULL);
+	if (ret == -ENODEV) goto h5enodev;
+
+	/* register disks */
+	int disk_src = starpu_disk_register(ops, (void *) hdf5_base_src, STARPU_DISK_SIZE_MIN);
+	if (disk_src == -ENOENT) goto h5enoent;
+
+	int disk_dst = starpu_disk_register(ops, (void *) hdf5_base_dst, STARPU_DISK_SIZE_MIN);
+	if (disk_dst == -ENOENT) goto h5enoent;
+
+	/* 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(hdf5_base_src, H5F_ACC_RDWR, H5P_DEFAULT);
+        if (file < 0)
+                goto h5fail;
+
+	/* 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;
+        }
+
+        H5Sclose(dataspace);
+        H5Fclose(file);
+
+	/* Open the file ON the disk */
+	void * data = starpu_disk_open(disk_src, (void *) path_obj_start, NX*sizeof(int));
+
+	starpu_data_handle_t vector_handleA;
+	starpu_vector_data_register(&vector_handleA, disk_src, (uintptr_t) data, NX, sizeof(int));
+
+	/* Move and invalidate copy to an other disk */
+	starpu_data_acquire_on_node(vector_handleA, disk_dst, STARPU_W);
+	starpu_data_release_on_node(vector_handleA, disk_dst);
+
+	starpu_data_acquire_on_node(vector_handleA, disk_src, STARPU_W);
+	starpu_data_release_on_node(vector_handleA, disk_src);
+
+	starpu_data_unregister(vector_handleA);
+
+	/* close them in StarPU */
+	starpu_disk_close(disk_src, data, NX*sizeof(int));
+
+	/* check results */
+        file = H5Fopen(hdf5_base_src, H5F_ACC_RDWR, H5P_DEFAULT);
+        if (file < 0)
+                goto h5fail;
+
+        dataset = H5Dopen2(file, path_obj_start, 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(hdf5_base_src);
+        unlink(hdf5_base_dst);
+
+	free(hdf5_base_src);
+	free(hdf5_base_dst);
+
+	if(try)
+		FPRINTF(stderr, "TEST SUCCESS\n");
+	else
+		FPRINTF(stderr, "TEST FAIL\n");
+	return (try ? EXIT_SUCCESS : EXIT_FAILURE);
+
+h5fail:
+	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();
+h5enodev:
+        unlink(hdf5_base_src);
+        unlink(hdf5_base_dst);
+	free(hdf5_base_src);
+	free(hdf5_base_dst);
+	return STARPU_TEST_SKIPPED;
+h5fail2:
+	free(hdf5_base_src);
+	free(hdf5_base_dst);
+	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)
+		return EXIT_FAILURE;
+	if (old == 0)
+		return 0;
+	return new;
+}
+
+int main(void)
+{
+	int ret = 0;
+	int ret2;
+	char s[128];
+	char *ptr;
+
+	snprintf(s, sizeof(s), "/tmp/%s-disk-XXXXXX", getenv("USER"));
+	ptr = _starpu_mkdtemp(s);
+	if (!ptr)
+	{
+		FPRINTF(stderr, "Cannot make directory '%s'\n", s);
+		return STARPU_TEST_SKIPPED;
+	}
+
+	ret = merge_result(ret, dotest(&starpu_disk_stdio_ops, s));
+	ret = merge_result(ret, dotest(&starpu_disk_unistd_ops, s));
+#ifdef STARPU_LINUX_SYS
+	if ((NX * sizeof(int)) % getpagesize() == 0)
+	{
+		ret = merge_result(ret, dotest(&starpu_disk_unistd_o_direct_ops, s));
+	}
+	else
+	{
+		ret = merge_result(ret, STARPU_TEST_SKIPPED);
+	}
+#endif
+#ifdef STARPU_HAVE_HDF5
+        ret = merge_result(ret, dotest_hdf5(&starpu_disk_hdf5_ops, s));
+#endif
+
+	ret2 = rmdir(s);
+	if (ret2 < 0)
+		STARPU_CHECK_RETURN_VALUE(-errno, "rmdir '%s'\n", s);
+	return ret;
+}

+ 22 - 8
tools/gdbinit

@@ -2,7 +2,7 @@
 # StarPU --- Runtime system for heterogeneous multicore architectures.
 #
 # Copyright (C) 2010-2017  Université de Bordeaux
-# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016  CNRS
+# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017  CNRS
 #
 # 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
@@ -792,23 +792,36 @@ define starpu-mpi-print-request
     printf "Request (struct _starpu_mpi_req *) %p data %p tag %d to MPI node %d type %s submitted %d completed %d posted %d detached %d is_internal_req %d\n", $request, $request->data_handle, $request->data_handle ? ((struct _starpu_mpi_node_tag *) ($request->data_handle->mpi_data))->data_tag : -1, $request->node_tag.rank, $request_type, $request->submitted, $request->completed, $request->posted, $request->detached, $request->is_internal_req
 end
 
-define starpu-mpi-print-ready-requests
-    set $list = (struct _starpu_mpi_req_list *) ready_requests
+define starpu-mpi-print-ready-recv-requests
+    set $list = (struct _starpu_mpi_req_list) ready_recv_requests
     if $list
-	set $request = $list->_head
+	set $request = $list.list._head
         while $request
             starpu-mpi-print-request $request
 	    set $request = $request->_next
 	end
     else
-	printf "No ready requests\n"
+	printf "No ready recv requests\n"
+    end
+end
+
+define starpu-mpi-print-ready-send-requests
+    set $list = (struct _starpu_mpi_req_prio_list) ready_send_requests
+    if $list
+	set $request = $list.list._head
+        while $request
+            starpu-mpi-print-request $request
+	    set $request = $request->_next
+	end
+    else
+	printf "No ready send requests\n"
     end
 end
 
 define starpu-mpi-print-detached-requests
-    set $list = (struct _starpu_mpi_req_list *) detached_requests
+    set $list = (struct _starpu_mpi_req_list) detached_requests
     if $list
-	set $request = $list->_head
+	set $request = $list.list._head
         while $request
             starpu-mpi-print-request $request
 	    set $request = $request->_next
@@ -906,7 +919,8 @@ starpu-print-registered-models     prints all registered performance models
 starpu-print-model                 prints a given performance model
 starpu-sched-data                  prints the data of the given scheduler
 starpu-sched-print-modular         prints the hierarchy of modular scheduling components
-starpu-mpi-print-ready-requests    prints all MPI ready requests
+starpu-mpi-print-ready-recv-requests    prints all MPI ready recv requests
+starpu-mpi-print-ready-send-requests    prints all MPI ready send requests
 starpu-mpi-print-detached-requests prints all MPI detached requests
 starpu-mpi-print-early-data        prints all MPI early received data
 starpu-mpi-print-early-requests    prints all MPI early requests