Browse Source

add files src/common/htable64.[ch] and make use of them, replacing previous htable32 use in starpu_mpi_insert_task.c and insert_task_cache.[ch]

Benjamin Lorendeau 13 years ago
parent
commit
148e38e2ef

+ 16 - 46
mpi/starpu_mpi_insert_task.c

@@ -21,16 +21,17 @@
 #include <starpu.h>
 #include <starpu.h>
 #include <starpu_data.h>
 #include <starpu_data.h>
 #include <common/utils.h>
 #include <common/utils.h>
+#include <common/htable64.h>
 #include <util/starpu_insert_task_utils.h>
 #include <util/starpu_insert_task_utils.h>
 #include <datawizard/coherency.h>
 #include <datawizard/coherency.h>
 
 
-//#define STARPU_MPI_VERBOSE	1
+//#define STARPU_MPI_VERBOSE 1
 #include <starpu_mpi_private.h>
 #include <starpu_mpi_private.h>
 
 
 /* Whether we are allowed to keep copies of remote data. Does not work
 /* Whether we are allowed to keep copies of remote data. Does not work
  * yet: the sender has to know whether the receiver has it, keeping it
  * yet: the sender has to know whether the receiver has it, keeping it
  * in an array indexed by node numbers. */
  * in an array indexed by node numbers. */
-#define MPI_CACHE 
+#define MPI_CACHE 1
 #include <starpu_mpi_insert_task_cache.h>
 #include <starpu_mpi_insert_task_cache.h>
 
 
 static void _starpu_mpi_tables_init()
 static void _starpu_mpi_tables_init()
@@ -40,11 +41,11 @@ static void _starpu_mpi_tables_init()
 		int i;
 		int i;
 
 
 		MPI_Comm_size(MPI_COMM_WORLD, &nb_nodes);
 		MPI_Comm_size(MPI_COMM_WORLD, &nb_nodes);
-		_STARPU_MPI_DEBUG("Initialising lists for cache\n");
-		sent_data = malloc(nb_nodes * sizeof(struct starpu_addr_node_list_t *));
-		for(i=0 ; i<nb_nodes ; i++) sent_data[i] = starpu_addr_node_list_new();
-		received_data = malloc(nb_nodes * sizeof(struct starpu_addr_node_list_t *));
-		for(i=0 ; i<nb_nodes ; i++) received_data[i] = starpu_addr_node_list_new();
+		_STARPU_MPI_DEBUG("Initialising htable for cache\n");
+		sent_data = malloc(nb_nodes * sizeof(struct starpu_htbl64_node *));
+		for(i=0 ; i<nb_nodes ; i++) sent_data[i] = NULL;
+		received_data = malloc(nb_nodes * sizeof(struct starpu_htbl64_node *));
+		for(i=0 ; i<nb_nodes ; i++) received_data[i] = NULL;
 	}
 	}
 }
 }
 
 
