diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /openmp/runtime/src/kmp_taskdeps.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'openmp/runtime/src/kmp_taskdeps.cpp')
-rw-r--r-- | openmp/runtime/src/kmp_taskdeps.cpp | 164 |
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)); } |