summaryrefslogtreecommitdiff
path: root/openmp/runtime/src/kmp_taskdeps.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /openmp/runtime/src/kmp_taskdeps.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'openmp/runtime/src/kmp_taskdeps.cpp')
-rw-r--r--openmp/runtime/src/kmp_taskdeps.cpp164
1 files changed, 127 insertions, 37 deletions
diff --git a/openmp/runtime/src/kmp_taskdeps.cpp b/openmp/runtime/src/kmp_taskdeps.cpp
index e1618f5cd9df..a654951f5b3b 100644
--- a/openmp/runtime/src/kmp_taskdeps.cpp
+++ b/openmp/runtime/src/kmp_taskdeps.cpp
@@ -35,7 +35,7 @@ static std::atomic<kmp_int32> kmp_node_id_seed = ATOMIC_VAR_INIT(0);
static void __kmp_init_node(kmp_depnode_t *node) {
node->dn.successors = NULL;
- node->dn.task = NULL; // will point to the rigth task
+ node->dn.task = NULL; // will point to the right task
// once dependences have been processed
for (int i = 0; i < MAX_MTX_DEPS; ++i)
node->dn.mtx_locks[i] = NULL;
@@ -205,7 +205,7 @@ static kmp_depnode_list_t *__kmp_add_node(kmp_info_t *thread,
return new_head;
}
-static inline void __kmp_track_dependence(kmp_depnode_t *source,
+static inline void __kmp_track_dependence(kmp_int32 gtid, kmp_depnode_t *source,
kmp_depnode_t *sink,
kmp_task_t *sink_task) {
#ifdef KMP_SUPPORT_GRAPH_OUTPUT
@@ -224,11 +224,14 @@ static inline void __kmp_track_dependence(kmp_depnode_t *source,
*/
if (ompt_enabled.ompt_callback_task_dependence) {
kmp_taskdata_t *task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
- kmp_taskdata_t *task_sink = KMP_TASK_TO_TASKDATA(sink_task);
+ ompt_data_t *sink_data;
+ if (sink_task)
+ sink_data = &(KMP_TASK_TO_TASKDATA(sink_task)->ompt_task_info.task_data);
+ else
+ sink_data = &__kmp_threads[gtid]->th.ompt_thread_info.task_data;
ompt_callbacks.ompt_callback(ompt_callback_task_dependence)(
- &(task_source->ompt_task_info.task_data),
- &(task_sink->ompt_task_info.task_data));
+ &(task_source->ompt_task_info.task_data), sink_data);
}
#endif /* OMPT_SUPPORT && OMPT_OPTIONAL */
}
@@ -246,7 +249,7 @@ __kmp_depnode_link_successor(kmp_int32 gtid, kmp_info_t *thread,
if (dep->dn.task) {
KMP_ACQUIRE_DEPNODE(gtid, dep);
if (dep->dn.task) {
- __kmp_track_dependence(dep, node, task);
+ __kmp_track_dependence(gtid, dep, node, task);
dep->dn.successors = __kmp_add_node(thread, dep->dn.successors, node);
KA_TRACE(40, ("__kmp_process_deps: T#%d adding dependence from %p to "
"%p\n",
@@ -272,7 +275,7 @@ static inline kmp_int32 __kmp_depnode_link_successor(kmp_int32 gtid,
// synchronously add source to sink' list of successors
KMP_ACQUIRE_DEPNODE(gtid, sink);
if (sink->dn.task) {
- __kmp_track_dependence(sink, source, task);
+ __kmp_track_dependence(gtid, sink, source, task);
sink->dn.successors = __kmp_add_node(thread, sink->dn.successors, source);
KA_TRACE(40, ("__kmp_process_deps: T#%d adding dependence from %p to "
"%p\n",
@@ -473,8 +476,8 @@ static bool __kmp_check_deps(kmp_int32 gtid, kmp_depnode_t *node,
npredecessors++;
// Update predecessors and obtain current value to check if there are still
- // any outstandig dependences (some tasks may have finished while we processed
- // the dependences)
+ // any outstanding dependences (some tasks may have finished while we
+ // processed the dependences)
npredecessors =
node->dn.npredecessors.fetch_add(npredecessors) + npredecessors;
@@ -498,7 +501,7 @@ task''
@param noalias_dep_list List of depend items with no aliasing
@return Returns either TASK_CURRENT_NOT_QUEUED if the current task was not
-suspendend and queued, or TASK_CURRENT_QUEUED if it was suspended and queued
+suspended and queued, or TASK_CURRENT_QUEUED if it was suspended and queued
Schedule a non-thread-switchable task with dependences for execution
*/
@@ -540,47 +543,40 @@ kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 gtid,
ompt_enabled.ompt_callback_dependences) {
kmp_int32 i;
- new_taskdata->ompt_task_info.ndeps = ndeps + ndeps_noalias;
- new_taskdata->ompt_task_info.deps =
- (ompt_dependence_t *)KMP_OMPT_DEPS_ALLOC(
- thread, (ndeps + ndeps_noalias) * sizeof(ompt_dependence_t));
+ int ompt_ndeps = ndeps + ndeps_noalias;
+ ompt_dependence_t *ompt_deps = (ompt_dependence_t *)KMP_OMPT_DEPS_ALLOC(
+ thread, (ndeps + ndeps_noalias) * sizeof(ompt_dependence_t));
- KMP_ASSERT(new_taskdata->ompt_task_info.deps != NULL);
+ KMP_ASSERT(ompt_deps != NULL);
for (i = 0; i < ndeps; i++) {
- new_taskdata->ompt_task_info.deps[i].variable.ptr =
- (void *)dep_list[i].base_addr;
+ ompt_deps[i].variable.ptr = (void *)dep_list[i].base_addr;
if (dep_list[i].flags.in && dep_list[i].flags.out)
- new_taskdata->ompt_task_info.deps[i].dependence_type =
- ompt_dependence_type_inout;
+ ompt_deps[i].dependence_type = ompt_dependence_type_inout;
else if (dep_list[i].flags.out)
- new_taskdata->ompt_task_info.deps[i].dependence_type =
- ompt_dependence_type_out;
+ ompt_deps[i].dependence_type = ompt_dependence_type_out;
else if (dep_list[i].flags.in)
- new_taskdata->ompt_task_info.deps[i].dependence_type =
- ompt_dependence_type_in;
+ ompt_deps[i].dependence_type = ompt_dependence_type_in;
+ else if (dep_list[i].flags.mtx)
+ ompt_deps[i].dependence_type = ompt_dependence_type_mutexinoutset;
}
for (i = 0; i < ndeps_noalias; i++) {
- new_taskdata->ompt_task_info.deps[ndeps + i].variable.ptr =
- (void *)noalias_dep_list[i].base_addr;
+ ompt_deps[ndeps + i].variable.ptr = (void *)noalias_dep_list[i].base_addr;
if (noalias_dep_list[i].flags.in && noalias_dep_list[i].flags.out)
- new_taskdata->ompt_task_info.deps[ndeps + i].dependence_type =
- ompt_dependence_type_inout;
+ ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inout;
else if (noalias_dep_list[i].flags.out)
- new_taskdata->ompt_task_info.deps[ndeps + i].dependence_type =
- ompt_dependence_type_out;
+ ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_out;
else if (noalias_dep_list[i].flags.in)
- new_taskdata->ompt_task_info.deps[ndeps + i].dependence_type =
- ompt_dependence_type_in;
+ ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_in;
+ else if (noalias_dep_list[i].flags.mtx)
+ ompt_deps[ndeps + i].dependence_type =
+ ompt_dependence_type_mutexinoutset;
}
ompt_callbacks.ompt_callback(ompt_callback_dependences)(
- &(new_taskdata->ompt_task_info.task_data),
- new_taskdata->ompt_task_info.deps, new_taskdata->ompt_task_info.ndeps);
+ &(new_taskdata->ompt_task_info.task_data), ompt_deps, ompt_ndeps);
/* We can now free the allocated memory for the dependencies */
- /* For OMPD we might want to delay the free until task_end */
- KMP_OMPT_DEPS_FREE(thread, new_taskdata->ompt_task_info.deps);
- new_taskdata->ompt_task_info.deps = NULL;
- new_taskdata->ompt_task_info.ndeps = 0;
+ /* For OMPD we might want to delay the free until end of this function */
+ KMP_OMPT_DEPS_FREE(thread, ompt_deps);
}
#endif /* OMPT_OPTIONAL */
#endif /* OMPT_SUPPORT */
@@ -642,6 +638,23 @@ kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 gtid,
return ret;
}
+#if OMPT_SUPPORT
+void __ompt_taskwait_dep_finish(kmp_taskdata_t *current_task,
+ ompt_data_t *taskwait_task_data) {
+ if (ompt_enabled.ompt_callback_task_schedule) {
+ ompt_data_t task_data = ompt_data_none;
+ ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
+ current_task ? &(current_task->ompt_task_info.task_data) : &task_data,
+ ompt_task_switch, taskwait_task_data);
+ ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
+ taskwait_task_data, ompt_task_complete,
+ current_task ? &(current_task->ompt_task_info.task_data) : &task_data);
+ }
+ current_task->ompt_task_info.frame.enter_frame.ptr = NULL;
+ *taskwait_task_data = ompt_data_none;
+}
+#endif /* OMPT_SUPPORT */
+
/*!
@ingroup TASKING
@param loc_ref location of the original task directive
@@ -668,6 +681,74 @@ void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
kmp_info_t *thread = __kmp_threads[gtid];
kmp_taskdata_t *current_task = thread->th.th_current_task;
+#if OMPT_SUPPORT
+ // this function represents a taskwait construct with depend clause
+ // We signal 4 events:
+ // - creation of the taskwait task
+ // - dependences of the taskwait task
+ // - schedule and finish of the taskwait task
+ ompt_data_t *taskwait_task_data = &thread->th.ompt_thread_info.task_data;
+ KMP_ASSERT(taskwait_task_data->ptr == NULL);
+ if (ompt_enabled.enabled) {
+ if (!current_task->ompt_task_info.frame.enter_frame.ptr)
+ current_task->ompt_task_info.frame.enter_frame.ptr =
+ OMPT_GET_FRAME_ADDRESS(0);
+ if (ompt_enabled.ompt_callback_task_create) {
+ ompt_data_t task_data = ompt_data_none;
+ ompt_callbacks.ompt_callback(ompt_callback_task_create)(
+ current_task ? &(current_task->ompt_task_info.task_data) : &task_data,
+ current_task ? &(current_task->ompt_task_info.frame) : NULL,
+ taskwait_task_data,
+ ompt_task_explicit | ompt_task_undeferred | ompt_task_mergeable, 1,
+ OMPT_GET_RETURN_ADDRESS(0));
+ }
+ }
+
+#if OMPT_OPTIONAL
+ /* OMPT grab all dependences if requested by the tool */
+ if (ndeps + ndeps_noalias > 0 && ompt_enabled.ompt_callback_dependences) {
+ kmp_int32 i;
+
+ int ompt_ndeps = ndeps + ndeps_noalias;
+ ompt_dependence_t *ompt_deps = (ompt_dependence_t *)KMP_OMPT_DEPS_ALLOC(
+ thread, (ndeps + ndeps_noalias) * sizeof(ompt_dependence_t));
+
+ KMP_ASSERT(ompt_deps != NULL);
+
+ for (i = 0; i < ndeps; i++) {
+ ompt_deps[i].variable.ptr = (void *)dep_list[i].base_addr;
+ if (dep_list[i].flags.in && dep_list[i].flags.out)
+ ompt_deps[i].dependence_type = ompt_dependence_type_inout;
+ else if (dep_list[i].flags.out)
+ ompt_deps[i].dependence_type = ompt_dependence_type_out;
+ else if (dep_list[i].flags.in)
+ ompt_deps[i].dependence_type = ompt_dependence_type_in;
+ else if (dep_list[i].flags.mtx)
+ ompt_deps[ndeps + i].dependence_type =
+ ompt_dependence_type_mutexinoutset;
+ }
+ for (i = 0; i < ndeps_noalias; i++) {
+ ompt_deps[ndeps + i].variable.ptr = (void *)noalias_dep_list[i].base_addr;
+ if (noalias_dep_list[i].flags.in && noalias_dep_list[i].flags.out)
+ ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inout;
+ else if (noalias_dep_list[i].flags.out)
+ ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_out;
+ else if (noalias_dep_list[i].flags.in)
+ ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_in;
+ else if (noalias_dep_list[i].flags.mtx)
+ ompt_deps[ndeps + i].dependence_type =
+ ompt_dependence_type_mutexinoutset;
+ }
+ ompt_callbacks.ompt_callback(ompt_callback_dependences)(
+ taskwait_task_data, ompt_deps, ompt_ndeps);
+ /* We can now free the allocated memory for the dependencies */
+ /* For OMPD we might want to delay the free until end of this function */
+ KMP_OMPT_DEPS_FREE(thread, ompt_deps);
+ ompt_deps = NULL;
+ }
+#endif /* OMPT_OPTIONAL */
+#endif /* OMPT_SUPPORT */
+
// We can return immediately as:
// - dependences are not computed in serial teams (except with proxy tasks)
// - if the dephash is not yet created it means we have nothing to wait for
@@ -682,6 +763,9 @@ void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking "
"dependencies : loc=%p\n",
gtid, loc_ref));
+#if OMPT_SUPPORT
+ __ompt_taskwait_dep_finish(current_task, taskwait_task_data);
+#endif /* OMPT_SUPPORT */
return;
}
@@ -694,6 +778,9 @@ void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking "
"dependencies : loc=%p\n",
gtid, loc_ref));
+#if OMPT_SUPPORT
+ __ompt_taskwait_dep_finish(current_task, taskwait_task_data);
+#endif /* OMPT_SUPPORT */
return;
}
@@ -705,6 +792,9 @@ void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
__kmp_task_stealing_constraint);
}
+#if OMPT_SUPPORT
+ __ompt_taskwait_dep_finish(current_task, taskwait_task_data);
+#endif /* OMPT_SUPPORT */
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d finished waiting : loc=%p\n",
gtid, loc_ref));
}