瀏覽代碼

Add STARPU_DATA_ACQUIRE_CB, which is the same as starpu_data_acquire_cb except that the code is passed inline as third parameter.

Samuel Thibault 14 年之前
父節點
當前提交
fba61a96c4
共有 4 個文件被更改,包括 150 次插入4 次删除
  1. 32 3
      doc/starpu.texi
  2. 8 1
      include/starpu_data.h
  3. 1 0
      tests/Makefile.am
  4. 109 0
      tests/datawizard/acquire_cb_insert.c

+ 32 - 3
doc/starpu.texi

@@ -1193,9 +1193,7 @@ starpu_vector_data_register(&handle, 0, (uintptr_t)vector, NX, sizeof(vector[0])
 starpu_filter f =
 @{
     .filter_func = starpu_block_filter_func_vector,
-    .nchildren = PARTS,
-    .get_nchildren = NULL,
-    .get_child_ops = NULL
+    .nchildren = PARTS
 @};
 starpu_data_partition(handle, &f);
 @end smallexample
@@ -1425,6 +1423,26 @@ task->cl_arg_size = arg_buffer_size;
 int ret = starpu_task_submit(task);
 @end smallexample
 
+If some part of the task insertion depends on the value of some computation,
+the @code{STARPU_DATA_ACQUIRE_CB} macro can be very convenient. For
+instance, assuming that the index variable @code{x} was registered as handle
+@code{x_handle}:
+
+@smallexample
+/* Compute which portion we will work on, e.g. pivot */
+starpu_insert_task(&which_index, STARPU_W, x_handle, 0);
+
+/* And submit the corresponding task */
+STARPU_DATA_ACQUIRE_CB(x_handle, STARPU_R, starpu_insert_task(&work, STARPU_W, starpu_data_get_sub_data(f_handle, 1, x), 0));
+@end smallexample
+
+The @code{STARPU_DATA_ACQUIRE_CB} macro submits an asynchronous request for
+acquiring data for the main application, and will execute the code given as
+third parameter when it is acquired. In other words, as soon as the value
+computed by the @code{which_index} codelet can be read, the portion of code
+passed as third parameter of @code{STARPU_DATA_ACQUIRE_CB} will be executed, and
+is allowed to read from @code{x} to use it e.g. as an index.
+
 @node Debugging
 @section Debugging
 
@@ -3330,6 +3348,7 @@ design their own data interfaces if required.
 * starpu_data_invalidate::      Invalidate all data replicates
 * starpu_data_acquire::         Access registered data from the application
 * starpu_data_acquire_cb::      Access registered data from the application asynchronously
+* STARPU_DATA_ACQUIRE_CB::      Access registered data from the application asynchronously, macro
 * starpu_data_release::         Release registered data from the application
 * starpu_data_set_wt_mask::     Set the Write-Through mask
 * starpu_data_prefetch_on_node:: Prefetch data to a given node
@@ -3481,6 +3500,16 @@ be called from task callbacks. Upon successful completion, this function
 returns 0.
 @end deftypefun
 
+@node STARPU_DATA_ACQUIRE_CB
+@subsection @code{STARPU_DATA_ACQUIRE_CB} -- Access registered data from the application asynchronously, macro
+@deftypefun STARPU_DATA_ACQUIRE_CB (starpu_data_handle @var{handle}, starpu_access_mode @var{mode}, code)
+@code{STARPU_DATA_ACQUIRE_CB} is the same as @code{starpu_data_acquire_cb},
+except that the code to be executed in a callback is directly provided as a
+macro parameter, and the data handle is automatically released after it. This
+permit to easily execute code which depends on the value of some registered
+data. This is non-blocking too and may be called from task callbacks.
+@end deftypefun
+
 @node starpu_data_release
 @subsection @code{starpu_data_release} -- Release registered data from the application
 @deftypefun void starpu_data_release (starpu_data_handle @var{handle})

+ 8 - 1
include/starpu_data.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2010  Université de Bordeaux 1
+ * Copyright (C) 2010-2011  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
@@ -60,6 +60,13 @@ void starpu_data_advise_as_important(starpu_data_handle handle, unsigned is_impo
 int starpu_data_acquire(starpu_data_handle handle, starpu_access_mode mode);
 int starpu_data_acquire_cb(starpu_data_handle handle,
 			starpu_access_mode mode, void (*callback)(void *), void *arg);
+#define STARPU_DATA_ACQUIRE_CB(handle, mode, code) { \
+	void callback(void *arg) { \
+		code; \
+		starpu_data_release(handle); \
+	} \
+	starpu_data_acquire_cb(handle, mode, callback, NULL); \
+}
 void starpu_data_release(starpu_data_handle handle);
 
 int starpu_malloc(void **A, size_t dim);

+ 1 - 0
tests/Makefile.am

@@ -116,6 +116,7 @@ testbin_PROGRAMS =				\
 	core/declare_deps_after_submission_synchronous	\
 	core/get_current_task			\
 	datawizard/acquire_cb			\
+	datawizard/acquire_cb_insert		\
 	datawizard/acquire_release		\
 	datawizard/acquire_release2		\
 	datawizard/data_implicit_deps		\

+ 109 - 0
tests/datawizard/acquire_cb_insert.c

@@ -0,0 +1,109 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 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>
+
+#define N 16
+#define M 4
+#define X 2
+
+#define FPRINTF(ofile, fmt, args ...) do { if (!getenv("STARPU_SSILENT")) {fprintf(ofile, fmt, ##args); }} while(0)
+
+void which_index_cpu(void *descr[], void *_args)
+{
+	int *x0 = (int *)STARPU_VARIABLE_GET_PTR(descr[0]);
+
+	/* A real case would actually compute something */
+	*x0 = X;
+}
+
+starpu_codelet which_index = {
+	.where = STARPU_CPU,
+	.cpu_func = which_index_cpu,
+        .nbuffers = 1
+};
+
+void work_cpu(void *descr[], void *_args)
+{
+	int i, n = STARPU_VECTOR_GET_NX(descr[0]);
+	float *x0 = (float *)STARPU_VECTOR_GET_PTR(descr[0]);
+
+	for (i = 0; i < n; i++)
+		x0[i] = i + 1;
+}
+
+starpu_codelet work = {
+	.where = STARPU_CPU,
+	.cpu_func = work_cpu,
+        .nbuffers = 1
+};
+
+static int x;
+
+int main(int argc, char **argv)
+{
+        int i;
+	float *f;
+	starpu_data_handle x_handle, f_handle;
+
+	starpu_init(NULL);
+
+	/* Declare x */
+	starpu_variable_data_register(&x_handle, 0, (uintptr_t)&x, sizeof(x));
+
+	/* Allocate and Declare f */
+	starpu_malloc((void**)&f, N * sizeof(*f));
+	memset(f, 0, N * sizeof(*f));
+	starpu_vector_data_register(&f_handle, 0, (uintptr_t)f, N, sizeof(*f));
+
+	/* Partition f */
+	struct starpu_data_filter filter = {
+		.filter_func = starpu_block_filter_func_vector,
+		.nchildren = M,
+	};
+	starpu_data_partition(f_handle, &filter);
+
+	/* Compute which portion we will work on */
+        starpu_insert_task(&which_index, STARPU_W, x_handle, 0);
+
+	/* And submit the corresponding task */
+	STARPU_DATA_ACQUIRE_CB(
+			x_handle,
+			STARPU_R,
+			starpu_insert_task(&work, STARPU_W, starpu_data_get_sub_data(f_handle, 1, x), 0)
+			);
+
+	starpu_task_wait_for_all();
+	starpu_data_unpartition(f_handle, 0);
+	starpu_data_unregister(f_handle);
+	starpu_data_unregister(x_handle);
+	starpu_shutdown();
+
+        FPRINTF(stderr, "VALUES: %d", x);
+
+        for(i=0 ; i<N ; i++) {
+		FPRINTF(stderr, " %f", f[i]);
+        }
+
+	STARPU_ASSERT(f[X*(N/M)] == 1);
+	STARPU_ASSERT(f[X*(N/M)+1] == 2);
+	STARPU_ASSERT(f[X*(N/M)+2] == 3);
+	STARPU_ASSERT(f[X*(N/M)+3] == 4);
+
+	FPRINTF(stderr, "\n");
+
+	return 0;
+}