瀏覽代碼

- add support for omp taskwait
- add testcase for omp taskwait

Olivier Aumage 11 年之前
父節點
當前提交
69335c0c20
共有 4 個文件被更改,包括 134 次插入0 次删除
  1. 1 0
      include/starpu_openmp.h
  2. 23 0
      src/util/openmp_runtime_support.c
  3. 5 0
      tests/Makefile.am
  4. 105 0
      tests/openmp/taskwait_01.c

+ 1 - 0
include/starpu_openmp.h

@@ -59,6 +59,7 @@ extern void starpu_omp_barrier(void) __STARPU_OMP_NOTHROW;
 extern void starpu_omp_master(void (*f)(void *arg), void *arg, int nowait) __STARPU_OMP_NOTHROW;
 extern void starpu_omp_single(void (*f)(void *arg), void *arg, int nowait) __STARPU_OMP_NOTHROW;
 extern void starpu_omp_critical(void (*f)(void *arg), void *arg, const char *name) __STARPU_OMP_NOTHROW;
+extern void starpu_omp_taskwait(void) __STARPU_OMP_NOTHROW;
 
 extern void starpu_omp_set_num_threads(int threads) __STARPU_OMP_NOTHROW;
 extern int starpu_omp_get_num_threads() __STARPU_OMP_NOTHROW;

+ 23 - 0
src/util/openmp_runtime_support.c

@@ -1039,6 +1039,29 @@ void starpu_omp_task_region(const struct starpu_codelet * const _task_region_cl,
 	}
 }
 
+static void task_childs__sleep_callback(void *_task)
+{
+	struct starpu_omp_task *task = _task;
+	_starpu_spin_unlock(&task->lock);
+}
+
+void starpu_omp_taskwait(void)
+{
+	struct starpu_omp_task *task = STARPU_PTHREAD_GETSPECIFIC(omp_task_key);
+	_starpu_spin_lock(&task->lock);
+	if (task->child_task_count > 0)
+	{
+		task->wait_on |= starpu_omp_task_wait_on_task_childs;
+		_starpu_task_prepare_for_continuation_ext(0, task_childs__sleep_callback, task);
+		starpu_omp_task_preempt();
+		STARPU_ASSERT(task->child_task_count == 0);
+	}
+	else
+	{
+		_starpu_spin_unlock(&task->lock);
+	}
+}
+
 /*
  * restore deprecated diagnostics (-Wdeprecated-declarations)
  */

+ 5 - 0
tests/Makefile.am

@@ -232,6 +232,8 @@ noinst_PROGRAMS =				\
 	openmp/parallel_critical_01		\
 	openmp/parallel_critical_named_01	\
 	openmp/task_01				\
+	openmp/task_01				\
+	openmp/taskwait_01			\
 	overlap/overlap				\
 	overlap/gpu_concurrency			\
 	parallel_tasks/explicit_combined_worker	\
@@ -481,6 +483,9 @@ openmp_parallel_critical_named_01_SOURCES = 	\
 openmp_task_01_SOURCES = 	\
 	openmp/task_01.c
 
+openmp_taskwait_01_SOURCES = 	\
+	openmp/taskwait_01.c
+
 ###################
 # Block interface #
 ###################

+ 105 - 0
tests/openmp/taskwait_01.c

@@ -0,0 +1,105 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2014  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 <pthread.h>
+#include <starpu.h>
+#include "../helper.h"
+#include <stdio.h>
+
+#if !defined(STARPU_OPENMP)
+int main(int argc, char **argv)
+{
+	return STARPU_TEST_SKIPPED;
+}
+#else
+__attribute__((constructor))
+static void omp_constructor(void)
+{
+	int ret = starpu_omp_init();
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_omp_init");
+}
+
+__attribute__((destructor))
+static void omp_destructor(void)
+{
+	starpu_omp_shutdown();
+}
+
+void task_region_g(void *buffers[], void *args)
+{
+	(void) buffers;
+	int i = (int)(intptr_t) args;
+	int worker_id;
+	pthread_t tid;
+	tid = pthread_self();
+	worker_id = starpu_worker_get_id();
+	printf("[tid %p] task thread = %d: explicit task \"g[%d]\"\n", (void *)tid, worker_id, i);
+}
+
+static struct starpu_codelet task_region_cl =
+{
+	.cpu_funcs    = { task_region_g, NULL },
+	.where        = STARPU_CPU,
+	.nbuffers     = 0,
+	.model        = NULL
+};
+
+void parallel_region_f(void *buffers[], void *args)
+{
+	(void) buffers;
+	(void) args;
+	int worker_id;
+	pthread_t tid;
+	int i = 0;
+
+	tid = pthread_self();
+	worker_id = starpu_worker_get_id();
+	printf("[tid %p] task thread = %d: implicit task \"f\"\n", (void *)tid, worker_id);
+	
+	/*
+	 * if_clause: 1
+	 * final_clause: 0
+	 * untied_clause: 1
+	 * mergeable_clause: 0
+	 */
+	starpu_omp_task_region(&task_region_cl, (void *)(intptr_t)i++, 1, 0, 1, 0);
+	starpu_omp_task_region(&task_region_cl, (void *)(intptr_t)i++, 1, 0, 1, 0);
+	starpu_omp_taskwait();
+	printf("[tid %p] task thread = %d: implicit task \"f\": taskwait\n", (void *)tid, worker_id);
+
+	starpu_omp_task_region(&task_region_cl, (void *)(intptr_t)i++, 1, 0, 1, 0);
+	starpu_omp_task_region(&task_region_cl, (void *)(intptr_t)i++, 1, 0, 1, 0);
+	starpu_omp_taskwait();
+	printf("[tid %p] task thread = %d: implicit task \"f\": taskwait\n", (void *)tid, worker_id);
+
+	starpu_omp_task_region(&task_region_cl, (void *)(intptr_t)i++, 1, 0, 1, 0);
+	starpu_omp_task_region(&task_region_cl, (void *)(intptr_t)i++, 1, 0, 1, 0);
+}
+
+static struct starpu_codelet parallel_region_cl =
+{
+	.cpu_funcs    = { parallel_region_f, NULL },
+	.where        = STARPU_CPU,
+	.nbuffers     = 0,
+	.model        = NULL
+};
+
+int
+main (int argc, char *argv[]) {
+	starpu_omp_parallel_region(&parallel_region_cl, NULL);
+	return 0;
+}
+#endif