Forráskód Böngészése

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

Nathalie Furmento 7 éve
szülő
commit
0e688f6842

+ 2 - 0
ChangeLog

@@ -50,6 +50,8 @@ New features:
     functions starpu_task_end_dep_add() which specifies the number of
     calls to the function starpu_task_end_dep_release() needed to
     trigger the task termination.
+  * Add possibility to define the sequential consistency at the task level
+    for each handle used by the task.
 
 Small features:
   * 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
 
+\subsection SequentialConsistency Sequential Consistency
+
 By default, task dependencies are inferred from data dependency (sequential
 coherency) by StarPU. The application can however disable sequential coherency
 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
 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
 starpu_task_declare_deps_array(). Dependencies between tasks can be
 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
     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
     Optional pointer which is passed to the codelet through the second
     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,
 ::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_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.
 </ul>
 
@@ -161,6 +161,12 @@ given values.
 Used when calling starpu_task_insert(), must be followed by an integer
 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)
 \ingroup API_Insert_Task
 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  \
 	reductions/dot_product			\
 	reductions/minmax_reduction		\
-	dependency/task_end_dep
+	dependency/task_end_dep			\
+	dependency/sequential_consistency
 
 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_NAME
         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_VALUE

+ 2 - 0
include/starpu_task.h

@@ -153,6 +153,8 @@ struct starpu_task
 	void *interfaces[STARPU_NMAXBUFS];
 	enum starpu_data_access_mode modes[STARPU_NMAXBUFS];
 
+	char *handles_sequential_consistency;
+
 	void *cl_arg;
 	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_TASK_DEPS_ARRAY	(27<<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, ...);
 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);
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        (void)va_arg(varg_list_copy, char *);
+                }
 		else
 		{
 			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++;
 			/* int* */
 		}
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+		{
+			arg_i++;
+			/* char* */
+		}
 		else
 		{
 			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) 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
  * 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_JOB_SET_ORDERED_BUFFER_HANDLE(j, handle, i);
+
 		enum starpu_data_access_mode mode = STARPU_TASK_GET_MODE(task, i);
 		_STARPU_JOB_SET_ORDERED_BUFFER_MODE(j, mode, i);
+
 		int node = -1;
 		if (task->cl->specific_nodes)
 			node = STARPU_CODELET_GET_NODE(task->cl, 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);
 }

+ 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;
  * 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,
-						   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;
 
@@ -214,7 +214,7 @@ struct starpu_task *_starpu_detect_implicit_data_deps_with_handle(struct starpu_
 	STARPU_ASSERT(!(mode & STARPU_SCRATCH));
         _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 *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);
-		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;
-		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);
 		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
 		 * 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);
 
 		if (new_task)

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

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * 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
  * it under the terms of the GNU Lesser General Public License as published by
@@ -22,7 +22,7 @@
 #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,
-						   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);
 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);

+ 3 - 0
src/core/jobs.h

@@ -62,6 +62,7 @@ struct _starpu_data_descr
 	starpu_data_handle_t handle;
 	enum starpu_data_access_mode mode;
 	int node;
+	unsigned sequential_consistency;
 };
 
 #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_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_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_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_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_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) 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
  * 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)
 			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);
 
 		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->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);
 		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_name	= STARPU_NAME;
 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_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_SCHED_CTX"))	{ return fstarpu_sched_ctx; }
 	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_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);
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        (void)va_arg(varg_list, char *);
+                }
 		else
 		{
 			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);
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        task->handles_sequential_consistency = va_arg(varg_list, char *);
+                }
 		else
 		{
 			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++;
                         task->color = *(int *)arglist[arg_i];
                 }
+		else if (arg_type==STARPU_HANDLES_SEQUENTIAL_CONSISTENCY)
+                {
+                        task->handles_sequential_consistency = (char *)arglist[arg_i];
+                }
 		else
 		{
 			STARPU_ABORT_MSG("unknown/unsupported argument %d, did you perhaps forget to end arguments with 0?", arg_type);