Prechádzať zdrojové kódy

New function starpu_codelet_unpack_args_and_copyleft() which allows to copy in a new buffer values which have not been unpacked by the current call

Nathalie Furmento 9 rokov pred
rodič
commit
e3bf388754

+ 3 - 0
ChangeLog

@@ -190,6 +190,9 @@ Small features:
   * New function starpu_mpi_wait_for_all(MPI_Comm comm) that allows to
     wait until all StarPU tasks and communications for the given
     communicator are completed.
+  * New function starpu_codelet_unpack_args_and_copyleft() which
+    allows to copy in a new buffer values which have not been unpacked by
+    the current call
 
 Changes:
   * Data interfaces (variable, vector, matrix and block) now define

+ 36 - 1
doc/doxygen/chapters/06tasks.doxy

@@ -1,7 +1,7 @@
 /*
  * This file is part of the StarPU Handbook.
  * Copyright (C) 2009--2011  Universit@'e de Bordeaux
- * Copyright (C) 2010, 2011, 2012, 2013, 2014  CNRS
+ * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2016  CNRS
  * Copyright (C) 2011, 2012 INRIA
  * See the file version.doxy for copying conditions.
  */
@@ -350,6 +350,41 @@ be executed, and is allowed to read from <c>i</c> to use it e.g. as an
 index. Note that this macro is only avaible when compiling StarPU with
 the compiler <c>gcc</c>.
 
+There is several ways of calling the function starpu_codelet_unpack_args().
+
+\code{.c}
+void func_cpu(void *descr[], void *_args)
+{
+        int ifactor;
+        float ffactor;
+
+        starpu_codelet_unpack_args(_args, &ifactor, &ffactor);
+}
+\endcode
+
+\code{.c}
+void func_cpu(void *descr[], void *_args)
+{
+        int ifactor;
+        float ffactor;
+
+        starpu_codelet_unpack_args(_args, &ifactor, NULL);
+        starpu_codelet_unpack_args(_args, &ifactor, &ffactor);
+}
+\endcode
+
+\code{.c}
+void func_cpu(void *descr[], void *_args)
+{
+        int ifactor;
+        float ffactor;
+	char buffer[100];
+
+        starpu_codelet_unpack_args_and_copyleft(_args, buffer, 100, &ifactor, NULL);
+        starpu_codelet_unpack_args(buffer, &ffactor);
+}
+\endcode
+
 \section GettingTaskChildren Getting Task Children
 
 It may be interesting to get the list of tasks which depend on a given task,

+ 7 - 1
doc/doxygen/chapters/api/insert_task.doxy

@@ -1,7 +1,7 @@
 /*
  * This file is part of the StarPU Handbook.
  * Copyright (C) 2009--2011  Universit@'e de Bordeaux
- * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015  CNRS
+ * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016  CNRS
  * Copyright (C) 2011, 2012 INRIA
  * See the file version.doxy for copying conditions.
  */
@@ -135,6 +135,12 @@ task automatically created using the function starpu_task_insert(). If
 some parameter is NULL, unpacking will stop there and ignore the remaining
 parameters.
 
+\fn void starpu_codelet_unpack_args_and_copyleft(void *cl_arg, void *buffer, size_t buffer_size, ...)
+\ingroup API_Insert_Task
+Similar to starpu_codelet_unpack_args(), but if some parameter is
+NULL, copy the part of cl_arg that has not been read in buffer which
+can then be used in a later call to one of the unpack functions.
+
 \fn struct starpu_task *starpu_task_build(struct starpu_codelet *cl, ...)
 \ingroup API_Insert_Task
 Create a task corresponding to \p cl with the following arguments.

+ 2 - 2
include/starpu_task_util.h

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010-2015  Université de Bordeaux
- * Copyright (C) 2010-2014  CNRS
+ * Copyright (C) 2010-2014, 2016  CNRS
  * Copyright (C) 2014       INRIA
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -67,7 +67,7 @@ int starpu_task_insert(struct starpu_codelet *cl, ...);
 int starpu_insert_task(struct starpu_codelet *cl, ...);
 
 void starpu_codelet_unpack_args(void *cl_arg, ...);