@@ -220,18 +221,9 @@ int starpu_mpi_insert_task(MPI_Comm comm, struct starpu_codelet *codelet, ...)
 				if (do_execute && mpi_rank != me && mpi_rank != -1) {
 				if (do_execute && mpi_rank != me && mpi_rank != -1) {
 					/* I will have to execute but I don't have the data, receive */
 					/* I will have to execute but I don't have the data, receive */
 #ifdef MPI_CACHE
 #ifdef MPI_CACHE
-					struct starpu_addr_node *it, *stored_data ;
-					void *already_received = NULL;
-					for (it = starpu_addr_node_list_begin(received_data[mpi_rank]); it != starpu_addr_node_list_end(received_data[mpi_rank]); it = starpu_addr_node_list_next(it)) {
-						if(((void *)it->ndata != NULL) && it->ndata == (uintptr_t)data) {
-							already_received=it->ndata;
-							break;
-						}
-					}
+					void *already_received = _starpu_htbl_search_64(received_data[mpi_rank], data);
 					if (!already_received) {
 					if (!already_received) {
-						stored_data = starpu_addr_node_new();
-						stored_data->ndata=(uintptr_t)data;
-						starpu_addr_node_list_push_front(received_data[mpi_rank], stored_data);
+						_starpu_htbl_insert_64(&received_data[mpi_rank], data, data);
 					}
 					}
 					else {
 					else {
 						_STARPU_MPI_DEBUG("Do not receive data %p from node %d as it is already available\n", data, mpi_rank);
 						_STARPU_MPI_DEBUG("Do not receive data %p from node %d as it is already available\n", data, mpi_rank);
@@ -246,22 +238,13 @@ int starpu_mpi_insert_task(MPI_Comm comm, struct starpu_codelet *codelet, ...)
 				if (!do_execute && mpi_rank == me) {
 				if (!do_execute && mpi_rank == me) {
 					/* Somebody else will execute it, and I have the data, send it. */
 					/* Somebody else will execute it, and I have the data, send it. */
 #ifdef MPI_CACHE
 #ifdef MPI_CACHE
-					struct starpu_addr_node *it, *stored_data;
-					void *already_sent = NULL;
-					for (it = starpu_addr_node_list_begin(sent_data[dest]); it != starpu_addr_node_list_end(sent_data[dest]); it = starpu_addr_node_list_next(it)) {
-						if((void *)it->ndata != NULL && it->ndata == (uintptr_t)data) {
-							already_sent=it;
-							break;
-						}
-					}
+					void *already_sent = _starpu_htbl_search_64(sent_data[dest], data);
 
 
 					if (!already_sent) {
 					if (!already_sent) {
-						stored_data = starpu_addr_node_new();
-						stored_data->ndata=(uintptr_t)data;
-						starpu_addr_node_list_push_front(sent_data[dest], stored_data);
+						_starpu_htbl_insert_64(&sent_data[dest], data, data);
 					}
 					}
 					else {
 					else {
-						_STARPU_MPI_DEBUG("Do not sent data %p to node %d as it has already been sent\n", data, dest);
+						_STARPU_MPI_DEBUG("Do not send data %p to node %d as it has already been sent\n", data, dest);
 					}
 					}
 					if (!already_sent)
 					if (!already_sent)
 #endif
 #endif
@@ -366,14 +349,7 @@ int starpu_mpi_insert_task(MPI_Comm comm, struct starpu_codelet *codelet, ...)
 					int n, size;
 					int n, size;
 					MPI_Comm_size(comm, &size);
 					MPI_Comm_size(comm, &size);
 					for(n=0 ; n<size ; n++) {
 					for(n=0 ; n<size ; n++) {
-						struct starpu_addr_node *it ;
-						void *already_sent = NULL;
-						for (it = starpu_addr_node_list_begin(sent_data[n]); it < starpu_addr_node_list_end(sent_data[n]); it = starpu_addr_node_list_next(it)) {
-						if((void *)it->ndata != NULL && it->ndata == (uintptr_t)data) {
-								already_sent=it->ndata;
-								break;
-							}
-						}
+						void *already_sent = _starpu_htbl_search_64(sent_data[n], data);
 
 
 						if (already_sent) {
 						if (already_sent) {
 							_STARPU_MPI_DEBUG("Posting request to clear send cache for data %p\n", data);
 							_STARPU_MPI_DEBUG("Posting request to clear send cache for data %p\n", data);
@@ -383,14 +359,7 @@ int starpu_mpi_insert_task(MPI_Comm comm, struct starpu_codelet *codelet, ...)
 				}
 				}
 				else {
 				else {
 					int mpi_rank = starpu_data_get_rank(data);
 					int mpi_rank = starpu_data_get_rank(data);
-					void *already_received=NULL;
-					struct starpu_addr_node *it;
-					for (it = starpu_addr_node_list_begin(received_data[mpi_rank]); it < starpu_addr_node_list_end(received_data[mpi_rank]); it = starpu_addr_node_list_next(it)) {
-						if((void *)it->ndata !=NULL && it->ndata == (uintptr_t)data) {
-							already_received=it->ndata;
-							break;
-						}
-					}
+					void *already_received=_starpu_htbl_search_64(received_data[mpi_rank], data);
 					if (already_received) {
 					if (already_received) {
 						/* Somebody else will write to the data, so discard our cached copy if any */
 						/* Somebody else will write to the data, so discard our cached copy if any */
 						/* TODO: starpu_mpi could just remember itself. */
 						/* TODO: starpu_mpi could just remember itself. */
@@ -434,6 +403,7 @@ int starpu_mpi_insert_task(MPI_Comm comm, struct starpu_codelet *codelet, ...)
 			va_arg(varg_list, starpu_data_handle_t);
 			va_arg(varg_list, starpu_data_handle_t);
 		}
 		}
 	}
 	}
+
 	va_end(varg_list);
 	va_end(varg_list);
 	_STARPU_MPI_LOG_OUT();
 	_STARPU_MPI_LOG_OUT();
 	return 0;
 	return 0;

+ 5 - 8
mpi/starpu_mpi_insert_task_cache.c

@@ -17,6 +17,7 @@
 
 
 #include <starpu_mpi_private.h>
 #include <starpu_mpi_private.h>
 #include <starpu_mpi_insert_task_cache.h>
 #include <starpu_mpi_insert_task_cache.h>
+#include <common/htable32.h>
 
 
 typedef struct _starpu_mpi_clear_cache_s {
 typedef struct _starpu_mpi_clear_cache_s {
         starpu_data_handle_t data;
         starpu_data_handle_t data;
@@ -24,24 +25,20 @@ typedef struct _starpu_mpi_clear_cache_s {
         int mode;
         int mode;
 } _starpu_mpi_clear_cache_t;
 } _starpu_mpi_clear_cache_t;
 
 
-struct starpu_addr_node_list **sent_data = NULL;
-struct starpu_addr_node_list **received_data = NULL;
+struct starpu_htbl64_node **sent_data = NULL;
+struct starpu_htbl64_node **received_data = NULL;
 
 
 void _starpu_mpi_clear_cache_callback(void *callback_arg)
 void _starpu_mpi_clear_cache_callback(void *callback_arg)
 {
 {
         _starpu_mpi_clear_cache_t *clear_cache = (_starpu_mpi_clear_cache_t *)callback_arg;
         _starpu_mpi_clear_cache_t *clear_cache = (_starpu_mpi_clear_cache_t *)callback_arg;
-		struct starpu_addr_node *stored_node = starpu_addr_node_new();
 
 
         if (clear_cache->mode == _STARPU_MPI_CLEAR_SENT_DATA) {
         if (clear_cache->mode == _STARPU_MPI_CLEAR_SENT_DATA) {
                 _STARPU_MPI_DEBUG("Clearing sent cache for data %p and rank %d\n", clear_cache->data, clear_cache->rank);
                 _STARPU_MPI_DEBUG("Clearing sent cache for data %p and rank %d\n", clear_cache->data, clear_cache->rank);
-				/* TODO: the implementation should be careful about freed memory. */
-				stored_node->ndata = (uintptr_t)clear_cache->data;
-				starpu_addr_node_list_push_front(sent_data[clear_cache->rank], stored_node);
+				_starpu_htbl_insert_64(&sent_data[clear_cache->rank], (uintptr_t)clear_cache->data, NULL);
         }
         }
         else if (clear_cache->mode == _STARPU_MPI_CLEAR_RECEIVED_DATA) {
         else if (clear_cache->mode == _STARPU_MPI_CLEAR_RECEIVED_DATA) {
                 _STARPU_MPI_DEBUG("Clearing received cache for data %p and rank %d\n", clear_cache->data, clear_cache->rank);
                 _STARPU_MPI_DEBUG("Clearing received cache for data %p and rank %d\n", clear_cache->data, clear_cache->rank);
-				stored_node->ndata = (uintptr_t)clear_cache->data;
-				starpu_addr_node_list_push_front(received_data[clear_cache->rank], stored_node);
+				_starpu_htbl_insert_64(&received_data[clear_cache->rank], (uintptr_t)clear_cache->data, NULL);
         }
         }
 
 
         free(clear_cache);
         free(clear_cache);

+ 2 - 6
mpi/starpu_mpi_insert_task_cache.h

@@ -21,11 +21,7 @@
 #define _STARPU_MPI_CLEAR_SENT_DATA     0
 #define _STARPU_MPI_CLEAR_SENT_DATA     0
 #define _STARPU_MPI_CLEAR_RECEIVED_DATA 1
 #define _STARPU_MPI_CLEAR_RECEIVED_DATA 1
 
 
-LIST_TYPE(starpu_addr_node, 
-		uintptr_t ndata;
-);
-
-extern struct starpu_addr_node_list **sent_data;
-extern struct starpu_addr_node_list **received_data;
+extern struct starpu_htbl64_node **sent_data;
+extern struct starpu_htbl64_node **received_data;
 
 
 void _starpu_mpi_clear_cache_request(starpu_data_handle_t data_handle, int rank, int mode);
 void _starpu_mpi_clear_cache_request(starpu_data_handle_t data_handle, int rank, int mode);

+ 2 - 0
src/Makefile.am

@@ -90,6 +90,7 @@ noinst_HEADERS = 						\
 	common/barrier.h					\
 	common/barrier.h					\
 	common/timing.h						\
 	common/timing.h						\
 	common/htable32.h					\
 	common/htable32.h					\
+	common/htable64.h					\
 	common/list.h						\
 	common/list.h						\
 	common/rwlock.h						\
 	common/rwlock.h						\
 	common/starpu_spinlock.h				\
 	common/starpu_spinlock.h				\
@@ -119,6 +120,7 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 						\
 	common/barrier.c					\
 	common/barrier.c					\
 	common/hash.c 						\
 	common/hash.c 						\
 	common/htable32.c					\
 	common/htable32.c					\
+	common/htable64.c					\
 	common/rwlock.c						\
 	common/rwlock.c						\
 	common/starpu_spinlock.c				\
 	common/starpu_spinlock.c				\
 	common/timing.c						\
 	common/timing.c						\

+ 106 - 0
src/common/htable64.c

@@ -0,0 +1,106 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2009-2010, 2012  Université de Bordeaux 1
+ * Copyright (C) 2010, 2011  Centre National de la Recherche Scientifique
+ *
+ * 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 <starpu.h>
+#include <common/config.h>
+#include <common/htable64.h>
+#include <stdint.h>
+#include <string.h>
+
+void *_starpu_htbl_search_64(struct starpu_htbl64_node *htbl, uint64_t key)
+{
+	unsigned currentbit;
+	unsigned keysize = sizeof(uint64_t)*8;
+
+	struct starpu_htbl64_node *current_htbl = htbl;
+	uint64_t mask = (1ULL<<_STARPU_HTBL64_NODE_SIZE)-1;
+
+	for(currentbit = 0; currentbit < keysize; currentbit+=_STARPU_HTBL64_NODE_SIZE)
+	{
+		if (STARPU_UNLIKELY(current_htbl == NULL))
+			return NULL;
+
+		unsigned last_currentbit =
+			keysize - (currentbit + _STARPU_HTBL64_NODE_SIZE);
+		uint64_t offloaded_mask = mask << last_currentbit;
+		unsigned current_index =
+			(key & (offloaded_mask)) >> (last_currentbit);
+
+		current_htbl = current_htbl->children[current_index];
+	}
+	return current_htbl;
+}
+
+/*
+ * returns the previous value of the tag, or NULL else
+ */
+
+void *_starpu_htbl_insert_64(struct starpu_htbl64_node **htbl, uint64_t key, void *entry)
+{
+	unsigned currentbit;
+	unsigned keysize = sizeof(uint64_t)*8;
+	struct starpu_htbl64_node **current_htbl_ptr = htbl;
+
+	uint64_t mask = (1ULL<<_STARPU_HTBL64_NODE_SIZE)-1;
+	for(currentbit = 0; currentbit < keysize; currentbit+=_STARPU_HTBL64_NODE_SIZE)
+	{
+		if (*current_htbl_ptr == NULL)
+		{
+			*current_htbl_ptr = (struct starpu_htbl64_node*)calloc(sizeof(struct starpu_htbl64_node), 1);
+			STARPU_ASSERT(*current_htbl_ptr);
+		}
+
+		unsigned last_currentbit =
+			keysize - (currentbit + _STARPU_HTBL64_NODE_SIZE);
+		uint64_t offloaded_mask = mask << last_currentbit;
+		unsigned current_index =
+			(key & (offloaded_mask)) >> (last_currentbit);
+
+		current_htbl_ptr =
+			&((*current_htbl_ptr)->children[current_index]);
+	}
+	void *old_entry = *current_htbl_ptr;
+	*current_htbl_ptr = (struct starpu_htbl64_node *) entry;
+
+	return old_entry;
+}
+
+static void _starpu_htbl_destroy_64_bit(struct starpu_htbl64_node *htbl, unsigned bit, void (*remove)(void*))
+{
+	unsigned keysize = sizeof(uint64_t)*8;
+	int i;
+
+	if (!htbl)
+		return;
+
+	if (bit >= keysize) {
+		/* entry, delete it */
+		if (remove)
+			remove(htbl);
+		return;
+	}
+
+	for (i = 0; i < 1ULL<<_STARPU_HTBL64_NODE_SIZE; i++) {
+		_starpu_htbl_destroy_64_bit(htbl->children[i], bit+_STARPU_HTBL64_NODE_SIZE, remove);
+	}
+
+	free(htbl);
+}
+void _starpu_htbl_destroy_64(struct starpu_htbl64_node *htbl, void (*remove)(void*))
+{
+	_starpu_htbl_destroy_64_bit(htbl, 0, remove);
+}

+ 46 - 0
src/common/htable64.h

@@ -0,0 +1,46 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2009-2010, 2012  Université de Bordeaux 1
+ * Copyright (C) 2010, 2011  Centre National de la Recherche Scientifique
+ *
+ * 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.
+ */
+
+#ifndef __GENERIC_HTABLE_H__
+#define __GENERIC_HTABLE_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define _STARPU_HTBL64_NODE_SIZE	8 
+
+/* Hierarchical table: all nodes have a 2^32 arity . */
+struct starpu_htbl64_node {
+	unsigned nentries;
+	struct starpu_htbl64_node *children[1ULL<<_STARPU_HTBL64_NODE_SIZE];
+};
+
+/* Look for a 64bit key into the hierchical table. Returns the entry if
+ * something is found, NULL otherwise. */
+void *_starpu_htbl_search_64(struct starpu_htbl64_node *htbl, uint64_t key);
+
+/* Insert an entry indexed by the 64bit key into the hierarchical table.
+ * Returns the entry that was previously associated to that key if any, NULL
+ * otherwise. */
+void *_starpu_htbl_insert_64(struct starpu_htbl64_node **htbl, uint64_t key, void *entry);
+
+/* Delete the content of the table, `remove' being called on each element */
+void _starpu_htbl_destroy_64(struct starpu_htbl64_node *htbl, void (*remove)(void*));
+
+#endif // __GENERIC_HTABLE_H__