[Openmp-commits] [openmp] [OpenMP][Archer] Allow stop-start via omp_control_tool (PR #137939)
via Openmp-commits
openmp-commits at lists.llvm.org
Wed Apr 30 02:10:34 PDT 2025
https://github.com/felilxtomski created https://github.com/llvm/llvm-project/pull/137939
Allows Archer to be paused, restarted and completely ended via `omp_control_tool`. TSan will also ignore memory accesses (writes) when Archer is paused or ended.
>From 741838fd30551cb2f4338966915361b90f50b078 Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Tue, 8 Apr 2025 09:37:02 +0200
Subject: [PATCH 1/9] [Archer] Add support for omp_control_tool
---
openmp/tools/archer/ompt-tsan.cpp | 43 +++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
index bb60fc6b603f4..0f7ed862d91c2 100644
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -32,6 +32,7 @@
#include <vector>
#include "omp-tools.h"
+#include "omp.h" /* For omp_control_tool_result_t */
// Define attribute that indicates that the fall through from the previous
// case label is intentional and should not be diagnosed by a compiler
@@ -601,6 +602,44 @@ static inline TaskData *ToTaskData(ompt_data_t *task_data) {
static std::unordered_map<ompt_wait_id_t, std::mutex> Locks;
static std::mutex LocksMutex;
+enum ArcherState { ACTIVE = 0, PAUSED, ENDED };
+static ArcherState archer_state{ACTIVE};
+
+static int ompt_tsan_control_tool(uint64_t command, uint64_t modifier,
+ void *arg, const void *codeptr_ra) {
+ omp_control_tool_result_t res = omp_control_tool_ignored;
+ switch (command) {
+ case omp_control_tool_start:
+ if (archer_state == ENDED || archer_state == ACTIVE)
+ return omp_control_tool_ignored;
+ if (archer_flags->verbose)
+ std::cout << "[Archer] Started operation\n";
+ archer_state = ACTIVE;
+ TsanIgnoreWritesEnd();
+ return omp_control_tool_success;
+ case omp_control_tool_pause:
+ if (archer_flags->verbose)
+ std::cout << "[Archer] Paused operation\n";
+ if (archer_state != ENDED) {
+ TsanIgnoreWritesBegin();
+ archer_state = PAUSED;
+ }
+ return omp_control_tool_success;
+ case omp_control_tool_flush:
+ return omp_control_tool_ignored;
+ case omp_control_tool_end:
+ archer_state = ENDED;
+ if (archer_flags->verbose) {
+ std::cout << "[Archer] Ended operation\n";
+ }
+ TsanIgnoreWritesBegin();
+ return omp_control_tool_success;
+ default:
+ return omp_control_tool_ignored;
+ }
+ return res;
+}
+
static void ompt_tsan_thread_begin(ompt_thread_t thread_type,
ompt_data_t *thread_data) {
ParallelDataPool::ThreadDataPool = new ParallelDataPool;
@@ -1191,6 +1230,7 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
findTsanFunction(__tsan_func_entry, (void (*)(const void *)));
findTsanFunction(__tsan_func_exit, (void (*)(void)));
+ SET_CALLBACK(control_tool);
SET_CALLBACK(thread_begin);
SET_CALLBACK(thread_end);
SET_CALLBACK(parallel_begin);
@@ -1221,6 +1261,8 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
static void ompt_tsan_finalize(ompt_data_t *tool_data) {
if (archer_flags->ignore_serial)
TsanIgnoreWritesEnd();
+ if (archer_state == PAUSED || archer_state == ENDED)
+ TsanIgnoreWritesEnd();
if (archer_flags->print_max_rss) {
struct rusage end;
getrusage(RUSAGE_SELF, &end);
@@ -1238,6 +1280,7 @@ ompt_start_tool(unsigned int omp_version, const char *runtime_version) {
if (!archer_flags->enabled) {
if (archer_flags->verbose)
std::cout << "Archer disabled, stopping operation" << std::endl;
+ archer_state = ENDED;
delete archer_flags;
return NULL;
}
>From ccf97a6892ba56d5434f5e6cf65810821a193d6e Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Tue, 8 Apr 2025 09:51:46 +0200
Subject: [PATCH 2/9] [Archer] Make archer state thread local
---
openmp/tools/archer/ompt-tsan.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
index 0f7ed862d91c2..7a231a68d36f9 100644
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -603,7 +603,7 @@ static std::unordered_map<ompt_wait_id_t, std::mutex> Locks;
static std::mutex LocksMutex;
enum ArcherState { ACTIVE = 0, PAUSED, ENDED };
-static ArcherState archer_state{ACTIVE};
+static thread_local ArcherState archer_state{ACTIVE};
static int ompt_tsan_control_tool(uint64_t command, uint64_t modifier,
void *arg, const void *codeptr_ra) {
>From 3429780da9a879ae323df8339ebfb7833594abf2 Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Tue, 29 Apr 2025 15:33:11 +0200
Subject: [PATCH 3/9] [Archer] Add tests for omp_control_tool
---
.../tests/control-tool/skipped-access.c | 42 +++++++++++++++++
.../tests/control-tool/skipped-barrier.c | 44 ++++++++++++++++++
.../tests/control-tool/verbose-output.c | 46 +++++++++++++++++++
openmp/tools/archer/tests/lit.cfg | 6 +++
4 files changed, 138 insertions(+)
create mode 100644 openmp/tools/archer/tests/control-tool/skipped-access.c
create mode 100644 openmp/tools/archer/tests/control-tool/skipped-barrier.c
create mode 100644 openmp/tools/archer/tests/control-tool/verbose-output.c
diff --git a/openmp/tools/archer/tests/control-tool/skipped-access.c b/openmp/tools/archer/tests/control-tool/skipped-access.c
new file mode 100644
index 0000000000000..db386154e1fdb
--- /dev/null
+++ b/openmp/tools/archer/tests/control-tool/skipped-access.c
@@ -0,0 +1,42 @@
+/*
+ * barrier.c -- Archer testcase
+ */
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+//
+// See tools/archer/LICENSE.txt for details.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// RUN: %libarcher-compile-and-run-verbose | FileCheck %s
+// REQUIRES: tsan
+#include <omp.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ int var = 0;
+
+#pragma omp parallel num_threads(2) shared(var)
+ {
+ if (omp_get_thread_num() == 0) {
+ var++;
+ }
+
+ /* We miss the race due to Archer being paused */
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+ if (omp_get_thread_num() == 1) {
+ var++;
+ }
+ omp_control_tool(omp_control_tool_start, 0, NULL);
+ }
+
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: reported
+// CHECK: DONE
diff --git a/openmp/tools/archer/tests/control-tool/skipped-barrier.c b/openmp/tools/archer/tests/control-tool/skipped-barrier.c
new file mode 100644
index 0000000000000..f3b1d17b7cfec
--- /dev/null
+++ b/openmp/tools/archer/tests/control-tool/skipped-barrier.c
@@ -0,0 +1,44 @@
+/*
+ * barrier.c -- Archer testcase
+ */
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+//
+// See tools/archer/LICENSE.txt for details.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// RUN: %libarcher-compile-and-run-race-verbose | FileCheck %s
+// REQUIRES: tsan
+#include <omp.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ int var = 0;
+
+#pragma omp parallel num_threads(2) shared(var)
+ {
+ if (omp_get_thread_num() == 0) {
+ var++;
+ }
+
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+#pragma omp barrier
+ omp_control_tool(omp_control_tool_start, 0, NULL);
+
+ if (omp_get_thread_num() == 1) {
+ var++;
+ }
+ }
+
+ fprintf(stderr, "DONE\n");
+ int error = (var != 2);
+ return error;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: DONE
+// CHECK: ThreadSanitizer: reported {{[1]}} warnings
diff --git a/openmp/tools/archer/tests/control-tool/verbose-output.c b/openmp/tools/archer/tests/control-tool/verbose-output.c
new file mode 100644
index 0000000000000..8979118758bf4
--- /dev/null
+++ b/openmp/tools/archer/tests/control-tool/verbose-output.c
@@ -0,0 +1,46 @@
+/*
+ * verbose-output.c -- Archer testcase
+ */
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+//
+// See tools/archer/LICENSE.txt for details.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+
+// RUN: %libarcher-compile-and-run-verbose | FileCheck %s
+// REQUIRES: tsan
+#include <omp.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+
+#pragma omp parallel num_threads(1)
+{
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+// omp_control_tool(omp_control_tool_start, 0, NULL);
+// omp_control_tool(omp_control_tool_end, 0, NULL);
+}
+
+//#pragma omp parallel num_threads(2)
+//{
+// omp_control_tool(omp_control_tool_pause, 0, NULL);
+// omp_control_tool(omp_control_tool_start, 0, NULL);
+//}
+
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: reported
+// CHECK-NOT: Warning: please export TSAN_OPTIONS
+// CHECK: DONE
+// CHECK: [Archer] Paused operation
+// CHECK: [Archer] Started operation
+// CHECK: [Archer] Ended operation
+
diff --git a/openmp/tools/archer/tests/lit.cfg b/openmp/tools/archer/tests/lit.cfg
index f8fbcad752a4c..a4383ac759b0b 100644
--- a/openmp/tools/archer/tests/lit.cfg
+++ b/openmp/tools/archer/tests/lit.cfg
@@ -104,10 +104,16 @@ config.environment['ARCHER_OPTIONS'] = "report_data_leak=1"
config.substitutions.append(("%libarcher-compile-and-run-race-noserial", \
"%%libarcher-compile && env ARCHER_OPTIONS=\"ignore_serial=1 %s\" %%libarcher-run-race" \
% config.environment['ARCHER_OPTIONS']))
+config.substitutions.append(("%libarcher-compile-and-run-race-verbose", \
+ "%%libarcher-compile && env ARCHER_OPTIONS=\"verbose=1 %s\" %%libarcher-run-race" \
+ % config.environment['ARCHER_OPTIONS']))
config.substitutions.append(("%libarcher-compile-and-run-race", \
"%libarcher-compile && %libarcher-run-race"))
config.substitutions.append(("%libarcher-compile-and-run-nosuppression", \
"%libarcher-compile && %libarcher-run-nosuppression"))
+config.substitutions.append(("%libarcher-compile-and-run-verbose", \
+ "%%libarcher-compile && env ARCHER_OPTIONS=\"verbose=1 %s\" %%libarcher-run" \
+ % config.environment['ARCHER_OPTIONS']))
config.substitutions.append(("%libarcher-compile-and-run", \
"%libarcher-compile && %libarcher-run"))
config.substitutions.append(("%libarcher-cxx-compile-and-run", \
>From dd13584f1bef4dc4df030f2f3737bf9fce7c603c Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Wed, 30 Apr 2025 08:09:18 +0200
Subject: [PATCH 4/9] Fix mismatch between TsanIgnoreWritesBegin and End
---
openmp/tools/archer/ompt-tsan.cpp | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
index 7a231a68d36f9..f6897da0bddf9 100644
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -620,7 +620,7 @@ static int ompt_tsan_control_tool(uint64_t command, uint64_t modifier,
case omp_control_tool_pause:
if (archer_flags->verbose)
std::cout << "[Archer] Paused operation\n";
- if (archer_state != ENDED) {
+ if (archer_state == ACTIVE) {
TsanIgnoreWritesBegin();
archer_state = PAUSED;
}
@@ -628,11 +628,12 @@ static int ompt_tsan_control_tool(uint64_t command, uint64_t modifier,
case omp_control_tool_flush:
return omp_control_tool_ignored;
case omp_control_tool_end:
- archer_state = ENDED;
if (archer_flags->verbose) {
std::cout << "[Archer] Ended operation\n";
}
- TsanIgnoreWritesBegin();
+ if (archer_state == ACTIVE)
+ TsanIgnoreWritesBegin();
+ archer_state = ENDED;
return omp_control_tool_success;
default:
return omp_control_tool_ignored;
@@ -664,6 +665,8 @@ static void ompt_tsan_thread_end(ompt_data_t *thread_data) {
delete TaskDataPool::ThreadDataPool;
delete DependencyDataPool::ThreadDataPool;
TsanIgnoreWritesEnd();
+ if (archer_state != ACTIVE)
+ TsanIgnoreWritesEnd();
}
/// OMPT event callbacks for handling parallel regions.
@@ -1261,8 +1264,8 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
static void ompt_tsan_finalize(ompt_data_t *tool_data) {
if (archer_flags->ignore_serial)
TsanIgnoreWritesEnd();
- if (archer_state == PAUSED || archer_state == ENDED)
- TsanIgnoreWritesEnd();
+// if (archer_state == PAUSED || archer_state == ENDED)
+// TsanIgnoreWritesEnd();
if (archer_flags->print_max_rss) {
struct rusage end;
getrusage(RUSAGE_SELF, &end);
>From c4838773539c28a01d7cf22d7488467d77ac0716 Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Wed, 30 Apr 2025 09:35:12 +0200
Subject: [PATCH 5/9] [Archer] Ignore happens before/after if archer is
disabled
---
openmp/tools/archer/ompt-tsan.cpp | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
index f6897da0bddf9..d2563bc79874d 100644
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -53,6 +53,9 @@
static int hasReductionCallback;
+enum ArcherState { ACTIVE = 0, PAUSED, ENDED };
+static thread_local ArcherState archer_state{ACTIVE};
+
namespace {
class ArcherFlags {
public:
@@ -172,10 +175,18 @@ DECLARE_TSAN_FUNCTION(__tsan_func_exit)
// This marker is used to define a happens-before arc. The race detector will
// infer an arc from the begin to the end when they share the same pointer
// argument.
-#define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
+#define TsanHappensBefore(cv) \
+do { \
+ if (archer_state ==ACTIVE) \
+ AnnotateHappensBefore(__FILE__, __LINE__, cv); \
+} while(0)
// This marker defines the destination of a happens-before arc.
-#define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
+#define TsanHappensAfter(cv) \
+do { \
+ if (archer_state ==ACTIVE) \
+ AnnotateHappensAfter(__FILE__, __LINE__, cv); \
+} while(0)
// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
#define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
@@ -602,9 +613,6 @@ static inline TaskData *ToTaskData(ompt_data_t *task_data) {
static std::unordered_map<ompt_wait_id_t, std::mutex> Locks;
static std::mutex LocksMutex;
-enum ArcherState { ACTIVE = 0, PAUSED, ENDED };
-static thread_local ArcherState archer_state{ACTIVE};
-
static int ompt_tsan_control_tool(uint64_t command, uint64_t modifier,
void *arg, const void *codeptr_ra) {
omp_control_tool_result_t res = omp_control_tool_ignored;
>From b5e8b27d1a912c4ffe19c8c1e972f0e300f197c9 Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Wed, 30 Apr 2025 09:35:40 +0200
Subject: [PATCH 6/9] [Archer] More extensive tests for tool control
---
.../tests/control-tool/skipped-barrier.c | 2 +-
.../tests/control-tool/verbose-output.c | 26 +++++++++++++------
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/openmp/tools/archer/tests/control-tool/skipped-barrier.c b/openmp/tools/archer/tests/control-tool/skipped-barrier.c
index f3b1d17b7cfec..f2f6544a38c0b 100644
--- a/openmp/tools/archer/tests/control-tool/skipped-barrier.c
+++ b/openmp/tools/archer/tests/control-tool/skipped-barrier.c
@@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
}
fprintf(stderr, "DONE\n");
- int error = (var != 2);
+ int error = 1;
return error;
}
diff --git a/openmp/tools/archer/tests/control-tool/verbose-output.c b/openmp/tools/archer/tests/control-tool/verbose-output.c
index 8979118758bf4..9b1d8eb47948e 100644
--- a/openmp/tools/archer/tests/control-tool/verbose-output.c
+++ b/openmp/tools/archer/tests/control-tool/verbose-output.c
@@ -19,23 +19,33 @@
int main(int argc, char *argv[]) {
+#pragma omp parallel num_threads(2)
+{
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+ omp_control_tool(omp_control_tool_start, 0, NULL);
+}
+
+#pragma omp parallel num_threads(2)
+{
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+}
+
#pragma omp parallel num_threads(1)
{
omp_control_tool(omp_control_tool_pause, 0, NULL);
-// omp_control_tool(omp_control_tool_start, 0, NULL);
-// omp_control_tool(omp_control_tool_end, 0, NULL);
}
-//#pragma omp parallel num_threads(2)
-//{
-// omp_control_tool(omp_control_tool_pause, 0, NULL);
-// omp_control_tool(omp_control_tool_start, 0, NULL);
-//}
+#pragma omp parallel num_threads(2)
+{
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+ omp_control_tool(omp_control_tool_start, 0, NULL);
+ omp_control_tool(omp_control_tool_end, 0, NULL);
+}
fprintf(stderr, "DONE\n");
return 0;
}
-
+// CHECK-NOT: One of the following ignores was not ended
// CHECK-NOT: ThreadSanitizer: data race
// CHECK-NOT: ThreadSanitizer: reported
// CHECK-NOT: Warning: please export TSAN_OPTIONS
>From 7b2a6c6697911e95c1cb4447b3e32cabe40ccef0 Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Wed, 30 Apr 2025 09:36:36 +0200
Subject: [PATCH 7/9] [Archer] clang-format
---
openmp/tools/archer/ompt-tsan.cpp | 22 +++++-----
.../tools/archer/tests/control-tool/ended.c | 43 +++++++++++++++++++
.../tests/control-tool/skipped-access.c | 2 +-
.../tests/control-tool/skipped-barrier.c | 3 +-
.../tests/control-tool/verbose-output.c | 20 ++++-----
5 files changed, 64 insertions(+), 26 deletions(-)
create mode 100644 openmp/tools/archer/tests/control-tool/ended.c
diff --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
index d2563bc79874d..c08a1ec52b152 100644
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -175,18 +175,18 @@ DECLARE_TSAN_FUNCTION(__tsan_func_exit)
// This marker is used to define a happens-before arc. The race detector will
// infer an arc from the begin to the end when they share the same pointer
// argument.
-#define TsanHappensBefore(cv) \
-do { \
- if (archer_state ==ACTIVE) \
- AnnotateHappensBefore(__FILE__, __LINE__, cv); \
-} while(0)
+#define TsanHappensBefore(cv) \
+ do { \
+ if (archer_state == ACTIVE) \
+ AnnotateHappensBefore(__FILE__, __LINE__, cv); \
+ } while (0)
// This marker defines the destination of a happens-before arc.
-#define TsanHappensAfter(cv) \
-do { \
- if (archer_state ==ACTIVE) \
- AnnotateHappensAfter(__FILE__, __LINE__, cv); \
-} while(0)
+#define TsanHappensAfter(cv) \
+ do { \
+ if (archer_state == ACTIVE) \
+ AnnotateHappensAfter(__FILE__, __LINE__, cv); \
+ } while (0)
// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
#define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
@@ -1272,8 +1272,6 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
static void ompt_tsan_finalize(ompt_data_t *tool_data) {
if (archer_flags->ignore_serial)
TsanIgnoreWritesEnd();
-// if (archer_state == PAUSED || archer_state == ENDED)
-// TsanIgnoreWritesEnd();
if (archer_flags->print_max_rss) {
struct rusage end;
getrusage(RUSAGE_SELF, &end);
diff --git a/openmp/tools/archer/tests/control-tool/ended.c b/openmp/tools/archer/tests/control-tool/ended.c
new file mode 100644
index 0000000000000..1b49e0f119be3
--- /dev/null
+++ b/openmp/tools/archer/tests/control-tool/ended.c
@@ -0,0 +1,43 @@
+/*
+ * ended.c -- Archer testcase
+ */
+
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+//
+// See tools/archer/LICENSE.txt for details.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// RUN: %libarcher-compile-and-run-verbose | FileCheck %s
+// REQUIRES: tsan
+#include <omp.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ int var = 0;
+
+#pragma omp parallel
+ { omp_control_tool(omp_control_tool_end, 0, NULL); }
+
+#pragma omp parallel num_threads(2) shared(var)
+ {
+ if (omp_get_thread_num() == 0) {
+ var++;
+ }
+
+ /* We miss the race due to Archer being paused */
+ if (omp_get_thread_num() == 1) {
+ var++;
+ }
+ }
+
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: ThreadSanitizer: data race
+// CHECK-NOT: ThreadSanitizer: reported
+// CHECK: DONE
diff --git a/openmp/tools/archer/tests/control-tool/skipped-access.c b/openmp/tools/archer/tests/control-tool/skipped-access.c
index db386154e1fdb..5ac5a138d64c1 100644
--- a/openmp/tools/archer/tests/control-tool/skipped-access.c
+++ b/openmp/tools/archer/tests/control-tool/skipped-access.c
@@ -1,5 +1,5 @@
/*
- * barrier.c -- Archer testcase
+ * skipped-access.c -- Archer testcase
*/
//===----------------------------------------------------------------------===//
diff --git a/openmp/tools/archer/tests/control-tool/skipped-barrier.c b/openmp/tools/archer/tests/control-tool/skipped-barrier.c
index f2f6544a38c0b..626b450114a05 100644
--- a/openmp/tools/archer/tests/control-tool/skipped-barrier.c
+++ b/openmp/tools/archer/tests/control-tool/skipped-barrier.c
@@ -1,5 +1,5 @@
/*
- * barrier.c -- Archer testcase
+ * skipped-barrier.c -- Archer testcase
*/
//===----------------------------------------------------------------------===//
@@ -25,6 +25,7 @@ int main(int argc, char *argv[]) {
var++;
}
+ /* TSan detects a race as Archer does not see the barrier */
omp_control_tool(omp_control_tool_pause, 0, NULL);
#pragma omp barrier
omp_control_tool(omp_control_tool_start, 0, NULL);
diff --git a/openmp/tools/archer/tests/control-tool/verbose-output.c b/openmp/tools/archer/tests/control-tool/verbose-output.c
index 9b1d8eb47948e..bd73593e72e82 100644
--- a/openmp/tools/archer/tests/control-tool/verbose-output.c
+++ b/openmp/tools/archer/tests/control-tool/verbose-output.c
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-
// RUN: %libarcher-compile-and-run-verbose | FileCheck %s
// REQUIRES: tsan
#include <omp.h>
@@ -20,32 +19,30 @@
int main(int argc, char *argv[]) {
#pragma omp parallel num_threads(2)
-{
+ {
+ omp_control_tool(omp_control_tool_start, 0, NULL);
omp_control_tool(omp_control_tool_pause, 0, NULL);
omp_control_tool(omp_control_tool_start, 0, NULL);
-}
+ }
#pragma omp parallel num_threads(2)
-{
- omp_control_tool(omp_control_tool_pause, 0, NULL);
-}
+ { omp_control_tool(omp_control_tool_pause, 0, NULL); }
#pragma omp parallel num_threads(1)
-{
- omp_control_tool(omp_control_tool_pause, 0, NULL);
-}
+ { omp_control_tool(omp_control_tool_pause, 0, NULL); }
#pragma omp parallel num_threads(2)
-{
+ {
omp_control_tool(omp_control_tool_pause, 0, NULL);
omp_control_tool(omp_control_tool_start, 0, NULL);
omp_control_tool(omp_control_tool_end, 0, NULL);
-}
+ }
fprintf(stderr, "DONE\n");
return 0;
}
// CHECK-NOT: One of the following ignores was not ended
+// CHECK-NOT: finished with ignores enabled
// CHECK-NOT: ThreadSanitizer: data race
// CHECK-NOT: ThreadSanitizer: reported
// CHECK-NOT: Warning: please export TSAN_OPTIONS
@@ -53,4 +50,3 @@ int main(int argc, char *argv[]) {
// CHECK: [Archer] Paused operation
// CHECK: [Archer] Started operation
// CHECK: [Archer] Ended operation
-
>From 29f248ece35016f7292dff49733d30176d0ae9fd Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Wed, 30 Apr 2025 10:39:03 +0200
Subject: [PATCH 8/9] [Archer] Add info on omp_control_tool to readme
---
openmp/tools/archer/README.md | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/openmp/tools/archer/README.md b/openmp/tools/archer/README.md
index b52626116d0f9..6cd614a418994 100644
--- a/openmp/tools/archer/README.md
+++ b/openmp/tools/archer/README.md
@@ -230,6 +230,35 @@ the report will look as follow:
<a id="orgcc38a36"></a>
+## Pausing Analysis
+
+Archer's analysis may be paused, restarted or ended using OpenMP's
+omp_control_tool functionality with omp_control_tool_[pause|start|end].
+
+Suppose a parallel for loop shall not be considered by Archer:
+
+ 1 #include <stdio.h>
+ 2 #include <omp.h>
+ 3
+ 4 #define N 1000
+ 5
+ 6 int main (int argc, char **argv)
+ 7 {
+ 8 int a[N];
+ 9
+ 10 #pragma omp parallel
+ 11 {
+ 12 omp_control_tool(omp_control_tool_pause, 0, NULL);
+ 13 #pragma omp for
+ 14 for (int i = 0; i < N - 1; i++) {
+ 15 a[i] = a[i + 1];
+ 16 }
+ 17 omp_control_tool(omp_control_tool_start, 0, NULL);
+ 18 }
+ 19 }
+
+For more information on the usage of omp_control_tool, see the OpenMP specification.
+
# Contacts and Support
- [Google group](https://groups.google.com/forum/#!forum/archer-pruner)
>From 71e4b8eb8eaaed9c8e779e100816a3506378fb49 Mon Sep 17 00:00:00 2001
From: "felix.tomski" <tomski at itc.rwth-aachen.de>
Date: Wed, 30 Apr 2025 11:04:04 +0200
Subject: [PATCH 9/9] Add tasking constructs to control tool tests
---
.../tests/control-tool/verbose-output.c | 34 ++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/openmp/tools/archer/tests/control-tool/verbose-output.c b/openmp/tools/archer/tests/control-tool/verbose-output.c
index bd73593e72e82..528c83f840419 100644
--- a/openmp/tools/archer/tests/control-tool/verbose-output.c
+++ b/openmp/tools/archer/tests/control-tool/verbose-output.c
@@ -13,11 +13,41 @@
// RUN: %libarcher-compile-and-run-verbose | FileCheck %s
// REQUIRES: tsan
+#include "ompt/ompt-signal.h"
#include <omp.h>
#include <stdio.h>
-int main(int argc, char *argv[]) {
+void foo() {
+
+ int x = 0, y = 2, sem = 0;
+#pragma omp task depend(inout : x) shared(x, sem)
+ {
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+ OMPT_SIGNAL(sem);
+ x++; // 1st Child Task
+ }
+
+#pragma omp task shared(y, sem)
+ {
+ omp_control_tool(omp_control_tool_pause, 0, NULL);
+ OMPT_SIGNAL(sem);
+ y--; // 2nd child task
+ }
+
+ OMPT_WAIT(sem, 2);
+#pragma omp taskwait depend(in : x) // 1st taskwait
+
+ printf("x=%d\n", x);
+
+#pragma omp taskwait // 2nd taskwait
+
+ printf("y=%d\n", y);
+}
+
+int main(int argc, char *argv[]) {
+ /* Try out different OpenMP constructs to check whether Tsan IgnoreBegin/Ends
+ * are matched correctly */
#pragma omp parallel num_threads(2)
{
omp_control_tool(omp_control_tool_start, 0, NULL);
@@ -38,6 +68,8 @@ int main(int argc, char *argv[]) {
omp_control_tool(omp_control_tool_end, 0, NULL);
}
+ foo();
+
fprintf(stderr, "DONE\n");
return 0;
}
More information about the Openmp-commits
mailing list