-
+void starpu_codelet_unpack_args_and_copyleft(void *cl_arg, void *buffer, size_t buffer_size, ...);
 void starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, ...);
 
 #ifdef __cplusplus

+ 34 - 8
src/util/starpu_task_insert.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010, 2012, 2014-2016  Université de Bordeaux
- * Copyright (C) 2011, 2012, 2013, 2014, 2015  CNRS
+ * Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016  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
@@ -32,17 +32,12 @@ void starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, ...)
 	va_end(varg_list);
 }
 
-void starpu_codelet_unpack_args(void *_cl_arg, ...)
+void _starpu_codelet_unpack_args_and_copyleft(char *cl_arg, void *_buffer, size_t buffer_size, va_list varg_list)
 {
-	char *cl_arg = (char *) _cl_arg;
 	int current_arg_offset = 0;
 	int nargs, arg;
-	va_list varg_list;
 
-	STARPU_ASSERT(cl_arg);
-	va_start(varg_list, _cl_arg);
-
-	/* We fill the different pointers with the appropriate arguments */
+     	/* We fill the different pointers with the appropriate arguments */
 	memcpy(&nargs, cl_arg, sizeof(nargs));
 	current_arg_offset += sizeof(nargs);
 
@@ -61,6 +56,37 @@ void starpu_codelet_unpack_args(void *_cl_arg, ...)
 		memcpy(argptr, cl_arg+current_arg_offset, arg_size);
 		current_arg_offset += arg_size;
 	}
+	if (buffer_size && arg < nargs)
+	{
+		int left = nargs-arg;
+		char *buffer = (char *) _buffer;
+		memcpy(buffer, (int *)&left, sizeof(left));
+		memcpy(buffer+sizeof(int), cl_arg+current_arg_offset, buffer_size-sizeof(int));
+	}
+}
+
+void starpu_codelet_unpack_args_and_copyleft(void *_cl_arg, void *buffer, size_t buffer_size, ...)
+{
+	char *cl_arg = (char *) _cl_arg;
+	va_list varg_list;
+
+	STARPU_ASSERT(cl_arg);
+	va_start(varg_list, buffer_size);
+
+	_starpu_codelet_unpack_args_and_copyleft(cl_arg, buffer, buffer_size, varg_list);
+
+	va_end(varg_list);
+}
+
+void starpu_codelet_unpack_args(void *_cl_arg, ...)
+{
+	char *cl_arg = (char *) _cl_arg;
+	va_list varg_list;
+
+	STARPU_ASSERT(cl_arg);
+	va_start(varg_list, _cl_arg);
+
+	_starpu_codelet_unpack_args_and_copyleft(cl_arg, NULL, 0, varg_list);
 
 	va_end(varg_list);
 }

+ 166 - 30
tests/main/insert_task_value.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2015  CNRS
+ * Copyright (C) 2015, 2016  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
@@ -23,92 +23,228 @@
  */
 
 #define IFACTOR 42
-#define FFACTOR 12.0
+#define FFACTOR 12.00
 
-void func_cpu(void *descr[], void *_args)
+void func_cpu_int_float(void *descr[], void *_args)
 {
 	int ifactor[2048];
 	float ffactor;
+	(void) descr;
 
 	starpu_codelet_unpack_args(_args, ifactor, &ffactor);
 
-	FPRINTF(stderr, "Values %d - %3.2f\n", ifactor[0], ffactor);
+	FPRINTF(stderr, "[func_cpu_int_float                ] Values %d - %3.2f\n", ifactor[0], ffactor);
 	assert(ifactor[0] == IFACTOR && ffactor == FFACTOR);
 }
 
