Browse Source

Add possibility to define the sequential consistency at the task level for each handle used by the task.

Nathalie Furmento 7 years ago
parent
commit
0e688f6842

+ 2 - 0
ChangeLog

@@ -50,6 +50,8 @@ New features:
     functions starpu_task_end_dep_add() which specifies the number of
     functions starpu_task_end_dep_add() which specifies the number of
     calls to the function starpu_task_end_dep_release() needed to
     calls to the function starpu_task_end_dep_release() needed to
     trigger the task termination.
     trigger the task termination.
+  * Add possibility to define the sequential consistency at the task level
+    for each handle used by the task.
 
 
 Small features:
 Small features:
   * Scheduling contexts may now be associated a user data pointer at creation
   * Scheduling contexts may now be associated a user data pointer at creation

+ 35 - 0
doc/doxygen/chapters/301_tasks.doxy

@@ -57,6 +57,8 @@ priority information to StarPU.
 
 
 \section TaskDependencies Task Dependencies
 \section TaskDependencies Task Dependencies
 
 
+\subsection SequentialConsistency Sequential Consistency
+
 By default, task dependencies are inferred from data dependency (sequential
 By default, task dependencies are inferred from data dependency (sequential
 coherency) by StarPU. The application can however disable sequential coherency
 coherency) by StarPU. The application can however disable sequential coherency
 for some data, and dependencies can be specifically expressed.
 for some data, and dependencies can be specifically expressed.
@@ -69,6 +71,39 @@ for all datas.
 Setting (or unsetting) sequential consistency can also be done at task
 Setting (or unsetting) sequential consistency can also be done at task
 level by setting the field starpu_task::sequential_consistency to 0.
 level by setting the field starpu_task::sequential_consistency to 0.
 
 
+Sequential consistency can also be set (or unset) for each handle of a
+specific task, this is done by using the field
+starpu_task::handles_sequential_consistency. When set, its value
+should be a array with the number of elements being the number of
+handles for the task, each element of the array being the sequential
+consistency for the i-th handle of the task. The field can easily be
+set when calling starpu_task_insert() with the flag
+::STARPU_HANDLES_SEQUENTIAL_CONSISTENCY
+
+\code{.c}
+char *seq_consistency = malloc(cl.nbuffers * sizeof(char));
+seq_consistency[0] = 1;
+seq_consistency[1] = 1;
+seq_consistency[2] = 0;
+ret = starpu_task_insert(&cl,
+	STARPU_RW, handleA, STARPU_RW, handleB, STARPU_RW, handleC,
+	STARPU_HANDLES_SEQUENTIAL_CONSISTENCY, seq_consistency,
+	0);
+free(seq_consistency);
+\endcode
+
+The internal algorithm used by StarPU to set up implicit dependency is
+as follows:
+\code{.c}
+if (sequential_consistency(task) == 1)
+    for(i=0 ; i<STARPU_TASK_GET_NBUFFERS(task) ; i++)
+      if (sequential_consistency(i-th data, task) == 1)
+        if (sequential_consistency(i-th data) == 1)
+           create_implicit_dependency(...)
+\endcode
+
+\subsection TasksAndTagsDependencies Tasks And Tags Dependencies
+
 One can explicitely set dependencies between tasks using
 One can explicitely set dependencies between tasks using
 starpu_task_declare_deps_array(). Dependencies between tasks can be
 starpu_task_declare_deps_array(). Dependencies between tasks can be
 expressed through tags associated to a tag with the field
 expressed through tags associated to a tag with the field

+ 4 - 0
doc/doxygen/chapters/api/codelet_and_tasks.doxy

@@ -520,6 +520,10 @@ the configuration of a task allocated with starpu_task_create().
     codelet, one should either define this field or the field
     codelet, one should either define this field or the field
     starpu_task::modes defined above.
     starpu_task::modes defined above.
 
 
