浏览代码

A codelet can now define a callback function pointer which will be called when the task does not define itself a callback function.

Nathalie Furmento 4 年之前
父节点
当前提交
6918c29eda
共有 5 个文件被更改,包括 128 次插入4 次删除
  1. 9 0
      ChangeLog
  2. 15 1
      include/starpu_task.h
  3. 5 3
      src/core/jobs.c
  4. 1 0
      tests/Makefile.am
  5. 98 0
      tests/main/callback.c

+ 9 - 0
ChangeLog

@@ -47,6 +47,15 @@ New features:
 Small changes:
   * Add a synthetic energy efficiency testcase.
 
+StarPU 1.3.8
+====================================================================
+
+Small features:
+  * A codelet can now define a callback function pointer which will be
+    automatically called when the task does not define itself a
+    callback function, in that case, it can still be called from the
+    task callback function.
+
 StarPU 1.3.7
 ====================================================================
 

+ 15 - 1
include/starpu_task.h

@@ -546,6 +546,20 @@ struct starpu_codelet
 	unsigned color;
 
 	/**
+	   Optional field, the default value is <c>NULL</c>. This is a
+	   function pointer of prototype <c>void (*f)(void *)</c>
+	   which specifies a possible callback. If this pointer is
+	   non-<c>NULL</c>, the callback function is executed on the
+	   host after the execution of the task. If the task defines a
+	   callback, the codelet callback is not called, unless called
+	   within the task callback function.
+	   The callback is passed the value contained in the
+	   starpu_task::callback_arg field. No callback is executed if
+	   the field is set to <c>NULL</c>.
+	*/
+	void (*callback_func)(void *);
+
+	/**
 	   Various flags for the codelet.
 	 */
 	int flags;
@@ -763,7 +777,7 @@ struct starpu_task
 	   <c>NULL</c>.
 
 	   With starpu_task_insert() and alike this can be specified thanks to
-	   ::STARPU_CALLBACK_ARG followed by the function pointer, or thanks to
+	   ::STARPU_CALLBACK_ARG followed by the argument pointer, or thanks to
 	   ::STARPU_CALLBACK_WITH_ARG or
 	   ::STARPU_CALLBACK_WITH_ARG_NFREE followed by the function
 	   pointer and the argument.

+ 5 - 3
src/core/jobs.c

@@ -425,7 +425,7 @@ void _starpu_handle_job_termination(struct _starpu_job *j)
 	{
 		/* the callback is executed after the dependencies so that we may remove the tag
 		 * of the task itself */
-		if (task->callback_func)
+		if (task->callback_func || (task->cl && task->cl->callback_func))
 		{
 			int profiling = starpu_profiling_status_get();
 			if (profiling && task->profiling_info)
@@ -435,7 +435,6 @@ void _starpu_handle_job_termination(struct _starpu_job *j)
 			 * within the callback */
 			_starpu_set_local_worker_status(STATUS_CALLBACK);
 
-
 			/* Perhaps we have nested callbacks (eg. with chains of empty
 			 * tasks). So we store the current task and we will restore it
 			 * later. */
@@ -444,7 +443,10 @@ void _starpu_handle_job_termination(struct _starpu_job *j)
 			_starpu_set_current_task(task);
 
 			_STARPU_TRACE_START_CALLBACK(j);
-			task->callback_func(task->callback_arg);
+			if (task->callback_func)
+				task->callback_func(task->callback_arg);
+			else
+				task->cl->callback_func(task->callback_arg);
 			_STARPU_TRACE_END_CALLBACK(j);
 
 			_starpu_set_current_task(current_task);

+ 1 - 0
tests/Makefile.am

@@ -148,6 +148,7 @@ XFAIL_TESTS	=				\
 myPROGRAMS =
 
 myPROGRAMS +=					\
+	main/callback				\
 	main/bind				\
 	main/mkdtemp				\
 	main/execute_schedule			\

+ 98 - 0
tests/main/callback.c

@@ -0,0 +1,98 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2020       Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
+ *
+ * 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>
+#include "../helper.h"
+
+void codelet_callback_func(void *arg)
+{
+	if (arg)
+	{
+		int *x = (int *)arg;
+		FPRINTF(stderr, "calling callback codelet arg %d\n", *x);
+	}
+	else
+		FPRINTF(stderr, "calling callback codelet arg %p\n", arg);
+}
+
+void task_callback_func(void *arg)
+{
+	FPRINTF(stderr, "\ncalling callback task arg %p\n", arg);
+	if (starpu_task_get_current()->cl->callback_func)
+		starpu_task_get_current()->cl->callback_func(arg);
+}
+
+struct starpu_codelet mycodelet =
+{
+	.where = STARPU_NOWHERE,
+	.callback_func = codelet_callback_func
+};
+
+struct starpu_codelet mycodelet2 =
+{
+	.where = STARPU_NOWHERE,
+};
+
+int main(void)
+{
+        int ret;
+	int value=12;
+	int value2=24;
+
+	ret = starpu_init(NULL);
+	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+
+	ret = starpu_task_insert(&mycodelet,
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	ret = starpu_task_insert(&mycodelet,
+				 STARPU_CALLBACK_ARG_NFREE, &value,
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	ret = starpu_task_insert(&mycodelet,
+				 STARPU_CALLBACK, &task_callback_func,
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	ret = starpu_task_insert(&mycodelet,
+				 STARPU_CALLBACK, &task_callback_func,
+				 STARPU_CALLBACK_ARG_NFREE, &value2,
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	ret = starpu_task_insert(&mycodelet2,
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	ret = starpu_task_insert(&mycodelet2,
+				 STARPU_CALLBACK, &task_callback_func,
+				 STARPU_CALLBACK_ARG_NFREE, &value,
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	starpu_shutdown();
+	return 0;
+
+enodev:
+	starpu_shutdown();
+	fprintf(stderr, "WARNING: No one can execute this task\n");
+	/* yes, we do not perform the computation but we did detect that no one
+ 	 * could perform the kernel, so this is not an error from StarPU */
+	return STARPU_TEST_SKIPPED;
+}