-void func_cpu2(void *descr[], void *_args)
+void func_cpu_int_float_multiple_unpack(void *descr[], void *_args)
 {
 	int ifactor[2048];
 	float ffactor;
+	(void) descr;
+
+	starpu_codelet_unpack_args(_args, ifactor, NULL);
+	starpu_codelet_unpack_args(_args, ifactor, &ffactor);
+
+	FPRINTF(stderr, "[func_cpu_int_float_multiple_unpack] Values %d - %3.2f\n", ifactor[0], ffactor);
+	assert(ifactor[0] == IFACTOR && ffactor == FFACTOR);
+}
+
+void func_cpu_int_float_unpack_copyleft(void *descr[], void *_args)
+{
+	int ifactor[2048];
+	float ffactor;
+	char buffer[1024];
+	(void) descr;
+
+	starpu_codelet_unpack_args_and_copyleft(_args, buffer, 1024, ifactor, NULL);
+	starpu_codelet_unpack_args(buffer, &ffactor);
+
+	FPRINTF(stderr, "[func_cpu_int_float_unpack_copyleft] Values %d - %3.2f\n", ifactor[0], ffactor);
+	assert(ifactor[0] == IFACTOR && ffactor == FFACTOR);
+}
+
+void func_cpu_float_int(void *descr[], void *_args)
+{
+	int ifactor[2048];
+	float ffactor;
+	(void) descr;
 
 	starpu_codelet_unpack_args(_args, &ffactor, ifactor);
 
-	FPRINTF(stderr, "Values %d - %3.2f\n", ifactor[0], ffactor);
+	FPRINTF(stderr, "[func_cpu_float_int                ] Values %d - %3.2f\n", ifactor[0], ffactor);
 	assert(ifactor[0] == IFACTOR && ffactor == FFACTOR);
 }
 
-struct starpu_codelet mycodelet =
+void func_cpu_float_int_multiple_unpack(void *descr[], void *_args)
 {
-	.cpu_funcs = {func_cpu},
-	.cpu_funcs_name = {"func_cpu"},
-};
+	int ifactor[2048];
+	float ffactor;
+	(void) descr;
+
+	starpu_codelet_unpack_args(_args, &ffactor, NULL);
+	starpu_codelet_unpack_args(_args, &ffactor, ifactor);
+
+	FPRINTF(stderr, "[func_cpu_float_int_multiple_unpack] Values %d - %3.2f\n", ifactor[0], ffactor);
+	assert(ifactor[0] == IFACTOR && ffactor == FFACTOR);
+}
 
-struct starpu_codelet mycodelet2 =
+void func_cpu_float_int_unpack_copyleft(void *descr[], void *_args)
 {
-	.cpu_funcs = {func_cpu2},
-	.cpu_funcs_name = {"func_cpu2"},
-};
+	int ifactor[2048];
+	float ffactor;
+	char buffer[10240];
+	(void) descr;
 
