[Openmp-commits] [openmp] 028cf8c - [OpenMP] Implement printing TDGs to dot files
Jose M Monsalve Diaz via Openmp-commits
openmp-commits at lists.llvm.org
Mon Jun 19 06:30:00 PDT 2023
Author: Adrian Munera
Date: 2023-06-19T08:27:38-05:00
New Revision: 028cf8c016b21961bd229f24ddffcad1cb95aa7a
URL: https://github.com/llvm/llvm-project/commit/028cf8c016b21961bd229f24ddffcad1cb95aa7a
DIFF: https://github.com/llvm/llvm-project/commit/028cf8c016b21961bd229f24ddffcad1cb95aa7a.diff
LOG: [OpenMP] Implement printing TDGs to dot files
This patch implements the "__kmp_print_tdg_dot" function, that prints a task dependency graph into a dot file containing the tasks and their dependencies.
It is activated through a new environment variable "KMP_TDG_DOT"
Reviewed By: tianshilei1992
Differential Revision: https://reviews.llvm.org/D150962
Added:
openmp/runtime/test/tasking/omp_record_replay_print_dot.cpp
Modified:
openmp/runtime/src/kmp.h
openmp/runtime/src/kmp_global.cpp
openmp/runtime/src/kmp_settings.cpp
openmp/runtime/src/kmp_tasking.cpp
Removed:
################################################################################
diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h
index 251a5f0ce76fd..f50fb01f793f0 100644
--- a/openmp/runtime/src/kmp.h
+++ b/openmp/runtime/src/kmp.h
@@ -2535,6 +2535,7 @@ typedef struct kmp_tdg_info {
kmp_int32 rec_num_taskred;
} kmp_tdg_info_t;
+extern int __kmp_tdg_dot;
extern kmp_int32 __kmp_max_tdgs;
extern kmp_tdg_info_t **__kmp_global_tdgs;
extern kmp_int32 __kmp_curr_tdg_idx;
diff --git a/openmp/runtime/src/kmp_global.cpp b/openmp/runtime/src/kmp_global.cpp
index 9557c519f835a..4ce0691abf8d6 100644
--- a/openmp/runtime/src/kmp_global.cpp
+++ b/openmp/runtime/src/kmp_global.cpp
@@ -559,6 +559,7 @@ int *__kmp_nesting_nth_level;
#if OMPX_TASKGRAPH
// TDG record & replay
+int __kmp_tdg_dot = 0;
kmp_int32 __kmp_max_tdgs = 100;
kmp_tdg_info_t **__kmp_global_tdgs = NULL;
kmp_int32 __kmp_curr_tdg_idx =
diff --git a/openmp/runtime/src/kmp_settings.cpp b/openmp/runtime/src/kmp_settings.cpp
index 7092d6eb9104c..181db20a5f58d 100644
--- a/openmp/runtime/src/kmp_settings.cpp
+++ b/openmp/runtime/src/kmp_settings.cpp
@@ -1267,6 +1267,16 @@ static void __kmp_std_print_max_tdgs(kmp_str_buf_t *buffer, char const *name,
void *data) {
__kmp_stg_print_int(buffer, name, __kmp_max_tdgs);
} // __kmp_std_print_max_tdgs
+
+static void __kmp_stg_parse_tdg_dot(char const *name, char const *value,
+ void *data) {
+ __kmp_stg_parse_bool(name, value, &__kmp_tdg_dot);
+} // __kmp_stg_parse_tdg_dot
+
+static void __kmp_stg_print_tdg_dot(kmp_str_buf_t *buffer, char const *name,
+ void *data) {
+ __kmp_stg_print_bool(buffer, name, __kmp_tdg_dot);
+} // __kmp_stg_print_tdg_dot
#endif
static void __kmp_stg_parse_num_hidden_helper_threads(char const *name,
@@ -5624,6 +5634,7 @@ static kmp_setting_t __kmp_stg_table[] = {
#if OMPX_TASKGRAPH
{"KMP_MAX_TDGS", __kmp_stg_parse_max_tdgs, __kmp_std_print_max_tdgs, NULL,
0, 0},
+ {"KMP_TDG_DOT", __kmp_stg_parse_tdg_dot, __kmp_stg_print_tdg_dot, NULL, 0, 0},
#endif
#if OMPT_SUPPORT
diff --git a/openmp/runtime/src/kmp_tasking.cpp b/openmp/runtime/src/kmp_tasking.cpp
index ee452440176bf..fefa609927e89 100644
--- a/openmp/runtime/src/kmp_tasking.cpp
+++ b/openmp/runtime/src/kmp_tasking.cpp
@@ -5467,6 +5467,39 @@ static kmp_tdg_info_t *__kmp_find_tdg(kmp_int32 tdg_id) {
return res;
}
+// __kmp_print_tdg_dot: prints the TDG to a dot file
+// tdg: ID of the TDG
+void __kmp_print_tdg_dot(kmp_tdg_info_t *tdg) {
+ kmp_int32 tdg_id = tdg->tdg_id;
+ KA_TRACE(10, ("__kmp_print_tdg_dot(enter): T#%d tdg_id=%d \n", gtid, tdg_id));
+
+ char file_name[20];
+ sprintf(file_name, "tdg_%d.dot", tdg_id);
+ kmp_safe_raii_file_t tdg_file(file_name, "w");
+
+ kmp_int32 num_tasks = KMP_ATOMIC_LD_RLX(&tdg->num_tasks);
+ fprintf(tdg_file,
+ "digraph TDG {\n"
+ " compound=true\n"
+ " subgraph cluster {\n"
+ " label=TDG_%d\n",
+ tdg_id);
+ for (kmp_int32 i = 0; i < num_tasks; i++) {
+ fprintf(tdg_file, " %d[style=bold]\n", i);
+ }
+ fprintf(tdg_file, " }\n");
+ for (kmp_int32 i = 0; i < num_tasks; i++) {
+ kmp_int32 nsuccessors = tdg->record_map[i].nsuccessors;
+ kmp_int32 *successors = tdg->record_map[i].successors;
+ if (nsuccessors > 0) {
+ for (kmp_int32 j = 0; j < nsuccessors; j++)
+ fprintf(tdg_file, " %d -> %d \n", i, successors[j]);
+ }
+ }
+ fprintf(tdg_file, "}");
+ KA_TRACE(10, ("__kmp_print_tdg_dot(exit): T#%d tdg_id=%d \n", gtid, tdg_id));
+}
+
// __kmp_start_record: launch the execution of a previous
// recorded TDG
// gtid: Global Thread ID
@@ -5636,6 +5669,9 @@ void __kmp_end_record(kmp_int32 gtid, kmp_tdg_info_t *tdg) {
this_record_map[i].npredecessors);
}
KMP_ATOMIC_ST_RLX(&__kmp_tdg_task_id, 0);
+
+ if (__kmp_tdg_dot)
+ __kmp_print_tdg_dot(tdg);
}
// __kmpc_end_record_task: wrapper around __kmp_end_record to mark
diff --git a/openmp/runtime/test/tasking/omp_record_replay_print_dot.cpp b/openmp/runtime/test/tasking/omp_record_replay_print_dot.cpp
new file mode 100644
index 0000000000000..2fe55f0815429
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_record_replay_print_dot.cpp
@@ -0,0 +1,80 @@
+// REQUIRES: ompx_taskgraph
+// RUN: %libomp-cxx-compile-and-run
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cassert>
+
+// Compiler-generated code (emulation)
+typedef struct ident {
+ void* dummy;
+} ident_t;
+
+#ifdef __cplusplus
+extern "C" {
+ int __kmpc_global_thread_num(ident_t *);
+ int __kmpc_start_record_task(ident_t *, int, int, int);
+ void __kmpc_end_record_task(ident_t *, int, int , int);
+}
+#endif
+
+void func(int *num_exec) {
+ #pragma omp atomic
+ (*num_exec)++;
+}
+
+std::string tdg_string= "digraph TDG {\n"
+" compound=true\n"
+" subgraph cluster {\n"
+" label=TDG_0\n"
+" 0[style=bold]\n"
+" 1[style=bold]\n"
+" 2[style=bold]\n"
+" 3[style=bold]\n"
+" }\n"
+" 0 -> 1 \n"
+" 1 -> 2 \n"
+" 1 -> 3 \n"
+"}";
+
+int main() {
+ int num_exec = 0;
+ int x, y;
+
+ setenv("KMP_TDG_DOT","TRUE",1);
+ remove("tdg_0.dot");
+
+ #pragma omp parallel
+ #pragma omp single
+ {
+ int gtid = __kmpc_global_thread_num(nullptr);
+ int res = __kmpc_start_record_task(nullptr, gtid, /* kmp_tdg_flags */ 0, /* tdg_id */ 0);
+ if (res) {
+ #pragma omp task depend(out : x)
+ func(&num_exec);
+ #pragma omp task depend(in : x) depend(out : y)
+ func(&num_exec);
+ #pragma omp task depend(in : y)
+ func(&num_exec);
+ #pragma omp task depend(in : y)
+ func(&num_exec);
+ }
+
+ __kmpc_end_record_task(nullptr, gtid, /* kmp_tdg_flags */ 0, /* tdg_id */ 0);
+ }
+
+ assert(num_exec == 4);
+
+ std::ifstream tdg_file("tdg_0.dot");
+ assert(tdg_file.is_open());
+
+ std::stringstream tdg_file_stream;
+ tdg_file_stream << tdg_file.rdbuf();
+ int equal = tdg_string.compare(tdg_file_stream.str());
+
+ assert(equal == 0);
+
+ std::cout << "Passed" << std::endl;
+ return 0;
+}
+// CHECK: Passed
More information about the Openmp-commits
mailing list