Explorar o código

Add `starpu_data_lookup'.

Ludovic Courtès %!s(int64=14) %!d(string=hai) anos
pai
achega
b5cabbca95

+ 1 - 0
.gitignore

@@ -23,3 +23,4 @@ Makefile.in
 .dirstamp
 /gcc-plugin/src/starpu-gcc-config.h
 /tests/datawizard/handle_to_pointer
+/tests/datawizard/data_lookup

+ 8 - 0
include/starpu_data_interfaces.h

@@ -21,6 +21,7 @@
 
 #include <starpu.h>
 #include <starpu_data.h>
+#include <starpu_util.h>
 
 #ifdef STARPU_USE_GORDON
 /* to get the gordon_strideSize_t data structure from gordon */
@@ -304,6 +305,13 @@ size_t starpu_bcsr_get_elemsize(starpu_data_handle);
 
 unsigned starpu_get_handle_interface_id(starpu_data_handle);
 
+extern starpu_data_handle starpu_data_lookup(const void *ptr);
+
+/* Internal functions.  */
+
+extern void _starpu_data_interface_init(void) STARPU_ATTRIBUTE_INTERNAL;
+extern void _starpu_data_interface_shutdown(void) STARPU_ATTRIBUTE_INTERNAL;
+
 #ifdef __cplusplus
 }
 #endif

+ 4 - 1
include/starpu_util.h

@@ -23,7 +23,6 @@
 #include <string.h>
 #include <assert.h>
 #include <starpu_config.h>
-#include <starpu_task.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -123,6 +122,10 @@ STARPU_ATOMIC_SOMETHING(or, old | value)
 #define STARPU_SYNCHRONIZE() __asm__ __volatile__("sync" ::: "memory")
 #endif
 
+/* Include this only here so that <starpu_data_interfaces.h> can use the
+ * macros above.  */
+#include <starpu_task.h>
+
 static __inline int starpu_get_env_number(const char *str)
 {
 	char *strval;

+ 5 - 1
src/core/workers.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009, 2010, 2011  Université de Bordeaux 1
  * Copyright (C) 2010, 2011  Centre National de la Recherche Scientifique
- * Copyright (C) 2010  Institut National de Recherche en Informatique et Automatique
+ * Copyright (C) 2010, 2011  Institut National de Recherche en Informatique et Automatique
  *
  * 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
@@ -318,6 +318,8 @@ int starpu_init(struct starpu_conf *user_conf)
 	
 	_starpu_open_debug_logfile();
 
+	_starpu_data_interface_init();
+
 	_starpu_timing_init();
 
 	_starpu_profiling_init();
@@ -484,6 +486,8 @@ void starpu_shutdown(void)
 	_starpu_stop_fxt_profiling();
 #endif
 
+	_starpu_data_interface_shutdown();
+
 	_starpu_close_debug_logfile();
 
 	PTHREAD_MUTEX_LOCK(&init_mutex);

+ 99 - 1
src/datawizard/interfaces/data_interface.c

@@ -15,8 +15,62 @@
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  */
 
+#include <stdint.h>
+
 #include <datawizard/datawizard.h>
 #include <core/dependencies/data_concurrency.h>
+#include <common/uthash.h>
+#include <starpu_spinlock.h>
+
+/* Entry in the `registered_handles' hash table.  */
+struct handle_entry
+{
+	UT_hash_handle hh;
+	void *pointer;
+	starpu_data_handle handle;
+};
+
+/* Hash table mapping host pointers to data handles.  */
+static struct handle_entry *registered_handles;
+static starpu_spinlock_t    registered_handles_lock;
+
+void _starpu_data_interface_init()
+{
+	_starpu_spin_init(&registered_handles_lock);
+}
+
+void _starpu_data_interface_shutdown()
+{
+	struct handle_entry *entry, *tmp;
+
+	_starpu_spin_destroy(&registered_handles_lock);
+
+	HASH_ITER(hh, registered_handles, entry, tmp) {
+		HASH_DEL(registered_handles, entry);
+		free(entry);
+	}
+
+	registered_handles = NULL;
+}
+
+starpu_data_handle starpu_data_lookup(const void *ptr)
+{
+	starpu_data_handle result;
+
+	_starpu_spin_lock(&registered_handles_lock);
+	{
+		struct handle_entry *entry;
+
+		HASH_FIND_PTR(registered_handles, &ptr, entry);
+		if(STARPU_UNLIKELY(entry == NULL))
+			result = NULL;
+		else
+			result = entry->handle;
+	}
+	_starpu_spin_unlock(&registered_handles_lock);
+
+	return result;
+}
 
 /* 
  * Start monitoring a piece of data
@@ -25,6 +79,8 @@
 static void _starpu_register_new_data(starpu_data_handle handle,
 					uint32_t home_node, uint32_t wt_mask)
 {
+	void *ptr;
+
 	STARPU_ASSERT(handle);
 
 	/* initialize the new lock */
@@ -127,10 +183,34 @@ static void _starpu_register_new_data(starpu_data_handle handle,
 
 		/* duplicate  the content of the interface on node 0 */
 		memcpy(replicate->data_interface, handle->per_node[0].data_interface, handle->ops->interface_size);
-	} 
+	}
 
 	/* now the data is available ! */
 	_starpu_spin_unlock(&handle->header_lock);