-int main(int argc, char **argv)
+	starpu_codelet_unpack_args_and_copyleft(_args, buffer, 1024, &ffactor, NULL);
+	starpu_codelet_unpack_args(buffer, ifactor);
+
+	FPRINTF(stderr, "[func_cpu_float_int_multiple_unpack] Values %d - %3.2f\n", ifactor[0], ffactor);
+	assert(ifactor[0] == IFACTOR && ffactor == FFACTOR);
+}
+
+int do_test_int_float_task_insert(starpu_cpu_func_t func, char* func_name)
 {
-        int ret;
 	int ifactor[2048];
 	float ffactor=FFACTOR;
-	struct starpu_task *task;
+	int ret;
+	struct starpu_codelet codelet;
 
-	ret = starpu_init(NULL);
-	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
-	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+	starpu_codelet_init(&codelet);
+	codelet.cpu_funcs[0] = func;
+	codelet.cpu_funcs_name[0] = func_name;
 
 	ifactor[0] = IFACTOR;
 
-	ret = starpu_task_insert(&mycodelet,
+	ret = starpu_task_insert(&codelet,
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 0);
-	if (ret == -ENODEV) goto enodev;
+	if (ret == -ENODEV) return ret;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+	starpu_task_wait_for_all();
+	return 0;
+}
 
-	ret = starpu_task_insert(&mycodelet2,
+int do_test_float_int_task_insert(starpu_cpu_func_t func, char* func_name)
+{
+	int ifactor[2048];
+	float ffactor=FFACTOR;
+	int ret;
+	struct starpu_codelet codelet;
+
+	starpu_codelet_init(&codelet);
+	codelet.cpu_funcs[0] = func;
+	codelet.cpu_funcs_name[0] = func_name;
+
+	ifactor[0] = IFACTOR;
+
+	ret = starpu_task_insert(&codelet,
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 0);
-	if (ret == -ENODEV) goto enodev;
+	if (ret == -ENODEV) return ret;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+	starpu_task_wait_for_all();
+	return 0;
+}
+
+int do_test_int_float_pack(starpu_cpu_func_t func, char* func_name)
+{
+	struct starpu_task *task;
+	struct starpu_codelet codelet;
+	int ret;
+	int ifactor[2048];
+	float ffactor=FFACTOR;
+
+	starpu_codelet_init(&codelet);
+	codelet.cpu_funcs[0] = func;
+	codelet.cpu_funcs_name[0] = func_name;
 
 	task = starpu_task_create();
 	task->synchronous = 1;
-	task->cl = &mycodelet;
+	task->cl = &codelet;
 	task->cl_arg_free = 1;
 	starpu_codelet_pack_args(&task->cl_arg, &task->cl_arg_size,
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 0);
 	ret = starpu_task_submit(task);
-	if (ret != -ENODEV)
-		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	if (ret == -ENODEV) return ret;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	starpu_task_wait_for_all();
+	return 0;
+}
+
+int do_test_float_int_pack(starpu_cpu_func_t func, char* func_name)
+{
+	struct starpu_task *task;
+	struct starpu_codelet codelet;
+	int ret;
+	int ifactor[2048];
+	float ffactor=FFACTOR;
+
+	starpu_codelet_init(&codelet);
+	codelet.cpu_funcs[0] = func;
+	codelet.cpu_funcs_name[0] = func_name;
 
 	task = starpu_task_create();
 	task->synchronous = 1;
-	task->cl = &mycodelet2;
+	task->cl = &codelet;
 	task->cl_arg_free = 1;
 	starpu_codelet_pack_args(&task->cl_arg, &task->cl_arg_size,
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 0);
 	ret = starpu_task_submit(task);
-	if (ret != -ENODEV)
-		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	if (ret == -ENODEV) return ret;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	starpu_task_wait_for_all();
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+        int ret;
+	int ifactor[2048];
+	float ffactor=FFACTOR;
+	struct starpu_task *task;
+	(void) argc;
+	(void) argv;
+
+	ifactor[0] = IFACTOR;
+
+	ret = starpu_init(NULL);
+	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+
+	ret = do_test_int_float_task_insert(func_cpu_int_float, "func_cpu_int_float_name");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_int_float_task_insert(func_cpu_int_float_multiple_unpack, "func_cpu_int_float_multiple_unpack");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_int_float_task_insert(func_cpu_int_float_unpack_copyleft, "func_cpu_int_float_unpack_copyleft");
+	if (ret == -ENODEV) goto enodev;
+
+	ret = do_test_float_int_task_insert(func_cpu_float_int, "func_cpu_float_int");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_float_int_task_insert(func_cpu_float_int_multiple_unpack, "func_cpu_float_int_multiple_unpack");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_float_int_task_insert(func_cpu_float_int_unpack_copyleft, "func_cpu_float_int_unpack_copyleft");
+	if (ret == -ENODEV) goto enodev;
+
+	ret = do_test_int_float_pack(func_cpu_int_float, "func_cpu_int_float_name");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_int_float_pack(func_cpu_int_float_multiple_unpack, "func_cpu_int_float_multiple_unpack");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_int_float_pack(func_cpu_int_float_unpack_copyleft, "func_cpu_int_float_unpack_copyleft");
+	if (ret == -ENODEV) goto enodev;
+
+	ret = do_test_float_int_pack(func_cpu_float_int, "func_cpu_float_int");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_float_int_pack(func_cpu_float_int_multiple_unpack, "func_cpu_float_int_multiple_unpack");
+	if (ret == -ENODEV) goto enodev;
+	ret = do_test_float_int_pack(func_cpu_float_int_unpack_copyleft, "func_cpu_float_int_unpack_copyleft");
+	if (ret == -ENODEV) goto enodev;
 
 	starpu_shutdown();