Browse Source

introduce starpu_data_fetch_on_node for fetches which can forcibly flush data out

Samuel Thibault 10 years ago
parent
commit
4ee5550b33

+ 2 - 0
ChangeLog

@@ -86,6 +86,8 @@ New features:
   * starpu_data_idle_prefetch_on_node and
     starpu_idle_prefetch_task_input_on_node allow to queue prefetches to be done
     only when the bus is idle.
+  * Make starpu_data_prefetch_on_node not forcibly flush data out, introduce
+    starpu_data_fetch_on_node for that.
 
 Small features:
   * Tasks can now have a name (via the field const char *name of

+ 10 - 1
doc/doxygen/chapters/api/data_management.doxy

@@ -168,10 +168,19 @@ modified, it is automatically transfered into those memory node. For
 instance a <c>1<<0</c> write-through mask means that the CUDA workers
 will commit their changes in main memory (node 0).
 
+\fn int starpu_data_fetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
+\ingroup API_Data_Management
+Issue a fetch request for a given data to a given node, i.e.
+requests that the data be replicated to the given node as soon as possible, so that it is
+available there for tasks. If the \p async parameter is 0, the call will
+block until the transfer is achieved, else the call will return immediately,
+after having just queued the request. In the latter case, the request will
+asynchronously wait for the completion of any task writing on the data.
+
 \fn int starpu_data_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
 \ingroup API_Data_Management
 Issue a prefetch request for a given data to a given node, i.e.
-requests that the data be replicated to the given node, so that it is
+requests that the data be replicated to the given node when there is room for it, so that it is
 available there for tasks. If the \p async parameter is 0, the call will
 block until the transfer is achieved, else the call will return immediately,
 after having just queued the request. In the latter case, the request will

+ 1 - 0
include/starpu_data.h

@@ -88,6 +88,7 @@ void starpu_data_display_memory_stats();
 
 int starpu_data_request_allocation(starpu_data_handle_t handle, unsigned node);
 
+int starpu_data_fetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async);
 int starpu_data_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async);
 int starpu_data_idle_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async);
 

+ 5 - 0
src/datawizard/user_interactions.c

@@ -447,6 +447,11 @@ int _starpu_prefetch_data_on_node_with_mode(starpu_data_handle_t handle, unsigne
 	return 0;
 }
 
+int starpu_data_fetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
+{
+	return _starpu_prefetch_data_on_node_with_mode(handle, node, async, STARPU_R, 0);
+}
+
 int starpu_data_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
 {
 	return _starpu_prefetch_data_on_node_with_mode(handle, node, async, STARPU_R, 1);

+ 12 - 2
tests/datawizard/allocate.c

@@ -43,6 +43,7 @@ int test_prefetch(unsigned memnodes)
 	buffers[0] = malloc(SIZE_ALLOC*1024*512);
 	STARPU_ASSERT(buffers[0]);
 
+	/* Prefetch half the memory */
 	starpu_variable_data_register(&handles[0], STARPU_MAIN_RAM, (uintptr_t)buffers[0], SIZE_ALLOC*1024*512);
 	for(i=1 ; i<memnodes ; i++)
 	{
@@ -56,6 +57,7 @@ int test_prefetch(unsigned memnodes)
 		STARPU_CHECK_RETURN_VALUE_IS((int) available_size, SIZE_ALLOC*1024*512, "starpu_memory_get_available (node %u)", i);
 	}
 
+	/* Prefetch a quarter of the memory */
 	buffers[1] = malloc(SIZE_ALLOC*1024*256);
 	STARPU_ASSERT(buffers[1]);
 
@@ -72,13 +74,14 @@ int test_prefetch(unsigned memnodes)
 		STARPU_CHECK_RETURN_VALUE_IS((int)available_size, SIZE_ALLOC*1024*256, "starpu_memory_get_available (node %u)", i);
 	}
 
+	/* Fetch a bit more than half of the memory, it should be able to push previous data out */
 	buffers[2] = malloc(SIZE_ALLOC*1024*600);
 	STARPU_ASSERT(buffers[2]);
 
 	starpu_variable_data_register(&handles[2], STARPU_MAIN_RAM, (uintptr_t)buffers[2], SIZE_ALLOC*1024*600);
 	for(i=1 ; i<memnodes ; i++)
 	{
-		starpu_data_prefetch_on_node(handles[2], i, 0);
+		starpu_data_fetch_on_node(handles[2], i, 0);
 	}
 
 	for(i=1 ; i<memnodes ; i++)
@@ -89,13 +92,14 @@ int test_prefetch(unsigned memnodes)
 		STARPU_CHECK_RETURN_VALUE((available_size == 0), "starpu_memory_get_available (node %u)", i);
 	}
 
+	/* Fetch half of the memory, it should be able to push previous data out */
 	buffers[3] = malloc(SIZE_ALLOC*1024*512);
 	STARPU_ASSERT(buffers[3]);
 
 	starpu_variable_data_register(&handles[3], STARPU_MAIN_RAM, (uintptr_t)buffers[3], SIZE_ALLOC*1024*512);
 	for(i=0 ; i<memnodes ; i++)
 	{
-		starpu_data_prefetch_on_node(handles[3], i, 0);
+		starpu_data_fetch_on_node(handles[3], i, 0);
 	}
 
 	for(i=1 ; i<memnodes ; i++)
@@ -130,26 +134,32 @@ void test_malloc()
 	float *buffer3;
 	size_t global_size;
 
+	/* Allocate one byte */
 	ret = starpu_malloc_flags((void **)&buffer, 1, STARPU_MALLOC_COUNT);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_malloc_flags");
 	FPRINTF(stderr, "Allocation succesfull for 1 b\n");
 
+	/* Allocate half the memory */
 	ret = starpu_malloc_flags((void **)&buffer2, SIZE_ALLOC*1024*512, STARPU_MALLOC_COUNT);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_malloc_flags");
 	FPRINTF(stderr, "Allocation succesfull for %d b\n", SIZE_ALLOC*1024*512);
 
+	/* Try to allocate the other half, should fail */
 	ret = starpu_malloc_flags((void **)&buffer3, SIZE_ALLOC*1024*512, STARPU_MALLOC_COUNT);
 	STARPU_CHECK_RETURN_VALUE_IS(ret, -ENOMEM, "starpu_malloc_flags");
 	FPRINTF(stderr, "Allocation failed for %d b\n", SIZE_ALLOC*1024*512);
 
+	/* Try to allocate the other half without counting it, should succeed */
 	ret = starpu_malloc_flags((void **)&buffer3, SIZE_ALLOC*1024*512, 0);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_malloc_flags");
 	FPRINTF(stderr, "Allocation successful for %d b\n", SIZE_ALLOC*1024*512);
 	starpu_free_flags(buffer3, SIZE_ALLOC*1024*512, 0);
 
+	/* Free the initial half-memory allocation */
 	starpu_free_flags(buffer2, SIZE_ALLOC*1024*512, STARPU_MALLOC_COUNT);
 	FPRINTF(stderr, "Freeing %d b\n", SIZE_ALLOC*1024*512);
 
+	/* Should not be able to allocate half the memory again */
 	ret = starpu_malloc_flags((void **)&buffer3, SIZE_ALLOC*1024*512, STARPU_MALLOC_COUNT);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_malloc_flags");
 	FPRINTF(stderr, "Allocation succesfull for %d b\n", SIZE_ALLOC*1024*512);