+
+	ptr = starpu_handle_to_pointer(handle);
+	if (ptr != NULL)
+	{
+		/* Register the mapping from PTR to HANDLE.  */
+		struct handle_entry *entry;
+
+		entry = malloc(sizeof(*entry));
+		STARPU_ASSERT(entry != NULL);
+
+		entry->pointer = ptr;
+		entry->handle = handle;
+
+		_starpu_spin_lock(&registered_handles_lock);
+		HASH_ADD_PTR(registered_handles, pointer, entry);
+
+		struct handle_entry *entry2;
+		HASH_FIND_PTR(registered_handles, &ptr, entry2);
+		STARPU_ASSERT(entry2 == entry);
+
+		_starpu_spin_unlock(&registered_handles_lock);
+
+		STARPU_ASSERT(starpu_data_lookup(ptr) == handle);
+	}
 }
 
 static starpu_data_handle _starpu_data_handle_allocate(struct starpu_data_interface_ops_t *interface_ops)
@@ -218,15 +298,33 @@ int starpu_data_set_rank(starpu_data_handle handle, int rank)
 
 void _starpu_data_free_interfaces(starpu_data_handle handle)
 {
+	void *ptr;
 	unsigned node;
 	unsigned worker;
 	unsigned nworkers = starpu_worker_get_count();
 
+	ptr = starpu_handle_to_pointer(handle);
+
 	for (node = 0; node < STARPU_MAXNODES; node++)
 		free(handle->per_node[node].data_interface);
 
 	for (worker = 0; worker < nworkers; worker++)
 		free(handle->per_worker[worker].data_interface);
+
+	if (ptr != NULL)
+	{
+		/* Remove the PTR -> HANDLE mapping.  */
+		struct handle_entry *entry;
+
+		_starpu_spin_lock(&registered_handles_lock);
+		HASH_FIND_PTR(registered_handles, &ptr, entry);
+		STARPU_ASSERT(entry != NULL);
+
+		HASH_DEL(registered_handles, entry);
+		free(entry);
+
+		_starpu_spin_unlock(&registered_handles_lock);
+	}
 }
 
 struct unregister_callback_arg {

+ 1 - 0
tests/Makefile.am

@@ -115,6 +115,7 @@ check_PROGRAMS += 				\
 	datawizard/acquire_release		\
 	datawizard/acquire_release2		\
 	datawizard/data_implicit_deps		\
+	datawizard/data_lookup			\
 	datawizard/scratch			\
 	datawizard/sync_and_notify_data		\
 	datawizard/sync_and_notify_data_implicit\

+ 114 - 0
tests/datawizard/data_lookup.c

@@ -0,0 +1,114 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2011  Institut National de Recherche en Informatique et Automatique
+ *
+ * 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.
+ */
+
+#undef NDEBUG
+#include <assert.h>
+
+#include <starpu.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#define VECTOR_COUNT    12
+#define VARIABLE_COUNT  42
+
+#define VECTOR_SIZE     123
+
+int main(int argc, char *argv[])
+{
+	int err;
+	size_t i;
+	void *vectors[VECTOR_COUNT], *variables[VARIABLE_COUNT];
+	starpu_data_handle vector_handles[VECTOR_COUNT];
+	starpu_data_handle variable_handles[VARIABLE_COUNT];
+
+	starpu_init(NULL);
+
+	/* Register data regions.  */
+
+	for(i = 0; i < VARIABLE_COUNT; i++)
+	{
+		err = starpu_malloc(&variables[i], sizeof(float));
+		assert(err == 0);
+		starpu_variable_data_register(&variable_handles[i], 0,
+					      (uintptr_t)variables[i],
+					      sizeof(float));
+	}
+
+	for(i = 0; i < VECTOR_COUNT; i++)
+	{
+		err = starpu_malloc(&vectors[i], VECTOR_SIZE * sizeof(float));
+		assert(err == 0);
+		starpu_vector_data_register(&vector_handles[i], 0,
+					    (uintptr_t)vectors[i],
+					    VECTOR_SIZE, sizeof(float));
+	}
+
+	/* Look them up.  */
+
+	for(i = 0; i < VARIABLE_COUNT; i++)
+	{
+		starpu_data_handle handle;
+
+		handle = starpu_data_lookup(variables[i]);
+		assert(handle == variable_handles[i]);
+	}
+
+	for(i = 0; i < VECTOR_COUNT; i++)
+	{
+		starpu_data_handle handle;
+
+		handle = starpu_data_lookup(vectors[i]);
+		assert(handle == vector_handles[i]);
+	}
+
+	/* Unregister them.  */
+
+	for(i = 0; i < VARIABLE_COUNT; i++)
+	{
+		starpu_data_unregister(variable_handles[i]);
+	}
+
+	for(i = 0; i < VECTOR_COUNT; i++)
+	{
+		starpu_data_unregister(vector_handles[i]);
+	}
+
+	/* Make sure we can no longer find them.  */
+
+	for(i = 0; i < VARIABLE_COUNT; i++)
+	{
+		starpu_data_handle handle;
+
+		handle = starpu_data_lookup(variables[i]);
+		assert(handle == NULL);
+		starpu_free(variables[i]);
+	}
+
+	for(i = 0; i < VECTOR_COUNT; i++)
+	{
+		starpu_data_handle handle;
+
+		handle = starpu_data_lookup(vectors[i]);
+		assert(handle == NULL);
+		starpu_free(vectors[i]);
+	}
+
+	starpu_shutdown();
+
+	return EXIT_SUCCESS;
+}