[Openmp-commits] [openmp] r259038 - [OMPT] Add support for ompt_event_task_dependences and ompt_event_task_dependence_pair
Jonas Hahnfeld via Openmp-commits
openmp-commits at lists.llvm.org
Thu Jan 28 02:39:52 PST 2016
Author: hahnfeld
Date: Thu Jan 28 04:39:52 2016
New Revision: 259038
URL: http://llvm.org/viewvc/llvm-project?rev=259038&view=rev
Log:
[OMPT] Add support for ompt_event_task_dependences and ompt_event_task_dependence_pair
The attached patch adds support for ompt_event_task_dependences and
ompt_event_task_dependence_pair events from the OMPT specification [1]. These
events only apply to OpenMP 4.0 and 4.1 (aka 4.5) because task dependencies
were introduced in 4.0.
With respect to the changes:
ompt_event_task_dependences
According to the specification, this event is raised after the task has been
created, thefore this event needs to be raised after ompt_event_task_begin
(in __kmp_task_start). However, the dependencies are known at
__kmpc_omp_task_with_deps which occurs before __kmp_task_start. My modifications
extend the ompt_task_info_t struct in order to store the dependencies of the
task when _kmpc_omp_task_with_deps occurs and then they are emitted in
__kmp_task_start just after raising the ompt_event_task_begin. The deps field
is allocated and valid until the event is raised and it is freed and set
to null afterwards.
ompt_event_task_dependence_pair
The processing of the dependences (i.e. checking whenever a dependence is
already satisfied) is done within __kmp_process_deps. That function checks
every dependence and calls the __kmp_track_dependence routine which gives some
support for graphical output. I used that routine to emit the dependence pair
but I also needed to know the sink_task. Despite the fact that the code within
KMP_SUPPORT_GRAPH_OUTPUT refers to task_sink it may be null because
sink->dn.task (there's a comment regarding this) and in fact it does not point
to a proper pointer value because the value is set in node->dn.task = task;
after the __kmp_process_deps calls in __kmp_check_deps. I have extended the
__kmp_process_deps and __kmp_track_dependence parameter list to receive the
sink_task.
[1] https://github.com/OpenMPToolsInterface/OMPT-Technical-Report/blob/target/ompt-tr.pdf
Patch by Harald Servat
Differential Revision: http://reviews.llvm.org/D14746
Modified:
openmp/trunk/runtime/src/include/40/ompt.h.var
openmp/trunk/runtime/src/include/41/ompt.h.var
openmp/trunk/runtime/src/kmp_taskdeps.cpp
openmp/trunk/runtime/src/kmp_tasking.c
openmp/trunk/runtime/src/ompt-event-specific.h
openmp/trunk/runtime/src/ompt-internal.h
Modified: openmp/trunk/runtime/src/include/40/ompt.h.var
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/include/40/ompt.h.var?rev=259038&r1=259037&r2=259038&view=diff
==============================================================================
--- openmp/trunk/runtime/src/include/40/ompt.h.var (original)
+++ openmp/trunk/runtime/src/include/40/ompt.h.var Thu Jan 28 04:39:52 2016
@@ -171,7 +171,10 @@
macro (ompt_event_destroy_lock, ompt_wait_callback_t, 59) /* lock destruction */ \
macro (ompt_event_destroy_nest_lock, ompt_wait_callback_t, 60) /* nest lock destruction */ \
\
- macro (ompt_event_flush, ompt_callback_t, 61) /* after executing flush */
+ macro (ompt_event_flush, ompt_callback_t, 61) /* after executing flush */ \
+ \
+ macro (ompt_event_task_dependences, ompt_task_dependences_callback_t, 69) /* report task dependences */\
+ macro (ompt_event_task_dependence_pair, ompt_task_pair_callback_t, 70) /* report task dependence pair */
@@ -206,6 +209,23 @@ typedef struct ompt_frame_s {
} ompt_frame_t;
+/*---------------------
+ * dependences types
+ *---------------------*/
+
+typedef enum ompt_task_dependence_flag_e {
+ // a two bit field for the dependence type
+ ompt_task_dependence_type_out = 1,
+ ompt_task_dependence_type_in = 2,
+ ompt_task_dependence_type_inout = 3,
+} ompt_task_dependence_flag_t;
+
+typedef struct ompt_task_dependence_s {
+ void *variable_addr;
+ uint32_t dependence_flags;
+} ompt_task_dependence_t;
+
+
/*****************************************************************************
* enumerations for thread states and runtime events
*****************************************************************************/
@@ -325,6 +345,13 @@ typedef void (*ompt_new_task_callback_t)
void *task_function /* pointer to outlined function */
);
+/* task dependences */
+typedef void (*ompt_task_dependences_callback_t) (
+ ompt_task_id_t task_id, /* ID of task with dependences */
+ const ompt_task_dependence_t *deps,/* vector of task dependences */
+ int ndeps /* number of dependences */
+);
+
/* program */
typedef void (*ompt_control_callback_t) (
uint64_t command, /* command of control call */
Modified: openmp/trunk/runtime/src/include/41/ompt.h.var
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/include/41/ompt.h.var?rev=259038&r1=259037&r2=259038&view=diff
==============================================================================
--- openmp/trunk/runtime/src/include/41/ompt.h.var (original)
+++ openmp/trunk/runtime/src/include/41/ompt.h.var Thu Jan 28 04:39:52 2016
@@ -171,7 +171,10 @@
macro (ompt_event_destroy_lock, ompt_wait_callback_t, 59) /* lock destruction */ \
macro (ompt_event_destroy_nest_lock, ompt_wait_callback_t, 60) /* nest lock destruction */ \
\
- macro (ompt_event_flush, ompt_callback_t, 61) /* after executing flush */
+ macro (ompt_event_flush, ompt_callback_t, 61) /* after executing flush */ \
+ \
+ macro (ompt_event_task_dependences, ompt_task_dependences_callback_t, 69) /* report task dependences */\
+ macro (ompt_event_task_dependence_pair, ompt_task_pair_callback_t, 70) /* report task dependence pair */
@@ -206,6 +209,23 @@ typedef struct ompt_frame_s {
} ompt_frame_t;
+/*---------------------
+ * dependences types
+ *---------------------*/
+
+typedef enum ompt_task_dependence_flag_e {
+ // a two bit field for the dependence type
+ ompt_task_dependence_type_out = 1,
+ ompt_task_dependence_type_in = 2,
+ ompt_task_dependence_type_inout = 3,
+} ompt_task_dependence_flag_t;
+
+typedef struct ompt_task_dependence_s {
+ void *variable_addr;
+ uint32_t dependence_flags;
+} ompt_task_dependence_t;
+
+
/*****************************************************************************
* enumerations for thread states and runtime events
*****************************************************************************/
@@ -325,6 +345,13 @@ typedef void (*ompt_new_task_callback_t)
void *task_function /* pointer to outlined function */
);
+/* task dependences */
+typedef void (*ompt_task_dependences_callback_t) (
+ ompt_task_id_t task_id, /* ID of task with dependences */
+ const ompt_task_dependence_t *deps,/* vector of task dependences */
+ int ndeps /* number of dependences */
+);
+
/* program */
typedef void (*ompt_control_callback_t) (
uint64_t command, /* command of control call */
Modified: openmp/trunk/runtime/src/kmp_taskdeps.cpp
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_taskdeps.cpp?rev=259038&r1=259037&r2=259038&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_taskdeps.cpp (original)
+++ openmp/trunk/runtime/src/kmp_taskdeps.cpp Thu Jan 28 04:39:52 2016
@@ -196,7 +196,8 @@ __kmp_depnode_list_free ( kmp_info_t *th
}
static inline void
-__kmp_track_dependence ( kmp_depnode_t *source, kmp_depnode_t *sink )
+__kmp_track_dependence ( kmp_depnode_t *source, kmp_depnode_t *sink,
+ kmp_task_t *sink_task )
{
#ifdef KMP_SUPPORT_GRAPH_OUTPUT
kmp_taskdata_t * task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
@@ -204,12 +205,27 @@ __kmp_track_dependence ( kmp_depnode_t *
__kmp_printf("%d(%s) -> %d(%s)\n", source->dn.id, task_source->td_ident->psource, sink->dn.id, task_sink->td_ident->psource);
#endif
+#if OMPT_SUPPORT && OMPT_TRACE
+ /* OMPT tracks dependences between task (a=source, b=sink) in which
+ task a blocks the execution of b through the ompt_new_dependence_callback */
+ if (ompt_enabled &&
+ ompt_callbacks.ompt_callback(ompt_event_task_dependence_pair))
+ {
+ kmp_taskdata_t * task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
+ kmp_taskdata_t * task_sink = KMP_TASK_TO_TASKDATA(sink_task);
+
+ ompt_callbacks.ompt_callback(ompt_event_task_dependence_pair)(
+ task_source->ompt_task_info.task_id,
+ task_sink->ompt_task_info.task_id);
+ }
+#endif /* OMPT_SUPPORT && OMPT_TRACE */
}
template< bool filter >
static inline kmp_int32
__kmp_process_deps ( kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t *hash,
- bool dep_barrier,kmp_int32 ndeps, kmp_depend_info_t *dep_list)
+ bool dep_barrier,kmp_int32 ndeps, kmp_depend_info_t *dep_list,
+ kmp_task_t *task )
{
KA_TRACE(30, ("__kmp_process_deps<%d>: T#%d processing %d depencies : dep_barrier = %d\n", filter, gtid, ndeps, dep_barrier ) );
@@ -231,7 +247,7 @@ __kmp_process_deps ( kmp_int32 gtid, kmp
if ( indep->dn.task ) {
KMP_ACQUIRE_DEPNODE(gtid,indep);
if ( indep->dn.task ) {
- __kmp_track_dependence(indep,node);
+ __kmp_track_dependence(indep,node,task);
indep->dn.successors = __kmp_add_node(thread, indep->dn.successors, node);
KA_TRACE(40,("__kmp_process_deps<%d>: T#%d adding dependence from %p to %p\n",
filter,gtid, KMP_TASK_TO_TASKDATA(indep->dn.task), KMP_TASK_TO_TASKDATA(node->dn.task)));
@@ -247,7 +263,7 @@ __kmp_process_deps ( kmp_int32 gtid, kmp
} else if ( last_out && last_out->dn.task ) {
KMP_ACQUIRE_DEPNODE(gtid,last_out);
if ( last_out->dn.task ) {
- __kmp_track_dependence(last_out,node);
+ __kmp_track_dependence(last_out,node,task);
last_out->dn.successors = __kmp_add_node(thread, last_out->dn.successors, node);
KA_TRACE(40,("__kmp_process_deps<%d>: T#%d adding dependence from %p to %p\n",
filter,gtid, KMP_TASK_TO_TASKDATA(last_out->dn.task), KMP_TASK_TO_TASKDATA(node->dn.task)));
@@ -312,8 +328,10 @@ __kmp_check_deps ( kmp_int32 gtid, kmp_d
// used to pack all npredecessors additions into a single atomic operation at the end
int npredecessors;
- npredecessors = __kmp_process_deps<true>(gtid, node, hash, dep_barrier, ndeps, dep_list);
- npredecessors += __kmp_process_deps<false>(gtid, node, hash, dep_barrier, ndeps_noalias, noalias_dep_list);
+ npredecessors = __kmp_process_deps<true>(gtid, node, hash, dep_barrier,
+ ndeps, dep_list, task);
+ npredecessors += __kmp_process_deps<false>(gtid, node, hash, dep_barrier,
+ ndeps_noalias, noalias_dep_list, task);
node->dn.task = task;
KMP_MB();
@@ -404,6 +422,51 @@ __kmpc_omp_task_with_deps( ident_t *loc_
kmp_info_t *thread = __kmp_threads[ gtid ];
kmp_taskdata_t * current_task = thread->th.th_current_task;
+#if OMPT_SUPPORT && OMPT_TRACE
+ /* OMPT grab all dependences if requested by the tool */
+ if (ompt_enabled && ndeps+ndeps_noalias > 0 &&
+ ompt_callbacks.ompt_callback(ompt_event_task_dependences))
+ {
+ kmp_int32 i;
+
+ new_taskdata->ompt_task_info.ndeps = ndeps+ndeps_noalias;
+ new_taskdata->ompt_task_info.deps = (ompt_task_dependence_t *)
+ KMP_OMPT_DEPS_ALLOC(thread,
+ (ndeps+ndeps_noalias)*sizeof(ompt_task_dependence_t));
+
+ KMP_ASSERT(new_taskdata->ompt_task_info.deps != NULL);
+
+ for (i = 0; i < ndeps; i++)
+ {
+ new_taskdata->ompt_task_info.deps[i].variable_addr =
+ (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_flags =
+ ompt_task_dependence_type_inout;
+ else if (dep_list[i].flags.out)
+ new_taskdata->ompt_task_info.deps[i].dependence_flags =
+ ompt_task_dependence_type_out;
+ else if (dep_list[i].flags.in)
+ new_taskdata->ompt_task_info.deps[i].dependence_flags =
+ ompt_task_dependence_type_in;
+ }
+ for (i = 0; i < ndeps_noalias; i++)
+ {
+ new_taskdata->ompt_task_info.deps[ndeps+i].variable_addr =
+ (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_flags =
+ ompt_task_dependence_type_inout;
+ else if (noalias_dep_list[i].flags.out)
+ new_taskdata->ompt_task_info.deps[ndeps+i].dependence_flags =
+ ompt_task_dependence_type_out;
+ else if (noalias_dep_list[i].flags.in)
+ new_taskdata->ompt_task_info.deps[ndeps+i].dependence_flags =
+ ompt_task_dependence_type_in;
+ }
+ }
+#endif /* OMPT_SUPPORT && OMPT_TRACE */
+
bool serial = current_task->td_flags.team_serial || current_task->td_flags.tasking_ser || current_task->td_flags.final;
#if OMP_41_ENABLED
serial = serial && !(new_taskdata->td_flags.proxy == TASK_PROXY);
Modified: openmp/trunk/runtime/src/kmp_tasking.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_tasking.c?rev=259038&r1=259037&r2=259038&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_tasking.c (original)
+++ openmp/trunk/runtime/src/kmp_tasking.c Thu Jan 28 04:39:52 2016
@@ -462,6 +462,22 @@ __kmp_task_start( kmp_int32 gtid, kmp_ta
taskdata->ompt_task_info.function);
}
#endif
+#if OMP_40_ENABLED && OMPT_SUPPORT && OMPT_TRACE
+ /* OMPT emit all dependences if requested by the tool */
+ if (ompt_enabled && taskdata->ompt_task_info.ndeps > 0 &&
+ ompt_callbacks.ompt_callback(ompt_event_task_dependences))
+ {
+ ompt_callbacks.ompt_callback(ompt_event_task_dependences)(
+ taskdata->ompt_task_info.task_id,
+ taskdata->ompt_task_info.deps,
+ taskdata->ompt_task_info.ndeps
+ );
+ /* We can now free the allocated memory for the dependencies */
+ KMP_OMPT_DEPS_FREE (thread, taskdata->ompt_task_info.deps);
+ taskdata->ompt_task_info.deps = NULL;
+ taskdata->ompt_task_info.ndeps = 0;
+ }
+#endif /* OMP_40_ENABLED && OMPT_SUPPORT && OMPT_TRACE */
return;
}
@@ -760,6 +776,10 @@ __kmp_task_init_ompt( kmp_taskdata_t * t
task->ompt_task_info.function = function;
task->ompt_task_info.frame.exit_runtime_frame = NULL;
task->ompt_task_info.frame.reenter_runtime_frame = NULL;
+#if OMP_40_ENABLED
+ task->ompt_task_info.ndeps = 0;
+ task->ompt_task_info.deps = NULL;
+#endif /* OMP_40_ENABLED */
}
}
#endif
Modified: openmp/trunk/runtime/src/ompt-event-specific.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/ompt-event-specific.h?rev=259038&r1=259037&r2=259038&view=diff
==============================================================================
--- openmp/trunk/runtime/src/ompt-event-specific.h (original)
+++ openmp/trunk/runtime/src/ompt-event-specific.h Thu Jan 28 04:39:52 2016
@@ -141,4 +141,12 @@
#define ompt_event_flush_implemented ompt_event_UNIMPLEMENTED
+#if OMP_40_ENABLED
+# define ompt_event_task_dependences_implemented ompt_event_MAY_ALWAYS_TRACE
+# define ompt_event_task_dependence_pair_implemented ompt_event_MAY_ALWAYS_TRACE
+#else
+# define ompt_event_task_dependences_implemented ompt_event_UNIMPLEMENTED
+# define ompt_event_task_dependence_pair_implemented ompt_event_UNIMPLEMENTED
+#endif /* OMP_40_ENABLED */
+
#endif
Modified: openmp/trunk/runtime/src/ompt-internal.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/ompt-internal.h?rev=259038&r1=259037&r2=259038&view=diff
==============================================================================
--- openmp/trunk/runtime/src/ompt-internal.h (original)
+++ openmp/trunk/runtime/src/ompt-internal.h Thu Jan 28 04:39:52 2016
@@ -26,9 +26,13 @@ typedef struct ompt_callbacks_s {
typedef struct {
- ompt_frame_t frame;
- void* function;
- ompt_task_id_t task_id;
+ ompt_frame_t frame;
+ void* function;
+ ompt_task_id_t task_id;
+#if OMP_40_ENABLED
+ int ndeps;
+ ompt_task_dependence_t *deps;
+#endif /* OMP_40_ENABLED */
} ompt_task_info_t;
@@ -62,6 +66,16 @@ typedef struct {
extern ompt_callbacks_t ompt_callbacks;
+#if OMP_40_ENABLED && OMPT_SUPPORT && OMPT_TRACE
+#if USE_FAST_MEMORY
+# define KMP_OMPT_DEPS_ALLOC __kmp_fast_allocate
+# define KMP_OMPT_DEPS_FREE __kmp_fast_free
+# else
+# define KMP_OMPT_DEPS_ALLOC __kmp_thread_malloc
+# define KMP_OMPT_DEPS_FREE __kmp_thread_free
+# endif
+#endif /* OMP_40_ENABLED && OMPT_SUPPORT && OMPT_TRACE */
+
#ifdef __cplusplus
extern "C" {
#endif
More information about the Openmp-commits
mailing list