+\var char *starpu_task::handles_sequential_consistency
+    Optional pointer to an array of characters which allows to define
+    the sequential consistency for each handle for the current task.
+
 \var void *starpu_task::cl_arg
 \var void *starpu_task::cl_arg
     Optional pointer which is passed to the codelet through the second
     Optional pointer which is passed to the codelet through the second
     argument of the codelet implementation (e.g.
     argument of the codelet implementation (e.g.

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

@@ -42,7 +42,7 @@ starpu_task::execute_on_a_specific_worker)
 <li> the specific values ::STARPU_VALUE, ::STARPU_CALLBACK,
 <li> the specific values ::STARPU_VALUE, ::STARPU_CALLBACK,
 ::STARPU_CALLBACK_ARG, ::STARPU_CALLBACK_WITH_ARG, ::STARPU_PRIORITY,
 ::STARPU_CALLBACK_ARG, ::STARPU_CALLBACK_WITH_ARG, ::STARPU_PRIORITY,
 ::STARPU_TAG, ::STARPU_TAG_ONLY, ::STARPU_FLOPS, ::STARPU_SCHED_CTX, ::STARPU_CL_ARGS, ::STARPU_CL_ARGS_NFREE,
 ::STARPU_TAG, ::STARPU_TAG_ONLY, ::STARPU_FLOPS, ::STARPU_SCHED_CTX, ::STARPU_CL_ARGS, ::STARPU_CL_ARGS_NFREE,
-::STARPU_TASK_DEPS_ARRAY, ::STARPU_TASK_COLOR
+::STARPU_TASK_DEPS_ARRAY, ::STARPU_TASK_COLOR, ::STARPU_HANDLES_SEQUENTIAL_CONSISTENCY
 followed by the appropriated objects as defined elsewhere.
 followed by the appropriated objects as defined elsewhere.
 </ul>
 </ul>
 
 
@@ -161,6 +161,12 @@ given values.
 Used when calling starpu_task_insert(), must be followed by an integer
 Used when calling starpu_task_insert(), must be followed by an integer
 representing a color
 representing a color
 
 
+\def STARPU_HANDLES_SEQUENTIAL_CONSISTENCY
+\ingroup API_Insert_Task
+Used when calling starpu_task_insert(), must be followed by an array
+of characters representing the sequential consistency for each buffer
+of the task.
+
 \fn void starpu_task_insert_data_make_room(struct starpu_codelet *cl, struct starpu_task *task, int *allocated_buffers, int current_buffer, int room)
 \fn void starpu_task_insert_data_make_room(struct starpu_codelet *cl, struct starpu_task *task, int *allocated_buffers, int current_buffer, int room)
 \ingroup API_Insert_Task
 \ingroup API_Insert_Task
 Assuming that there are already \p current_buffer data handles passed to
 Assuming that there are already \p current_buffer data handles passed to

+ 2 - 1
examples/Makefile.am

@@ -250,7 +250,8 @@ STARPU_EXAMPLES +=				\
 	worker_collections/worker_tree_example  \
 	worker_collections/worker_tree_example  \
 	reductions/dot_product			\
 	reductions/dot_product			\
 	reductions/minmax_reduction		\
 	reductions/minmax_reduction		\
-	dependency/task_end_dep
+	dependency/task_end_dep			\
+	dependency/sequential_consistency
 
 
 endif
 endif
 
 

+ 168 - 0
examples/dependency/sequential_consistency.c

@@ -0,0 +1,168 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2018                                     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
+ * 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 FPRINTF(ofile, fmt, ...) do { if (!getenv("STARPU_SSILENT")) {fprintf(ofile, fmt, ## __VA_ARGS__); }} while(0)
+
+void cpu_codeletA(void *descr[], void *args);
+void cpu_codeletB(void *descr[], void *args);
+void cpu_codeletC(void *descr[], void *args);
+
+struct starpu_codelet clA =
+{
+	.cpu_funcs = {cpu_codeletA},
+	.cpu_funcs_name = {"cpu_codeletA"},
+	.nbuffers = 1,
+	.modes = {STARPU_RW},
+	.name = "codeletA"
+};
+
+struct starpu_codelet clB =
+{
+	.cpu_funcs = {cpu_codeletB},
+	.cpu_funcs_name = {"cpu_codeletB"},
+	.nbuffers = 1,
+	.modes = {STARPU_RW},
+	.name = "codeletB"
+};
+
+struct starpu_codelet clC =
+{
+	.cpu_funcs = {cpu_codeletC},
+	.cpu_funcs_name = {"cpu_codeletC"},
+	.nbuffers = 1,
+	.modes = {STARPU_RW},
+	.name = "codeletC"
+};
+
+void cpu_codeletA(void *descr[], void *args)
+{
+	int *val = (int *)STARPU_VARIABLE_GET_PTR(descr[0]);
+	starpu_data_handle_t value_handle;
+	starpu_tag_t tagHoldC;
+	int ret;
+	char handle_sequential_consistency = 0;
+
+	FPRINTF(stderr, "[Task A] Value = %d\n", *val);
+
+	starpu_codelet_unpack_args(args, &value_handle, &tagHoldC);
+
+	// With several data, one would need to use a dynamically
+	// allocated array for the sequential consistency,
+	// the array could be freed immediately after calling
+	// starpu_task_insert()
+
+	ret = starpu_task_insert(&clB,
+				 STARPU_RW, value_handle,
+				 STARPU_CALLBACK_WITH_ARG, starpu_tag_notify_from_apps, tagHoldC,
+				 STARPU_HANDLES_SEQUENTIAL_CONSISTENCY, &handle_sequential_consistency,
+				 STARPU_NAME, "taskB",
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	*val *= 2;
+}
+
+void cpu_codeletB(void *descr[], void *args)
+{
+	(void)args;
+	int *val = (int *)STARPU_VARIABLE_GET_PTR(descr[0]);
+
+	FPRINTF(stderr, "[Task B] Value = %d\n", *val);
+	STARPU_ASSERT_MSG(*val == 24, "Incorrect value %d (expected 24)\n", *val);
+	*val += 1;
+}
+
+void cpu_codeletC(void *descr[], void *args)
+{
+	(void)args;
+	int *val = (int *)STARPU_VARIABLE_GET_PTR(descr[0]);
+
+	FPRINTF(stderr, "[Task C] Value = %d\n", *val);
+	STARPU_ASSERT_MSG(*val == 25, "Incorrect value %d (expected 25)\n", *val);
+	*val *= 2;
+}
+
+/*
+ * Submit taskA and hold it
+ * Submit taskC and hold it
+ * Release taskA
+ * Execute taskA       --> submit taskB
+ * Execute taskB       --> callback: release taskC
+ *
+ * All three tasks use the same data in RW, taskB is submitted after
+ * taskC, so taskB should normally only execute after taskC but as the
+ * sequential consistency for (taskB, data) is unset, taskB can
+ * execute straightaway
+ */
+int main(void)
+{
+        int value=12;
+	int ret;
+	starpu_data_handle_t value_handle;
+	starpu_tag_t tagHoldA = 42;
+	starpu_tag_t tagHoldC = 84;
+	starpu_tag_t tagA = 421;
+	starpu_tag_t tagC = 842;
+
+        ret = starpu_init(NULL);
+	if (STARPU_UNLIKELY(ret == -ENODEV))
+	{
+		return 77;
+	}
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+
+	if (starpu_cpu_worker_get_count() < 1)
+	{
+		FPRINTF(stderr, "This application requires at least 1 cpu worker\n");
+		starpu_shutdown();
+		return 77;
+	}
+
+	starpu_variable_data_register(&value_handle, STARPU_MAIN_RAM, (uintptr_t)&value, sizeof(value));
+
+	starpu_tag_declare_deps_array(tagA, 1, &tagHoldA);
+	starpu_tag_declare_deps_array(tagC, 1, &tagHoldC);
+
+	ret = starpu_task_insert(&clA,
+				 STARPU_TAG, tagA,
+				 STARPU_RW, value_handle,
+				 STARPU_VALUE, &value_handle, sizeof(starpu_data_handle_t),
+				 STARPU_VALUE, &tagHoldC, sizeof(starpu_tag_t),
+				 STARPU_NAME, "taskA",
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+	ret = starpu_task_insert(&clC,
+				 STARPU_TAG, tagC,
+				 STARPU_RW, value_handle,
+				 STARPU_NAME, "taskC",
+				 0);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	// Release taskA (we want to make sure it will execute after taskC has been submitted)
+	starpu_tag_notify_from_apps(tagHoldA);
+
+	starpu_data_unregister(value_handle);
+
+	STARPU_ASSERT_MSG(value == 50, "Incorrect value %d (expected 50)\n", value);
+
+	starpu_shutdown();
+
+	FPRINTF(stderr, "Value = %d\n", value);
+
+	return ret;
+}

+ 1 - 0
include/fstarpu_mod.f90

@@ -56,6 +56,7 @@ module fstarpu_mod
         type(c_ptr), bind(C) :: FSTARPU_TAG_ONLY
         type(c_ptr), bind(C) :: FSTARPU_TAG_ONLY
         type(c_ptr), bind(C) :: FSTARPU_NAME
         type(c_ptr), bind(C) :: FSTARPU_NAME
         type(c_ptr), bind(C) :: FSTARPU_TASK_COLOR
         type(c_ptr), bind(C) :: FSTARPU_TASK_COLOR
+        type(c_ptr), bind(C) :: FSTARPU_HANDLES_SEQUENTIAL_CONSISTENCY
         type(c_ptr), bind(C) :: FSTARPU_NODE_SELECTION_POLICY
         type(c_ptr), bind(C) :: FSTARPU_NODE_SELECTION_POLICY
 
 
         type(c_ptr), bind(C) :: FSTARPU_VALUE
         type(c_ptr), bind(C) :: FSTARPU_VALUE

+ 2 - 0
include/starpu_task.h

@@ -153,6 +153,8 @@ struct starpu_task
 	void *interfaces[STARPU_NMAXBUFS];
 	void *interfaces[STARPU_NMAXBUFS];
 	enum starpu_data_access_mode modes[STARPU_NMAXBUFS];
 	enum starpu_data_access_mode modes[STARPU_NMAXBUFS];
 
 
+	char *handles_sequential_consistency;
+
 	void *cl_arg;
 	void *cl_arg;
 	size_t cl_arg_size;
 	size_t cl_arg_size;
 
 

+ 2 - 1
include/starpu_task_util.h

@@ -64,7 +64,8 @@ void starpu_create_sync_task(starpu_tag_t sync_tag, unsigned ndeps, starpu_tag_t
 #define STARPU_CL_ARGS_NFREE	(26<<STARPU_MODE_SHIFT)
 #define STARPU_CL_ARGS_NFREE	(26<<STARPU_MODE_SHIFT)
 #define STARPU_TASK_DEPS_ARRAY	(27<<STARPU_MODE_SHIFT)
 #define STARPU_TASK_DEPS_ARRAY	(27<<STARPU_MODE_SHIFT)
 #define STARPU_TASK_COLOR       (28<<STARPU_MODE_SHIFT)
 #define STARPU_TASK_COLOR       (28<<STARPU_MODE_SHIFT)
-#define STARPU_SHIFTED_MODE_MAX (29<<STARPU_MODE_SHIFT)
+#define STARPU_HANDLES_SEQUENTIAL_CONSISTENCY (29<<STARPU_MODE_SHIFT)
+#define STARPU_SHIFTED_MODE_MAX (30<<STARPU_MODE_SHIFT)
 
 
 int starpu_task_set(struct starpu_task *task, struct starpu_codelet *cl, ...);
 int starpu_task_set(struct starpu_task *task, struct starpu_codelet *cl, ...);
 struct starpu_task *starpu_task_build(struct starpu_codelet *cl, ...);
 struct starpu_task *starpu_task_build(struct starpu_codelet *cl, ...);

+ 4 - 0
mpi/src/starpu_mpi_task_insert.c

@@ -452,6 +452,10 @@ int _starpu_mpi_task_decode_v(struct starpu_codelet *codelet, int me, int nb_nod
                 {
                 {
                         (void)va_arg(varg_list_copy, int);
                         (void)va_arg(varg_list_copy, int);
                 }
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        (void)va_arg(varg_list_copy, char *);
+                }
 		else
 		else
 		{
 		{
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);

+ 5 - 0
mpi/src/starpu_mpi_task_insert_fortran.c

@@ -298,6 +298,11 @@ int _fstarpu_mpi_task_decode_v(struct starpu_codelet *codelet, int me, int nb_no
 			arg_i++;
 			arg_i++;
 			/* int* */
 			/* int* */
 		}
 		}
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+		{
+			arg_i++;
+			/* char* */
+		}
 		else
 		else
 		{
 		{
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);

+ 6 - 1
src/core/dependencies/data_concurrency.c

@@ -2,7 +2,7 @@
  *
  *
  * Copyright (C) 2013,2015,2017                           Inria
  * Copyright (C) 2013,2015,2017                           Inria
  * Copyright (C) 2009-2015,2017-2018                      Université de Bordeaux
  * Copyright (C) 2009-2015,2017-2018                      Université de Bordeaux
- * Copyright (C) 2010-2013,2015,2017                      CNRS
+ * Copyright (C) 2010-2013,2015,2017,2018                 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
@@ -348,12 +348,17 @@ void _starpu_job_set_ordered_buffers(struct _starpu_job *j)
 	{
 	{
 		starpu_data_handle_t handle = STARPU_TASK_GET_HANDLE(task, i);
 		starpu_data_handle_t handle = STARPU_TASK_GET_HANDLE(task, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_HANDLE(j, handle, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_HANDLE(j, handle, i);
+
 		enum starpu_data_access_mode mode = STARPU_TASK_GET_MODE(task, i);
 		enum starpu_data_access_mode mode = STARPU_TASK_GET_MODE(task, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_MODE(j, mode, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_MODE(j, mode, i);
+
 		int node = -1;
 		int node = -1;
 		if (task->cl->specific_nodes)
 		if (task->cl->specific_nodes)
 			node = STARPU_CODELET_GET_NODE(task->cl, i);
 			node = STARPU_CODELET_GET_NODE(task->cl, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_NODE(j, node, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_NODE(j, node, i);
+
+		unsigned sequential_consistency = task->handles_sequential_consistency ? task->handles_sequential_consistency[i] : handle->sequential_consistency;
+		_STARPU_JOB_SET_ORDERED_BUFFER_SEQUENTIAL_CONSISTENCY(j, sequential_consistency, i);
 	}
 	}
 	_starpu_sort_task_handles(_STARPU_JOB_GET_ORDERED_BUFFERS(j), nbuffers);
 	_starpu_sort_task_handles(_STARPU_JOB_GET_ORDERED_BUFFERS(j), nbuffers);
 }
 }

+ 6 - 5
src/core/dependencies/implicit_data_deps.c

@@ -203,7 +203,7 @@ static void _starpu_add_sync_task(starpu_data_handle_t handle, struct starpu_tas
 /* NB : handle->sequential_consistency_mutex must be hold by the caller;
 /* NB : handle->sequential_consistency_mutex must be hold by the caller;
  * returns a task, to be submitted after releasing that mutex. */
  * returns a task, to be submitted after releasing that mutex. */
 struct starpu_task *_starpu_detect_implicit_data_deps_with_handle(struct starpu_task *pre_sync_task, struct starpu_task *post_sync_task, struct _starpu_task_wrapper_dlist *post_sync_task_dependency_slot,
 struct starpu_task *_starpu_detect_implicit_data_deps_with_handle(struct starpu_task *pre_sync_task, struct starpu_task *post_sync_task, struct _starpu_task_wrapper_dlist *post_sync_task_dependency_slot,
-						   starpu_data_handle_t handle, enum starpu_data_access_mode mode)
+								  starpu_data_handle_t handle, enum starpu_data_access_mode mode, unsigned task_handle_sequential_consistency)
 {
 {
 	struct starpu_task *task = NULL;
 	struct starpu_task *task = NULL;
 
 
@@ -214,7 +214,7 @@ struct starpu_task *_starpu_detect_implicit_data_deps_with_handle(struct starpu_
 	STARPU_ASSERT(!(mode & STARPU_SCRATCH));
 	STARPU_ASSERT(!(mode & STARPU_SCRATCH));
         _STARPU_LOG_IN();
         _STARPU_LOG_IN();
 
 
-	if (handle->sequential_consistency)
+	if (handle->sequential_consistency && task_handle_sequential_consistency)
 	{
 	{
 		struct _starpu_job *pre_sync_job = _starpu_get_job_associated_to_task(pre_sync_task);
 		struct _starpu_job *pre_sync_job = _starpu_get_job_associated_to_task(pre_sync_task);
 		struct _starpu_job *post_sync_job = _starpu_get_job_associated_to_task(post_sync_task);
 		struct _starpu_job *post_sync_job = _starpu_get_job_associated_to_task(post_sync_task);
@@ -414,9 +414,10 @@ void _starpu_detect_implicit_data_deps(struct starpu_task *task)
 		}
 		}
 
 
 		STARPU_PTHREAD_MUTEX_LOCK(&handle->sequential_consistency_mutex);
 		STARPU_PTHREAD_MUTEX_LOCK(&handle->sequential_consistency_mutex);
-		if (!handle->sequential_consistency)
+		unsigned task_handle_sequential_consistency = _STARPU_JOB_GET_ORDERED_BUFFER_SEQUENTIAL_CONSISTENCY(j, buffer);
+		if (!handle->sequential_consistency || !task_handle_sequential_consistency)
 			j->sequential_consistency = 0;
 			j->sequential_consistency = 0;
-		new_task = _starpu_detect_implicit_data_deps_with_handle(task, task, &dep_slots[buffer], handle, mode);
+		new_task = _starpu_detect_implicit_data_deps_with_handle(task, task, &dep_slots[buffer], handle, mode, task_handle_sequential_consistency);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 		if (new_task)
 		if (new_task)
 		{
 		{
@@ -629,7 +630,7 @@ int _starpu_data_wait_until_available(starpu_data_handle_t handle, enum starpu_d
 
 
 		/* It is not really a RW access, but we want to make sure that
 		/* It is not really a RW access, but we want to make sure that
 		 * all previous accesses are done */
 		 * all previous accesses are done */
-		new_task = _starpu_detect_implicit_data_deps_with_handle(sync_task, sync_task, &_starpu_get_job_associated_to_task(sync_task)->implicit_dep_slot, handle, mode);
+		new_task = _starpu_detect_implicit_data_deps_with_handle(sync_task, sync_task, &_starpu_get_job_associated_to_task(sync_task)->implicit_dep_slot, handle, mode, sequential_consistency);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 
 
 		if (new_task)
 		if (new_task)

+ 2 - 2
src/core/dependencies/implicit_data_deps.h

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
  * Copyright (C) 2010-2012,2014-2015,2017-2018            Université de Bordeaux
  * Copyright (C) 2010-2012,2014-2015,2017-2018            Université de Bordeaux
- * Copyright (C) 2010-2011,2013,2015,2017                 CNRS
+ * Copyright (C) 2010-2011,2013,2015,2017,2018            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
@@ -22,7 +22,7 @@
 #include <common/config.h>
 #include <common/config.h>
 
 
 struct starpu_task *_starpu_detect_implicit_data_deps_with_handle(struct starpu_task *pre_sync_task, struct starpu_task *post_sync_task, struct _starpu_task_wrapper_dlist *post_sync_task_dependency_slot,
 struct starpu_task *_starpu_detect_implicit_data_deps_with_handle(struct starpu_task *pre_sync_task, struct starpu_task *post_sync_task, struct _starpu_task_wrapper_dlist *post_sync_task_dependency_slot,
-						   starpu_data_handle_t handle, enum starpu_data_access_mode mode);
+								  starpu_data_handle_t handle, enum starpu_data_access_mode mode, unsigned task_handle_sequential_consistency);
 int _starpu_test_implicit_data_deps_with_handle(starpu_data_handle_t handle, enum starpu_data_access_mode mode);
 int _starpu_test_implicit_data_deps_with_handle(starpu_data_handle_t handle, enum starpu_data_access_mode mode);
 void _starpu_detect_implicit_data_deps(struct starpu_task *task);
 void _starpu_detect_implicit_data_deps(struct starpu_task *task);
 void _starpu_release_data_enforce_sequential_consistency(struct starpu_task *task, struct _starpu_task_wrapper_dlist *task_dependency_slot, starpu_data_handle_t handle);
 void _starpu_release_data_enforce_sequential_consistency(struct starpu_task *task, struct _starpu_task_wrapper_dlist *task_dependency_slot, starpu_data_handle_t handle);

+ 3 - 0
src/core/jobs.h

@@ -62,6 +62,7 @@ struct _starpu_data_descr
 	starpu_data_handle_t handle;
 	starpu_data_handle_t handle;
 	enum starpu_data_access_mode mode;
 	enum starpu_data_access_mode mode;
 	int node;
 	int node;
+	unsigned sequential_consistency;
 };
 };
 
 
 #ifdef STARPU_DEBUG
 #ifdef STARPU_DEBUG
@@ -269,10 +270,12 @@ int _starpu_push_local_task(struct _starpu_worker *worker, struct starpu_task *t
 #define _STARPU_JOB_GET_ORDERED_BUFFER_HANDLE(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].handle : job->ordered_buffers[i].handle)
 #define _STARPU_JOB_GET_ORDERED_BUFFER_HANDLE(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].handle : job->ordered_buffers[i].handle)
 #define _STARPU_JOB_GET_ORDERED_BUFFER_MODE(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].mode : job->ordered_buffers[i].mode)
 #define _STARPU_JOB_GET_ORDERED_BUFFER_MODE(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].mode : job->ordered_buffers[i].mode)
 #define _STARPU_JOB_GET_ORDERED_BUFFER_NODE(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].node : job->ordered_buffers[i].node)
 #define _STARPU_JOB_GET_ORDERED_BUFFER_NODE(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].node : job->ordered_buffers[i].node)
+#define _STARPU_JOB_GET_ORDERED_BUFFER_SEQUENTIAL_CONSISTENCY(job, i) ((job->dyn_ordered_buffers) ? job->dyn_ordered_buffers[i].sequential_consistency : job->ordered_buffers[i].sequential_consistency)
 
 
 #define _STARPU_JOB_SET_ORDERED_BUFFER_HANDLE(job, handle, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].handle = (handle); else job->ordered_buffers[i].handle = (handle);} while(0)
 #define _STARPU_JOB_SET_ORDERED_BUFFER_HANDLE(job, handle, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].handle = (handle); else job->ordered_buffers[i].handle = (handle);} while(0)
 #define _STARPU_JOB_SET_ORDERED_BUFFER_MODE(job, __mode, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].mode = __mode; else job->ordered_buffers[i].mode = __mode;} while(0)
 #define _STARPU_JOB_SET_ORDERED_BUFFER_MODE(job, __mode, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].mode = __mode; else job->ordered_buffers[i].mode = __mode;} while(0)
 #define _STARPU_JOB_SET_ORDERED_BUFFER_NODE(job, __node, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].node = __node; else job->ordered_buffers[i].node = __node;} while(0)
 #define _STARPU_JOB_SET_ORDERED_BUFFER_NODE(job, __node, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].node = __node; else job->ordered_buffers[i].node = __node;} while(0)
+#define _STARPU_JOB_SET_ORDERED_BUFFER_SEQUENTIAL_CONSISTENCY(job, sequential_consistency, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i].sequential_consistency = (sequential_consistency); else job->ordered_buffers[i].sequential_consistency = (sequential_consistency);} while(0)
 
 
 #define _STARPU_JOB_SET_ORDERED_BUFFER(job, buffer, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i] = buffer; else job->ordered_buffers[i] = buffer;} while(0)
 #define _STARPU_JOB_SET_ORDERED_BUFFER(job, buffer, i) do { if (job->dyn_ordered_buffers) job->dyn_ordered_buffers[i] = buffer; else job->ordered_buffers[i] = buffer;} while(0)
 #define _STARPU_JOB_GET_ORDERED_BUFFERS(job) (job->dyn_ordered_buffers) ? job->dyn_ordered_buffers : job->ordered_buffers
 #define _STARPU_JOB_GET_ORDERED_BUFFERS(job) (job->dyn_ordered_buffers) ? job->dyn_ordered_buffers : job->ordered_buffers

+ 3 - 3
src/datawizard/user_interactions.c

@@ -2,7 +2,7 @@
  *
  *
  * Copyright (C) 2011-2013,2017                           Inria
  * Copyright (C) 2011-2013,2017                           Inria
  * Copyright (C) 2009-2018                                Université de Bordeaux
  * Copyright (C) 2009-2018                                Université de Bordeaux
- * Copyright (C) 2010-2013,2015-2017                      CNRS
+ * Copyright (C) 2010-2013,2015-2018                      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
@@ -237,7 +237,7 @@ int starpu_data_acquire_on_node_cb_sequential_consistency_sync_jobids(starpu_dat
 		if (quick)
 		if (quick)
 			pre_sync_job->quick_next = post_sync_job;
 			pre_sync_job->quick_next = post_sync_job;
 
 
-		new_task = _starpu_detect_implicit_data_deps_with_handle(wrapper->pre_sync_task, wrapper->post_sync_task, &_starpu_get_job_associated_to_task(wrapper->post_sync_task)->implicit_dep_slot, handle, mode);
+		new_task = _starpu_detect_implicit_data_deps_with_handle(wrapper->pre_sync_task, wrapper->post_sync_task, &_starpu_get_job_associated_to_task(wrapper->post_sync_task)->implicit_dep_slot, handle, mode, sequential_consistency);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 
 
 		if (new_task)
 		if (new_task)
@@ -370,7 +370,7 @@ int starpu_data_acquire_on_node(starpu_data_handle_t handle, int node, enum star
 		wrapper.post_sync_task->detach = 1;
 		wrapper.post_sync_task->detach = 1;
 		wrapper.post_sync_task->type = STARPU_TASK_TYPE_DATA_ACQUIRE;
 		wrapper.post_sync_task->type = STARPU_TASK_TYPE_DATA_ACQUIRE;
 
 
-		new_task = _starpu_detect_implicit_data_deps_with_handle(wrapper.pre_sync_task, wrapper.post_sync_task, &_starpu_get_job_associated_to_task(wrapper.post_sync_task)->implicit_dep_slot, handle, mode);
+		new_task = _starpu_detect_implicit_data_deps_with_handle(wrapper.pre_sync_task, wrapper.post_sync_task, &_starpu_get_job_associated_to_task(wrapper.post_sync_task)->implicit_dep_slot, handle, mode, sequential_consistency);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 		STARPU_PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
 		if (new_task)
 		if (new_task)
 		{
 		{

+ 2 - 0
src/util/fstarpu.c

@@ -58,6 +58,7 @@ static const intptr_t fstarpu_tag	= STARPU_TAG;
 static const intptr_t fstarpu_tag_only	= STARPU_TAG_ONLY;
 static const intptr_t fstarpu_tag_only	= STARPU_TAG_ONLY;
 static const intptr_t fstarpu_name	= STARPU_NAME;
 static const intptr_t fstarpu_name	= STARPU_NAME;
 static const intptr_t fstarpu_task_color	= STARPU_TASK_COLOR;
 static const intptr_t fstarpu_task_color	= STARPU_TASK_COLOR;
+static const intptr_t fstarpu_handles_sequential_consistency	= STARPU_HANDLES_SEQUENTIAL_CONSISTENCY;
 static const intptr_t fstarpu_node_selection_policy	= STARPU_NODE_SELECTION_POLICY;
 static const intptr_t fstarpu_node_selection_policy	= STARPU_NODE_SELECTION_POLICY;
 
 
 static const intptr_t fstarpu_value = STARPU_VALUE;
 static const intptr_t fstarpu_value = STARPU_VALUE;
@@ -135,6 +136,7 @@ intptr_t fstarpu_get_constant(char *s)
 	else if (!strcmp(s, "FSTARPU_VALUE"))	{ return fstarpu_value; }
 	else if (!strcmp(s, "FSTARPU_VALUE"))	{ return fstarpu_value; }
 	else if (!strcmp(s, "FSTARPU_SCHED_CTX"))	{ return fstarpu_sched_ctx; }
 	else if (!strcmp(s, "FSTARPU_SCHED_CTX"))	{ return fstarpu_sched_ctx; }
 	else if (!strcmp(s, "FSTARPU_TASK_COLOR"))	{ return fstarpu_task_color; }
 	else if (!strcmp(s, "FSTARPU_TASK_COLOR"))	{ return fstarpu_task_color; }
+	else if (!strcmp(s, "FSTARPU_HANDLES_SEQUENTIAL_CONSISTENCY"))	{ return fstarpu_handles_sequential_consistency; }
 
 
 	else if (!strcmp(s, "FSTARPU_CPU_WORKER"))	{ return fstarpu_cpu_worker; }
 	else if (!strcmp(s, "FSTARPU_CPU_WORKER"))	{ return fstarpu_cpu_worker; }
 	else if (!strcmp(s, "FSTARPU_CUDA_WORKER"))	{ return fstarpu_cuda_worker; }
 	else if (!strcmp(s, "FSTARPU_CUDA_WORKER"))	{ return fstarpu_cuda_worker; }

+ 12 - 0
src/util/starpu_task_insert_utils.c

@@ -196,6 +196,10 @@ int _starpu_codelet_pack_args(void **arg_buffer, size_t *arg_buffer_size, va_lis
                 {
                 {
                         (void)va_arg(varg_list, int);
                         (void)va_arg(varg_list, int);
                 }
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        (void)va_arg(varg_list, char *);
+                }
 		else
 		else
 		{
 		{
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
@@ -490,6 +494,10 @@ int _starpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *ta
                 {
                 {
                         task->color = va_arg(varg_list, int);
                         task->color = va_arg(varg_list, int);
                 }
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        task->handles_sequential_consistency = va_arg(varg_list, char *);
+                }
 		else
 		else
 		{
 		{
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
 			STARPU_ABORT_MSG("Unrecognized argument %d, did you perhaps forget to end arguments with 0?\n", arg_type);
@@ -729,6 +737,10 @@ int _fstarpu_task_insert_create(struct starpu_codelet *cl, struct starpu_task *t
                         arg_i++;
                         arg_i++;
                         task->color = *(int *)arglist[arg_i];
                         task->color = *(int *)arglist[arg_i];
                 }
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        task->handles_sequential_consistency = (char *)arglist[arg_i];
+                }
 		else
 		else
 		{
 		{
 			STARPU_ABORT_MSG("unknown/unsupported argument %d, did you perhaps forget to end arguments with 0?", arg_type);
 			STARPU_ABORT_MSG("unknown/unsupported argument %d, did you perhaps forget to end arguments with 0?", arg_type);