Browse Source

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 years ago
parent
commit
e3bf388754

+ 3 - 0
ChangeLog

@@ -190,6 +190,9 @@ Small features:
   * New function starpu_mpi_wait_for_all(MPI_Comm comm) that allows to
   * New function starpu_mpi_wait_for_all(MPI_Comm comm) that allows to
     wait until all StarPU tasks and communications for the given
     wait until all StarPU tasks and communications for the given
     communicator are completed.
     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:
 Changes:
   * Data interfaces (variable, vector, matrix and block) now define
   * 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.
  * This file is part of the StarPU Handbook.
  * Copyright (C) 2009--2011  Universit@'e de Bordeaux
  * 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
  * Copyright (C) 2011, 2012 INRIA
  * See the file version.doxy for copying conditions.
  * 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
 index. Note that this macro is only avaible when compiling StarPU with
 the compiler <c>gcc</c>.
 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
 \section GettingTaskChildren Getting Task Children
 
 
 It may be interesting to get the list of tasks which depend on a given task,
 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.
  * This file is part of the StarPU Handbook.
  * Copyright (C) 2009--2011  Universit@'e de Bordeaux
  * 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
  * Copyright (C) 2011, 2012 INRIA
  * See the file version.doxy for copying conditions.
  * 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
 some parameter is NULL, unpacking will stop there and ignore the remaining
 parameters.
 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, ...)
 \fn struct starpu_task *starpu_task_build(struct starpu_codelet *cl, ...)
 \ingroup API_Insert_Task
 \ingroup API_Insert_Task
 Create a task corresponding to \p cl with the following arguments.
 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.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
  * Copyright (C) 2010-2015  Université de Bordeaux
  * Copyright (C) 2010-2015  Université de Bordeaux
- * Copyright (C) 2010-2014  CNRS
+ * Copyright (C) 2010-2014, 2016  CNRS
  * Copyright (C) 2014       INRIA
  * Copyright (C) 2014       INRIA
  *
  *
  * StarPU is free software; you can redistribute it and/or modify
  * 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, ...);
 int starpu_insert_task(struct starpu_codelet *cl, ...);
 
 
 void starpu_codelet_unpack_args(void *cl_arg, ...);
 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, ...);
 void starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, ...);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 34 - 8
src/util/starpu_task_insert.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
  * Copyright (C) 2010, 2012, 2014-2016  Université de Bordeaux
  * 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
  * 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
  * 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);
 	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 current_arg_offset = 0;
 	int nargs, arg;
 	int nargs, arg;
-	va_list varg_list;
 
 
-	STARPU_ASSERT(cl_arg);
+     	/* We fill the different pointers with the appropriate arguments */
-	va_start(varg_list, _cl_arg);
-
-	/* We fill the different pointers with the appropriate arguments */
 	memcpy(&nargs, cl_arg, sizeof(nargs));
 	memcpy(&nargs, cl_arg, sizeof(nargs));
 	current_arg_offset += 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);
 		memcpy(argptr, cl_arg+current_arg_offset, arg_size);
 		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);
 	va_end(varg_list);
 }
 }

+ 166 - 30
tests/main/insert_task_value.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* 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
  * 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
  * it under the terms of the GNU Lesser General Public License as published by
@@ -23,92 +23,228 @@
  */
  */
 
 
 #define IFACTOR 42
 #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];
 	int ifactor[2048];
 	float ffactor;
 	float ffactor;
+	(void) descr;
 
 
 	starpu_codelet_unpack_args(_args, ifactor, &ffactor);
 	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);
 	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];
 	int ifactor[2048];
 	float ffactor;
 	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);
 	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);
 	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},
+	int ifactor[2048];
-	.cpu_funcs_name = {"func_cpu"},
+	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},
+	int ifactor[2048];
-	.cpu_funcs_name = {"func_cpu2"},
+	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];
 	int ifactor[2048];
 	float ffactor=FFACTOR;
 	float ffactor=FFACTOR;
-	struct starpu_task *task;
+	int ret;
+	struct starpu_codelet codelet;
 
 
-	ret = starpu_init(NULL);
+	starpu_codelet_init(&codelet);
-	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
+	codelet.cpu_funcs[0] = func;
-	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+	codelet.cpu_funcs_name[0] = func_name;
 
 
 	ifactor[0] = IFACTOR;
 	ifactor[0] = IFACTOR;
 
 
-	ret = starpu_task_insert(&mycodelet,
+	ret = starpu_task_insert(&codelet,
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 0);
 				 0);
-	if (ret == -ENODEV) goto enodev;
+	if (ret == -ENODEV) return ret;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
 	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, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 0);
 				 0);
-	if (ret == -ENODEV) goto enodev;
+	if (ret == -ENODEV) return ret;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
 	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 = starpu_task_create();
 	task->synchronous = 1;
 	task->synchronous = 1;
-	task->cl = &mycodelet;
+	task->cl = &codelet;
 	task->cl_arg_free = 1;
 	task->cl_arg_free = 1;
 	starpu_codelet_pack_args(&task->cl_arg, &task->cl_arg_size,
 	starpu_codelet_pack_args(&task->cl_arg, &task->cl_arg_size,
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 0);
 				 0);
 	ret = starpu_task_submit(task);
 	ret = starpu_task_submit(task);
-	if (ret != -ENODEV)
+	if (ret == -ENODEV) return ret;
-		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	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 = starpu_task_create();
 	task->synchronous = 1;
 	task->synchronous = 1;
-	task->cl = &mycodelet2;
+	task->cl = &codelet;
 	task->cl_arg_free = 1;
 	task->cl_arg_free = 1;
 	starpu_codelet_pack_args(&task->cl_arg, &task->cl_arg_size,
 	starpu_codelet_pack_args(&task->cl_arg, &task->cl_arg_size,
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, &ffactor, sizeof(ffactor),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 STARPU_VALUE, ifactor, 2048*sizeof(ifactor[0]),
 				 0);
 				 0);
 	ret = starpu_task_submit(task);
 	ret = starpu_task_submit(task);
-	if (ret != -ENODEV)
+	if (ret == -ENODEV) return ret;
-		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	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();
 	starpu_shutdown();